--- /dev/null
+--- 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(®s);\
++ }\
++ 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) ®s->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(®s);
++}
++#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(®s);
++ 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(®s);
++ 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(®s);
++ 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, ®s, 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, ®s);
++ 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, ®s);
++ if ((!usethread || usethread == current) &&
++ hexToInt(&ptr, ®no) &&
++ *ptr++ == '=' && (regno >= 0)) {
++ regno =
++ (regno >= NUMREGS ? _GS : regno);
++ hex2mem(ptr, (char *) &gdb_regs[regno],
++ 4, 0);
++ gdb_regs_to_regs(gdb_regs, ®s);
++ 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(®s);
++ }
++ 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,÷_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(¤t->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(¤t->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(¤t->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 = ®ion->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(¤t->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(¤t->mm->mmap_sem);
++
++ if (error != N_TXTADDR(ex)) {
++ send_sig(SIGKILL, current, 0);
++ return error;
++ }
++
++ down_write(¤t->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(¤t->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(¤t->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(¤t->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 <linux/list.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <asm/semaphore.h>
++#include <asm/errno.h>
++
++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, &cache, list)
++ if (i->id == id) {
++ i->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(&obj->list);
++ kfree(obj);
++ cache_num--;
++}
++
++/* Must be holding cache_lock */
++static void __cache_add(struct object *obj)
++{
++ list_add(&obj->list, &cache);
++ if (++cache_num > MAX_CACHE_SIZE) {
++ struct object *i, *outcast = NULL;
++ list_for_each_entry(i, &cache, list) {
++ if (!outcast || i->popularity < outcast->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->name, name, sizeof(obj->name));
++ obj->id = id;
++ obj->popularity = 0;
++
++ down(&cache_lock);
++ __cache_add(obj);
++ up(&cache_lock);
++ return 0;
++}
++
++void cache_delete(int id)
++{
++ down(&cache_lock);
++ __cache_delete(__cache_find(id));
++ up(&cache_lock);
++}
++
++int cache_find(int id, char *name)
++{
++ struct object *obj;
++ int ret = -ENOENT;
++
++ down(&cache_lock);
++ obj = __cache_find(id);
++ if (obj) {
++ ret = 0;
++ strcpy(name, obj->name);
++ }
++ up(&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->id = id;
++ obj->popularity = 0;
++
++- down(&cache_lock);
+++ spin_lock_irqsave(&cache_lock, flags);
++ __cache_add(obj);
++- up(&cache_lock);
+++ spin_unlock_irqrestore(&cache_lock, flags);
++ return 0;
++ }
++
++ void cache_delete(int id)
++ {
++- down(&cache_lock);
+++ unsigned long flags;
+++
+++ spin_lock_irqsave(&cache_lock, flags);
++ __cache_delete(__cache_find(id));
++- up(&cache_lock);
+++ spin_unlock_irqrestore(&cache_lock, flags);
++ }
++
++ int cache_find(int id, char *name)
++ {
++ struct object *obj;
++ int ret = -ENOENT;
+++ unsigned long flags;
++
++- down(&cache_lock);
+++ spin_lock_irqsave(&cache_lock, flags);
++ obj = __cache_find(id);
++ if (obj) {
++ ret = 0;
++ strcpy(name, obj->name);
++ }
++- up(&cache_lock);
+++ spin_unlock_irqrestore(&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->refcnt == 0)
+++ kfree(obj);
+++}
+++
+++static void __object_get(struct object *obj)
+++{
+++ obj->refcnt++;
+++}
+++
+++void object_put(struct object *obj)
+++{
+++ unsigned long flags;
+++
+++ spin_lock_irqsave(&cache_lock, flags);
+++ __object_put(obj);
+++ spin_unlock_irqrestore(&cache_lock, flags);
+++}
+++
+++void object_get(struct object *obj)
+++{
+++ unsigned long flags;
+++
+++ spin_lock_irqsave(&cache_lock, flags);
+++ __object_get(obj);
+++ spin_unlock_irqrestore(&cache_lock, flags);
+++}
+++
++ /* Must be holding cache_lock */
++ static struct object *__cache_find(int id)
++ {
++@@ -35,6 +65,7 @@
++ {
++ BUG_ON(!obj);
++ list_del(&obj->list);
+++ __object_put(obj);
++ cache_num--;
++ }
++
++@@ -63,6 +94,7 @@
++ strlcpy(obj->name, name, sizeof(obj->name));
++ obj->id = id;
++ obj->popularity = 0;
+++ obj->refcnt = 1; /* The cache holds a reference */
++
++ spin_lock_irqsave(&cache_lock, flags);
++ __cache_add(obj);
++@@ -79,18 +111,15 @@
++ spin_unlock_irqrestore(&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(&cache_lock, flags);
++ obj = __cache_find(id);
++- if (obj) {
++- ret = 0;
++- strcpy(name, obj->name);
++- }
+++ if (obj)
+++ __object_get(obj);
++ spin_unlock_irqrestore(&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->refcnt == 0)
++- kfree(obj);
++-}
++-
++-static void __object_get(struct object *obj)
++-{
++- obj->refcnt++;
++-}
++-
++ void object_put(struct object *obj)
++ {
++- unsigned long flags;
++-
++- spin_lock_irqsave(&cache_lock, flags);
++- __object_put(obj);
++- spin_unlock_irqrestore(&cache_lock, flags);
+++ if (atomic_dec_and_test(&obj->refcnt))
+++ kfree(obj);
++ }
++
++ void object_get(struct object *obj)
++ {
++- unsigned long flags;
++-
++- spin_lock_irqsave(&cache_lock, flags);
++- __object_get(obj);
++- spin_unlock_irqrestore(&cache_lock, flags);
+++ atomic_inc(&obj->refcnt);
++ }
++
++ /* Must be holding cache_lock */
++@@ -65,7 +47,7 @@
++ {
++ BUG_ON(!obj);
++ list_del(&obj->list);
++- __object_put(obj);
+++ object_put(obj);
++ cache_num--;
++ }
++
++@@ -94,7 +76,7 @@
++ strlcpy(obj->name, name, sizeof(obj->name));
++ obj->id = id;
++ obj->popularity = 0;
++- obj->refcnt = 1; /* The cache holds a reference */
+++ atomic_set(&obj->refcnt, 1); /* The cache holds a reference */
++
++ spin_lock_irqsave(&cache_lock, flags);
++ __cache_add(obj);
++@@ -119,7 +101,7 @@
++ spin_lock_irqsave(&cache_lock, flags);
++ obj = __cache_find(id);
++ if (obj)
++- __object_get(obj);
+++ object_get(obj);
++ spin_unlock_irqrestore(&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->id = id;
++ obj->popularity = 0;
++ atomic_set(&obj->refcnt, 1); /* The cache holds a reference */
+++ spin_lock_init(&obj->lock);
++
++ spin_lock_irqsave(&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(&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->next;
++ del_timer(&list->timer);
++ kfree(list);
++ list = next;
++ }
++
++ spin_unlock_bh(&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->next = i->next;
+- i->next = new;
+- </programlisting>
++ retry:
++ spin_lock_bh(&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->next;
++ if (!del_timer(&list->timer)) {
++ /* Give timer a chance to delete this */
++ spin_unlock_bh(&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->next = i->next;
+- wmb();
+- i->next = new;
++ spin_unlock_bh(&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->next = list->next;
++ wmb();
++ list->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->next = old->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 <linux/list.h>
++ #include <linux/slab.h>
++ #include <linux/string.h>
+++#include <linux/rcupdate.h>
++ #include <asm/semaphore.h>
++ #include <asm/errno.h>
++
++ 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, &cache, list) {
+++ list_for_each_entry_rcu(i, &cache, list) {
++ if (i->id == id) {
++ i->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(&obj->list);
++- object_put(obj);
+++ list_del_rcu(&obj->list);
++ cache_num--;
+++ call_rcu(&obj->rcu, cache_delete_rcu, obj);
++ }
++
++ /* Must be holding cache_lock */
++ static void __cache_add(struct object *obj)
++ {
++- list_add(&obj->list, &cache);
+++ list_add_rcu(&obj->list, &cache);
++ if (++cache_num > MAX_CACHE_SIZE) {
++ struct object *i, *outcast = NULL;
++ list_for_each_entry(i, &cache, list) {
++@@ -85,6 +94,7 @@
++ obj->popularity = 0;
++ atomic_set(&obj->refcnt, 1); /* The cache holds a reference */
++ spin_lock_init(&obj->lock);
+++ INIT_RCU_HEAD(&obj->rcu);
++
++ spin_lock_irqsave(&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(&cache_lock, flags);
+++ rcu_read_lock();
++ obj = __cache_find(id);
++ if (obj)
++ object_get(obj);
++- spin_unlock_irqrestore(&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(&x->use, 1);
+- spin_lock_bh(&list_lock);
+- ... insert in list ...
+- spin_unlock_bh(&list_lock);
+- }
+-
+- struct foo *get_foo(int desc)
+- {
+- struct foo *ret;
+-
+- spin_lock_bh(&list_lock);
+- ... find in list ...
+- if (ret) atomic_inc(&ret->use);
+- spin_unlock_bh(&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(&x->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(&lock);
++ disable_irq(irq);
++ ...
++ enable_irq(irq);
++ spin_unlock(&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(&list_lock);
+- ... remove from list ...
+- spin_unlock_bh(&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(&list_lock);
+-
+- while (list) {
+- struct foo *next = list->next;
+- del_timer(&list->timer);
+- kfree(list);
+- list = next;
+- }
+-
+- spin_unlock_bh(&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(&list_lock);
+-
+- while (list) {
+- struct foo *next = list->next;
+- if (!del_timer(&list->timer)) {
+- /* Give timer a chance to delete this */
+- spin_unlock_bh(&list_lock);
+- goto retry;
+- }
+- kfree(list);
+- list = next;
+- }
+-
+- spin_unlock_bh(&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",
+- ®ion_obj->region.address_space->address_space, handler,
+- ACPI_HIDWORD (address), ACPI_LODWORD (address),
++ ®ion_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(ð1394_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(¶m, 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(¶m, 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(¶m, I8042_CMD_AUX_LOOP) || param != 0xa9)
+ return -1;
+- }
++ param = 0xa4;
++ if (i8042_command(¶m, 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(¶m, 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(¶m, I8042_CMD_MUX_PFX + i);
++ i8042_command(¶m, 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(¶m, I8042_CMD_AUX_LOOP) || param != 0x0f)
+- return -1;
+- param = 0x56;
+- if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != 0xa9)
+- return -1;
+- param = 0xa4;
+- if (i8042_command(¶m, 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(¶m, I8042_CMD_MUX_PFX + i);
+- i8042_command(¶m, 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(¶m, 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(¶m, 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(®s, 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, ®s, 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, ®);
++ pcmcia_access_configuration_register(link->handle, ®);
+ 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, ®);
++ pcmcia_access_configuration_register(link->handle, ®);
+ 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, ®);
++ pcmcia_access_configuration_register(link->handle, ®);
+ /* 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, ®);
++ pcmcia_access_configuration_register(link->handle, ®);
+ /* 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,
+- ®))) {
++ if ((err = pcmcia_access_configuration_register(link->handle, ®))) {
+ 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,
+- ®))) {
++ if ((err = pcmcia_access_configuration_register(link->handle, ®))) {
+ 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(¤t->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(¤t->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, ®);
++ last_ret = pcmcia_access_configuration_register(link->handle, ®);
++ if (last_ret) {
++ last_fn = AccessConfigurationRegister;
++ goto cs_failed;
++ }
+ reg.Action = CS_WRITE;
+ reg.Value = reg.Value | 1;
+- CS_CHECK(AccessConfigurationRegister, link->handle, ®);
++ last_ret = pcmcia_access_configuration_register(link->handle, ®);
++ 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(¤t->sighand->siglock);
+ siginitsetinv (¤t->blocked, sigmask(SIGHUP) | sigmask(SIGKILL) | sigmask(SIGSTOP) | sigmask(SIGCONT));
+ recalc_sigpending();
+ spin_unlock_irq(¤t->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(¤t->sighand->siglock);
++ flush_signal_handlers(current, 1);
++ sigemptyset(¤t->blocked);
++ recalc_sigpending();
++ spin_unlock_irq(¤t->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(¤t->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();