diff -Naur linux.2210/Makefile linux.2210.vw/Makefile --- linux.2210/Makefile Fri May 28 18:10:19 1999 +++ linux.2210.vw/Makefile Thu Jul 15 04:48:08 1999 @@ -18,7 +18,7 @@ HOSTCC =gcc HOSTCFLAGS =-Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -CROSS_COMPILE = +CROSS_COMPILE = AS =$(CROSS_COMPILE)as LD =$(CROSS_COMPILE)ld @@ -91,6 +91,11 @@ ifdef CONFIG_SMP CFLAGS += -D__SMP__ AFLAGS += -D__SMP__ +endif + +ifdef CONFIG_VISWS +CFLAGS += -DCONFIG_VISWS_HACKS +AFLAGS += -DCONFIG_VISWS_HACKS endif # diff -Naur linux.2210/arch/i386/config.in linux.2210.vw/arch/i386/config.in --- linux.2210/arch/i386/config.in Mon Apr 26 13:49:17 1999 +++ linux.2210.vw/arch/i386/config.in Thu Jul 15 04:48:08 1999 @@ -194,6 +194,8 @@ fi endmenu +source drivers/usb/Config.in + mainmenu_option next_comment comment 'Kernel hacking' diff -Naur linux.2210/arch/i386/kernel/bios32.c linux.2210.vw/arch/i386/kernel/bios32.c --- linux.2210/arch/i386/kernel/bios32.c Sat Apr 24 17:49:37 1999 +++ linux.2210.vw/arch/i386/kernel/bios32.c Thu Jul 15 04:48:08 1999 @@ -352,6 +352,7 @@ * * This should be close to trivial, but it isn't, because there are buggy * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID. + * XXX maybe Lithium is "buggy" this way as well? */ __initfunc(int pci_sanity_check(struct pci_access *a)) { @@ -1145,7 +1146,12 @@ pci_write_config_word(dev, PCI_COMMAND, cmd); } } -#if defined(CONFIG_X86_IO_APIC) +#if defined(CONFIG_X86_IO_APIC) || defined(CONFIG_X86_VISWS_APIC) +#ifdef CONFIG_X86_IO_APIC +#define PCI_IRQ(b,s,p) IO_APIC_get_PCI_irq_vector(b,s,p) +#elif CONFIG_X86_VISWS_APIC +#define PCI_IRQ(b,s,p) visws_get_PCI_irq_vector(b,s,p) +#endif /* * Recalculate IRQ numbers if we use the I/O APIC */ @@ -1157,13 +1163,14 @@ pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); if (pin) { pin--; /* interrupt pins are numbered starting from 1 */ - irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin); + irq = PCI_IRQ(dev->bus->number, + PCI_SLOT(dev->devfn), pin); if (irq < 0 && dev->bus->parent) { /* go back to the bridge */ struct pci_dev * bridge = dev->bus->self; pin = (pin + PCI_SLOT(dev->devfn)) % 4; - irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, - PCI_SLOT(bridge->devfn), pin); + irq = PCI_IRQ(bridge->bus->number, + PCI_SLOT(bridge->devfn), pin); if (irq >= 0) printk(KERN_WARNING "PCI: using PPB(B%d,I%d,P%d) to get irq %d\n", bridge->bus->number, PCI_SLOT(bridge->devfn), pin, irq); diff -Naur linux.2210/arch/i386/kernel/head.S linux.2210.vw/arch/i386/kernel/head.S --- linux.2210/arch/i386/kernel/head.S Thu Jan 14 22:57:25 1999 +++ linux.2210.vw/arch/i386/kernel/head.S Thu Jul 15 04:48:08 1999 @@ -40,6 +40,12 @@ ENTRY(stext) ENTRY(_stext) startup_32: +#ifdef CONFIG_VISWS_HACKS + movl $0x101000,%eax + movl %eax,%cr3 + lgdt gdt_descr + lidt idt_descr +#endif /* * Set segments to known values */ diff -Naur linux.2210/arch/i386/kernel/i386_ksyms.c linux.2210.vw/arch/i386/kernel/i386_ksyms.c --- linux.2210/arch/i386/kernel/i386_ksyms.c Mon May 10 10:32:45 1999 +++ linux.2210.vw/arch/i386/kernel/i386_ksyms.c Thu Jul 15 04:48:08 1999 @@ -115,3 +115,10 @@ #ifdef CONFIG_VT EXPORT_SYMBOL(screen_info); #endif + +#ifdef CONFIG_VISWS_HACKS +extern u_long sgivw_gfx_mem_phys; +extern u_long sgivw_gfx_mem_size; +EXPORT_SYMBOL(sgivw_gfx_mem_phys); +EXPORT_SYMBOL(sgivw_gfx_mem_size); +#endif diff -Naur linux.2210/arch/i386/kernel/io_apic.c linux.2210.vw/arch/i386/kernel/io_apic.c --- linux.2210/arch/i386/kernel/io_apic.c Thu May 6 16:07:03 1999 +++ linux.2210.vw/arch/i386/kernel/io_apic.c Thu Jul 15 04:48:08 1999 @@ -558,27 +558,6 @@ return 0; } -int irq_vector[NR_IRQS] = { IRQ0_TRAP_VECTOR , 0 }; - -static int __init assign_irq_vector(int irq) -{ - static int current_vector = IRQ0_TRAP_VECTOR, offset = 0; - if (IO_APIC_VECTOR(irq) > 0) - return IO_APIC_VECTOR(irq); - current_vector += 8; - if (current_vector > 0xFE) { - offset++; - current_vector = IRQ0_TRAP_VECTOR + offset; - printk("WARNING: ASSIGN_IRQ_VECTOR wrapped back to %02X\n", - current_vector); - } - if (current_vector == SYSCALL_VECTOR) - panic("ran out of interrupt sources!"); - - IO_APIC_VECTOR(irq) = current_vector; - return current_vector; -} - void __init setup_IO_APIC_irqs(void) { struct IO_APIC_route_entry entry; @@ -985,7 +964,7 @@ if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) { desc->status = status | IRQ_REPLAY; - send_IPI_self(IO_APIC_VECTOR(irq)); + send_IPI_self(IRQ_VECTOR(irq)); } } @@ -1175,7 +1154,7 @@ * 0x80, because int 0x80 is hm, kind of importantish. ;) */ for (i = 0; i < NR_IRQS ; i++) { - if (IO_APIC_VECTOR(i) > 0) { + if (IRQ_VECTOR(i) > 0) { if (IO_APIC_irq_trigger(i)) irq_desc[i].handler = &ioapic_level_irq_type; else @@ -1203,7 +1182,7 @@ irq_desc[i].handler = &no_irq_type; } } - init_IRQ_SMP(); + init_IRQ_MORE_TRAPS(); } /* diff -Naur linux.2210/arch/i386/kernel/irq.c linux.2210.vw/arch/i386/kernel/irq.c --- linux.2210/arch/i386/kernel/irq.c Mon May 10 10:32:45 1999 +++ linux.2210.vw/arch/i386/kernel/irq.c Thu Jul 15 04:48:08 1999 @@ -292,7 +292,7 @@ */ BUILD_16_IRQS(0x0) -#ifdef CONFIG_X86_IO_APIC +#if defined(CONFIG_X86_IO_APIC) || defined(CONFIG_X86_VISWS_APIC) /* * The IO-APIC gives us many more interrupt sources. Most of these * are unused but an SMP system is supposed to have enough memory ... @@ -348,7 +348,7 @@ static void (*interrupt[NR_IRQS])(void) = { IRQLIST_16(0x0), -#ifdef CONFIG_X86_IO_APIC +#if defined(CONFIG_X86_IO_APIC) || defined(CONFIG_X86_VISWS_APIC) IRQLIST_16(0x1), IRQLIST_16(0x2), IRQLIST_16(0x3), IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7), IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb), @@ -955,6 +955,11 @@ */ unsigned long probe_irq_on(void) { +#ifdef CONFIG_VISWS_HACKS +/* XXX current startup/shutdown_cobalt_irq() code + * XXX will break if we use it this way + */ +#else unsigned int i; unsigned long delay; @@ -993,7 +998,7 @@ } } spin_unlock_irq(&irq_controller_lock); - +#endif return 0x12345678; } @@ -1006,6 +1011,12 @@ nr_irqs = 0; irq_found = 0; +#ifdef CONFIG_VISWS_HACKS +/* XXX we _could_ look in the 8259 and if we see what we + * XXX know is IDEn we can here return the proper + * XXX cobalt-direct entry... hmmm + */ +#else spin_lock_irq(&irq_controller_lock); for (i=0; i 1) irq_found = -irq_found; +#endif return irq_found; } +#if defined(CONFIG_X86_IO_APIC) || defined(CONFIG_X86_VISWS_APIC) + +int irq_vector[NR_IRQS] = { IRQ0_TRAP_VECTOR , 0 }; + +int __init assign_irq_vector(int irq) +{ + static int current_vector = IRQ0_TRAP_VECTOR, offset = 0; + if (IRQ_VECTOR(irq) > 0) + return IRQ_VECTOR(irq); + current_vector += 8; + if (current_vector > 0xFE) { + offset++; + current_vector = IRQ0_TRAP_VECTOR + offset; + printk("WARNING: ASSIGN_IRQ_VECTOR wrapped back to %02X\n", + current_vector); + } + if (current_vector == SYSCALL_VECTOR) + panic("ran out of interrupt sources!"); + + IRQ_VECTOR(irq) = current_vector; + return current_vector; +} +#endif + void init_ISA_irqs (void) { int i; @@ -1055,11 +1091,6 @@ { int i; -#ifndef CONFIG_X86_VISWS_APIC - init_ISA_irqs(); -#else - init_VISWS_APIC_irqs(); -#endif /* * Cover the whole vector space, no vector can escape * us. (some of these will be overridden and become @@ -1071,11 +1102,17 @@ set_intr_gate(vector, interrupt[i]); } +#ifndef CONFIG_X86_VISWS_APIC + init_ISA_irqs(); +#else + init_VISWS_APIC_irqs(); +#endif + #ifdef __SMP__ /* IRQ0 must be given a fixed assignment and initialized - before init_IRQ_SMP. + before init_IRQ_MORE_TRAPS. */ set_intr_gate(IRQ0_TRAP_VECTOR, interrupt[0]); @@ -1117,13 +1154,52 @@ #endif } -#ifdef CONFIG_X86_IO_APIC -__initfunc(void init_IRQ_SMP(void)) +#if defined(CONFIG_X86_IO_APIC) || defined(CONFIG_X86_VISWS_APIC) +/* + * An IO-APIC PC has more traps if SMP. + * The Visual Workstation always has more traps (whether SMP or not). + */ +__initfunc(void init_IRQ_MORE_TRAPS(void)) { int i; for (i = 0; i < NR_IRQS ; i++) - if (IO_APIC_VECTOR(i) > 0) - set_intr_gate(IO_APIC_VECTOR(i), interrupt[i]); + if (IRQ_VECTOR(i) > 0) + set_intr_gate(IRQ_VECTOR(i), interrupt[i]); } -#endif +/* + * Visual Workstation always uses the cpu/local APICs for interrupts. + * IO-APIC PCs use this only when SMP + */ +void __init enable_local_APIC(void) +{ + unsigned long value; + + value = apic_read(APIC_SPIV); + value |= (1<<8); /* Enable APIC (bit==1) */ + value &= ~(1<<9); /* Enable focus processor (bit==0) */ + value |= 0xff; /* Set spurious IRQ vector to 0xff */ + apic_write(APIC_SPIV,value); + + /* + * Set Task Priority to 'accept all' + */ + value = apic_read(APIC_TASKPRI); + value &= ~APIC_TPRI_MASK; + apic_write(APIC_TASKPRI,value); + + /* + * Clear the logical destination ID, just to be safe. + * also, put the APIC into flat delivery mode. + */ + value = apic_read(APIC_LDR); + value &= ~APIC_LDR_MASK; + apic_write(APIC_LDR,value); + + value = apic_read(APIC_DFR); + value |= SET_APIC_DFR(0xf); + apic_write(APIC_DFR, value); + + udelay(100); /* B safe */ +} +#endif diff -Naur linux.2210/arch/i386/kernel/irq.h linux.2210.vw/arch/i386/kernel/irq.h --- linux.2210/arch/i386/kernel/irq.h Tue May 11 10:37:06 1999 +++ linux.2210.vw/arch/i386/kernel/irq.h Thu Jul 15 05:05:47 1999 @@ -79,9 +79,10 @@ extern irq_desc_t irq_desc[NR_IRQS]; extern int irq_vector[NR_IRQS]; -#define IO_APIC_VECTOR(irq) irq_vector[irq] +#define IRQ_VECTOR(irq) irq_vector[irq] -extern void init_IRQ_SMP(void); +extern int assign_irq_vector(int irq); +extern void init_IRQ_MORE_TRAPS(void); extern int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *); extern int setup_x86_irq(unsigned int, struct irqaction *); @@ -102,6 +103,7 @@ extern void init_VISWS_APIC_irqs(void); extern void setup_IO_APIC(void); extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn); +extern int visws_get_PCI_irq_vector(int bus, int slot, int fn); extern void make_8259A_irq(unsigned int irq); extern void send_IPI(int dest, int vector); extern void init_pic_mode(void); diff -Naur linux.2210/arch/i386/kernel/process.c linux.2210.vw/arch/i386/kernel/process.c --- linux.2210/arch/i386/kernel/process.c Fri Apr 30 08:13:37 1999 +++ linux.2210.vw/arch/i386/kernel/process.c Thu Jul 15 04:48:08 1999 @@ -168,6 +168,57 @@ return 0; } +#ifdef CONFIG_VISWS + +#include +#include + +static void +visws_restart(void) +{ + /* + * This machine resets by poking this + * register on PIIX4. + */ + outb(PIIX4_RESET_VAL, PIIX4_RESET_PORT); +} + +static void +visws_power_off(void) +{ + unsigned short pm_status; + + /* + * Clearing the event before the button is released seems to + * re-enable it, thus preventing shutdown. + */ + while ((pm_status = inw(PMSTS_PORT)) & 0x100) { + outw(pm_status, PMSTS_PORT); + } + + /* + * Here's the magic write that actually sequences + * the PIIX4 to shutdown the power. + */ + outw(PM_SUSPEND_ENABLE, PMCNTRL_PORT); + + /* + * Need 10msec delay before generating special + * cycle so PIIX4 will shut down system. + */ + udelay(10000); + + /* + * PIIX4 has asserted stopclk and is waiting to see + * the stop special cycle. Generate one of those + * by hand now. + */ + pcibios_write_config_dword(PIIX4_BUS, SPECIAL_DEV, SPECIAL_REG, + PIIX_SPECIAL_STOP); +} +#endif /* CONFIG_VISWS */ + + /* * This routine reboots the machine by asking the keyboard * controller to pulse the reset-line low. We try that for a while, @@ -279,6 +330,10 @@ init_pic_mode(); #endif +#ifdef CONFIG_VISWS + visws_restart(); +#endif /* CONFIG_VISWS */ + if(!reboot_thru_bios) { /* rebooting needs to touch the page at absolute addr 0 */ *((unsigned short *)__va(0x472)) = reboot_mode; @@ -386,6 +441,9 @@ void machine_power_off(void) { +#ifdef CONFIG_VISWS + visws_power_off(); +#endif /* CONFIG_VISWS */ #if defined(CONFIG_APM) && defined(CONFIG_APM_POWER_OFF) apm_power_off(); #endif diff -Naur linux.2210/arch/i386/kernel/setup.c linux.2210.vw/arch/i386/kernel/setup.c --- linux.2210/arch/i386/kernel/setup.c Tue Jun 8 10:43:21 1999 +++ linux.2210.vw/arch/i386/kernel/setup.c Thu Jul 15 04:52:54 1999 @@ -47,8 +47,11 @@ #include #include #include -#include #include +#ifdef CONFIG_VISWS +#include +#include +#endif /* * Machine setup.. @@ -123,54 +126,17 @@ char visws_board_type = -1; char visws_board_rev = -1; -#define PIIX_PM_START 0x0F80 - -#define SIO_GPIO_START 0x0FC0 - -#define SIO_PM_START 0x0FC8 - -#define PMBASE PIIX_PM_START -#define GPIREG0 (PMBASE+0x30) -#define GPIREG(x) (GPIREG0+((x)/8)) -#define PIIX_GPI_BD_ID1 18 -#define PIIX_GPI_BD_REG GPIREG(PIIX_GPI_BD_ID1) - -#define PIIX_GPI_BD_SHIFT (PIIX_GPI_BD_ID1 % 8) - -#define SIO_INDEX 0x2e -#define SIO_DATA 0x2f - -#define SIO_DEV_SEL 0x7 -#define SIO_DEV_ENB 0x30 -#define SIO_DEV_MSB 0x60 -#define SIO_DEV_LSB 0x61 - -#define SIO_GP_DEV 0x7 - -#define SIO_GP_BASE SIO_GPIO_START -#define SIO_GP_MSB (SIO_GP_BASE>>8) -#define SIO_GP_LSB (SIO_GP_BASE&0xff) - -#define SIO_GP_DATA1 (SIO_GP_BASE+0) - -#define SIO_PM_DEV 0x8 - -#define SIO_PM_BASE SIO_PM_START -#define SIO_PM_MSB (SIO_PM_BASE>>8) -#define SIO_PM_LSB (SIO_PM_BASE&0xff) -#define SIO_PM_INDEX (SIO_PM_BASE+0) -#define SIO_PM_DATA (SIO_PM_BASE+1) - -#define SIO_PM_FER2 0x1 - -#define SIO_PM_GP_EN 0x80 +#ifdef CONFIG_VISWS_HACKS +u_long sgivw_gfx_mem_phys = 0; +u_long sgivw_gfx_mem_size = -1; +#endif static void visws_get_board_type_and_rev(void) { int raw; - visws_board_type = (char)(inb_p(PIIX_GPI_BD_REG) & PIIX_GPI_BD_REG) + visws_board_type = (char)(inb_p(PIIX_GPI_BD_REG) & PIIX_GPI_BD_MASK) >> PIIX_GPI_BD_SHIFT; /* * Get Board rev. @@ -222,29 +188,31 @@ raw = inb_p(SIO_GP_DATA1); raw &= 0x7f; /* 7 bits of valid board revision ID. */ - if (visws_board_type == VISWS_320) { + switch (visws_board_type) { + case VISWS_320: if (raw < 0x6) { visws_board_rev = 4; } else if (raw < 0xc) { visws_board_rev = 5; } else { visws_board_rev = 6; - } - } else if (visws_board_type == VISWS_540) { - visws_board_rev = 2; - } else { - visws_board_rev = raw; - } - - printk("Silicon Graphics %s (rev %d)\n", - visws_board_type == VISWS_320 ? "320" : - (visws_board_type == VISWS_540 ? "540" : - "unknown"), - visws_board_rev); + break; + case VISWS_540: + visws_board_rev = 2; + break; + default: + visws_board_rev = raw; + break; } -#endif + printk("Silicon Graphics %s (rev %d)\n", + visws_board_type == VISWS_320 ? "320" : + (visws_board_type == VISWS_540 ? "540" : + "unknown"), + visws_board_rev); +} +#endif static char command_line[COMMAND_LINE_SIZE] = { 0, }; char saved_command_line[COMMAND_LINE_SIZE]; @@ -257,9 +225,19 @@ int len = 0; #ifdef CONFIG_VISWS + /* + * Excecpt for COMMAND_LINE nothing presently (July 15, 1999) fills + * out the PARAM block on a Visual Workstation. We'll make this + * explicit by skipping any code that looks in there. + */ visws_get_board_type_and_rev(); -#endif +#define MEGS 128 /* XXX HACK how to get mem config? */ + /* XXX 128 will always work... smallest mem size */ + printk("VISWS HACK: hard-wiring physical mem size to %dMb\n", MEGS); + memory_end = MEGS<<20; /* Happens to be PAGE_MASK safe */ + +#else /* !CONFIG_VISWS */ ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV); drive_info = DRIVE_INFO; screen_info = SCREEN_INFO; @@ -284,6 +262,8 @@ #endif memory_end &= PAGE_MASK; + + #ifdef CONFIG_BLK_DEV_RAM rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK; rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0); @@ -291,6 +271,7 @@ #endif if (!MOUNT_ROOT_RDONLY) root_mountflags &= ~MS_RDONLY; +#endif memory_start = (unsigned long) &_end; init_task.mm->start_code = PAGE_OFFSET; init_task.mm->end_code = (unsigned long) &_etext; @@ -323,6 +304,23 @@ } } } +#ifdef CONFIG_VISWS_HACKS + /* + * "gfxmem=XXX[kKmM]" overrides the default + * graphics memory size + */ + if (c == ' ' && !memcmp(from,"gfxmem=",7)) { + if (to != command_line) to--; + sgivw_gfx_mem_size = simple_strtoul(from+7, &from, 0); + if ( *from == 'K' || *from == 'k' ) { + sgivw_gfx_mem_size <<= 10; + from++; + } else if ( *from == 'M' || *from == 'm' ) { + sgivw_gfx_mem_size <<= 20; + from++; + } + } +#endif c = *(from++); if (!c) break; @@ -333,6 +331,28 @@ *to = '\0'; *cmdline_p = command_line; +#ifdef CONFIG_VISWS_HACKS + #define VISWS_GFX_MEM_MEGS 16 + if (sgivw_gfx_mem_size == -1) + sgivw_gfx_mem_size = VISWS_GFX_MEM_MEGS<<20; + /* truncate gfxmem size down to nearest megabyte */ + sgivw_gfx_mem_size &= ~((1<<20)-1); + memory_end -= sgivw_gfx_mem_size; + printk("VISWS HACK: taking %ldMb for gfx memory -- leaving %ldMb for kernel\n", + sgivw_gfx_mem_size>>20, memory_end>>20); + sgivw_gfx_mem_phys = memory_end; + printk("sgivw_gfx_mem_phys %lx\n", sgivw_gfx_mem_phys); +#endif + +#ifdef CONFIG_VISWS + /* + * Using 'hlt' in cpu_idle() on a Visual Workstation can tickle + * a h/w bug in memory refresh that can spontaneously reset + * or even power-off the system. + */ + boot_cpu_data.hlt_works_ok = 0; +#endif + #define VMALLOC_RESERVE (64 << 20) /* 64MB for vmalloc */ #define MAXMEM ((unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE)) @@ -375,12 +395,13 @@ request_region(0xf0,0x10,"fpu"); #ifdef CONFIG_VT -#if defined(CONFIG_VGA_CONSOLE) +#if defined(CONFIG_VGA_CONSOLE) && !defined(CONFIG_VISWS) conswitchp = &vga_con; #elif defined(CONFIG_DUMMY_CONSOLE) conswitchp = &dummy_con; #endif #endif + /* * Check the bugs that will bite us before we get booting */ diff -Naur linux.2210/arch/i386/kernel/smp.c linux.2210.vw/arch/i386/kernel/smp.c --- linux.2210/arch/i386/kernel/smp.c Wed Jun 2 11:29:27 1999 +++ linux.2210.vw/arch/i386/kernel/smp.c Thu Jul 15 04:48:08 1999 @@ -716,37 +716,6 @@ atomic_set(&smp_commenced,1); } -void __init enable_local_APIC(void) -{ - unsigned long value; - - value = apic_read(APIC_SPIV); - value |= (1<<8); /* Enable APIC (bit==1) */ - value &= ~(1<<9); /* Enable focus processor (bit==0) */ - value |= 0xff; /* Set spurious IRQ vector to 0xff */ - apic_write(APIC_SPIV,value); - - /* - * Set Task Priority to 'accept all' - */ - value = apic_read(APIC_TASKPRI); - value &= ~APIC_TPRI_MASK; - apic_write(APIC_TASKPRI,value); - - /* - * Clear the logical destination ID, just to be safe. - * also, put the APIC into flat delivery mode. - */ - value = apic_read(APIC_LDR); - value &= ~APIC_LDR_MASK; - apic_write(APIC_LDR,value); - - value = apic_read(APIC_DFR); - value |= SET_APIC_DFR(0xf); - apic_write(APIC_DFR, value); - - udelay(100); /* B safe */ -} unsigned long __init init_smp_mappings(unsigned long memory_start) { diff -Naur linux.2210/arch/i386/kernel/time.c linux.2210.vw/arch/i386/kernel/time.c --- linux.2210/arch/i386/kernel/time.c Thu Apr 29 11:53:41 1999 +++ linux.2210.vw/arch/i386/kernel/time.c Thu Jul 15 04:48:08 1999 @@ -54,7 +54,7 @@ #include #include -#include +#include /* * for x86_do_profile() @@ -680,9 +680,6 @@ /* Enable (unmask) the timer interrupt */ co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) & ~CO_CTRL_TIMEMASK); - /* Wire cpu IDT entry to s/w handler (and Cobalt APIC to IDT) */ - setup_x86_irq(CO_IRQ_TIMER, &irq0); -#else - setup_x86_irq(0, &irq0); #endif + setup_x86_irq(0, &irq0); } diff -Naur linux.2210/arch/i386/kernel/trampoline.S linux.2210.vw/arch/i386/kernel/trampoline.S --- linux.2210/arch/i386/kernel/trampoline.S Wed May 6 11:42:54 1998 +++ linux.2210.vw/arch/i386/kernel/trampoline.S Thu Jul 15 04:48:08 1999 @@ -54,8 +54,13 @@ lmsw %ax # into protected mode jmp flush_instr flush_instr: +#ifdef CONFIG_VISWS_HACKS + ljmpl $__KERNEL_CS, $0x00100016 + # jump to startup_32 + 0x16 +#else ljmpl $__KERNEL_CS, $0x00100000 # jump to startup_32 +#endif idt_48: .word 0 # idt limit = 0 diff -Naur linux.2210/arch/i386/kernel/traps.c linux.2210.vw/arch/i386/kernel/traps.c --- linux.2210/arch/i386/kernel/traps.c Tue Feb 16 14:20:05 1999 +++ linux.2210.vw/arch/i386/kernel/traps.c Thu Jul 15 04:48:08 1999 @@ -38,8 +38,8 @@ #ifdef CONFIG_X86_VISWS_APIC #include -#include -#include +#include +#include #endif #include "irq.h" @@ -579,57 +579,6 @@ } #ifdef CONFIG_X86_VISWS_APIC - -/* - * On Rev 005 motherboards legacy device interrupt lines are wired directly - * to Lithium from the 307. But the PROM leaves the interrupt type of each - * 307 logical device set appropriate for the 8259. Later we'll actually use - * the 8259, but for now we have to flip the interrupt types to - * level triggered, active lo as required by Lithium. - */ - -#define REG 0x2e /* The register to read/write */ -#define DEV 0x07 /* Register: Logical device select */ -#define VAL 0x2f /* The value to read/write */ - -static void -superio_outb(int dev, int reg, int val) -{ - outb(DEV, REG); - outb(dev, VAL); - outb(reg, REG); - outb(val, VAL); -} - -static int __attribute__ ((unused)) -superio_inb(int dev, int reg) -{ - outb(DEV, REG); - outb(dev, VAL); - outb(reg, REG); - return inb(VAL); -} - -#define FLOP 3 /* floppy logical device */ -#define PPORT 4 /* parallel logical device */ -#define UART5 5 /* uart2 logical device (not wired up) */ -#define UART6 6 /* uart1 logical device (THIS is the serial port!) */ -#define IDEST 0x70 /* int. destination (which 307 IRQ line) reg. */ -#define ITYPE 0x71 /* interrupt type register */ - -/* interrupt type bits */ -#define LEVEL 0x01 /* bit 0, 0 == edge triggered */ -#define ACTHI 0x02 /* bit 1, 0 == active lo */ - -static void -superio_init(void) -{ - if (visws_board_type == VISWS_320 && visws_board_rev == 5) { - superio_outb(UART6, IDEST, 0); /* 0 means no intr propagated */ - printk("SGI 320 rev 5: disabling 307 uart1 interrupt\n"); - } -} - static void lithium_init(void) { @@ -640,22 +589,33 @@ printk("Lithium PCI Bridge B (PIIX4), Bus Number: %d\n", li_pcib_read16(LI_PCI_BUSNUM) & 0xff); - /* XXX blindly enables all interrupts */ - li_pcia_write16(LI_PCI_INTEN, 0xffff); - li_pcib_write16(LI_PCI_INTEN, 0xffff); + /* XXX blindly enables all device interrupts */ + /* XXX even more blindly does not enable any error interrupts */ + /* NOTE: Lithium error interrupts share LI_INTD */ +#define A01234 (LI_INTA_0|LI_INTA_1|LI_INTA_2|LI_INTA_3|LI_INTA_4) +#define BCD (LI_INTB|LI_INTC|LI_INTD) +#define ALLDEVS (A01234|BCD) + li_pcia_write16(LI_PCI_INTEN, ALLDEVS); + li_pcib_write16(LI_PCI_INTEN, ALLDEVS); } static void cobalt_init(void) { /* - * On normal SMP PC this is used only with SMP, but we have to - * use it and set it up here to start the Cobalt clock + * On normal SMP PC the local APIC is used only with SMP. + * On Visual Workstations all interrupts always go through + * the local APIC including the clock which is why we have + * initialize and enable the local APIC so early. */ set_fixmap(FIX_APIC_BASE, APIC_PHYS_BASE); + enable_local_APIC(); printk("Local APIC ID %lx\n", apic_read(APIC_ID)); printk("Local APIC Version %lx\n", apic_read(APIC_VERSION)); + /* + * And, now we go out to the Cobalt APIC and enable it. + */ set_fixmap(FIX_CO_CPU, CO_CPU_PHYS); printk("Cobalt Revision %lx\n", co_cpu_read(CO_CPU_REV)); @@ -702,7 +662,6 @@ load_TR(0); load_ldt(0); #ifdef CONFIG_X86_VISWS_APIC - superio_init(); lithium_init(); cobalt_init(); #endif diff -Naur linux.2210/arch/i386/kernel/visws_apic.c linux.2210.vw/arch/i386/kernel/visws_apic.c --- linux.2210/arch/i386/kernel/visws_apic.c Thu May 6 16:12:23 1999 +++ linux.2210.vw/arch/i386/kernel/visws_apic.c Thu Jul 15 04:48:08 1999 @@ -36,10 +36,18 @@ #include #include -#include +#include #include "irq.h" +#define LEGACY_IRQS +#define SERIAL_HACK + +#ifndef CONFIG_SMP +int skip_ioapic_setup; /* No IO-APIC to ever skip on Cobalt! */ +#endif + +#ifdef LEGACY_IRQS /* * This is the PIIX4-based 8259 that is wired up indirectly to Cobalt * -- not the manner expected by the normal 8259 code in irq.c. @@ -51,8 +59,6 @@ * controller. Device drivers only see the virtual interrupt sources. */ -#define CO_IRQ_BASE 0x20 /* This is the 0x20 in init_IRQ()! */ - static void startup_piix4_master_irq(unsigned int irq); static void shutdown_piix4_master_irq(unsigned int irq); static void do_piix4_master_IRQ(unsigned int irq, struct pt_regs * regs); @@ -81,6 +87,7 @@ enable_piix4_virtual_irq, disable_piix4_virtual_irq }; +#endif /* * This is the SGI Cobalt (IO-)APIC: @@ -90,7 +97,7 @@ static void enable_cobalt_irq(unsigned int irq); static void disable_cobalt_irq(unsigned int irq); static void startup_cobalt_irq(unsigned int irq); -#define shutdown_cobalt_irq disable_cobalt_irq +static void shutdown_cobalt_irq(unsigned int irq); static struct hw_interrupt_type cobalt_irq_type = { "Cobalt-APIC", @@ -112,32 +119,74 @@ /* * Cobalt (IO)-APIC functions to handle PCI devices. + * + * Correctness and clarity are prioritized over performance. */ -static void disable_cobalt_irq(unsigned int irq) +/* + * Returns Cobalt APIC entry for this irq + * + * 'irq' MUST be a cobalt-direct interrupt. something's coded very wrong + * if we get here with a piix4-8259 irq + * + * Note: here we know that the ide driver defaults IDE{0,1} to IRQ 1{4,5}! + * A drag, because we need to check/map these aliases/warts in IRQ number space. + * (Ideally we'd rather give IDEx CO_IRQ(CO_APIC_IDEx), but there's no great way + * to implement probe_irq_on/off) + */ +static int is_co_apic(unsigned int irq) { - /* XXX undo the APIC entry here? */ + if (IS_CO_APIC(irq)) { + return CO_APIC(irq); + } + /* Here are those yucky aliases that wreak havoc on beauty */ + switch (irq) { + case 0: return CO_APIC_CPU; + case CO_IRQ_IDE0: return CO_APIC_IDE0; + case CO_IRQ_IDE1: return CO_APIC_IDE1; + default: return -1; + } + /* NOTREACHED */ +} - /* - * definitely, we do not want to have IRQ storms from - * unused devices --mingo - */ +/* XXX ouch... is this really our only choice for masking this interrupt? */ +/* XXX not fully safe for 2 reasons: + * 1) should not touch an apic entry while (whole) apic is enabled + * 2) careful about storing to IRR bit (unless we know this intr is idle) + */ +static void disable_cobalt_irq(unsigned int irq) /* disable_irq() */ +{ + int ent = is_co_apic(irq); + if (ent == -1) { + return; /* could actually be a panic */ + } + + /* Note: h/w nada like read-mod-write! Vec saved in IRQ_VECTOR() */ + co_apic_write(CO_APIC_LO(ent), CO_APIC_MASK); + (void)co_apic_read(CO_APIC_LO(ent)); /* sync cpu to cobalt apic */ } -static void enable_cobalt_irq(unsigned int irq) +static void enable_cobalt_irq(unsigned int irq) /* enable_irq() */ { + int ent = is_co_apic(irq); + if (ent == -1) { + return; /* ALL irqs use do_cobalt_IRQ() which calls here */ + } + + /* Note: this clears the CO_APIC_MASK bit, and assumes _HI okay */ + co_apic_write(CO_APIC_LO(ent), CO_APIC_LEVEL|IRQ_VECTOR(irq)); } /* * Set the given Cobalt APIC Redirection Table entry to point * to the given IDT vector/index. */ -static void co_apic_set(int entry, int idtvec) +static void co_apic_set(int entry, int irq) { - co_apic_write(CO_APIC_LO(entry), CO_APIC_LEVEL | (CO_IRQ_BASE+idtvec)); + printk("IRQ %d, Cobalt APIC Entry %d, IDT Vector %x: enabling\n", + irq, entry, IRQ_VECTOR(irq)); + co_apic_write(CO_APIC_LO(entry), CO_APIC_LEVEL|IRQ_VECTOR(irq)); co_apic_write(CO_APIC_HI(entry), 0); - - printk("Cobalt APIC Entry %d IDT Vector %d\n", entry, idtvec); } /* @@ -145,48 +194,39 @@ * map this to the Cobalt APIC entry where it's physically wired. * This is called via request_irq -> setup_x86_irq -> irq_desc->startup() */ -static void startup_cobalt_irq(unsigned int irq) +static void startup_cobalt_irq(unsigned int irq) /* request_irq() */ { + int ent; /* - * These "irq"'s are wired to the same Cobalt APIC entries - * for all (known) motherboard types/revs + * Protect this code from probe_irq_on/off() */ - switch (irq) { - case CO_IRQ_TIMER: co_apic_set(CO_APIC_CPU, CO_IRQ_TIMER); - return; + if (irq_desc[irq].status & IRQ_AUTODETECT) { + return; + } - case CO_IRQ_ENET: co_apic_set(CO_APIC_ENET, CO_IRQ_ENET); - return; +#ifdef SERIAL_HACK + if (irq == 4) { /* XXX terrible hack for serial interrupt prob */ + return; /* XXX fixed on factory h/w? */ + } +#endif + ent = is_co_apic(irq); + if (ent == -1) { + return; /* Could very well be a panic */ + } - case CO_IRQ_SERIAL: return; /* XXX move to piix4-8259 "virtual" */ + co_apic_set(ent, irq); +} - case CO_IRQ_8259: co_apic_set(CO_APIC_8259, CO_IRQ_8259); - return; - - case CO_IRQ_IDE: - switch (visws_board_type) { - case VISWS_320: - switch (visws_board_rev) { - case 5: - co_apic_set(CO_APIC_0_5_IDE0, CO_IRQ_IDE); - co_apic_set(CO_APIC_0_5_IDE1, CO_IRQ_IDE); - return; - case 6: - co_apic_set(CO_APIC_0_6_IDE0, CO_IRQ_IDE); - co_apic_set(CO_APIC_0_6_IDE1, CO_IRQ_IDE); - return; - } - case VISWS_540: - switch (visws_board_rev) { - case 2: - co_apic_set(CO_APIC_1_2_IDE0, CO_IRQ_IDE); - return; - } - } - break; - default: - panic("huh?"); +static void shutdown_cobalt_irq(unsigned int irq) /* free_irq() */ +{ +#ifdef SERIAL_HACK + if (irq == 4) { /* XXX terrible hack for serial interrupt prob */ + return; /* XXX fixed on factory h/w? */ } +#endif + printk("IRQ %d, Cobalt APIC Entry %d, IDT Vector %x: masking\n", + irq, is_co_apic(irq), IRQ_VECTOR(irq)); + disable_cobalt_irq(irq); } /* @@ -200,7 +240,8 @@ spin_lock(&irq_controller_lock); { unsigned int status; - /* XXX APIC EOI? */ + disable_cobalt_irq(irq); + apic_write(APIC_EOI, APIC_EIO_ACK); status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING); action = NULL; if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) { @@ -217,9 +258,6 @@ handle_IRQ_event(irq, regs, action); - (void)co_cpu_read(CO_CPU_REV); /* Sync driver ack to its h/w */ - apic_write(APIC_EOI, APIC_EIO_ACK); /* Send EOI to Cobalt APIC */ - spin_lock(&irq_controller_lock); { unsigned int status = desc->status & ~IRQ_INPROGRESS; @@ -230,13 +268,15 @@ spin_unlock(&irq_controller_lock); } +#ifdef LEGACY_IRQS /* * PIIX4-8259 master/virtual functions to handle: * * floppy * parallel * serial - * audio (?) + * [ps2 kbd] + * [ps2 mouse] * * None of these get Cobalt APIC entries, neither do they have IDT * entries. These interrupts are purely virtual and distributed from @@ -252,6 +292,8 @@ static void startup_piix4_master_irq(unsigned int irq) { + /* irq should only ever be CO_IRQ_8259 */ + /* ICW1 */ outb(0x11, 0x20); outb(0x11, 0xa0); @@ -277,10 +319,6 @@ static void shutdown_piix4_master_irq(unsigned int irq) { - /* - * [we skip the 8259 magic here, not strictly necessary] - */ - shutdown_cobalt_irq(irq); } @@ -324,6 +362,7 @@ * handle this 'virtual interrupt' as a Cobalt one now. */ kstat.irqs[smp_processor_id()][irq]++; + kstat.irqs[smp_processor_id()][realirq]++; do_cobalt_IRQ(realirq, regs); spin_lock(&irq_controller_lock); @@ -343,14 +382,9 @@ static void enable_piix4_virtual_irq(unsigned int irq) { - /* - * assumes this irq is one of the legacy devices - */ - unsigned int mask = inb(0x21); mask &= ~(1 << irq); outb(mask, 0x21); - enable_cobalt_irq(irq); } /* @@ -358,52 +392,104 @@ */ static void disable_piix4_virtual_irq(unsigned int irq) { - unsigned int mask; - - disable_cobalt_irq(irq); - - mask = inb(0x21); + unsigned int mask = inb(0x21); mask &= ~(1 << irq); outb(mask, 0x21); } static struct irqaction master_action = { no_action, 0, 0, "PIIX4-8259", NULL, NULL }; +#endif + +/* + * Called from bios32.c:pcibios_fixup_devices() + * Our chance to fill in the proper irqs. + * XXX properly map bus num to _bridge_ num + * XXX a big table (indexed by bridge/slot/line) might really be easiest! + */ +int +visws_get_PCI_irq_vector(int bus, int slot, int line) +{ +#define BRIDGE_A 1 /* XXX simplistic bus numbering! */ +#define BRIDGE_B 0 /* XXX simplistic bus numbering! */ +/* XXX note how we pass the bus number as the "bridge id" -- simplistic! */ +#define BASE(bridge) ((bridge) == BRIDGE_B ? \ + CO_APIC_PCIB_BASE0 : \ + CO_APIC_PCIA_BASE0) + if (bus == BRIDGE_B && slot == 4 && line == 3) { + return CO_IRQ(CO_APIC_PIIX4_USB); /* Breaks all patterns */ + } + if (line == 0) { /* First pin spread down 1 APIC entry per slot */ + return CO_IRQ(BASE(bus) + slot); + } + /* lines 1,2,3 from any slot is shared in this twirly pattern */ + if (bus == BRIDGE_A) { + /* lines 1-3 from devices 0 1 rotate over 2 apic entries */ + return CO_IRQ(CO_APIC_PCIA_BASE123 + ((slot + (line-1)) % 2)); + } else { /* bus == BRIDGE_B */ + /* lines 1-3 from devices 0-3 rotate over 3 apic entries */ + if (slot == 0) slot = 3; /* same pattern */ + return CO_IRQ(CO_APIC_PCIA_BASE123 + ((3-slot) + (line-1) % 3)); + } + /* NOTREACHED */ +#undef BRIDGE_A +#undef BRIDGE_B +#undef BASE +} + +/* + * Maps the combination of PIIX4 8259-pair irqs plus Cobalt APIC irqs + * to CPU IDT vectors. Just initializes visws_irq_vector[] and IRQ_VEC(irq). + */ +#if (CO_IRQ_APIC0 + CO_APIC_LAST + 1) > NR_IRQS +_NR_IRQS too small +#endif + -void init_VISWS_APIC_irqs(void) +void init_VISWS_APIC_irqs(void) /* init_IRQ() */ { int i; - for (i = 0; i < 16; i++) { + for (i = 0; i < CO_IRQ_APIC0 + CO_APIC_LAST + 1; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 0; - /* - * Cobalt IRQs are mapped to standard ISA - * interrupt vectors: - */ - switch (i) { - /* - * Only CO_IRQ_8259 will be raised - * externally. - */ - case CO_IRQ_8259: + /* Some legacy irqs are handled specially */ + /* This if/else "switch" must match co_apic_entry()! */ + if (i == 0) { /* IRQ 0 is system clock -- Cobalt timer */ + irq_desc[i].handler = &cobalt_irq_type; +#ifdef SERIAL_HACK + } else if (i == 4) { /* serial hack! */ + irq_desc[i].handler = &cobalt_irq_type; +#endif + } else if (i == CO_IRQ_IDE0) { + irq_desc[i].handler = &cobalt_irq_type; + } else if (i == CO_IRQ_IDE1) { + irq_desc[i].handler = &cobalt_irq_type; +#ifdef LEGACY_IRQS + } else if (i == CO_IRQ_8259) { irq_desc[i].handler = &piix4_master_irq_type; - break; - case CO_IRQ_FLOPPY: - case CO_IRQ_PARLL: + } else if (i < CO_IRQ_APIC0) { /* normal legacy */ irq_desc[i].handler = &piix4_virtual_irq_type; - break; - default: +#endif + } else if (IS_CO_APIC(i)) { irq_desc[i].handler = &cobalt_irq_type; - break; } + (void)assign_irq_vector(i); } +#ifdef LEGACY_IRQS /* * The master interrupt is always present: */ setup_x86_irq(CO_IRQ_8259, &master_action); -} +#endif + /* + * Enable IDT vectors for all valid IRQs. + * All unused IDT vectors generate 'Unexpected interrupt', + * see irq.c:strange_interrupt(). + */ + init_IRQ_MORE_TRAPS(); +} diff -Naur linux.2210/drivers/block/floppy.c linux.2210.vw/drivers/block/floppy.c --- linux.2210/drivers/block/floppy.c Wed Jun 9 16:42:49 1999 +++ linux.2210.vw/drivers/block/floppy.c Thu Jul 15 04:48:08 1999 @@ -3589,11 +3589,21 @@ /* read drive info out of physical CMOS */ drive=0; +#ifdef CONFIG_VISWS_HACKS +printk("VISWS HACK: floppy drive 0 hardwired to 1.44Mb (cmos WAR)\n"); + UDP->cmos = 4; /* drivers/block/README.fd */ +#else if (!UDP->cmos) UDP->cmos = FLOPPY0_TYPE; +#endif drive=1; +#ifdef CONFIG_VISWS_HACKS +printk("VISWS HACK: floppy drive 1 hardwired to (none) (cmos WAR)\n"); + UDP->cmos = 16; /* means "no drive" */ +#else if (!UDP->cmos && FLOPPY1_TYPE) UDP->cmos = FLOPPY1_TYPE; +#endif /* XXX */ /* additional physical CMOS drive detection should go here */ diff -Naur linux.2210/drivers/block/ide-probe.c linux.2210.vw/drivers/block/ide-probe.c --- linux.2210/drivers/block/ide-probe.c Mon Mar 22 12:44:18 1999 +++ linux.2210.vw/drivers/block/ide-probe.c Thu Jul 15 04:48:08 1999 @@ -409,8 +409,10 @@ if (hwif->noprobe) return; +#ifndef CONFIG_VISWS_HACKS if (hwif->io_ports[IDE_DATA_OFFSET] == HD_DATA) probe_cmos_for_drives (hwif); +#endif if ((hwif->chipset != ide_4drives || !hwif->mate->present) #if CONFIG_BLK_DEV_PDC4030 && (hwif->chipset != ide_pdc4030 || hwif->channel == 0) diff -Naur linux.2210/drivers/char/i2c.c linux.2210.vw/drivers/char/i2c.c --- linux.2210/drivers/char/i2c.c Thu Jan 14 22:53:02 1999 +++ linux.2210.vw/drivers/char/i2c.c Thu Jul 15 04:48:08 1999 @@ -387,7 +387,10 @@ return bus->i2c_read(bus, addr); i2c_start(bus); - i2c_sendbyte(bus,addr,0); + if (i2c_sendbyte(bus,addr,0)) { + i2c_stop(bus); + return -1; + } ret = i2c_readbyte(bus,1); i2c_stop(bus); return ret; diff -Naur linux.2210/drivers/char/serial.c linux.2210.vw/drivers/char/serial.c --- linux.2210/drivers/char/serial.c Tue Mar 23 13:13:58 1999 +++ linux.2210.vw/drivers/char/serial.c Thu Jul 15 04:48:08 1999 @@ -100,7 +100,7 @@ #undef SERIAL_DEBUG_FLOW #undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT -#define RS_STROBE_TIME (10*HZ) +#define RS_STROBE_TIME (HZ/10) #define RS_ISR_PASS_LIMIT 256 #define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT) diff -Naur linux.2210/drivers/scsi/Config.in linux.2210.vw/drivers/scsi/Config.in --- linux.2210/drivers/scsi/Config.in Wed Jun 9 16:59:34 1999 +++ linux.2210.vw/drivers/scsi/Config.in Thu Jul 15 04:48:08 1999 @@ -122,6 +122,7 @@ dep_tristate 'Qlogic FAS SCSI support' CONFIG_SCSI_QLOGIC_FAS $CONFIG_SCSI if [ "$CONFIG_PCI" = "y" ]; then dep_tristate 'Qlogic ISP SCSI support' CONFIG_SCSI_QLOGIC_ISP $CONFIG_SCSI + dep_tristate 'Qlogic 1X80 SCSI support' CONFIG_SCSI_QLOGIC_1X80 $CONFIG_SCSI dep_tristate 'Qlogic ISP FC SCSI support' CONFIG_SCSI_QLOGIC_FC $CONFIG_SCSI fi dep_tristate 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE $CONFIG_SCSI diff -Naur linux.2210/drivers/scsi/Makefile linux.2210.vw/drivers/scsi/Makefile --- linux.2210/drivers/scsi/Makefile Thu Apr 29 11:53:41 1999 +++ linux.2210.vw/drivers/scsi/Makefile Thu Jul 15 04:48:08 1999 @@ -282,6 +282,16 @@ endif endif + + +ifeq ($(CONFIG_SCSI_QLOGIC_1X80),y) +L_OBJS += qla1280.o +else + ifeq ($(CONFIG_SCSI_QLOGIC_1X80),m) + M_OBJS += qla1280.o + endif +endif + ifeq ($(CONFIG_SCSI_ACARD),y) L_OBJS += atp870u.o else diff -Naur linux.2210/drivers/scsi/hosts.c linux.2210.vw/drivers/scsi/hosts.c --- linux.2210/drivers/scsi/hosts.c Mon Apr 12 09:51:04 1999 +++ linux.2210.vw/drivers/scsi/hosts.c Thu Jul 15 04:48:08 1999 @@ -175,6 +175,10 @@ #include "qlogicisp.h" #endif +#ifdef CONFIG_SCSI_QLOGIC_1X80 +#include "qla1280host.h" +#endif + #ifdef CONFIG_SCSI_QLOGIC_FC #include "qlogicfc.h" #endif @@ -487,6 +491,9 @@ #endif #ifdef CONFIG_SCSI_QLOGIC_ISP QLOGICISP, +#endif +#ifdef CONFIG_SCSI_QLOGIC_1X80 + QLA1280, #endif #ifdef CONFIG_SCSI_QLOGIC_FC QLOGICFC, diff -Naur linux.2210/drivers/scsi/isp_fw.h linux.2210.vw/drivers/scsi/isp_fw.h --- linux.2210/drivers/scsi/isp_fw.h Wed Dec 31 16:00:00 1969 +++ linux.2210.vw/drivers/scsi/isp_fw.h Thu Jul 15 04:48:08 1999 @@ -0,0 +1,1894 @@ +/************************************************************************ + * * + * --- ISP1240/1080/1280 Initiator Firmware --- * + * 32 LUN Support * + * * + ************************************************************************ + * * + * NOTICE * + * * + * COPYRIGHT 1999 QLOGIC CORPORATION * + * ALL RIGHTS RESERVED * + * * + * This computer program is CONFIDENTIAL and contains TRADE SECRETS of * + * QLOGIC CORPORATION. The receipt or possession of this program does * + * not convey any rights to reproduce or disclose its contents, or to * + * manufacture, use, or sell anything that it may describe, in whole or * + * in part, without the specific written consent of QLOGIC CORPORATION. * + * Any reproduction of this program without the express written consent * + * of QLOGIC CORPORATION is a violation of the copyright laws and may * + * subject you to civil liability and criminal prosecution. * + * * + ************************************************************************ + */ + + +/* + * Firmware Version 8.09.00 (10:38 Apr 16, 1999) + */ + +unsigned short ql12_risc_code_version = 8*1024+9; + +unsigned char ql12_firmware_version[] = {8,9,0}; + +#define QL12_FW_VERSION_STRING "8.9.0" + +unsigned short ql12_risc_code_addr01 = 0x1000 ; + +unsigned short ql12_risc_code01[] = { + 0x0078, 0x1041, 0x0000, 0x39e3, 0x0000, 0x2043, 0x4f50, 0x5952, + 0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932, 0x2c31, + 0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749, 0x4320, + 0x434f, 0x5250, 0x4f52, 0x4154, 0x494f, 0x4e00, 0x2049, 0x5350, + 0x3132, 0x3430, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056, + 0x6572, 0x7369, 0x6f6e, 0x2030, 0x382e, 0x3039, 0x2020, 0x2043, + 0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20, 0x3030, 0x2050, + 0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020, 0x3030, 0x2020, + 0x2400, 0x20c9, 0x93ff, 0x2001, 0x04fc, 0x2004, 0xa086, 0x1080, + 0x00c0, 0x1054, 0x2071, 0x0100, 0x70a0, 0x70a2, 0x20c1, 0x0010, + 0x2089, 0x136a, 0x0078, 0x106d, 0x2001, 0x04fc, 0x2004, 0xa086, + 0x1280, 0x00c0, 0x1069, 0x2071, 0x0200, 0x70a0, 0x70a2, 0x2071, + 0x0100, 0x70a0, 0x70a2, 0x20c1, 0x0010, 0x2089, 0x13ea, 0x0078, + 0x106d, 0x20c1, 0x0020, 0x2089, 0x1312, 0x2071, 0x0010, 0x70c3, + 0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3, + 0x0008, 0x2001, 0x04fe, 0x70d6, 0x20c1, 0x0021, 0x2019, 0x0000, + 0x2009, 0xfeff, 0x2100, 0x200b, 0xa5a5, 0xa1ec, 0x7fff, 0x2d64, + 0x206b, 0x0a0a, 0xaddc, 0x3fff, 0x2b54, 0x205b, 0x5050, 0x2114, + 0xa286, 0xa5a5, 0x0040, 0x10a4, 0xa386, 0x000f, 0x0040, 0x10a0, + 0x2c6a, 0x2a5a, 0x20c1, 0x0020, 0x2019, 0x000f, 0x0078, 0x1080, + 0x2c6a, 0x2a5a, 0x0078, 0x10a2, 0x2c6a, 0x2a5a, 0x2130, 0x2128, + 0xa1a2, 0x4a00, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, + 0xa192, 0x9400, 0x2009, 0x0000, 0x2001, 0x0032, 0x1078, 0x2078, + 0x2218, 0x2079, 0x4a00, 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9, + 0x0040, 0x42a4, 0x8109, 0x00c0, 0x10bf, 0x2001, 0x04fc, 0x2004, + 0xa086, 0x1080, 0x00c0, 0x10db, 0x2071, 0x0100, 0x0d7e, 0x2069, + 0x4a40, 0x1078, 0x49ae, 0x0d7f, 0x7810, 0xc0ed, 0x7812, 0x781b, + 0x0064, 0x0078, 0x1100, 0x2001, 0x04fc, 0x2004, 0xa086, 0x1280, + 0x00c0, 0x10fb, 0x7814, 0xc0ed, 0xc0d5, 0x7816, 0x781b, 0x0064, + 0x2071, 0x0200, 0x0d7e, 0x2069, 0x4a40, 0x1078, 0x49ae, 0x2069, + 0x4a80, 0x2071, 0x0100, 0x1078, 0x49ae, 0x7814, 0xc0d4, 0x7816, + 0x0d7f, 0x0078, 0x1100, 0x7814, 0xc0e5, 0x7816, 0x781b, 0x003c, + 0x7eca, 0x7cc2, 0x7bc6, 0x7867, 0x0000, 0x7800, 0xc08d, 0x7802, + 0x2031, 0x0030, 0x78af, 0x0101, 0x7823, 0x0002, 0x7827, 0x0002, + 0x2009, 0x0002, 0x2069, 0x4a40, 0x681b, 0x0003, 0x6823, 0x0007, + 0x6827, 0x00fa, 0x682b, 0x0008, 0x682f, 0x0028, 0x6837, 0x0000, + 0x683b, 0x0006, 0x6833, 0x0008, 0x683f, 0x0000, 0x8109, 0x0040, + 0x1154, 0x68d3, 0x000a, 0x68c3, 0x4ac0, 0x2079, 0x4a00, 0x7814, + 0xd0e4, 0x00c0, 0x113a, 0xd0ec, 0x00c0, 0x113e, 0x68d7, 0x7329, + 0x0078, 0x1140, 0x68d7, 0x730d, 0x0078, 0x1140, 0x68d7, 0x7329, + 0x68c7, 0x4fc0, 0x68cb, 0x4ec0, 0x68cf, 0x8fc0, 0x68ab, 0x9244, + 0x68af, 0x9249, 0x68b3, 0x9244, 0x68b7, 0x9244, 0x68a7, 0x0001, + 0x2069, 0x4a80, 0x0078, 0x1114, 0x68d3, 0x000a, 0x68c3, 0x4cc0, + 0x7814, 0xd0e4, 0x00c0, 0x1160, 0x68d7, 0x7439, 0x0078, 0x1162, + 0x68d7, 0x7419, 0x68c7, 0x6fc0, 0x68cb, 0x4f40, 0x68cf, 0x90d0, + 0x68ab, 0x9249, 0x68af, 0x924e, 0x68b3, 0x9249, 0x68b7, 0x9249, + 0x68a7, 0x0001, 0x7810, 0xd0ec, 0x00c0, 0x11b8, 0x7814, 0xd0e4, + 0x00c0, 0x11aa, 0x0e7e, 0x2069, 0x4ec0, 0x2071, 0x0200, 0x70ec, + 0xd0e4, 0x00c0, 0x118b, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078, + 0x2007, 0x0078, 0x1191, 0x2019, 0x0c0a, 0x2021, 0x000a, 0x1078, + 0x2007, 0x2069, 0x4f40, 0x2071, 0x0100, 0x70ec, 0xd0e4, 0x00c0, + 0x11a1, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078, 0x2007, 0x0078, + 0x11a7, 0x2019, 0x0c0a, 0x2021, 0x000a, 0x1078, 0x2007, 0x0e7f, + 0x0078, 0x11d1, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x2069, 0x4ec0, + 0x1078, 0x2007, 0x2069, 0x4f40, 0x1078, 0x2007, 0x0078, 0x11d1, + 0x2069, 0x4ec0, 0x0e7e, 0x2071, 0x0100, 0x70ec, 0xd0e4, 0x00c0, + 0x11ca, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078, 0x2007, 0x0e7f, + 0x0078, 0x11d1, 0x2019, 0x0c0a, 0x2021, 0x000a, 0x1078, 0x2007, + 0x0e7f, 0x2011, 0x0002, 0x2069, 0x4fc0, 0x2009, 0x0002, 0x20a9, + 0x0100, 0x683f, 0x0000, 0x680b, 0x0040, 0x7bc8, 0xa386, 0xfeff, + 0x00c0, 0x11e8, 0x6817, 0x0100, 0x681f, 0x0064, 0x0078, 0x11ec, + 0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010, 0x00f0, 0x11d9, + 0x8109, 0x00c0, 0x11d7, 0x8211, 0x0040, 0x11fa, 0x2069, 0x6fc0, + 0x0078, 0x11d5, 0x1078, 0x2611, 0x1078, 0x441d, 0x1078, 0x1df2, + 0x1078, 0x4957, 0x2091, 0x2100, 0x2079, 0x4a00, 0x7810, 0xd0ec, + 0x0040, 0x120e, 0x2071, 0x0020, 0x0078, 0x1210, 0x2071, 0x0050, + 0x2091, 0x2200, 0x2079, 0x4a00, 0x2071, 0x0020, 0x2091, 0x2300, + 0x2079, 0x4a00, 0x7810, 0xd0ec, 0x0040, 0x1222, 0x2079, 0x0100, + 0x0078, 0x1224, 0x2079, 0x0200, 0x2071, 0x4a40, 0x2091, 0x2400, + 0x2079, 0x0100, 0x2071, 0x4a80, 0x2091, 0x2000, 0x2079, 0x4a00, + 0x2071, 0x0010, 0x3200, 0xa085, 0x303d, 0x2090, 0x2071, 0x0010, + 0x70c3, 0x0000, 0x0090, 0x1243, 0x70c0, 0xa086, 0x0002, 0x00c0, + 0x1243, 0x1078, 0x159d, 0x2039, 0x0000, 0x7810, 0xd0ec, 0x00c0, + 0x12c5, 0x1078, 0x1472, 0x78ac, 0xa005, 0x00c0, 0x1261, 0x0068, + 0x1257, 0x786c, 0xa065, 0x0040, 0x1257, 0x1078, 0x2368, 0x1078, + 0x209f, 0x0068, 0x126e, 0x786c, 0xa065, 0x0040, 0x1261, 0x1078, + 0x2368, 0x0068, 0x126e, 0x2009, 0x4a47, 0x2011, 0x4a87, 0x2104, + 0x220c, 0xa105, 0x0040, 0x126e, 0x1078, 0x1f1e, 0x2071, 0x4a40, + 0x70a4, 0xa005, 0x0040, 0x1293, 0x7450, 0xa485, 0x0000, 0x0040, + 0x1293, 0x2079, 0x0200, 0x2091, 0x8000, 0x72d4, 0xa28c, 0x303d, + 0x2190, 0x1078, 0x2a9c, 0x2091, 0x8000, 0x2091, 0x303d, 0x0068, + 0x1293, 0x2079, 0x4a00, 0x786c, 0xa065, 0x0040, 0x1293, 0x2071, + 0x0010, 0x1078, 0x2368, 0x00e0, 0x129b, 0x2079, 0x4a00, 0x2071, + 0x0010, 0x1078, 0x4765, 0x2071, 0x4a80, 0x70a4, 0xa005, 0x0040, + 0x12b3, 0x7050, 0xa025, 0x0040, 0x12b3, 0x2079, 0x0100, 0x2091, + 0x8000, 0x72d4, 0xa28c, 0x303d, 0x2190, 0x1078, 0x2a9c, 0x2091, + 0x8000, 0x2091, 0x303d, 0x2079, 0x4a00, 0x2071, 0x0010, 0x0068, + 0x12bf, 0x786c, 0xa065, 0x0040, 0x12bf, 0x1078, 0x2368, 0x00e0, + 0x1249, 0x1078, 0x4765, 0x0078, 0x1249, 0x1078, 0x1472, 0x78ac, + 0xa005, 0x00c0, 0x12dd, 0x0068, 0x12d3, 0x786c, 0xa065, 0x0040, + 0x12d3, 0x1078, 0x2368, 0x1078, 0x209f, 0x0068, 0x12e7, 0x786c, + 0xa065, 0x0040, 0x12dd, 0x1078, 0x2368, 0x0068, 0x12e7, 0x2009, + 0x4a47, 0x2104, 0xa005, 0x0040, 0x12e7, 0x1078, 0x1f1e, 0x2071, + 0x4a40, 0x70a4, 0xa005, 0x0040, 0x1302, 0x7450, 0xa485, 0x0000, + 0x0040, 0x1302, 0x2079, 0x0100, 0x2091, 0x8000, 0x72d4, 0xa28c, + 0x303d, 0x2190, 0x1078, 0x2a9c, 0x2091, 0x8000, 0x2091, 0x303d, + 0x2079, 0x4a00, 0x2071, 0x0010, 0x0068, 0x130c, 0x786c, 0xa065, + 0x0040, 0x130c, 0x1078, 0x2368, 0x00e0, 0x12c5, 0x1078, 0x4765, + 0x0078, 0x12c5, 0x1332, 0x1332, 0x1334, 0x1334, 0x1341, 0x1341, + 0x1341, 0x1341, 0x134c, 0x134c, 0x1359, 0x1359, 0x1341, 0x1341, + 0x1341, 0x1341, 0x1332, 0x1332, 0x1334, 0x1334, 0x1341, 0x1341, + 0x1341, 0x1341, 0x134c, 0x134c, 0x1359, 0x1359, 0x1341, 0x1341, + 0x1341, 0x1341, 0x0078, 0x1332, 0x007e, 0x107e, 0x127e, 0x2091, + 0x2400, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, + 0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13ba, 0x127f, 0x107f, + 0x007f, 0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, + 0x2300, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, + 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, 0x2300, 0x1078, 0x290b, + 0x2091, 0x2400, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, + 0x8001, 0x007c, 0x138a, 0x138a, 0x138c, 0x138c, 0x1399, 0x1399, + 0x1399, 0x1399, 0x13a4, 0x13a4, 0x138c, 0x138c, 0x1399, 0x1399, + 0x1399, 0x1399, 0x13a5, 0x13a5, 0x13a5, 0x13a5, 0x13a5, 0x13a5, + 0x13a5, 0x13a5, 0x13a5, 0x13a5, 0x13a5, 0x13a5, 0x13a5, 0x13a5, + 0x13a5, 0x13a5, 0x0078, 0x138a, 0x007e, 0x107e, 0x127e, 0x2091, + 0x2300, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, + 0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13c7, 0x127f, 0x107f, + 0x007f, 0x2091, 0x8001, 0x007c, 0x007c, 0x107e, 0x127e, 0x0d7e, + 0x0e7e, 0x0f7e, 0x007e, 0x2071, 0x0100, 0x2069, 0x4a40, 0x2079, + 0x4a00, 0x1078, 0x49ae, 0x007f, 0x0f7f, 0x0e7f, 0x0d7f, 0x127f, + 0x107f, 0x007c, 0x3c00, 0xa084, 0x0007, 0x0079, 0x13bf, 0x13d0, + 0x13d0, 0x13d2, 0x13d2, 0x13d7, 0x13d7, 0x13dc, 0x13dc, 0x3c00, + 0xa084, 0x0003, 0x0079, 0x13cc, 0x13d0, 0x13d0, 0x13e5, 0x13e5, + 0x1078, 0x28ec, 0x2091, 0x2200, 0x1078, 0x44b7, 0x007c, 0x2091, + 0x2100, 0x1078, 0x44b7, 0x007c, 0x2091, 0x2100, 0x1078, 0x44b7, + 0x2091, 0x2200, 0x1078, 0x44b7, 0x007c, 0x2091, 0x2100, 0x1078, + 0x44b7, 0x007c, 0x140a, 0x140a, 0x140c, 0x140c, 0x1419, 0x1419, + 0x1419, 0x1419, 0x1424, 0x1424, 0x1431, 0x1431, 0x1419, 0x1419, + 0x1419, 0x1419, 0x1442, 0x1442, 0x1442, 0x1442, 0x1442, 0x1442, + 0x1442, 0x1442, 0x1442, 0x1442, 0x1442, 0x1442, 0x1442, 0x1442, + 0x1442, 0x1442, 0x0078, 0x140a, 0x007e, 0x107e, 0x127e, 0x2091, + 0x2400, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, + 0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13ba, 0x127f, 0x107f, + 0x007f, 0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, + 0x2300, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, + 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, 0x2300, 0x1078, 0x290b, + 0x2091, 0x2400, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, + 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x0d7e, 0x0e7e, 0x0f7e, + 0x2079, 0x4a00, 0x2071, 0x0200, 0x2069, 0x4a40, 0x3d00, 0xd08c, + 0x00c0, 0x1456, 0x2069, 0x4a80, 0x2071, 0x0100, 0x1078, 0x49ae, + 0x0f7f, 0x0e7f, 0x0d7f, 0x127f, 0x107f, 0x007f, 0x007c, 0x7008, + 0x800b, 0x00c8, 0x146d, 0x7007, 0x0002, 0xa08c, 0x01e0, 0x00c0, + 0x146e, 0xd09c, 0x0040, 0x146d, 0x087a, 0x097a, 0x70c3, 0x4002, + 0x0078, 0x15a0, 0x0068, 0x14f7, 0x2061, 0x0000, 0x6018, 0xd084, + 0x00c0, 0x14f7, 0x7828, 0xa005, 0x00c0, 0x1482, 0x0010, 0x14f8, + 0x0078, 0x14f7, 0x7910, 0xd1f4, 0x0040, 0x148a, 0x2001, 0x4007, + 0x0078, 0x159f, 0x7914, 0xd1ec, 0x0040, 0x14a5, 0xd0fc, 0x0040, + 0x149b, 0x007e, 0x1078, 0x1d82, 0x007f, 0x0040, 0x14a5, 0x2001, + 0x4007, 0x0078, 0x159f, 0x007e, 0x1078, 0x1d72, 0x007f, 0x0040, + 0x14a5, 0x2001, 0x4007, 0x0078, 0x159f, 0x7910, 0xd0fc, 0x00c0, + 0x14af, 0x2061, 0x4a40, 0xc19c, 0xc7fc, 0x0078, 0x14b3, 0x2061, + 0x4a80, 0xc19d, 0xc7fd, 0x6064, 0xa005, 0x00c0, 0x14f7, 0x7912, + 0x6083, 0x0000, 0x7828, 0xc0fc, 0xa086, 0x0018, 0x00c0, 0x14c4, + 0x0c7e, 0x1078, 0x1b13, 0x0c7f, 0x782b, 0x0000, 0x607c, 0xa065, + 0x0040, 0x14dd, 0x0c7e, 0x609c, 0x1078, 0x1e5d, 0x0c7f, 0x609f, + 0x0000, 0x1078, 0x1c3f, 0x2009, 0x0018, 0x6087, 0x0103, 0x1078, + 0x1d92, 0x00c0, 0x14f1, 0x1078, 0x1de4, 0x7810, 0xd09c, 0x00c0, + 0x14e5, 0x2061, 0x4a40, 0x0078, 0x14e9, 0x2061, 0x4a80, 0xc09c, + 0x7812, 0x607f, 0x0000, 0x60d4, 0xd0dc, 0x0040, 0x14f5, 0xc0dc, + 0x60d6, 0x2001, 0x4005, 0x0078, 0x159f, 0x0078, 0x159d, 0x007c, + 0x7810, 0xd0f4, 0x0040, 0x1500, 0x2001, 0x4007, 0x0078, 0x159f, + 0xa006, 0x70c2, 0x70c6, 0x70ca, 0x70ce, 0x70da, 0x70c0, 0xa08a, + 0x0040, 0x00c8, 0x150d, 0x0079, 0x1514, 0x2100, 0xa08a, 0x0040, + 0x00c8, 0x15ab, 0x0079, 0x1554, 0x159d, 0x15f3, 0x15bc, 0x162b, + 0x1663, 0x1663, 0x15b3, 0x1c57, 0x166e, 0x15ab, 0x15c0, 0x15c2, + 0x15c4, 0x15c6, 0x1c5c, 0x15ab, 0x167c, 0x16d4, 0x1b35, 0x1c51, + 0x15c8, 0x19a7, 0x19e9, 0x1a1f, 0x1a6b, 0x1962, 0x196f, 0x1983, + 0x1996, 0x17a4, 0x1cdc, 0x1706, 0x1713, 0x171f, 0x172b, 0x1741, + 0x174d, 0x1750, 0x175c, 0x1768, 0x1770, 0x178c, 0x1798, 0x15ab, + 0x15ab, 0x15ab, 0x15ab, 0x17b1, 0x17c3, 0x17df, 0x1815, 0x183d, + 0x184d, 0x1850, 0x1881, 0x18b2, 0x18c4, 0x1931, 0x1941, 0x1d32, + 0x15ab, 0x15ab, 0x15ab, 0x1951, 0x15ab, 0x15ab, 0x15ab, 0x15ab, + 0x15ab, 0x1c81, 0x1c87, 0x15ab, 0x15ab, 0x15ab, 0x1c8b, 0x1cd8, + 0x15ab, 0x15ab, 0x1ce8, 0x1cf7, 0x15ed, 0x165d, 0x1676, 0x16ce, + 0x1b2f, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x1d39, 0x1c73, 0x1c7d, + 0x15ab, 0x15ab, 0x1d02, 0x1d1b, 0x15ab, 0x15ab, 0x15ab, 0x15ab, + 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, + 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, + 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, + 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x72ca, 0x71c6, 0x2001, 0x4006, + 0x0078, 0x159f, 0x73ce, 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, + 0x0068, 0x15a0, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x5000, + 0x2091, 0x4080, 0x007c, 0x70c3, 0x4001, 0x0078, 0x15a0, 0x70c3, + 0x4006, 0x0078, 0x15a0, 0x2099, 0x0041, 0x20a1, 0x0041, 0x20a9, + 0x0005, 0x53a3, 0x0078, 0x159d, 0x70c4, 0x70c3, 0x0004, 0x007a, + 0x0078, 0x159d, 0x0078, 0x159d, 0x0078, 0x159d, 0x0078, 0x159d, + 0x2091, 0x8000, 0x70c3, 0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, + 0x70cf, 0x2020, 0x70d3, 0x0008, 0x2001, 0x0009, 0x70d6, 0x2079, + 0x0000, 0x781b, 0x0001, 0x2031, 0x0030, 0x2059, 0x1000, 0x2029, + 0x041a, 0x2051, 0x0445, 0x2061, 0x0447, 0x20c1, 0x0020, 0x2091, + 0x5000, 0x2091, 0x4080, 0x0078, 0x0418, 0x75d8, 0x74dc, 0x75da, + 0x74de, 0x0078, 0x15f6, 0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8, + 0x73cc, 0x70c4, 0x20a0, 0x2099, 0x0030, 0x7003, 0x0001, 0x7007, + 0x0006, 0x731a, 0x721e, 0x7422, 0x7526, 0x2021, 0x0040, 0x81ff, + 0x0040, 0x159d, 0xa182, 0x0040, 0x00c8, 0x1610, 0x2120, 0xa006, + 0x2008, 0x8403, 0x7012, 0x7007, 0x0004, 0x7007, 0x0001, 0x7008, + 0xd0fc, 0x0040, 0x1617, 0x7007, 0x0002, 0xa084, 0x01e0, 0x0040, + 0x1625, 0x70c3, 0x4002, 0x0078, 0x15a0, 0x24a8, 0x53a5, 0x0078, + 0x1607, 0x0078, 0x159d, 0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8, + 0x73cc, 0x70c4, 0x2098, 0x20a1, 0x0030, 0x7003, 0x0000, 0x7007, + 0x0006, 0x731a, 0x721e, 0x7422, 0x7526, 0x2021, 0x0040, 0x7007, + 0x0006, 0x81ff, 0x0040, 0x159d, 0xa182, 0x0040, 0x00c8, 0x164a, + 0x2120, 0xa006, 0x2008, 0x8403, 0x7012, 0x24a8, 0x53a6, 0x7007, + 0x0001, 0x7008, 0xd0fc, 0x0040, 0x1651, 0xa084, 0x01e0, 0x0040, + 0x163f, 0x70c3, 0x4002, 0x0078, 0x15a0, 0x75d8, 0x74dc, 0x75da, + 0x74de, 0x0078, 0x162e, 0x71c4, 0x70c8, 0x2114, 0xa79e, 0x0004, + 0x00c0, 0x166b, 0x200a, 0x72ca, 0x0078, 0x159c, 0x70c7, 0x0008, + 0x70cb, 0x0009, 0x70cf, 0x0000, 0x0078, 0x159d, 0x75d8, 0x76dc, + 0x75da, 0x76de, 0x0078, 0x167f, 0x2029, 0x0000, 0x2530, 0x70c4, + 0x72c8, 0x73cc, 0x74d0, 0x70c6, 0x72ca, 0x73ce, 0x74d2, 0xa005, + 0x0040, 0x16c9, 0x8001, 0x7872, 0xa084, 0xfc00, 0x0040, 0x1697, + 0x78ac, 0xc085, 0x78ae, 0x2001, 0x4005, 0x0078, 0x159f, 0x7b7e, + 0x7a7a, 0x7e86, 0x7d82, 0x7c76, 0xa48c, 0xff00, 0x0040, 0x16af, + 0x8407, 0x8004, 0x8004, 0x810c, 0x810c, 0x810f, 0xa118, 0xa291, + 0x0000, 0xa6b1, 0x0000, 0xa581, 0x0000, 0x0078, 0x16b9, 0x8407, + 0x8004, 0x8004, 0xa318, 0xa291, 0x0000, 0xa6b1, 0x0000, 0xa581, + 0x0000, 0x731a, 0x721e, 0x7622, 0x7026, 0xa605, 0x0040, 0x16c3, + 0x7a10, 0xc2c5, 0x7a12, 0x78ac, 0xa084, 0xfffc, 0x78ae, 0x0078, + 0x16cc, 0x78ac, 0xc085, 0x78ae, 0x0078, 0x159d, 0x75d8, 0x76dc, + 0x75da, 0x76de, 0x0078, 0x16d7, 0x2029, 0x0000, 0x2530, 0x70c4, + 0x72c8, 0x73cc, 0x74d4, 0x70c6, 0x72ca, 0x73ce, 0x74d6, 0xa005, + 0x0040, 0x1701, 0x8001, 0x7892, 0xa084, 0xfc00, 0x0040, 0x16ef, + 0x78ac, 0xc0c5, 0x78ae, 0x2001, 0x4005, 0x0078, 0x159f, 0x7a9a, + 0x7b9e, 0x7da2, 0x7ea6, 0x2600, 0xa505, 0x0040, 0x16fa, 0x7a10, + 0xc2c5, 0x7a12, 0x7c96, 0x78ac, 0xa084, 0xfcff, 0x78ae, 0x0078, + 0x1704, 0x78ac, 0xc0c5, 0x78ae, 0x0078, 0x159d, 0x2009, 0x0000, + 0x786c, 0xa065, 0x0040, 0x1710, 0x8108, 0x6000, 0x0078, 0x1709, + 0x7ac4, 0x0078, 0x159b, 0x2009, 0x4a48, 0x210c, 0x7810, 0xd0ec, + 0x00c0, 0x159c, 0x2011, 0x4a88, 0x2214, 0x0078, 0x159b, 0x2009, + 0x4a49, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x159c, 0x2011, 0x4a89, + 0x2214, 0x0078, 0x159b, 0x2061, 0x4a40, 0x6128, 0x622c, 0x8214, + 0x8214, 0x8214, 0x7810, 0xd0ec, 0x00c0, 0x173f, 0x2061, 0x4a80, + 0x6328, 0x73da, 0x632c, 0x831c, 0x831c, 0x831c, 0x73de, 0x0078, + 0x159b, 0x2009, 0x4a4c, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x159c, + 0x2011, 0x4a8c, 0x2214, 0x0078, 0x159b, 0x7918, 0x0078, 0x159c, + 0x2009, 0x4a4d, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x159c, 0x2011, + 0x4a8d, 0x2214, 0x0078, 0x159b, 0x2009, 0x4a4e, 0x210c, 0x7810, + 0xd0ec, 0x00c0, 0x159c, 0x2011, 0x4a8e, 0x2214, 0x0078, 0x159b, + 0x7920, 0x7810, 0xd0ec, 0x00c0, 0x159c, 0x7a24, 0x0078, 0x159b, + 0x71c4, 0xd1fc, 0x00c0, 0x1778, 0x2011, 0x4ec0, 0x0078, 0x177a, + 0x2011, 0x4f40, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, + 0xa268, 0x6a00, 0x6804, 0xd09c, 0x0040, 0x1789, 0x6b08, 0x0078, + 0x178a, 0x6b0c, 0x0078, 0x159a, 0x77c4, 0x1078, 0x1e02, 0x2091, + 0x8000, 0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708, 0x0078, 0x159a, + 0x2061, 0x4a40, 0x6118, 0x7810, 0xd0ec, 0x00c0, 0x159c, 0x2061, + 0x4a80, 0x6218, 0x0078, 0x159b, 0x77c4, 0x1078, 0x1e02, 0x2091, + 0x8000, 0x6908, 0x6a18, 0x6b10, 0x77da, 0x2091, 0x8001, 0x0078, + 0x159a, 0x71c4, 0x2110, 0xa294, 0x000f, 0xa282, 0x0010, 0x00c8, + 0x1595, 0x1078, 0x2729, 0xa384, 0x4000, 0x0040, 0x17c1, 0xa295, + 0x0020, 0x0078, 0x159a, 0x71c4, 0x2100, 0xc0bc, 0xa082, 0x0010, + 0x00c8, 0x1595, 0xd1bc, 0x00c0, 0x17d2, 0x2011, 0x4a48, 0x2204, + 0x0078, 0x17d6, 0x2011, 0x4a88, 0x2204, 0xc0bd, 0x007e, 0x2100, + 0xc0bc, 0x2012, 0x1078, 0x2686, 0x017f, 0x0078, 0x159c, 0x71c4, + 0x2021, 0x4a49, 0x2404, 0x70c6, 0x2019, 0x0000, 0x0078, 0x17ee, + 0x71c8, 0x2021, 0x4a89, 0x2404, 0x70ca, 0xc3fd, 0x2011, 0x180d, + 0x20a9, 0x0008, 0x2204, 0xa106, 0x0040, 0x17fd, 0x8210, 0x00f0, + 0x17f2, 0x71c4, 0x72c8, 0x0078, 0x1594, 0xa292, 0x180d, 0x027e, + 0x2122, 0x017f, 0x1078, 0x26a7, 0x7810, 0xd0ec, 0x00c0, 0x180b, + 0xd3fc, 0x0040, 0x17e8, 0x0078, 0x159d, 0x03e8, 0x00fa, 0x01f4, + 0x02ee, 0x0064, 0x0019, 0x0032, 0x004b, 0x2061, 0x4a40, 0x6128, + 0x622c, 0x8214, 0x8214, 0x8214, 0x70c4, 0x602a, 0x70c8, 0x8003, + 0x8003, 0x8003, 0x602e, 0x7810, 0xd0ec, 0x00c0, 0x183b, 0x027e, + 0x017e, 0x2061, 0x4a80, 0x6128, 0x622c, 0x8214, 0x8214, 0x8214, + 0x70d8, 0x602a, 0x70dc, 0x8003, 0x8003, 0x8003, 0x602e, 0x71da, + 0x72de, 0x017f, 0x027f, 0x0078, 0x159b, 0x2061, 0x4a40, 0x6130, + 0x70c4, 0x6032, 0x7810, 0xd0ec, 0x00c0, 0x159c, 0x2061, 0x4a80, + 0x6230, 0x70c8, 0x6032, 0x0078, 0x159b, 0x7918, 0x0078, 0x159c, + 0x71c4, 0xa184, 0xffcf, 0x0040, 0x185c, 0x7810, 0xd0ec, 0x00c0, + 0x1595, 0x72c8, 0x0078, 0x1594, 0x2011, 0x4a4d, 0x2204, 0x2112, + 0x007e, 0x2019, 0x0000, 0x1078, 0x270e, 0x7810, 0xd0ec, 0x0040, + 0x186c, 0x017f, 0x0078, 0x159c, 0x71c8, 0xa184, 0xffcf, 0x0040, + 0x1875, 0x2110, 0x71c4, 0x0078, 0x1594, 0x2011, 0x4a8d, 0x2204, + 0x2112, 0x007e, 0xc3fd, 0x1078, 0x270e, 0x027f, 0x017f, 0x0078, + 0x159b, 0x71c4, 0xa182, 0x0010, 0x0048, 0x188d, 0x7810, 0xd0ec, + 0x00c0, 0x1595, 0x72c8, 0x0078, 0x1594, 0x2011, 0x4a4e, 0x2204, + 0x007e, 0x2112, 0x2019, 0x0000, 0x1078, 0x26ec, 0x7810, 0xd0ec, + 0x0040, 0x189d, 0x017f, 0x0078, 0x159c, 0x71c8, 0xa182, 0x0010, + 0x0048, 0x18a6, 0x2110, 0x71c4, 0x0078, 0x1594, 0x2011, 0x4a8e, + 0x2204, 0x007e, 0x2112, 0xc3fd, 0x1078, 0x26ec, 0x027f, 0x017f, + 0x0078, 0x159b, 0x71c4, 0x72c8, 0xa184, 0xfffd, 0x00c0, 0x1594, + 0xa284, 0xfffd, 0x00c0, 0x1594, 0x2100, 0x7920, 0x7822, 0x2200, + 0x7a24, 0x7826, 0x0078, 0x159b, 0x71c4, 0xd1fc, 0x00c0, 0x18cc, + 0x2011, 0x4ec0, 0x0078, 0x18ce, 0x2011, 0x4f40, 0x8107, 0xa084, + 0x000f, 0x8003, 0x8003, 0x8003, 0xa268, 0x2019, 0x0000, 0x72c8, + 0xa284, 0x0080, 0x0040, 0x18e2, 0x6c14, 0x84ff, 0x00c0, 0x18e2, + 0x6817, 0x0040, 0xa284, 0x0040, 0x0040, 0x18ec, 0x6c10, 0x84ff, + 0x00c0, 0x18ec, 0x6813, 0x0001, 0x6800, 0x007e, 0xa226, 0x0040, + 0x1909, 0x6a02, 0xd4ec, 0x0040, 0x18f6, 0xc3a5, 0xd4e4, 0x0040, + 0x18fa, 0xc39d, 0xd4f4, 0x0040, 0x1909, 0x810f, 0xd2f4, 0x0040, + 0x1905, 0x1078, 0x276b, 0x0078, 0x1909, 0x1078, 0x2749, 0x0078, + 0x1909, 0x72cc, 0x6808, 0xa206, 0x0040, 0x1929, 0xa2a4, 0x00ff, + 0x7814, 0xd0e4, 0x00c0, 0x191c, 0xa482, 0x0028, 0x0048, 0x1926, + 0x0040, 0x1926, 0x0078, 0x1920, 0xa482, 0x0043, 0x0048, 0x1926, + 0x71c4, 0x71c6, 0x027f, 0x72ca, 0x0078, 0x1596, 0x6a0a, 0xa39d, + 0x000a, 0x6804, 0xa305, 0x6806, 0x027f, 0x6b0c, 0x71c4, 0x0078, + 0x159a, 0x77c4, 0x1078, 0x1e02, 0x2091, 0x8000, 0x6a14, 0x6b1c, + 0x2091, 0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e, 0x2708, 0x0078, + 0x159a, 0x70c4, 0x2061, 0x4a40, 0x6118, 0x601a, 0x7810, 0xd0ec, + 0x00c0, 0x159c, 0x70c8, 0x2061, 0x4a80, 0x6218, 0x601a, 0x0078, + 0x159b, 0x71c4, 0x72c8, 0x73cc, 0xa182, 0x0010, 0x00c8, 0x1595, + 0x1078, 0x278d, 0xa384, 0x4000, 0x0040, 0x1960, 0xa295, 0x0020, + 0x0078, 0x159a, 0x77c4, 0x1078, 0x1e02, 0x2091, 0x8000, 0x6a08, + 0xc28d, 0x6a0a, 0x2091, 0x8001, 0x2708, 0x0078, 0x159b, 0x77c4, + 0x1078, 0x1e02, 0x2091, 0x8000, 0x6a08, 0xa294, 0xfff9, 0x6a0a, + 0x6804, 0xa005, 0x0040, 0x197e, 0x1078, 0x25de, 0x2091, 0x8001, + 0x2708, 0x0078, 0x159b, 0x77c4, 0x1078, 0x1e02, 0x2091, 0x8000, + 0x6a08, 0xc295, 0x6a0a, 0x6804, 0xa005, 0x0040, 0x1991, 0x1078, + 0x25de, 0x2091, 0x8001, 0x2708, 0x0078, 0x159b, 0x77c4, 0x2041, + 0x0001, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078, + 0x1e1d, 0x2091, 0x8001, 0x2708, 0x6a08, 0x0078, 0x159b, 0x77c4, + 0x7814, 0xd0e4, 0x00c0, 0x19bb, 0xd7fc, 0x0040, 0x19b5, 0x1078, + 0x1d82, 0x0040, 0x19bb, 0x0078, 0x159f, 0x1078, 0x1d72, 0x0040, + 0x19bb, 0x0078, 0x159f, 0x73c8, 0x72cc, 0x77c6, 0x73ca, 0x72ce, + 0x1078, 0x1e9a, 0x00c0, 0x19e5, 0x6818, 0xa005, 0x0040, 0x19df, + 0x2708, 0x077e, 0x1078, 0x27bd, 0x077f, 0x00c0, 0x19df, 0x2001, + 0x0015, 0xd7fc, 0x00c0, 0x19d8, 0x2061, 0x4a40, 0x0078, 0x19db, + 0xc0fd, 0x2061, 0x4a80, 0x782a, 0x2091, 0x8001, 0x007c, 0x2091, + 0x8001, 0x2001, 0x4005, 0x0078, 0x159f, 0x2091, 0x8001, 0x0078, + 0x159d, 0x77c4, 0x7814, 0xd0e4, 0x00c0, 0x19fd, 0xd7fc, 0x0040, + 0x19f7, 0x1078, 0x1d82, 0x0040, 0x19fd, 0x0078, 0x159f, 0x1078, + 0x1d72, 0x0040, 0x19fd, 0x0078, 0x159f, 0x77c6, 0x2041, 0x0021, + 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078, 0x1e1d, + 0x2009, 0x0016, 0xd7fc, 0x00c0, 0x1a11, 0x2061, 0x4a40, 0x0078, + 0x1a14, 0x2061, 0x4a80, 0xc1fd, 0x6067, 0x0003, 0x6776, 0x6083, + 0x000f, 0x792a, 0x1078, 0x25de, 0x2091, 0x8001, 0x007c, 0x77c8, + 0x77ca, 0x77c4, 0x77c6, 0x7814, 0xd0e4, 0x00c0, 0x1a36, 0xd7fc, + 0x0040, 0x1a30, 0x1078, 0x1d82, 0x0040, 0x1a36, 0x0078, 0x159f, + 0x1078, 0x1d72, 0x0040, 0x1a36, 0x0078, 0x159f, 0xa7bc, 0xff00, + 0x2091, 0x8000, 0x2009, 0x0017, 0xd7fc, 0x00c0, 0x1a43, 0x2061, + 0x4a40, 0x0078, 0x1a46, 0x2061, 0x4a80, 0xc1fd, 0x6067, 0x0002, + 0x6776, 0x6083, 0x000f, 0x792a, 0x1078, 0x25de, 0x2091, 0x8001, + 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0010, 0x2091, 0x8000, + 0x70c8, 0xa005, 0x0040, 0x1a5f, 0x60d4, 0xc0fd, 0x60d6, 0x1078, + 0x1e1d, 0x70c8, 0x683e, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1a5f, + 0x2091, 0x8001, 0x007c, 0x7814, 0xd0e4, 0x00c0, 0x1a7f, 0x72c8, + 0xd284, 0x0040, 0x1a79, 0x1078, 0x1d82, 0x0040, 0x1a7f, 0x0078, + 0x159f, 0x1078, 0x1d72, 0x0040, 0x1a7f, 0x0078, 0x159f, 0x72c8, + 0x72ca, 0x78ac, 0xa084, 0x0003, 0x00c0, 0x1aaa, 0x2039, 0x0000, + 0xd284, 0x0040, 0x1a8c, 0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, + 0x2051, 0x0008, 0x1078, 0x1e02, 0x2091, 0x8000, 0x6808, 0xc0d4, + 0xa80d, 0x690a, 0x2091, 0x8001, 0x8738, 0xa784, 0x001f, 0x00c0, + 0x1a92, 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, + 0x00c0, 0x1a92, 0x2091, 0x8000, 0x72c8, 0xd284, 0x00c0, 0x1abc, + 0x7810, 0xd0ec, 0x0040, 0x1ab8, 0x2069, 0x0100, 0x0078, 0x1abe, + 0x2069, 0x0200, 0x0078, 0x1abe, 0x2069, 0x0100, 0x6830, 0xd0b4, + 0x0040, 0x1ada, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, 0xd094, + 0x0040, 0x1acc, 0x00f0, 0x1ac6, 0x684b, 0x0009, 0x20a9, 0x0014, + 0x6848, 0xd084, 0x0040, 0x1ad6, 0x00f0, 0x1ad0, 0x20a9, 0x00fa, + 0x00f0, 0x1ad8, 0x2079, 0x4a00, 0x2009, 0x0018, 0x72c8, 0xd284, + 0x00c0, 0x1ae6, 0x2061, 0x4a40, 0x0078, 0x1ae9, 0x2061, 0x4a80, + 0xc1fd, 0x792a, 0x6067, 0x0001, 0x6083, 0x000f, 0x60a7, 0x0000, + 0x60a8, 0x60b2, 0x60b6, 0x60d4, 0xd0b4, 0x0040, 0x1b03, 0xc0b4, + 0x60d6, 0x0c7e, 0x60b8, 0xa065, 0x6008, 0xc0d4, 0x600a, 0x6018, + 0x8001, 0x601a, 0x0c7f, 0x60d4, 0xa084, 0x77ff, 0x60d6, 0x78ac, + 0xc08d, 0x78ae, 0x6808, 0xa084, 0xfffd, 0x680a, 0x681b, 0x0047, + 0x2091, 0x8001, 0x007c, 0xd7fc, 0x00c0, 0x1b1a, 0x2069, 0x4a40, + 0x0078, 0x1b1c, 0x2069, 0x4a80, 0x78ac, 0xc08c, 0x78ae, 0xd084, + 0x00c0, 0x1b26, 0x0d7e, 0x1078, 0x1efa, 0x0d7f, 0x71c4, 0x71c6, + 0x6916, 0x81ff, 0x00c0, 0x1b2e, 0x68a7, 0x0001, 0x007c, 0x75d8, + 0x74dc, 0x75da, 0x74de, 0x0078, 0x1b38, 0x2029, 0x0000, 0x2520, + 0x71c4, 0x73c8, 0x72cc, 0x71c6, 0x73ca, 0x72ce, 0x2079, 0x4a00, + 0x7dde, 0x7cda, 0x7bd6, 0x7ad2, 0x1078, 0x1ddb, 0x0040, 0x1c3b, + 0x20a9, 0x0005, 0x20a1, 0x4a14, 0x2091, 0x8000, 0x41a1, 0x2091, + 0x8001, 0x2009, 0x0040, 0x1078, 0x1fcf, 0x0040, 0x1b5b, 0x1078, + 0x1de4, 0x0078, 0x1c3b, 0x6004, 0xa08c, 0x00ff, 0xa18e, 0x0009, + 0x00c0, 0x1b66, 0x007e, 0x1078, 0x234b, 0x007f, 0xa084, 0xff00, + 0x8007, 0x8009, 0x0040, 0x1bda, 0x0c7e, 0x2c68, 0x1078, 0x1ddb, + 0x0040, 0x1bac, 0x2c00, 0x689e, 0x8109, 0x00c0, 0x1b6d, 0x609f, + 0x0000, 0x0c7f, 0x0c7e, 0x7ddc, 0x7cd8, 0x7bd4, 0x7ad0, 0xa290, + 0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x7dde, + 0x7cda, 0x7bd6, 0x7ad2, 0x2c68, 0x689c, 0xa065, 0x0040, 0x1bd9, + 0x2009, 0x0040, 0x1078, 0x1fcf, 0x00c0, 0x1bc3, 0x6004, 0xa084, + 0x00ff, 0xa086, 0x0002, 0x00c0, 0x1bac, 0x6004, 0xa084, 0x00ff, + 0xa086, 0x000a, 0x00c0, 0x1ba8, 0x017e, 0x1078, 0x2347, 0x017f, + 0x2d00, 0x6002, 0x0078, 0x1b7b, 0x0c7f, 0x0c7e, 0x609c, 0x1078, + 0x1e5d, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1c3f, 0x2009, 0x0018, + 0x6008, 0xc0cd, 0x600a, 0x6004, 0x6086, 0x1078, 0x1d92, 0x1078, + 0x1de4, 0x0078, 0x1c3b, 0x0c7f, 0x0c7e, 0x609c, 0x1078, 0x1e5d, + 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1c3f, 0x2009, 0x0018, 0x6087, + 0x0103, 0x601b, 0x0003, 0x1078, 0x1d92, 0x1078, 0x1de4, 0x0078, + 0x1c3b, 0x0c7f, 0x7814, 0xd0e4, 0x00c0, 0x1bff, 0x6114, 0xd1fc, + 0x0040, 0x1be8, 0x1078, 0x1d82, 0x0040, 0x1bff, 0x0078, 0x1bec, + 0x1078, 0x1d72, 0x0040, 0x1bff, 0x2029, 0x0000, 0x2520, 0x2009, + 0x0018, 0x73c8, 0x72cc, 0x6087, 0x0103, 0x601b, 0x0021, 0x1078, + 0x1d92, 0x1078, 0x1de4, 0x2001, 0x4007, 0x0078, 0x159f, 0x74c4, + 0x73c8, 0x72cc, 0x6014, 0x2091, 0x8000, 0x0e7e, 0x2009, 0x0012, + 0xd0fc, 0x00c0, 0x1c0f, 0x2071, 0x4a40, 0x0078, 0x1c12, 0x2071, + 0x4a80, 0xc1fd, 0x792a, 0x7067, 0x0005, 0x71d4, 0xa18c, 0xf77f, + 0x71d6, 0x736a, 0x726e, 0x7472, 0x7076, 0x707b, 0x0000, 0x2c00, + 0x707e, 0xa02e, 0x2530, 0x611c, 0xa184, 0x0060, 0x0040, 0x1c2a, + 0x1078, 0x43c1, 0x0e7f, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x60af, + 0x0000, 0x60b3, 0x0000, 0x6714, 0x6023, 0x0000, 0x1078, 0x25de, + 0x2091, 0x8001, 0x007c, 0x70c3, 0x4005, 0x0078, 0x15a0, 0x20a9, + 0x0005, 0x2099, 0x4a14, 0x2091, 0x8000, 0x530a, 0x2091, 0x8001, + 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, + 0x007c, 0x71c4, 0x70c7, 0x0000, 0x791e, 0x0078, 0x159d, 0x71c4, + 0x71c6, 0x2168, 0x0078, 0x1c5e, 0x2069, 0x1000, 0x690c, 0xa016, + 0x2d04, 0xa210, 0x8d68, 0x8109, 0x00c0, 0x1c60, 0xa285, 0x0000, + 0x00c0, 0x1c6e, 0x70c3, 0x4000, 0x0078, 0x1c70, 0x70c3, 0x4003, + 0x70ca, 0x0078, 0x15a0, 0x7964, 0x71c6, 0x71c4, 0xa182, 0x0003, + 0x00c8, 0x1595, 0x7966, 0x0078, 0x159d, 0x7964, 0x71c6, 0x0078, + 0x159d, 0x7900, 0x71c6, 0x71c4, 0x7902, 0x0078, 0x159d, 0x7900, + 0x71c6, 0x0078, 0x159d, 0x70c4, 0xd08c, 0x0040, 0x1c94, 0x7a10, + 0xd2ec, 0x00c0, 0x1c94, 0xc08c, 0x2011, 0x0000, 0xa08c, 0x000d, + 0x0040, 0x1ca8, 0x810c, 0x0048, 0x1ca4, 0x8210, 0x810c, 0x810c, + 0x0048, 0x1ca4, 0x8210, 0x810c, 0x81ff, 0x00c0, 0x1596, 0x8210, + 0x7a0e, 0xd28c, 0x0040, 0x1cd4, 0x7910, 0xc1cd, 0x7912, 0x2009, + 0x0021, 0x2019, 0x0003, 0xd284, 0x0040, 0x1cce, 0x8108, 0x2019, + 0x0041, 0x2011, 0x924e, 0x2312, 0x2019, 0x0042, 0x8210, 0x2312, + 0x2019, 0x0043, 0x8210, 0x2312, 0x2019, 0x0046, 0x8210, 0x2312, + 0x2019, 0x0047, 0x8210, 0x2312, 0x2019, 0x0006, 0x2011, 0x9253, + 0x2112, 0x2011, 0x9273, 0x2312, 0x7904, 0x7806, 0x0078, 0x159c, + 0x7804, 0x70c6, 0x0078, 0x159d, 0x2091, 0x8000, 0x2019, 0x0000, + 0x2011, 0x0000, 0x2009, 0x0000, 0x2091, 0x8001, 0x0078, 0x159a, + 0x77c4, 0x1078, 0x1e02, 0x2091, 0x8000, 0x6830, 0xa084, 0xff00, + 0x8007, 0x2010, 0x2091, 0x8001, 0x2708, 0x0078, 0x159b, 0x77c4, + 0x1078, 0x1e02, 0x2091, 0x8000, 0x6a34, 0x2091, 0x8001, 0x2708, + 0x0078, 0x159b, 0x77c4, 0x077e, 0xa7bc, 0xff00, 0x20a9, 0x0008, + 0x72c8, 0x8217, 0x1078, 0x1e02, 0x2091, 0x8000, 0x6c30, 0x6a32, + 0x2091, 0x8001, 0x8738, 0x00f0, 0x1d0a, 0x077f, 0x2708, 0x8427, + 0x2410, 0x0078, 0x159b, 0x77c4, 0x077e, 0xa7bc, 0xff00, 0x20a9, + 0x0008, 0x72c8, 0x1078, 0x1e02, 0x2091, 0x8000, 0x6c34, 0x6a36, + 0x2091, 0x8001, 0x8738, 0x00f0, 0x1d22, 0x077f, 0x2708, 0x2410, + 0x0078, 0x159b, 0x2011, 0x4a3c, 0x220c, 0x70c4, 0x2012, 0x0078, + 0x159c, 0x71c4, 0xd1fc, 0x00c0, 0x1d41, 0x2011, 0x4ec0, 0x0078, + 0x1d43, 0x2011, 0x4f40, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, + 0x8003, 0xa268, 0x6a14, 0xd2b4, 0x0040, 0x1d52, 0x2011, 0x0001, + 0x0078, 0x1d54, 0x2011, 0x0000, 0x6b0c, 0x0078, 0x159a, 0x017e, + 0x7814, 0xd0f4, 0x0040, 0x1d64, 0x2001, 0x4007, 0x70db, 0x0000, + 0xa18d, 0x0001, 0x0078, 0x1d70, 0xd0fc, 0x0040, 0x1d6f, 0x2001, + 0x4007, 0x70db, 0x0001, 0xa18d, 0x0001, 0x0078, 0x1d70, 0xa006, + 0x017f, 0x007c, 0x017e, 0x7814, 0xd0f4, 0x0040, 0x1d7f, 0x2001, + 0x4007, 0x70db, 0x0000, 0xa18d, 0x0001, 0x0078, 0x1d80, 0xa006, + 0x017f, 0x007c, 0x017e, 0x7814, 0xd0fc, 0x0040, 0x1d8f, 0x2001, + 0x4007, 0x70db, 0x0001, 0xa18d, 0x0001, 0x0078, 0x1d90, 0xa006, + 0x017f, 0x007c, 0x7112, 0x721a, 0x731e, 0x7810, 0xd0c4, 0x0040, + 0x1d9b, 0x7422, 0x7526, 0xac80, 0x0001, 0x8108, 0x810c, 0x81a9, + 0x8098, 0x20a1, 0x0030, 0x7003, 0x0000, 0x6084, 0x20a2, 0x53a6, + 0x7007, 0x0001, 0x7974, 0xa184, 0xff00, 0x0040, 0x1db8, 0x810f, + 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0078, 0x1dbb, + 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006, 0xa211, + 0x7d10, 0xd5c4, 0x0040, 0x1dc8, 0x7b84, 0xa319, 0x7c80, 0xa421, + 0x7008, 0xd0fc, 0x0040, 0x1dc8, 0x7003, 0x0001, 0x7007, 0x0006, + 0x711a, 0x721e, 0x7d10, 0xd5c4, 0x0040, 0x1dd8, 0x7322, 0x7426, + 0xa084, 0x01e0, 0x007c, 0x7848, 0xa065, 0x0040, 0x1de3, 0x2c04, + 0x784a, 0x2063, 0x0000, 0x007c, 0x0f7e, 0x2079, 0x4a00, 0x7848, + 0x2062, 0x2c00, 0xa005, 0x00c0, 0x1def, 0x1078, 0x28ec, 0x784a, + 0x0f7f, 0x007c, 0x2011, 0x9400, 0x7a4a, 0x7bc4, 0x8319, 0x0040, + 0x1dff, 0xa280, 0x0032, 0x2012, 0x2010, 0x0078, 0x1df6, 0x2013, + 0x0000, 0x007c, 0x017e, 0x027e, 0xd7fc, 0x00c0, 0x1e0b, 0x2011, + 0x4fc0, 0x0078, 0x1e0d, 0x2011, 0x6fc0, 0xa784, 0x0f00, 0x800b, + 0xa784, 0x001f, 0x0040, 0x1e18, 0x8003, 0x8003, 0x8003, 0x8003, + 0xa105, 0xa268, 0x027f, 0x017f, 0x007c, 0x1078, 0x1e02, 0x2900, + 0x682a, 0x2a00, 0x682e, 0x6808, 0xa084, 0xf9ef, 0xa80d, 0x690a, + 0xd7fc, 0x00c0, 0x1e2f, 0x2009, 0x4a53, 0x0078, 0x1e31, 0x2009, + 0x4a93, 0x210c, 0x6804, 0xa005, 0x0040, 0x1e41, 0xa116, 0x00c0, + 0x1e41, 0x2060, 0x6000, 0x6806, 0x017e, 0x200b, 0x0000, 0x0078, + 0x1e44, 0x2009, 0x0000, 0x017e, 0x6804, 0xa065, 0x0040, 0x1e59, + 0x6000, 0x6806, 0x1078, 0x1e6f, 0x1078, 0x201b, 0x6810, 0x7908, + 0x8109, 0x790a, 0x8001, 0x6812, 0x00c0, 0x1e44, 0x7910, 0xc1a5, + 0x7912, 0x017f, 0x6902, 0x6906, 0x007c, 0xa065, 0x0040, 0x1e6e, + 0x2008, 0x609c, 0xa005, 0x0040, 0x1e6b, 0x2062, 0x609f, 0x0000, + 0xa065, 0x0078, 0x1e61, 0x7848, 0x794a, 0x2062, 0x007c, 0x6007, + 0x0103, 0x608f, 0x0000, 0x20a9, 0x001c, 0xac80, 0x0005, 0x20a0, + 0x2001, 0x0000, 0x40a4, 0x6828, 0x601a, 0x682c, 0x6022, 0x007c, + 0x0e7e, 0xd7fc, 0x00c0, 0x1e8a, 0x2071, 0x4a40, 0x2031, 0x4ac0, + 0x0078, 0x1e8e, 0x2071, 0x4a80, 0x2031, 0x4cc0, 0x7050, 0xa08c, + 0x0200, 0x00c0, 0x1e98, 0xa608, 0x2d0a, 0x8000, 0x7052, 0xa006, + 0x0e7f, 0x007c, 0x0f7e, 0xd7fc, 0x00c0, 0x1ea2, 0x2079, 0x4a40, + 0x0078, 0x1ea4, 0x2079, 0x4a80, 0x1078, 0x1e02, 0x2091, 0x8000, + 0x6804, 0x780a, 0xa065, 0x0040, 0x1ef8, 0x0078, 0x1eb6, 0x2c00, + 0x780a, 0x2060, 0x6000, 0xa065, 0x0040, 0x1ef8, 0x6010, 0xa306, + 0x00c0, 0x1eaf, 0x600c, 0xa206, 0x00c0, 0x1eaf, 0x2c28, 0x784c, + 0xac06, 0x00c0, 0x1ec5, 0x0078, 0x1ef5, 0x6804, 0xac06, 0x00c0, + 0x1ed3, 0x6000, 0x2060, 0x6806, 0xa005, 0x00c0, 0x1ed3, 0x6803, + 0x0000, 0x0078, 0x1edd, 0x6400, 0x7808, 0x2060, 0x6402, 0xa486, + 0x0000, 0x00c0, 0x1edd, 0x2c00, 0x6802, 0x2560, 0x0f7f, 0x1078, + 0x1e6f, 0x0f7e, 0x601b, 0x0005, 0x6023, 0x0020, 0x0f7f, 0x1078, + 0x201b, 0x0f7e, 0x7908, 0x8109, 0x790a, 0x6810, 0x8001, 0x6812, + 0x00c0, 0x1ef5, 0x7810, 0xc0a5, 0x7812, 0x2001, 0xffff, 0xa005, + 0x0f7f, 0x007c, 0x077e, 0x2700, 0x2039, 0x0000, 0xd0fc, 0x0040, + 0x1f02, 0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, + 0x2091, 0x8000, 0x1078, 0x1e1d, 0x8738, 0xa784, 0x001f, 0x00c0, + 0x1f0a, 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, + 0x00c0, 0x1f0a, 0x2091, 0x8001, 0x077f, 0x007c, 0x2061, 0x0000, + 0x6018, 0xd084, 0x00c0, 0x1f3e, 0x7810, 0xd08c, 0x0040, 0x1f2f, + 0xc08c, 0x7812, 0xc7fc, 0x2069, 0x4a40, 0x0078, 0x1f34, 0xc08d, + 0x7812, 0x2069, 0x4a80, 0xc7fd, 0x2091, 0x8000, 0x681c, 0x681f, + 0x0000, 0x2091, 0x8001, 0xa005, 0x00c0, 0x1f3f, 0x007c, 0xa08c, + 0xfff0, 0x0040, 0x1f45, 0x1078, 0x28ec, 0x0079, 0x1f47, 0x1f57, + 0x1f5a, 0x1f60, 0x1f64, 0x1f58, 0x1f68, 0x1f58, 0x1f58, 0x1f58, + 0x1f6e, 0x1f9f, 0x1fa3, 0x1fa9, 0x1f58, 0x1f58, 0x1f58, 0x007c, + 0x1078, 0x28ec, 0x1078, 0x1efa, 0x2001, 0x8001, 0x0078, 0x1fbe, + 0x2001, 0x8003, 0x0078, 0x1fbe, 0x2001, 0x8004, 0x0078, 0x1fbe, + 0x1078, 0x1efa, 0x2001, 0x8006, 0x0078, 0x1fbe, 0x2091, 0x8000, + 0x077e, 0xd7fc, 0x00c0, 0x1f7a, 0x2069, 0x4a40, 0x2039, 0x0009, + 0x0078, 0x1f7e, 0x2069, 0x4a80, 0x2039, 0x0009, 0x6800, 0xa086, + 0x0000, 0x0040, 0x1f88, 0x007f, 0x6f1e, 0x2091, 0x8001, 0x007c, + 0x6874, 0x077f, 0xa0bc, 0xff00, 0x2041, 0x0021, 0x2049, 0x0004, + 0x2051, 0x0010, 0x1078, 0x1e1d, 0x8738, 0xa784, 0x001f, 0x00c0, + 0x1f92, 0x2091, 0x8001, 0x2001, 0x800a, 0x0078, 0x1fbe, 0x2001, + 0x800c, 0x0078, 0x1fbe, 0x1078, 0x1efa, 0x2001, 0x800d, 0x0078, + 0x1fbe, 0x7814, 0xd0e4, 0x00c0, 0x1fbc, 0xd0ec, 0x0040, 0x1fb6, + 0xd7fc, 0x0040, 0x1fb6, 0x78ec, 0x0078, 0x1fb7, 0x78e4, 0x70c6, + 0x2001, 0x800e, 0x0078, 0x1fbe, 0x0078, 0x1f58, 0x70c2, 0xd7fc, + 0x00c0, 0x1fc6, 0x70db, 0x0000, 0x0078, 0x1fc8, 0x70db, 0x0001, + 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x4080, 0x007c, 0xac80, + 0x0001, 0x81ff, 0x0040, 0x1ffa, 0x2099, 0x0030, 0x20a0, 0x700c, + 0xa084, 0x03ff, 0x0040, 0x1fdc, 0x7018, 0x007e, 0x701c, 0x007e, + 0x7020, 0x007e, 0x7024, 0x007e, 0x7112, 0x81ac, 0x721a, 0x731e, + 0x7422, 0x7526, 0x7003, 0x0001, 0x7007, 0x0001, 0x7008, 0x800b, + 0x00c8, 0x1fee, 0x7007, 0x0002, 0xa08c, 0x01e0, 0x00c0, 0x1ffa, + 0x53a5, 0xa006, 0x7003, 0x0000, 0x7007, 0x0004, 0x007f, 0x7026, + 0x007f, 0x7022, 0x007f, 0x701e, 0x007f, 0x701a, 0x007c, 0x2011, + 0x0020, 0x2009, 0x0010, 0x6b0a, 0x6c0e, 0x6803, 0xfd00, 0x6807, + 0x0018, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290, 0x0004, 0x8109, + 0x00c0, 0x200b, 0x007c, 0x6004, 0x6086, 0x2c08, 0x2063, 0x0000, + 0x7868, 0xa005, 0x796a, 0x0040, 0x2028, 0x2c02, 0x0078, 0x2029, + 0x796e, 0x007c, 0x0c7e, 0x2061, 0x4a00, 0x6887, 0x0103, 0x2d08, + 0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0040, 0x203a, 0x2d02, + 0x0078, 0x203b, 0x616e, 0x0c7f, 0x007c, 0x2091, 0x8000, 0x2c04, + 0x786e, 0xa005, 0x00c0, 0x2045, 0x786a, 0x2091, 0x8001, 0x609c, + 0xa005, 0x0040, 0x205e, 0x0c7e, 0x2060, 0x2008, 0x609c, 0xa005, + 0x0040, 0x205a, 0x2062, 0x609f, 0x0000, 0xa065, 0x609c, 0xa005, + 0x00c0, 0x2052, 0x7848, 0x794a, 0x2062, 0x0c7f, 0x7848, 0x2062, + 0x609f, 0x0000, 0xac85, 0x0000, 0x00c0, 0x2068, 0x1078, 0x28ec, + 0x784a, 0x007c, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e, + 0x00c8, 0x2073, 0xa200, 0x00f0, 0x206e, 0x8086, 0x818e, 0x007c, + 0x157e, 0x20a9, 0x0010, 0xa005, 0x0040, 0x2099, 0xa11a, 0x00c8, + 0x2099, 0x8213, 0x818d, 0x0048, 0x208c, 0xa11a, 0x00c8, 0x208d, + 0x00f0, 0x2081, 0x0078, 0x2091, 0xa11a, 0x2308, 0x8210, 0x00f0, + 0x2081, 0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080, 0x007f, 0x157f, + 0x007c, 0x007e, 0x3200, 0xa085, 0x0800, 0x0078, 0x2095, 0x7d74, + 0x70d0, 0xa506, 0x0040, 0x2185, 0x7810, 0x2050, 0x7800, 0xd08c, + 0x0040, 0x20c1, 0xdaec, 0x0040, 0x20c1, 0x0e7e, 0x2091, 0x8000, + 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x20be, 0x7008, 0x0e7f, + 0xa086, 0x0008, 0x0040, 0x20c1, 0x0078, 0x2185, 0x0e7f, 0x0078, + 0x2185, 0x1078, 0x1ddb, 0x0040, 0x2185, 0xa046, 0x7970, 0x2500, + 0x8000, 0xa112, 0x2009, 0x0040, 0x00c8, 0x20d0, 0x0078, 0x20d7, + 0x72d0, 0xa206, 0x0040, 0x20d7, 0x8840, 0x2009, 0x0080, 0x0c7e, + 0x7112, 0x7007, 0x0001, 0x2099, 0x0030, 0x20a9, 0x0020, 0xac80, + 0x0001, 0x20a0, 0x2061, 0x0000, 0x88ff, 0x0040, 0x20e9, 0x1078, + 0x1ddb, 0x7008, 0xd0fc, 0x0040, 0x20e9, 0x7007, 0x0002, 0x2091, + 0x8001, 0xa08c, 0x01e0, 0x00c0, 0x2120, 0x53a5, 0x8cff, 0x00c0, + 0x20fe, 0x88ff, 0x0040, 0x216f, 0x0078, 0x2108, 0x2c00, 0x788e, + 0x20a9, 0x0020, 0xac80, 0x0001, 0x20a0, 0x53a5, 0x0078, 0x216f, + 0xa046, 0x7218, 0x731c, 0xdac4, 0x0040, 0x2110, 0x7420, 0x7524, + 0xa292, 0x0040, 0xa39b, 0x0000, 0xa4a3, 0x0000, 0xa5ab, 0x0000, + 0x721a, 0x731e, 0xdac4, 0x0040, 0x2120, 0x7422, 0x7526, 0xa006, + 0x7007, 0x0004, 0x0040, 0x216f, 0x8cff, 0x0040, 0x2129, 0x1078, + 0x1de4, 0x0c7f, 0x1078, 0x1de4, 0xa046, 0x7888, 0x8000, 0x788a, + 0xa086, 0x0002, 0x0040, 0x214f, 0x7a7c, 0x7b78, 0xdac4, 0x0040, + 0x213b, 0x7c84, 0x7d80, 0x7974, 0x8107, 0x8004, 0x8004, 0xa210, + 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x721a, 0x731e, + 0xdac4, 0x0040, 0x2185, 0x7422, 0x7526, 0x0078, 0x2185, 0x6014, + 0xd0fc, 0x00c0, 0x2157, 0x2069, 0x4a40, 0x0078, 0x2159, 0x2069, + 0x4a80, 0x2091, 0x8000, 0x681f, 0x0002, 0x88ff, 0x0040, 0x2165, + 0xa046, 0x788c, 0x2060, 0x0078, 0x214f, 0x788b, 0x0000, 0x78ac, + 0xa085, 0x0003, 0x78ae, 0x2091, 0x8001, 0x0078, 0x2185, 0x0c7f, + 0x788b, 0x0000, 0x1078, 0x2319, 0x6004, 0xa084, 0x000f, 0x1078, + 0x2186, 0x88ff, 0x0040, 0x2183, 0x788c, 0x2060, 0x6004, 0xa084, + 0x000f, 0x1078, 0x2186, 0x0078, 0x209f, 0x007c, 0x0079, 0x2188, + 0x2198, 0x21b6, 0x21d4, 0x2198, 0x21e5, 0x21a9, 0x2198, 0x2198, + 0x2198, 0x21b4, 0x21d2, 0x2198, 0x2198, 0x2198, 0x2198, 0x2198, + 0x2039, 0x0400, 0x78bc, 0xa705, 0x78be, 0x6008, 0xa705, 0x600a, + 0x1078, 0x2228, 0x609c, 0x78ba, 0x609f, 0x0000, 0x1078, 0x2303, + 0x007c, 0x78bc, 0xd0c4, 0x0040, 0x21af, 0x0078, 0x2198, 0x601c, + 0xc0bd, 0x601e, 0x0078, 0x21bc, 0x1078, 0x234b, 0x78bc, 0xd0c4, + 0x0040, 0x21bc, 0x0078, 0x2198, 0x78bf, 0x0000, 0x6004, 0x8007, + 0xa084, 0x00ff, 0x78b2, 0x8001, 0x0040, 0x21cf, 0x1078, 0x2228, + 0x0040, 0x21cf, 0x78bc, 0xc0c5, 0x78be, 0x0078, 0x21d1, 0x0078, + 0x2247, 0x007c, 0x1078, 0x2347, 0x78bc, 0xa08c, 0x0e00, 0x00c0, + 0x21dc, 0xd0c4, 0x00c0, 0x21de, 0x0078, 0x2198, 0x1078, 0x2228, + 0x00c0, 0x21e4, 0x0078, 0x2247, 0x007c, 0x78bc, 0xd0c4, 0x0040, + 0x21eb, 0x0078, 0x2198, 0x78bf, 0x0000, 0x6714, 0x2011, 0x0001, + 0x22a8, 0x6018, 0xa084, 0x00ff, 0xa005, 0x0040, 0x220b, 0xa7bc, + 0xff00, 0x20a9, 0x0020, 0xa08e, 0x0001, 0x0040, 0x220b, 0xa7bc, + 0x8000, 0x2011, 0x0002, 0x20a9, 0x0100, 0xa08e, 0x0002, 0x0040, + 0x220b, 0x0078, 0x2225, 0x1078, 0x1e02, 0x2d00, 0x2091, 0x8000, + 0x682b, 0x0000, 0x682f, 0x0000, 0x6808, 0xa084, 0xffde, 0x680a, + 0xade8, 0x0010, 0x2091, 0x8001, 0x00f0, 0x220e, 0x8211, 0x0040, + 0x2225, 0x20a9, 0x0100, 0x0078, 0x220e, 0x1078, 0x1de4, 0x007c, + 0x609f, 0x0000, 0x78b4, 0xa06d, 0x2c00, 0x78b6, 0x00c0, 0x2233, + 0x78ba, 0x0078, 0x223b, 0x689e, 0x2d00, 0x6002, 0x78b8, 0xad06, + 0x00c0, 0x223b, 0x6002, 0x78b0, 0x8001, 0x78b2, 0x00c0, 0x2246, + 0x78bc, 0xc0c4, 0x78be, 0x78b8, 0x2060, 0xa006, 0x007c, 0x0e7e, + 0xa02e, 0x2530, 0x7dba, 0x7db6, 0x65ae, 0x65b2, 0x601c, 0x60a2, + 0x2048, 0xa984, 0xe1ff, 0x601e, 0xa984, 0x0060, 0x0040, 0x225a, + 0x1078, 0x43c1, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x6714, 0x2071, + 0x4a80, 0xd7fc, 0x00c0, 0x2266, 0x2071, 0x4a40, 0xa784, 0x0f00, + 0x800b, 0xa784, 0x001f, 0x0040, 0x2271, 0x8003, 0x8003, 0x8003, + 0x8003, 0xa105, 0x71c4, 0xa168, 0x2700, 0x8007, 0xa084, 0x000f, + 0x8003, 0x8003, 0x8003, 0x71c8, 0xa100, 0x60c2, 0x2091, 0x8000, + 0x7810, 0xd0f4, 0x00c0, 0x228b, 0x6e08, 0xd684, 0x0040, 0x22a1, + 0xd9fc, 0x00c0, 0x22a1, 0x2091, 0x8001, 0x1078, 0x1e6f, 0x2091, + 0x8000, 0x1078, 0x201b, 0x2091, 0x8001, 0x7814, 0xd0e4, 0x00c0, + 0x2301, 0x7810, 0xd0f4, 0x0040, 0x2301, 0x601b, 0x0021, 0x0078, + 0x2301, 0x6024, 0xa096, 0x0001, 0x00c0, 0x22a8, 0x8000, 0x6026, + 0x6a10, 0x6814, 0xa202, 0x0048, 0x22bb, 0x0040, 0x22bb, 0x2091, + 0x8001, 0x2039, 0x0200, 0x609c, 0x78ba, 0x609f, 0x0000, 0x1078, + 0x2303, 0x0078, 0x2301, 0x2c08, 0xd9fc, 0x0040, 0x22de, 0x6800, + 0xa065, 0x0040, 0x22de, 0x6a04, 0x7000, 0xa084, 0x0002, 0x0040, + 0x22d9, 0x704c, 0xa206, 0x00c0, 0x22d9, 0x6b04, 0x2160, 0x2304, + 0x6002, 0xa005, 0x00c0, 0x22d5, 0x6902, 0x2260, 0x6102, 0x0078, + 0x22ea, 0x2160, 0x6202, 0x6906, 0x0078, 0x22ea, 0x6800, 0x6902, + 0xa065, 0x0040, 0x22e6, 0x6102, 0x0078, 0x22e7, 0x6906, 0x2160, + 0x6003, 0x0000, 0x2160, 0xd9fc, 0x0040, 0x22f1, 0xa6b4, 0xfffc, + 0x6e0a, 0x6810, 0x7d08, 0x8528, 0x7d0a, 0x8000, 0x6812, 0x2091, + 0x8001, 0xd6b4, 0x0040, 0x2301, 0xa6b6, 0x0040, 0x6e0a, 0x1078, + 0x1e80, 0x0e7f, 0x007c, 0x6008, 0xa705, 0x600a, 0x2091, 0x8000, + 0x1078, 0x201b, 0x2091, 0x8001, 0x78b8, 0xa065, 0x0040, 0x2316, + 0x609c, 0x78ba, 0x609f, 0x0000, 0x0078, 0x2303, 0x78b6, 0x78ba, + 0x007c, 0x7970, 0x7874, 0x2818, 0xd384, 0x0040, 0x2323, 0x8000, + 0xa112, 0x0048, 0x2328, 0x8000, 0xa112, 0x00c8, 0x2338, 0xc384, + 0x7a7c, 0x721a, 0x7a78, 0x721e, 0xdac4, 0x0040, 0x2333, 0x7a84, + 0x7222, 0x7a80, 0x7226, 0xa006, 0xd384, 0x0040, 0x2338, 0x8000, + 0x7876, 0x70d2, 0x781c, 0xa005, 0x0040, 0x2346, 0x8001, 0x781e, + 0x00c0, 0x2346, 0x0068, 0x2346, 0x2091, 0x4080, 0x007c, 0x2039, + 0x235f, 0x0078, 0x234d, 0x2039, 0x2365, 0x2704, 0xa005, 0x0040, + 0x235e, 0xac00, 0x2068, 0x6908, 0x6810, 0x6912, 0x680a, 0x690c, + 0x6814, 0x6916, 0x680e, 0x8738, 0x0078, 0x234d, 0x007c, 0x0003, + 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0015, 0x001b, 0x0000, + 0x2041, 0x0000, 0x780c, 0x0079, 0x236d, 0x2535, 0x2508, 0x2371, + 0x23e5, 0x2039, 0x9274, 0x2734, 0x7d10, 0x0078, 0x238c, 0x6084, + 0xa086, 0x0103, 0x00c0, 0x23ce, 0x6114, 0x6018, 0xa105, 0x00c0, + 0x23ce, 0x8603, 0xa080, 0x9255, 0x620c, 0x2202, 0x8000, 0x6210, + 0x2202, 0x1078, 0x203d, 0x8630, 0xa68e, 0x000f, 0x0040, 0x2454, + 0x786c, 0xa065, 0x00c0, 0x2377, 0x7808, 0xa602, 0x00c8, 0x239d, + 0xd5ac, 0x00c0, 0x239d, 0x263a, 0x007c, 0xa682, 0x0003, 0x00c8, + 0x2454, 0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, + 0x23c9, 0x2011, 0x9255, 0x2204, 0x70c6, 0x8210, 0x2204, 0x70ca, + 0xd684, 0x00c0, 0x23b9, 0x8210, 0x2204, 0x70da, 0x8210, 0x2204, + 0x70de, 0xa685, 0x8020, 0x70c2, 0x681b, 0x0001, 0x2091, 0x4080, + 0x7810, 0xa084, 0xffcf, 0x7812, 0x2091, 0x8001, 0x203b, 0x0000, + 0x007c, 0x7810, 0xc0ad, 0x7812, 0x0078, 0x2454, 0x263a, 0x1078, + 0x253f, 0x00c0, 0x254e, 0x786c, 0xa065, 0x00c0, 0x2377, 0x2091, + 0x8000, 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0040, 0x23e0, 0xc0ad, + 0x7812, 0x2091, 0x8001, 0x0078, 0x254e, 0x2039, 0x9274, 0x2734, + 0x7d10, 0x0078, 0x23fc, 0x6084, 0xa086, 0x0103, 0x00c0, 0x243d, + 0x6114, 0x6018, 0xa105, 0x00c0, 0x243d, 0xa680, 0x9255, 0x620c, + 0x2202, 0x1078, 0x203d, 0x8630, 0xa68e, 0x001e, 0x0040, 0x2454, + 0x786c, 0xa065, 0x00c0, 0x23eb, 0x7808, 0xa602, 0x00c8, 0x240d, + 0xd5ac, 0x00c0, 0x240d, 0x263a, 0x007c, 0xa682, 0x0006, 0x00c8, + 0x2454, 0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, + 0x2438, 0x2011, 0x9255, 0x2009, 0x924e, 0x26a8, 0x211c, 0x2204, + 0x201a, 0x8108, 0x8210, 0x00f0, 0x241e, 0xa685, 0x8030, 0x70c2, + 0x681b, 0x0001, 0x2091, 0x4080, 0x7810, 0xa084, 0xffcf, 0x7812, + 0x2091, 0x8001, 0xa006, 0x2009, 0x9275, 0x200a, 0x203a, 0x007c, + 0x7810, 0xc0ad, 0x7812, 0x0078, 0x2454, 0x263a, 0x1078, 0x253f, + 0x00c0, 0x254e, 0x786c, 0xa065, 0x00c0, 0x23eb, 0x2091, 0x8000, + 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0040, 0x244f, 0xc0ad, 0x7812, + 0x2091, 0x8001, 0x0078, 0x254e, 0x2091, 0x8000, 0x7007, 0x0004, + 0x7994, 0x70d4, 0xa102, 0x0048, 0x2465, 0x0040, 0x246f, 0x7b90, + 0xa302, 0x00c0, 0x246f, 0x0078, 0x2468, 0x8002, 0x00c0, 0x246f, + 0x263a, 0x7810, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x007c, 0xa184, + 0xff00, 0x0040, 0x247c, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, + 0x8007, 0xa100, 0x0078, 0x247f, 0x8107, 0x8004, 0x8004, 0x7a9c, + 0xa210, 0x721a, 0x7a98, 0xa006, 0xa211, 0x721e, 0xd4c4, 0x0040, + 0x248f, 0x7aa4, 0xa211, 0x7222, 0x7aa0, 0xa211, 0x7226, 0x20a1, + 0x0030, 0x7003, 0x0000, 0x2009, 0x9254, 0x260a, 0x8109, 0x2198, + 0x2104, 0xd084, 0x0040, 0x249d, 0x8633, 0xa6b0, 0x0002, 0x26a8, + 0x53a6, 0x8603, 0x7012, 0x7007, 0x0001, 0x7990, 0x7894, 0x8000, + 0xa10a, 0x00c8, 0x24ac, 0xa006, 0x2028, 0x7974, 0xa184, 0xff00, + 0x0040, 0x24bb, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, + 0xa100, 0x0078, 0x24be, 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, + 0x7a78, 0xa006, 0xa211, 0xd4c4, 0x0040, 0x24ca, 0x7b84, 0xa319, + 0x7c80, 0xa421, 0x7008, 0xd0fc, 0x0040, 0x24ca, 0xa084, 0x01e0, + 0x0040, 0x24ef, 0x7d10, 0x2031, 0x9254, 0x2634, 0x78a8, 0x8000, + 0x78aa, 0xd08c, 0x00c0, 0x24e4, 0x7007, 0x0006, 0x7004, 0xd094, + 0x00c0, 0x24de, 0x0078, 0x2456, 0x2069, 0x4a47, 0x206b, 0x0003, + 0x78ac, 0xa085, 0x0300, 0x78ae, 0xa006, 0x0078, 0x24f8, 0x2030, + 0x75d6, 0x2091, 0x4080, 0x7d96, 0x7d10, 0xa5ac, 0xffcf, 0x7d12, + 0x2091, 0x8001, 0x78aa, 0x7007, 0x0006, 0x263a, 0x7003, 0x0001, + 0x711a, 0x721e, 0xd5c4, 0x0040, 0x2507, 0x7322, 0x7426, 0x007c, + 0x6084, 0xa086, 0x0103, 0x00c0, 0x252b, 0x6114, 0x6018, 0xa105, + 0x00c0, 0x252b, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, 0x252b, + 0x600c, 0x70c6, 0x6010, 0x70ca, 0x70c3, 0x8020, 0x681b, 0x0001, + 0x2091, 0x4080, 0x1078, 0x203d, 0x0068, 0x252a, 0x786c, 0xa065, + 0x00c0, 0x2508, 0x007c, 0x1078, 0x253f, 0x00c0, 0x254e, 0x786c, + 0xa065, 0x00c0, 0x2508, 0x0078, 0x254e, 0x1078, 0x253f, 0x00c0, + 0x254e, 0x786c, 0xa065, 0x00c0, 0x2535, 0x0078, 0x254e, 0x1078, + 0x2554, 0x00c0, 0x2546, 0xa085, 0x0001, 0x007c, 0x1078, 0x2563, + 0x00c0, 0x254c, 0x2041, 0x0001, 0x7d10, 0x007c, 0x88ff, 0x0040, + 0x2553, 0x2091, 0x4080, 0x007c, 0x7b90, 0x7994, 0x70d4, 0xa102, + 0x00c0, 0x255d, 0xa385, 0x0000, 0x007c, 0x0048, 0x2561, 0xa302, + 0x007c, 0x8002, 0x007c, 0x7810, 0xd0ec, 0x0040, 0x257b, 0x0e7e, + 0x2091, 0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x2578, + 0x7008, 0x0e7f, 0xa086, 0x0008, 0x0040, 0x257b, 0x0078, 0x25cc, + 0x0e7f, 0x0078, 0x25cc, 0xa184, 0xff00, 0x0040, 0x2588, 0x810f, + 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0078, 0x258b, + 0x8107, 0x8004, 0x8004, 0x7a9c, 0x7b98, 0x7ca4, 0x7da0, 0xa210, + 0xa006, 0xa319, 0xa421, 0xa529, 0x2009, 0x0018, 0x6028, 0xa005, + 0x0040, 0x259c, 0x2009, 0x0040, 0x1078, 0x1d92, 0x0040, 0x25be, + 0x78a8, 0x8000, 0x78aa, 0xd08c, 0x00c0, 0x25cc, 0x6014, 0xd0fc, + 0x00c0, 0x25ae, 0x2069, 0x4a40, 0x0078, 0x25b0, 0x2069, 0x4a80, + 0x2091, 0x8000, 0x681f, 0x0003, 0x78ab, 0x0000, 0x78ac, 0xa085, + 0x0300, 0x78ae, 0x2091, 0x8001, 0x0078, 0x25cc, 0x78ab, 0x0000, + 0x1078, 0x203d, 0x7990, 0x7894, 0x8000, 0xa10a, 0x00c8, 0x25c9, + 0xa006, 0x7896, 0x70d6, 0xa006, 0x2071, 0x0010, 0x2091, 0x8001, + 0x007c, 0x2138, 0xd7fc, 0x00c0, 0x25d9, 0x2009, 0x4a59, 0x0078, + 0x25db, 0x2009, 0x4a99, 0x2091, 0x8000, 0x200a, 0x0f7e, 0xd7fc, + 0x00c0, 0x25f2, 0x2009, 0x4a40, 0x2001, 0x4a04, 0x2004, 0xd0ec, + 0x0040, 0x25ee, 0x2079, 0x0100, 0x0078, 0x25f6, 0x2079, 0x0200, + 0x0078, 0x25f6, 0x2009, 0x4a80, 0x2079, 0x0100, 0x2104, 0xa086, + 0x0000, 0x00c0, 0x260f, 0xd7fc, 0x00c0, 0x2602, 0x2009, 0x4a45, + 0x0078, 0x2604, 0x2009, 0x4a85, 0x2104, 0xa005, 0x00c0, 0x260f, + 0x7830, 0xa084, 0x00c0, 0x00c0, 0x260f, 0x781b, 0x0045, 0x0f7f, + 0x007c, 0x2009, 0x0002, 0x2069, 0x4a00, 0x6810, 0xd0ec, 0x00c0, + 0x2672, 0x2071, 0x4a80, 0x2079, 0x0100, 0x2021, 0x4cbf, 0x784b, + 0x000f, 0x2019, 0x4205, 0xd184, 0x0040, 0x2632, 0x6810, 0xd0ec, + 0x0040, 0x262e, 0x20a1, 0x012b, 0x0078, 0x2634, 0x20a1, 0x022b, + 0x0078, 0x2634, 0x20a1, 0x012b, 0x2304, 0xa005, 0x0040, 0x2641, + 0x789a, 0x8318, 0x23ac, 0x8318, 0x2398, 0x53a6, 0x3318, 0x0078, + 0x2634, 0x789b, 0x0020, 0x20a9, 0x0010, 0x78af, 0x0000, 0x78af, + 0x8020, 0x00f0, 0x2645, 0x7003, 0x0000, 0x017e, 0xd18c, 0x2009, + 0x0000, 0x0040, 0x2654, 0xc1bd, 0x1078, 0x283d, 0x017f, 0x7020, + 0xa084, 0x000f, 0x007e, 0x6814, 0xd0e4, 0x007f, 0x00c0, 0x2664, + 0xa085, 0x6340, 0x0078, 0x2666, 0xa085, 0x62c0, 0x7806, 0x780f, + 0x9200, 0x7843, 0x00d8, 0x7853, 0x0080, 0x780b, 0x0008, 0x7456, + 0x7053, 0x0000, 0x8109, 0x0040, 0x2685, 0x2071, 0x4a40, 0x6810, + 0xd0ec, 0x0040, 0x267f, 0x2079, 0x0100, 0x0078, 0x2681, 0x2079, + 0x0200, 0x2021, 0x4abf, 0x0078, 0x261f, 0x007c, 0x017e, 0xd1bc, + 0x00c0, 0x269a, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, + 0x0040, 0x2696, 0x2011, 0x0101, 0x0078, 0x269c, 0x2011, 0x0201, + 0x0078, 0x269c, 0x2011, 0x0101, 0xa18c, 0x000f, 0x2204, 0xa084, + 0xfff0, 0xa105, 0x2012, 0x017f, 0x1078, 0x283d, 0x007c, 0xd3fc, + 0x00c0, 0x26ba, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, + 0x0040, 0x26b6, 0x2011, 0x0101, 0x0078, 0x26bc, 0x2011, 0x0201, + 0x0078, 0x26bc, 0x2011, 0x0101, 0x20a9, 0x0009, 0x810b, 0x00f0, + 0x26be, 0xa18c, 0x0e00, 0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012, + 0x007c, 0x2019, 0x0002, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x0040, + 0x26d6, 0x8319, 0x2009, 0x0101, 0x0078, 0x26d8, 0x2009, 0x0101, + 0x20a9, 0x0005, 0x8213, 0x00f0, 0x26da, 0xa294, 0x00e0, 0x2104, + 0xa084, 0xff1f, 0xa205, 0x200a, 0x8319, 0x0040, 0x26eb, 0x2009, + 0x0201, 0x0078, 0x26d8, 0x007c, 0xd3fc, 0x00c0, 0x26ff, 0x007e, + 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x26fb, 0x2011, + 0x0101, 0x0078, 0x2701, 0x2011, 0x0201, 0x0078, 0x2701, 0x2011, + 0x0101, 0x20a9, 0x000c, 0x810b, 0x00f0, 0x2703, 0xa18c, 0xf000, + 0x2204, 0xa084, 0x0fff, 0xa105, 0x2012, 0x007c, 0xd3fc, 0x00c0, + 0x2721, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, + 0x271d, 0x2011, 0x0102, 0x0078, 0x2723, 0x2011, 0x0202, 0x0078, + 0x2723, 0x2011, 0x0102, 0x2204, 0xa084, 0xffcf, 0xa105, 0x2012, + 0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x273d, 0x007e, 0x2001, 0x4a04, + 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2739, 0x2061, 0x0100, 0x0078, + 0x273f, 0x2061, 0x0200, 0x0078, 0x273f, 0x2061, 0x0100, 0xc1bc, + 0x8103, 0x8003, 0xa080, 0x0020, 0x609a, 0x62ac, 0x63ac, 0x0c7f, + 0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x275d, 0x007e, 0x2001, 0x4a04, + 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2759, 0x2061, 0x0100, 0x0078, + 0x275f, 0x2061, 0x0200, 0x0078, 0x275f, 0x2061, 0x0100, 0xc1bc, + 0x8103, 0x8003, 0xa080, 0x0022, 0x609a, 0x60a4, 0xa084, 0xffdf, + 0x60ae, 0x0c7f, 0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x277f, 0x007e, + 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x277b, 0x2061, + 0x0100, 0x0078, 0x2781, 0x2061, 0x0200, 0x0078, 0x2781, 0x2061, + 0x0100, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0022, 0x609a, 0x60a4, + 0xa085, 0x0020, 0x60ae, 0x0c7f, 0x007c, 0x0c7e, 0xd1bc, 0x00c0, + 0x27a1, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, + 0x279d, 0x2061, 0x0100, 0x0078, 0x27a3, 0x2061, 0x0200, 0x0078, + 0x27a3, 0x2061, 0x0100, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0020, + 0x609a, 0x60a4, 0xa28c, 0x0020, 0x0040, 0x27b1, 0xc2ac, 0xa39d, + 0x4000, 0xc3fc, 0xd3b4, 0x00c0, 0x27b6, 0xc3fd, 0x62ae, 0x2010, + 0x60a4, 0x63ae, 0x2018, 0x0c7f, 0x007c, 0x2091, 0x8000, 0x0c7e, + 0x0e7e, 0x6818, 0xa005, 0x0040, 0x281b, 0xd1fc, 0x0040, 0x27cc, + 0x2061, 0x91d0, 0x0078, 0x27ce, 0x2061, 0x90c0, 0x1078, 0x2823, + 0x0040, 0x2801, 0x20a9, 0x0101, 0xd1fc, 0x0040, 0x27db, 0x2061, + 0x90d0, 0x0078, 0x27dd, 0x2061, 0x8fc0, 0x0c7e, 0x1078, 0x2823, + 0x0040, 0x27e8, 0x0c7f, 0x8c60, 0x00f0, 0x27dd, 0x0078, 0x281b, + 0x007f, 0xd1fc, 0x0040, 0x27f2, 0xa082, 0x90d0, 0x2071, 0x4a80, + 0x0078, 0x27f6, 0xa082, 0x8fc0, 0x2071, 0x4a40, 0x707a, 0x7176, + 0x2001, 0x0004, 0x7066, 0x7083, 0x000f, 0x1078, 0x25d1, 0x0078, + 0x2817, 0xd1fc, 0x00c0, 0x2808, 0x2071, 0x4a40, 0x0078, 0x280a, + 0x2071, 0x4a80, 0x6020, 0xc0dd, 0x6022, 0x7176, 0x2c00, 0x707e, + 0x2001, 0x0006, 0x7066, 0x7083, 0x000f, 0x1078, 0x25d1, 0x2001, + 0x0000, 0x0078, 0x281d, 0x2001, 0x0001, 0x2091, 0x8001, 0xa005, + 0x0e7f, 0x0c7f, 0x007c, 0x2c04, 0xa005, 0x0040, 0x283a, 0x2060, + 0x6010, 0xa306, 0x00c0, 0x2837, 0x600c, 0xa206, 0x00c0, 0x2837, + 0x6014, 0xa106, 0x00c0, 0x2837, 0xa006, 0x0078, 0x283c, 0x6000, + 0x0078, 0x2824, 0xa085, 0x0001, 0x007c, 0x0f7e, 0x0e7e, 0x017e, + 0xd1bc, 0x00c0, 0x2855, 0x2079, 0x4a40, 0x007e, 0x2001, 0x4a04, + 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2851, 0x2071, 0x0100, 0x0078, + 0x2859, 0x2071, 0x0200, 0x0078, 0x2859, 0x2079, 0x4a80, 0x2071, + 0x0100, 0x7920, 0xa18c, 0x000f, 0x70ec, 0xd0c4, 0x00c0, 0x2863, + 0x017f, 0x0078, 0x287e, 0x810b, 0x810b, 0x810b, 0x810b, 0x007f, + 0xd0bc, 0x00c0, 0x287b, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, + 0x007f, 0x0040, 0x2877, 0xa18d, 0x0f00, 0x0078, 0x287d, 0xa18d, + 0x0f00, 0x0078, 0x287d, 0xa18d, 0x0800, 0x2104, 0x0e7f, 0x0f7f, + 0x007c, 0x0e7e, 0x2001, 0x4a01, 0x2004, 0xd0ac, 0x00c0, 0x28ea, + 0x68e4, 0xd0ac, 0x0040, 0x28ea, 0xa084, 0x0006, 0x00c0, 0x28ea, + 0x6014, 0xd0fc, 0x00c0, 0x2898, 0x2071, 0x4ec0, 0x0078, 0x289a, + 0x2071, 0x4f40, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, + 0xae70, 0x7004, 0xa084, 0x000a, 0x00c0, 0x28ea, 0x7108, 0xa194, + 0xff00, 0x0040, 0x28ea, 0xa18c, 0x00ff, 0x2001, 0x000a, 0xa106, + 0x0040, 0x28cd, 0x2001, 0x000c, 0xa106, 0x0040, 0x28d1, 0x2001, + 0x0012, 0xa106, 0x0040, 0x28d5, 0x2001, 0x0014, 0xa106, 0x0040, + 0x28d9, 0x2001, 0x0019, 0xa106, 0x0040, 0x28dd, 0x2001, 0x0032, + 0xa106, 0x0040, 0x28e1, 0x0078, 0x28e5, 0x2009, 0x000c, 0x0078, + 0x28e7, 0x2009, 0x0012, 0x0078, 0x28e7, 0x2009, 0x0014, 0x0078, + 0x28e7, 0x2009, 0x0019, 0x0078, 0x28e7, 0x2009, 0x0020, 0x0078, + 0x28e7, 0x2009, 0x003f, 0x0078, 0x28e7, 0x2011, 0x0000, 0x2100, + 0xa205, 0x700a, 0x0e7f, 0x007c, 0x0068, 0x28ec, 0x2091, 0x8000, + 0x2071, 0x0000, 0x007e, 0x7018, 0xd084, 0x00c0, 0x28f3, 0x007f, + 0x2071, 0x0010, 0x70ca, 0x007f, 0x70c6, 0x70c3, 0x8002, 0x70db, + 0x0809, 0x70df, 0x0000, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, + 0x4080, 0x0078, 0x2909, 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x78a0, + 0x708e, 0x7592, 0x7496, 0x769a, 0x779e, 0xa594, 0x003f, 0xd4f4, + 0x0040, 0x2920, 0xa784, 0x007d, 0x00c0, 0x417b, 0x1078, 0x28ec, + 0xa49c, 0x000f, 0xa382, 0x0004, 0x0050, 0x292b, 0xa3a6, 0x0007, + 0x00c0, 0x28ec, 0x2418, 0x8507, 0xa084, 0x000f, 0x0079, 0x2930, + 0x2f45, 0x3035, 0x3060, 0x32c1, 0x363b, 0x36a1, 0x3741, 0x37bd, + 0x38a1, 0x398a, 0x2943, 0x2940, 0x2d2a, 0x2e43, 0x360e, 0x2940, + 0x1078, 0x28ec, 0x007c, 0xa006, 0x0078, 0x294d, 0x7808, 0xc08d, + 0x780a, 0xa006, 0x7002, 0x704e, 0x7046, 0x70d2, 0x7060, 0xa005, + 0x00c0, 0x2a64, 0x7064, 0xa084, 0x0007, 0x0079, 0x2957, 0x295f, + 0x29cf, 0x29d8, 0x29e3, 0x29ee, 0x2a4a, 0x29f9, 0x29cf, 0x7830, + 0xd0bc, 0x00c0, 0x2942, 0x71d4, 0xd1b4, 0x00c0, 0x29ac, 0x70a4, + 0xa086, 0x0001, 0x0040, 0x2942, 0x70b4, 0xa06d, 0x6800, 0xa065, + 0xa055, 0x789b, 0x0010, 0x6b0c, 0x7baa, 0x6808, 0xa045, 0x6d10, + 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001, 0x0040, 0x2982, 0x69bc, + 0x7daa, 0x79aa, 0x68c0, 0xa04d, 0x6e1c, 0x2001, 0x0010, 0x0078, + 0x2bbd, 0x7060, 0xa005, 0x00c0, 0x2942, 0x0c7e, 0x0d7e, 0x70b4, + 0xa06d, 0x6800, 0xa065, 0xa055, 0x789b, 0x0010, 0x6b0c, 0x7baa, + 0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001, + 0x0040, 0x29a5, 0x69bc, 0x7daa, 0x79aa, 0x68c0, 0xa04d, 0x6e1c, + 0x2001, 0x0020, 0x0078, 0x2bbd, 0x1078, 0x411c, 0x00c0, 0x2942, + 0x781b, 0x005b, 0x70bc, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, + 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, 0x780a, 0x68bc, + 0x7042, 0xc1b4, 0x71d6, 0x70b8, 0xa065, 0x68c0, 0x705a, 0x7003, + 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x007c, 0x1078, + 0x411c, 0x00c0, 0x29d7, 0x781b, 0x0047, 0x7003, 0x0004, 0x007c, + 0x1078, 0x411c, 0x00c0, 0x29e2, 0x2011, 0x000c, 0x1078, 0x2a09, + 0x7003, 0x0004, 0x007c, 0x1078, 0x411c, 0x00c0, 0x29ed, 0x2011, + 0x0006, 0x1078, 0x2a09, 0x7003, 0x0004, 0x007c, 0x1078, 0x411c, + 0x00c0, 0x29f8, 0x2011, 0x000d, 0x1078, 0x2a09, 0x7003, 0x0004, + 0x007c, 0x1078, 0x411c, 0x00c0, 0x2a08, 0x2011, 0x0006, 0x1078, + 0x2a09, 0x707c, 0x707f, 0x0000, 0x2068, 0x704e, 0x7003, 0x0001, + 0x007c, 0x7174, 0xc1fc, 0x8107, 0x7882, 0x789b, 0x0010, 0xa286, + 0x000c, 0x00c0, 0x2a18, 0x7aaa, 0x2001, 0x0001, 0x0078, 0x2a2d, + 0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, 0xa286, 0x000d, 0x0040, + 0x2a26, 0x7aaa, 0x2001, 0x0002, 0x0078, 0x2a2d, 0x78ab, 0x0020, + 0x7178, 0x79aa, 0x7aaa, 0x2001, 0x0004, 0x789b, 0x0060, 0x78aa, + 0x785b, 0x0004, 0x781b, 0x0108, 0x1078, 0x4131, 0x7083, 0x000f, + 0x70d4, 0xd0b4, 0x0040, 0x2a49, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, + 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, + 0x0c7f, 0x007c, 0x1078, 0x411c, 0x00c0, 0x2942, 0x707c, 0x2068, + 0x7774, 0x1078, 0x3fe1, 0x2c50, 0x1078, 0x41f0, 0x789b, 0x0010, + 0x6814, 0xa084, 0x001f, 0xc0bd, 0x78aa, 0x6e1c, 0x2041, 0x0001, + 0x2001, 0x0004, 0x0078, 0x2bc3, 0x1078, 0x411c, 0x00c0, 0x2942, + 0x789b, 0x0010, 0x7060, 0x2068, 0x6f14, 0x70d4, 0xd0b4, 0x0040, + 0x2a7e, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084, + 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x1078, 0x3fe1, + 0x2c50, 0x1078, 0x41f0, 0x6824, 0xa005, 0x0040, 0x2a8f, 0xa082, + 0x0006, 0x0048, 0x2a8d, 0x0078, 0x2a8f, 0x6827, 0x0005, 0x6814, + 0xa084, 0x001f, 0xc0bd, 0x78aa, 0x2031, 0x0020, 0x2041, 0x0001, + 0x2001, 0x0003, 0x0078, 0x2bc3, 0xc28d, 0x72d6, 0x72c0, 0xa200, + 0xa015, 0x7154, 0x8108, 0xa12a, 0x0048, 0x2aa7, 0x71c0, 0x2164, + 0x6504, 0x85ff, 0x00c0, 0x2abe, 0x7156, 0x8421, 0x00c0, 0x2aa2, + 0x70d4, 0xd08c, 0x0040, 0x2aba, 0x70d0, 0xa005, 0x00c0, 0x2aba, + 0x70d3, 0x000a, 0x007c, 0x2200, 0x0078, 0x2aac, 0x70d4, 0xc08c, + 0x70d6, 0x70d3, 0x0000, 0x603c, 0xa005, 0x00c0, 0x2abb, 0x6708, + 0xa784, 0x073f, 0x0040, 0x2aed, 0xd7d4, 0x00c0, 0x2abb, 0xa784, + 0x0021, 0x00c0, 0x2abb, 0xa784, 0x0002, 0x0040, 0x2ade, 0xa784, + 0x0004, 0x0040, 0x2abb, 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0218, + 0x00c0, 0x2abb, 0xa784, 0x0100, 0x0040, 0x2aed, 0x6018, 0xa005, + 0x00c0, 0x2abb, 0xa7bc, 0xfeff, 0x670a, 0x2568, 0x6823, 0x0000, + 0x6e1c, 0xa684, 0x000e, 0x6318, 0x0040, 0x2afe, 0x601c, 0xa302, + 0x0048, 0x2b01, 0x0040, 0x2b01, 0x0078, 0x2abb, 0x83ff, 0x00c0, + 0x2abb, 0x2d58, 0x2c50, 0x7156, 0xd7bc, 0x00c0, 0x2b09, 0x7028, + 0x6022, 0xc7bc, 0x670a, 0x68c0, 0xa065, 0xa04d, 0x6100, 0x2a60, + 0x2041, 0x0001, 0x6b14, 0xa39c, 0x001f, 0xa39d, 0x00c0, 0xd1fc, + 0x0040, 0x2b1d, 0xd684, 0x0040, 0x2b1f, 0xa39c, 0xffbf, 0xd6a4, + 0x0040, 0x2b24, 0xa39d, 0x0020, 0xa684, 0x000e, 0x00c0, 0x2b6f, + 0xc7a5, 0x670a, 0x2c00, 0x68c6, 0x77a4, 0xa786, 0x0001, 0x00c0, + 0x2b43, 0x70d4, 0xd0b4, 0x00c0, 0x2b43, 0x7000, 0xa082, 0x0002, + 0x00c8, 0x2b43, 0x7830, 0xd0bc, 0x00c0, 0x2b43, 0x789b, 0x0010, + 0x7baa, 0x0078, 0x2bbb, 0x8739, 0x77a6, 0x2750, 0x77b0, 0xa7b0, + 0x0005, 0x70ac, 0xa606, 0x00c0, 0x2b4e, 0x76a8, 0x76b2, 0x2c3a, + 0x8738, 0x2d3a, 0x8738, 0x283a, 0x8738, 0x233a, 0x8738, 0x253a, + 0x7830, 0xd0bc, 0x0040, 0x2b66, 0x2091, 0x8000, 0x2091, 0x303d, + 0x70d4, 0xa084, 0x303d, 0x2091, 0x8000, 0x2090, 0xaad5, 0x0000, + 0x0040, 0x2b6e, 0x8421, 0x2200, 0x00c0, 0x2aa1, 0x007c, 0xd1dc, + 0x0040, 0x3be5, 0x2029, 0x0020, 0xd69c, 0x00c0, 0x2b7c, 0x8528, + 0xd68c, 0x00c0, 0x2b7c, 0x8528, 0x8840, 0x6f14, 0x610c, 0x8108, + 0xa18c, 0x00ff, 0x70cc, 0xa160, 0x2c64, 0x8cff, 0x0040, 0x2b9b, + 0x6014, 0xa706, 0x00c0, 0x2b84, 0x60b8, 0x8001, 0x60ba, 0x00c0, + 0x2b7f, 0x2a60, 0x6008, 0xa085, 0x0100, 0x600a, 0x2200, 0x8421, + 0x00c0, 0x2aa1, 0x007c, 0x2a60, 0x610e, 0x69be, 0x2c00, 0x68c6, + 0x8840, 0x6008, 0xc0d5, 0x600a, 0x77a4, 0xa786, 0x0001, 0x00c0, + 0x2b43, 0x70d4, 0xd0b4, 0x00c0, 0x2b43, 0x7000, 0xa082, 0x0002, + 0x00c8, 0x2b43, 0x7830, 0xd0bc, 0x00c0, 0x2b43, 0x789b, 0x0010, + 0x7baa, 0x7daa, 0x79aa, 0x2001, 0x0002, 0x007e, 0x6018, 0x8000, + 0x601a, 0x0078, 0x2bc4, 0x007e, 0x2960, 0x6104, 0x2a60, 0xa184, + 0x0018, 0x0040, 0x2be0, 0xa184, 0x0010, 0x0040, 0x2bd3, 0x1078, + 0x3df6, 0x00c0, 0x2c05, 0xa184, 0x0008, 0x0040, 0x2be0, 0x69a0, + 0xa184, 0x0600, 0x00c0, 0x2be0, 0x1078, 0x3cda, 0x0078, 0x2c05, + 0x69a0, 0xa184, 0x1e00, 0x0040, 0x2c10, 0xa184, 0x0800, 0x0040, + 0x2bf9, 0x0c7e, 0x2960, 0x6000, 0xa085, 0x2000, 0x6002, 0x6104, + 0xa18d, 0x0010, 0x6106, 0x0c7f, 0x1078, 0x3df6, 0x00c0, 0x2c05, + 0x69a0, 0xa184, 0x0200, 0x0040, 0x2c01, 0x1078, 0x3d3a, 0x0078, + 0x2c05, 0xa184, 0x0400, 0x00c0, 0x2bdc, 0x69a0, 0xa184, 0x1000, + 0x0040, 0x2c10, 0x6914, 0xa18c, 0xff00, 0x810f, 0x1078, 0x2749, + 0x027f, 0xa68c, 0x00e0, 0xa684, 0x0060, 0x0040, 0x2c1d, 0xa086, + 0x0060, 0x00c0, 0x2c1d, 0xa18d, 0x4000, 0xa18d, 0x0104, 0x69b6, + 0x789b, 0x0060, 0x2800, 0x78aa, 0x6818, 0xc0fd, 0x681a, 0xd6bc, + 0x0040, 0x2c38, 0xc0fc, 0x7087, 0x0000, 0xa08a, 0x000d, 0x0050, + 0x2c36, 0xa08a, 0x000c, 0x7186, 0x2001, 0x000c, 0x800c, 0x718a, + 0x78aa, 0x3518, 0x3340, 0x3428, 0x8000, 0x80ac, 0xaf80, 0x002b, + 0x20a0, 0x789b, 0x0000, 0xad80, 0x000b, 0x2098, 0x53a6, 0x23a8, + 0x2898, 0x25a0, 0xa286, 0x0020, 0x00c0, 0x2c70, 0x70d4, 0xc0b5, + 0x70d6, 0x2c00, 0x70ba, 0x2d00, 0x70be, 0x6814, 0xc0fc, 0x8007, + 0x7882, 0xa286, 0x0002, 0x0040, 0x2ca6, 0x70a4, 0x8000, 0x70a6, + 0x74b4, 0xa498, 0x0005, 0x70ac, 0xa306, 0x00c0, 0x2c68, 0x73a8, + 0x73b6, 0xa286, 0x0010, 0x0040, 0x2942, 0x0d7f, 0x0c7f, 0x007c, + 0x7000, 0xa005, 0x00c0, 0x2c4e, 0xa286, 0x0002, 0x00c0, 0x2cc0, + 0x1078, 0x411c, 0x00c0, 0x2c4e, 0x6814, 0xc0fc, 0x8007, 0x7882, + 0x2091, 0x8000, 0x781b, 0x005b, 0x68b4, 0x785a, 0x6894, 0x78d6, + 0x78de, 0x6898, 0x78d2, 0x78da, 0x2091, 0x8001, 0x7808, 0xc08d, + 0x780a, 0x127e, 0x0d7e, 0x0c7e, 0x70d4, 0xa084, 0x2700, 0x2090, + 0x0c7f, 0x0d7f, 0x127f, 0x2900, 0x705a, 0x68bc, 0x7042, 0x7003, + 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x7830, 0xd0bc, + 0x0040, 0x2cb2, 0x2091, 0x303d, 0x70d4, 0xa084, 0x303d, 0x2091, + 0x8000, 0x2090, 0x70a4, 0xa005, 0x00c0, 0x2cb7, 0x007c, 0x8421, + 0x0040, 0x2cb6, 0x7250, 0x70c0, 0xa200, 0xa015, 0x0078, 0x2aa1, + 0xa286, 0x0010, 0x00c0, 0x2cf1, 0x1078, 0x411c, 0x00c0, 0x2c4e, + 0x6814, 0xc0fc, 0x8007, 0x7882, 0x781b, 0x005b, 0x68b4, 0x785a, + 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, + 0x780a, 0x70a4, 0x8000, 0x70a6, 0x74b4, 0xa490, 0x0005, 0x70ac, + 0xa206, 0x00c0, 0x2ce4, 0x72a8, 0x72b6, 0x2900, 0x705a, 0x68bc, + 0x7042, 0x7003, 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, + 0x007c, 0x6bb4, 0xa39d, 0x2000, 0x7b5a, 0x6814, 0xc0fc, 0x8007, + 0x7882, 0x6b94, 0x7bd6, 0x7bde, 0x6e98, 0x7ed2, 0x7eda, 0x781b, + 0x005b, 0x2900, 0x705a, 0x7202, 0x7808, 0xc08d, 0x780a, 0x2300, + 0xa605, 0x0040, 0x2d1c, 0x70d4, 0xa084, 0x2700, 0xa086, 0x2300, + 0x00c0, 0x2d16, 0x2009, 0x0000, 0x0078, 0x2d18, 0x2009, 0x0001, + 0xa284, 0x000f, 0x1079, 0x2d20, 0xad80, 0x0009, 0x7046, 0x007c, + 0x2d28, 0x45f7, 0x45f7, 0x45e4, 0x45f7, 0x2d28, 0x2d28, 0x2d28, + 0x1078, 0x28ec, 0x7808, 0xa084, 0xfffd, 0x780a, 0x0f7e, 0x2079, + 0x4a00, 0x78ac, 0x0f7f, 0xd084, 0x0040, 0x2d4e, 0x7064, 0xa086, + 0x0001, 0x00c0, 0x2d3e, 0x7066, 0x0078, 0x2e27, 0x7064, 0xa086, + 0x0005, 0x00c0, 0x2d4c, 0x707c, 0x2068, 0x681b, 0x0004, 0x6817, + 0x0000, 0x6820, 0xc09d, 0x6822, 0x7067, 0x0000, 0x70a7, 0x0000, + 0x70a8, 0x70b2, 0x70b6, 0x70d4, 0xd0b4, 0x0040, 0x2d64, 0xc0b4, + 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, + 0x6018, 0x8001, 0x601a, 0x0c7f, 0x157e, 0x2011, 0x0004, 0x7164, + 0xa186, 0x0001, 0x0040, 0x2d7d, 0xa186, 0x0007, 0x00c0, 0x2d74, + 0x701f, 0x0005, 0x0078, 0x2d7d, 0x701f, 0x0001, 0x7067, 0x0000, + 0x70d4, 0xc0dd, 0x70d6, 0x0078, 0x2d7f, 0x7067, 0x0000, 0x2001, + 0x4a0a, 0x2004, 0xa084, 0x00ff, 0xa086, 0x0018, 0x0040, 0x2d8f, + 0x7018, 0x7016, 0xa005, 0x00c0, 0x2d8f, 0x70a7, 0x0001, 0x1078, + 0x4326, 0x20a9, 0x0010, 0x2039, 0x0000, 0x1078, 0x3edb, 0xa7b8, + 0x0100, 0x00f0, 0x2d95, 0x7000, 0x0079, 0x2d9e, 0x2dcd, 0x2db3, + 0x2db3, 0x2da8, 0x2dcd, 0x2dcd, 0x2dcd, 0x2da6, 0x1078, 0x28ec, + 0x7060, 0xa005, 0x0040, 0x2dcd, 0xad06, 0x00c0, 0x2db3, 0x6800, + 0x7062, 0x0078, 0x2dc5, 0x6820, 0xd084, 0x00c0, 0x2dc1, 0x6f14, + 0x1078, 0x3fe1, 0x6008, 0xc0d4, 0x600a, 0x1078, 0x3bb5, 0x0078, + 0x2dc5, 0x705c, 0x2060, 0x6800, 0x6002, 0x6a1a, 0x6817, 0x0000, + 0x6820, 0xc09d, 0x6822, 0x1078, 0x202a, 0xb284, 0x0400, 0x0040, + 0x2dd5, 0x2021, 0x91d0, 0x0078, 0x2dd7, 0x2021, 0x90c0, 0x1078, + 0x2e2c, 0xb284, 0x0400, 0x0040, 0x2de1, 0x2021, 0x4a98, 0x0078, + 0x2de3, 0x2021, 0x4a58, 0x1078, 0x2e2c, 0x20a9, 0x0101, 0xb284, + 0x0400, 0x0040, 0x2def, 0x2021, 0x90d0, 0x0078, 0x2df1, 0x2021, + 0x8fc0, 0x1078, 0x2e2c, 0x8420, 0x00f0, 0x2df1, 0xb284, 0x0300, + 0x0040, 0x2dfe, 0x2061, 0x4fc0, 0x0078, 0x2e00, 0x2061, 0x6fc0, + 0x2021, 0x0002, 0x20a9, 0x0100, 0x6110, 0x81ff, 0x0040, 0x2e1d, + 0x6018, 0x017e, 0x007e, 0x2011, 0x4a02, 0x220c, 0xa102, 0x2012, + 0x007f, 0x017f, 0xa102, 0x0050, 0x2e1d, 0x6012, 0x00c0, 0x2e1d, + 0x2011, 0x4a04, 0x2204, 0xc0a5, 0x2012, 0x601b, 0x0000, 0xace0, + 0x0010, 0x00f0, 0x2e04, 0x8421, 0x00c0, 0x2e02, 0x157f, 0x7003, + 0x0000, 0x704f, 0x0000, 0x007c, 0x047e, 0x2404, 0xa005, 0x0040, + 0x2e3f, 0x2068, 0x6800, 0x007e, 0x6a1a, 0x6817, 0x0000, 0x6820, + 0xc09d, 0x6822, 0x1078, 0x202a, 0x007f, 0x0078, 0x2e2e, 0x047f, + 0x2023, 0x0000, 0x007c, 0xa282, 0x0003, 0x0050, 0x2e49, 0x1078, + 0x28ec, 0x2300, 0x0079, 0x2e4c, 0x2e4f, 0x2eda, 0x2ef7, 0xa282, + 0x0002, 0x0040, 0x2e55, 0x1078, 0x28ec, 0x7064, 0x7067, 0x0000, + 0x7083, 0x0000, 0x0079, 0x2e5c, 0x2e64, 0x2e64, 0x2e66, 0x2ea6, + 0x3bf1, 0x2e64, 0x2ea6, 0x2e64, 0x1078, 0x28ec, 0x7774, 0x1078, + 0x3edb, 0x7774, 0xa7bc, 0x8f00, 0x1078, 0x3fe1, 0x6018, 0xa005, + 0x0040, 0x2e9d, 0xd7fc, 0x00c0, 0x2e79, 0x2021, 0x90c0, 0x0078, + 0x2e7b, 0x2021, 0x91d0, 0x2009, 0x0005, 0x2011, 0x0010, 0x1078, + 0x2f12, 0x0040, 0x2e9d, 0x157e, 0x20a9, 0x0101, 0xd7fc, 0x00c0, + 0x2e8d, 0x2021, 0x8fc0, 0x0078, 0x2e8f, 0x2021, 0x90d0, 0x047e, + 0x2009, 0x0005, 0x2011, 0x0010, 0x1078, 0x2f12, 0x047f, 0x0040, + 0x2e9c, 0x8420, 0x00f0, 0x2e8f, 0x157f, 0x8738, 0xa784, 0x001f, + 0x00c0, 0x2e6c, 0x0078, 0x2946, 0x0078, 0x2946, 0x7774, 0x1078, + 0x3fe1, 0x6018, 0xa005, 0x0040, 0x2ed8, 0xd7fc, 0x00c0, 0x2eb4, + 0x2021, 0x90c0, 0x0078, 0x2eb6, 0x2021, 0x91d0, 0x2009, 0x0005, + 0x2011, 0x0020, 0x1078, 0x2f12, 0x0040, 0x2ed8, 0x157e, 0x20a9, + 0x0101, 0xd7fc, 0x00c0, 0x2ec8, 0x2021, 0x8fc0, 0x0078, 0x2eca, + 0x2021, 0x90d0, 0x047e, 0x2009, 0x0005, 0x2011, 0x0020, 0x1078, + 0x2f12, 0x047f, 0x0040, 0x2ed7, 0x8420, 0x00f0, 0x2eca, 0x157f, + 0x0078, 0x2946, 0x2200, 0x0079, 0x2edd, 0x2ee0, 0x2ee2, 0x2ee2, + 0x1078, 0x28ec, 0x2009, 0x0012, 0x7064, 0xa086, 0x0002, 0x0040, + 0x2eeb, 0x2009, 0x000e, 0x6818, 0xd0fc, 0x0040, 0x2ef0, 0x691a, + 0x7067, 0x0000, 0x70d4, 0xc0dd, 0x70d6, 0x0078, 0x40c9, 0x2200, + 0x0079, 0x2efa, 0x2eff, 0x2ee2, 0x2efd, 0x1078, 0x28ec, 0x1078, + 0x4326, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3b7a, 0x1078, 0x3bd2, + 0x6008, 0xa084, 0xfbef, 0x600a, 0x1078, 0x3b6b, 0x0040, 0x3b7a, + 0x0078, 0x2946, 0x2404, 0xa005, 0x0040, 0x2f41, 0x2068, 0x2d04, + 0x007e, 0x6814, 0xa706, 0x0040, 0x2f21, 0x2d20, 0x007f, 0x0078, + 0x2f13, 0x007f, 0x2022, 0x691a, 0x6817, 0x0000, 0x6820, 0xa205, + 0x6822, 0x1078, 0x202a, 0x2021, 0x4a02, 0x241c, 0x8319, 0x2322, + 0x6010, 0x8001, 0x6012, 0x00c0, 0x2f3a, 0x2021, 0x4a04, 0x2404, + 0xc0a5, 0x2022, 0x6008, 0xa084, 0xf9ef, 0x600a, 0x1078, 0x3bd2, + 0x007c, 0xa085, 0x0001, 0x0078, 0x2f40, 0x2300, 0x0079, 0x2f48, + 0x2f4d, 0x2f4b, 0x2fce, 0x1078, 0x28ec, 0x78e4, 0xa005, 0x00d0, + 0x2f84, 0x3208, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, + 0x0040, 0x2f5e, 0xa18c, 0x0300, 0x0078, 0x2f60, 0xa18c, 0x0400, + 0x0040, 0x2f66, 0x0018, 0x2942, 0x0078, 0x2f68, 0x0028, 0x2942, + 0x2008, 0xa084, 0x0030, 0x00c0, 0x2f70, 0x781b, 0x005b, 0x007c, + 0x78ec, 0xa084, 0x0003, 0x0040, 0x2f6d, 0x2100, 0xa084, 0x0007, + 0x0079, 0x2f7a, 0x2fae, 0x2fb8, 0x2fa3, 0x2f82, 0x4111, 0x4111, + 0x2f82, 0x2fc3, 0x1078, 0x28ec, 0x7000, 0xa086, 0x0004, 0x00c0, + 0x2f9e, 0x7064, 0xa086, 0x0002, 0x00c0, 0x2f94, 0x2011, 0x0002, + 0x2019, 0x0000, 0x0078, 0x2e43, 0x7064, 0xa086, 0x0006, 0x0040, + 0x2f8e, 0x7064, 0xa086, 0x0004, 0x0040, 0x2f8e, 0x79e4, 0x2001, + 0x0003, 0x0078, 0x3304, 0x6818, 0xd0fc, 0x0040, 0x2fa9, 0x681b, + 0x001d, 0x1078, 0x3eae, 0x781b, 0x0061, 0x007c, 0x6818, 0xd0fc, + 0x0040, 0x2fb4, 0x681b, 0x001d, 0x1078, 0x3eae, 0x0078, 0x40ed, + 0x6818, 0xd0fc, 0x0040, 0x2fbe, 0x681b, 0x001d, 0x1078, 0x3eae, + 0x781b, 0x00ef, 0x007c, 0x6818, 0xd0fc, 0x0040, 0x2fc9, 0x681b, + 0x001d, 0x1078, 0x3eae, 0x781b, 0x00bf, 0x007c, 0xa584, 0x000f, + 0x00c0, 0x2feb, 0x7000, 0x0079, 0x2fd5, 0x2946, 0x2fdd, 0x2fdf, + 0x3b7a, 0x3b7a, 0x3b7a, 0x2fdd, 0x2fdd, 0x1078, 0x28ec, 0x1078, + 0x3bd2, 0x6008, 0xa084, 0xfbef, 0x600a, 0x1078, 0x3b6b, 0x0040, + 0x3b7a, 0x0078, 0x2946, 0x78e4, 0xa005, 0x00d0, 0x2f84, 0x3208, + 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2ffc, + 0xa18c, 0x0300, 0x0078, 0x2ffe, 0xa18c, 0x0400, 0x0040, 0x3004, + 0x0018, 0x2f84, 0x0078, 0x3006, 0x0028, 0x2f84, 0x2008, 0xa084, + 0x0030, 0x00c0, 0x300e, 0x781b, 0x005b, 0x007c, 0x78ec, 0xa084, + 0x0003, 0x0040, 0x300b, 0x2100, 0xa184, 0x0007, 0x0079, 0x3018, + 0x3027, 0x302b, 0x3022, 0x3020, 0x4111, 0x4111, 0x3020, 0x410b, + 0x1078, 0x28ec, 0x1078, 0x3eb6, 0x781b, 0x0061, 0x007c, 0x1078, + 0x3eb6, 0x0078, 0x40ed, 0x1078, 0x3eb6, 0x781b, 0x00ef, 0x007c, + 0x1078, 0x3eb6, 0x781b, 0x00bf, 0x007c, 0x2300, 0x0079, 0x3038, + 0x303d, 0x303b, 0x303f, 0x1078, 0x28ec, 0x0078, 0x37bd, 0x681b, + 0x0016, 0x78a3, 0x0000, 0x79e4, 0xa184, 0x0030, 0x0040, 0x37bd, + 0x78ec, 0xa084, 0x0003, 0x0040, 0x37bd, 0xa184, 0x0100, 0x0040, + 0x3043, 0xa184, 0x0007, 0x0079, 0x3055, 0x305d, 0x302b, 0x2fa3, + 0x40c9, 0x4111, 0x4111, 0x40c9, 0x410b, 0x1078, 0x40d5, 0x007c, + 0xa282, 0x0005, 0x0050, 0x3066, 0x1078, 0x28ec, 0x2300, 0x0079, + 0x3069, 0x306c, 0x328b, 0x3296, 0x2200, 0x0079, 0x306f, 0x3089, + 0x3076, 0x3089, 0x3074, 0x326e, 0x1078, 0x28ec, 0x789b, 0x0018, + 0x78a8, 0xa084, 0x00ff, 0xa082, 0x0020, 0x0048, 0x3e9d, 0xa08a, + 0x0004, 0x00c8, 0x3e9d, 0x0079, 0x3085, 0x3e9d, 0x3e9d, 0x3e9d, + 0x3e47, 0x789b, 0x0018, 0x79a8, 0xa184, 0x0080, 0x0040, 0x309a, + 0x0078, 0x3e9d, 0x7000, 0xa005, 0x00c0, 0x3090, 0x2011, 0x0004, + 0x0078, 0x3998, 0xa184, 0x00ff, 0xa08a, 0x0010, 0x00c8, 0x3e9d, + 0x0079, 0x30a2, 0x30b4, 0x30b2, 0x30c9, 0x30cd, 0x318f, 0x3e9d, + 0x3e9d, 0x3191, 0x3e9d, 0x3e9d, 0x326a, 0x326a, 0x3e9d, 0x3e9d, + 0x3e9d, 0x326c, 0x1078, 0x28ec, 0xd6e4, 0x0040, 0x30bf, 0x2001, + 0x0300, 0x8000, 0x8000, 0x783a, 0x781b, 0x00ba, 0x007c, 0x6818, + 0xd0fc, 0x0040, 0x30c7, 0x681b, 0x001d, 0x0078, 0x30b7, 0x0078, + 0x40c9, 0x681b, 0x001d, 0x0078, 0x3ea7, 0x6920, 0x6922, 0xa684, + 0x1800, 0x00c0, 0x3121, 0x6820, 0xd084, 0x00c0, 0x3127, 0x6818, + 0xa086, 0x0008, 0x00c0, 0x30de, 0x681b, 0x0000, 0xd6d4, 0x0040, + 0x318c, 0xd6bc, 0x0040, 0x311e, 0x7087, 0x0000, 0x6818, 0xa084, + 0x003f, 0xa08a, 0x000d, 0x0050, 0x311e, 0xa08a, 0x000c, 0x7186, + 0x2001, 0x000c, 0x800c, 0x718a, 0x789b, 0x0061, 0x78aa, 0x157e, + 0x137e, 0x147e, 0x017e, 0x3208, 0xa18c, 0x0300, 0x0040, 0x3110, + 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x310c, + 0x20a1, 0x012b, 0x0078, 0x3112, 0x20a1, 0x022b, 0x0078, 0x3112, + 0x20a1, 0x012b, 0x017f, 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, + 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f, 0x781b, 0x0064, + 0x007c, 0xd6e4, 0x0040, 0x3127, 0x781b, 0x0076, 0x007c, 0xa684, + 0x0060, 0x0040, 0x3189, 0xd6dc, 0x0040, 0x3189, 0xd6fc, 0x00c0, + 0x3133, 0x0078, 0x314a, 0xc6fc, 0x7e5a, 0x6eb6, 0x7adc, 0x79d8, + 0x78d0, 0x801b, 0x00c8, 0x313d, 0x8000, 0xa084, 0x003f, 0xa108, + 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, + 0xa303, 0x68ae, 0xd6f4, 0x0040, 0x3150, 0xc6f4, 0x7e5a, 0x6eb6, + 0x7000, 0xa086, 0x0003, 0x00c0, 0x315e, 0x007e, 0x1078, 0x4326, + 0x1078, 0x45f7, 0x007f, 0x781b, 0x0073, 0x007c, 0xa006, 0x1078, + 0x46e5, 0x6ab0, 0x69ac, 0x6c98, 0x6b94, 0x2200, 0xa105, 0x0040, + 0x316d, 0x2200, 0xa422, 0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda, + 0x6ba6, 0x7bd6, 0x7bde, 0x2300, 0xa405, 0x00c0, 0x317d, 0xc6f5, + 0x7e5a, 0x6eb6, 0x781b, 0x0073, 0x007c, 0x781b, 0x0073, 0x2200, + 0xa115, 0x00c0, 0x3186, 0x1078, 0x45f7, 0x007c, 0x1078, 0x462d, + 0x007c, 0x781b, 0x0076, 0x007c, 0x781b, 0x0064, 0x007c, 0x1078, + 0x28ec, 0x0078, 0x31dd, 0x6920, 0xd1c4, 0x0040, 0x31a6, 0xc1c4, + 0x6922, 0x0c7e, 0x7058, 0x2060, 0x6000, 0xc0e4, 0x6002, 0x6004, + 0xa084, 0xfff5, 0x6006, 0x0c7f, 0x0078, 0x31d1, 0xd1cc, 0x0040, + 0x31d1, 0xc1cc, 0x6922, 0x0c7e, 0x7058, 0x2060, 0x6000, 0xc0ec, + 0x6002, 0x6004, 0xc0a4, 0x6006, 0x2008, 0x2c48, 0x0c7f, 0xd19c, + 0x0040, 0x31d1, 0x1078, 0x3fdd, 0x1078, 0x3cda, 0x88ff, 0x0040, + 0x31d1, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a, + 0xd6d4, 0x00c0, 0x31ce, 0x781b, 0x0061, 0x007c, 0x781b, 0x0075, + 0x007c, 0x7e58, 0xd6d4, 0x00c0, 0x31d8, 0x781b, 0x0064, 0x007c, + 0x781b, 0x0076, 0x007c, 0x0078, 0x3ea2, 0x2019, 0x0000, 0x7990, + 0xa18c, 0x0007, 0x00c0, 0x31eb, 0x6820, 0xa084, 0x0100, 0x0040, + 0x31db, 0x2009, 0x0008, 0x789b, 0x0010, 0x78a8, 0xa094, 0x00ff, + 0xa286, 0x0001, 0x00c0, 0x3207, 0x2300, 0x7ca8, 0xa400, 0x2018, + 0xa102, 0x0040, 0x31ff, 0x0048, 0x31ff, 0x0078, 0x3201, 0x0078, + 0x3193, 0x24a8, 0x7aa8, 0x00f0, 0x3201, 0x0078, 0x31ed, 0xa284, + 0x00f0, 0xa086, 0x0020, 0x00c0, 0x325b, 0x8318, 0x8318, 0x2300, + 0xa102, 0x0040, 0x3217, 0x0048, 0x3217, 0x0078, 0x3258, 0xa286, + 0x0023, 0x0040, 0x31db, 0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58, + 0xa684, 0xfff1, 0xc0a5, 0x2030, 0x7e5a, 0x6008, 0xc0a5, 0x600a, + 0x0c7e, 0x7058, 0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f, 0xd1a4, + 0x0040, 0x3238, 0x1078, 0x3fdd, 0x1078, 0x3df6, 0x0078, 0x3246, + 0x0c7e, 0x7058, 0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f, 0xd19c, + 0x0040, 0x31d1, 0x1078, 0x3fdd, 0x1078, 0x3cda, 0x88ff, 0x0040, + 0x31d1, 0x789b, 0x0060, 0x2800, 0x78aa, 0xc695, 0x7e5a, 0xd6d4, + 0x00c0, 0x3255, 0x781b, 0x0061, 0x007c, 0x781b, 0x0075, 0x007c, + 0x7aa8, 0x0078, 0x31ed, 0x8318, 0x2300, 0xa102, 0x0040, 0x3264, + 0x0048, 0x3264, 0x0078, 0x31ed, 0xa284, 0x0080, 0x00c0, 0x3ea7, + 0x0078, 0x3ea2, 0x0078, 0x3ea7, 0x0078, 0x3e9d, 0x7058, 0xa04d, + 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa08e, 0x0001, 0x0040, + 0x327b, 0x1078, 0x28ec, 0x7aa8, 0xa294, 0x00ff, 0x78a8, 0xa084, + 0x00ff, 0xa08a, 0x0004, 0x00c8, 0x3e9d, 0x0079, 0x3287, 0x3e9d, + 0x3c2c, 0x3e9d, 0x3d9e, 0xa282, 0x0000, 0x00c0, 0x3291, 0x1078, + 0x28ec, 0x1078, 0x3eae, 0x781b, 0x0075, 0x007c, 0xa282, 0x0003, + 0x00c0, 0x329c, 0x1078, 0x28ec, 0xd4fc, 0x00c0, 0x32bc, 0x7064, + 0xa005, 0x0040, 0x32a5, 0x1078, 0x28ec, 0x6f14, 0x7776, 0xa7bc, + 0x8f00, 0x1078, 0x3fe1, 0x6008, 0xa085, 0x0021, 0x600a, 0x8738, + 0xa784, 0x001f, 0x00c0, 0x32a9, 0x1078, 0x3eb2, 0x7067, 0x0002, + 0x701f, 0x0009, 0x0078, 0x32be, 0x1078, 0x3ebe, 0x781b, 0x0075, + 0x007c, 0xa282, 0x0004, 0x0050, 0x32c7, 0x1078, 0x28ec, 0x2300, + 0x0079, 0x32ca, 0x32cd, 0x346b, 0x34ae, 0xa286, 0x0003, 0x0040, + 0x3304, 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x71d4, 0xd1b4, 0x0078, + 0x32fc, 0x0040, 0x32fc, 0x7868, 0xa084, 0x00ff, 0x00c0, 0x32fc, + 0xa282, 0x0002, 0x00c8, 0x32fc, 0x0d7e, 0x783b, 0x8300, 0x781b, + 0x004c, 0x70bc, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, + 0x6898, 0x78d2, 0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x0d7f, + 0x2001, 0x0000, 0x0078, 0x3308, 0x783b, 0x1300, 0x781b, 0x004a, + 0x2001, 0x0000, 0x0078, 0x3308, 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, + 0x704a, 0x68a0, 0xd0ec, 0x0040, 0x3310, 0x6008, 0xc08d, 0x600a, + 0xa284, 0x000f, 0x0079, 0x3314, 0x344b, 0x3321, 0x331e, 0x35ae, + 0x35f2, 0x2946, 0x331c, 0x331c, 0x1078, 0x28ec, 0x6008, 0xc0d4, + 0x600a, 0xd6e4, 0x00c0, 0x3328, 0x1078, 0x4326, 0x0040, 0x3404, + 0x7868, 0xa08c, 0x00ff, 0x0040, 0x3369, 0xa186, 0x0008, 0x00c0, + 0x333e, 0x1078, 0x3bd2, 0x6008, 0xc0a4, 0x600a, 0x1078, 0x3b6b, + 0x0040, 0x3369, 0x1078, 0x4326, 0x0078, 0x3353, 0xa186, 0x0028, + 0x00c0, 0x3369, 0x1078, 0x4326, 0x6008, 0xc0a4, 0x600a, 0x6018, + 0xa005, 0x0040, 0x3353, 0x8001, 0x601a, 0x0040, 0x3353, 0x8001, + 0x0040, 0x3353, 0x601e, 0x6820, 0xd084, 0x0040, 0x2946, 0xc084, + 0x6822, 0x705c, 0x0c7e, 0x2060, 0x6800, 0x6002, 0x0c7f, 0x6004, + 0x6802, 0xa005, 0x2d00, 0x00c0, 0x3366, 0x6002, 0x6006, 0x0078, + 0x2946, 0x017e, 0x81ff, 0x00c0, 0x33b0, 0x7000, 0xa086, 0x0030, + 0x0040, 0x33b0, 0x71d4, 0xd1b4, 0x00c0, 0x3397, 0x7060, 0xa005, + 0x00c0, 0x33b0, 0x70a4, 0xa086, 0x0001, 0x0040, 0x33b0, 0x7003, + 0x0000, 0x047e, 0x057e, 0x077e, 0x067e, 0x0c7e, 0x0d7e, 0x1078, + 0x296c, 0x0d7f, 0x0c7f, 0x067f, 0x077f, 0x057f, 0x047f, 0x71d4, + 0xd1b4, 0x00c0, 0x33b0, 0x7003, 0x0040, 0x0078, 0x33b0, 0x1078, + 0x411c, 0x00c0, 0x33b0, 0x781b, 0x005b, 0x0d7e, 0x70bc, 0xa06d, + 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, + 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x7808, 0xc08d, 0x780a, 0x0d7f, + 0x1078, 0x34e8, 0x017f, 0x81ff, 0x0040, 0x3403, 0xa684, 0xdf00, + 0x681e, 0x682b, 0x0000, 0x6f14, 0xa186, 0x0002, 0x00c0, 0x3404, + 0x70d4, 0xd0b4, 0x0040, 0x33d1, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, + 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, + 0x0c7f, 0x6820, 0xd0dc, 0x00c0, 0x3404, 0x8717, 0xa294, 0x000f, + 0x8213, 0x8213, 0x8213, 0xb284, 0x0300, 0x0040, 0x33e3, 0xa290, + 0x4ec0, 0x0078, 0x33e5, 0xa290, 0x4f40, 0xa290, 0x0000, 0x221c, + 0xd3c4, 0x00c0, 0x33ed, 0x0078, 0x33f3, 0x8210, 0x2204, 0xa085, + 0x0018, 0x2012, 0x8211, 0xd3d4, 0x0040, 0x33fe, 0x68a0, 0xd0c4, + 0x00c0, 0x33fe, 0x1078, 0x3562, 0x0078, 0x2946, 0x6008, 0xc08d, + 0x600a, 0x0078, 0x3404, 0x692a, 0x6916, 0x6818, 0xd0fc, 0x0040, + 0x340b, 0x7048, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x6410, 0x84ff, + 0x0040, 0x3420, 0x2009, 0x4a02, 0x2104, 0x8001, 0x200a, 0x8421, + 0x6412, 0x00c0, 0x3420, 0x2021, 0x4a04, 0x2404, 0xc0a5, 0x2022, + 0x6018, 0xa005, 0x0040, 0x3428, 0x8001, 0x601a, 0x00c0, 0x342b, + 0x6008, 0xc0a4, 0x600a, 0x6820, 0xd084, 0x00c0, 0x3437, 0x6800, + 0xa005, 0x00c0, 0x3434, 0x6002, 0x6006, 0x0078, 0x343b, 0x705c, + 0x2060, 0x6800, 0x6002, 0x2061, 0x4a00, 0x6887, 0x0103, 0x2d08, + 0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0040, 0x344a, 0x2d02, + 0x0078, 0x344b, 0x616e, 0x7200, 0xa286, 0x0030, 0x0040, 0x345b, + 0xa286, 0x0040, 0x00c0, 0x2946, 0x7003, 0x0002, 0x704c, 0x2068, + 0x68c4, 0x2060, 0x007c, 0x7003, 0x0002, 0x70bc, 0xa06d, 0x68bc, + 0x7042, 0x70b8, 0xa065, 0x68c0, 0x705a, 0x2d00, 0x704e, 0xad80, + 0x0009, 0x7046, 0x007c, 0xa282, 0x0004, 0x0048, 0x3471, 0x1078, + 0x28ec, 0x2200, 0x0079, 0x3474, 0x3478, 0x3489, 0x3496, 0x3489, + 0xa586, 0x1300, 0x0040, 0x3489, 0xa586, 0x8300, 0x00c0, 0x346f, + 0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084, 0xfbef, + 0x600a, 0x7000, 0xa086, 0x0005, 0x0040, 0x3493, 0x1078, 0x3eae, + 0x781b, 0x0075, 0x007c, 0x781b, 0x0076, 0x007c, 0x7890, 0x8007, + 0x8001, 0xa084, 0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c, + 0x00ff, 0xa186, 0x0003, 0x0040, 0x34ab, 0xa186, 0x0000, 0x0040, + 0x34ab, 0x0078, 0x3e9d, 0x781b, 0x0076, 0x007c, 0x6820, 0xc095, + 0x6822, 0x82ff, 0x00c0, 0x34b8, 0x1078, 0x3eae, 0x0078, 0x34bf, + 0x8211, 0x0040, 0x34bd, 0x1078, 0x28ec, 0x1078, 0x3ebe, 0x781b, + 0x0075, 0x007c, 0x1078, 0x4131, 0x7830, 0xa084, 0x00c0, 0x00c0, + 0x34e5, 0x017e, 0x3208, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, + 0x007f, 0x0040, 0x34d7, 0xa18c, 0x0300, 0x0078, 0x34d9, 0xa18c, + 0x0400, 0x017f, 0x0040, 0x34e0, 0x0018, 0x34e5, 0x0078, 0x34e2, + 0x0028, 0x34e5, 0x791a, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c, + 0xa684, 0x0060, 0x00c0, 0x34f2, 0x682f, 0x0000, 0x6833, 0x0000, + 0x0078, 0x3561, 0xd6dc, 0x00c0, 0x350a, 0x68b4, 0xd0dc, 0x00c0, + 0x350a, 0x6998, 0x6a94, 0x692e, 0x6a32, 0x7048, 0xa005, 0x00c0, + 0x3507, 0x2200, 0xa105, 0x0040, 0x4326, 0x704b, 0x0015, 0x0078, + 0x4326, 0x007c, 0xd6ac, 0x0040, 0x3530, 0xd6f4, 0x0040, 0x3516, + 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x4326, 0x68b4, 0xa084, + 0x4000, 0xa635, 0xd6f4, 0x00c0, 0x3510, 0x7048, 0xa005, 0x00c0, + 0x3523, 0x704b, 0x0015, 0xd6dc, 0x00c0, 0x352c, 0x68b4, 0xd0dc, + 0x0040, 0x352c, 0x6ca8, 0x6da4, 0x6c2e, 0x6d32, 0x0078, 0x4326, + 0xd6f4, 0x0040, 0x3539, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, + 0x4326, 0x68b4, 0xa084, 0x4800, 0xa635, 0xd6f4, 0x00c0, 0x3533, + 0x7048, 0xa005, 0x00c0, 0x3546, 0x704b, 0x0015, 0x2408, 0x2510, + 0x2700, 0x80fb, 0x00c8, 0x354d, 0x8000, 0xa084, 0x003f, 0xa108, + 0xa291, 0x0000, 0x692e, 0x6a32, 0x2100, 0xa205, 0x00c0, 0x355a, + 0x0078, 0x4326, 0x7000, 0xa086, 0x0006, 0x0040, 0x3561, 0x0078, + 0x4326, 0x007c, 0x6008, 0xc0cd, 0xd3cc, 0x0040, 0x3568, 0xc08d, + 0x600a, 0x681b, 0x0006, 0x688f, 0x0000, 0x6893, 0x0000, 0x6a30, + 0x692c, 0x6a3e, 0x6942, 0x682f, 0x0003, 0x6833, 0x0000, 0x6837, + 0x0020, 0x6897, 0x0000, 0x689b, 0x0020, 0x7000, 0x0079, 0x3580, + 0x2946, 0x3592, 0x358a, 0x3588, 0x3588, 0x3588, 0x3588, 0x3588, + 0x1078, 0x28ec, 0x6820, 0xd084, 0x00c0, 0x3592, 0x1078, 0x3bb5, + 0x0078, 0x3598, 0x705c, 0x2c50, 0x2060, 0x6800, 0x6002, 0x2a60, + 0x3208, 0xa18c, 0x0300, 0x0040, 0x35a1, 0x2021, 0x4a58, 0x0078, + 0x35a3, 0x2021, 0x4a98, 0x2404, 0xa005, 0x0040, 0x35aa, 0x2020, + 0x0078, 0x35a3, 0x2d22, 0x206b, 0x0000, 0x007c, 0x1078, 0x3bbc, + 0x1078, 0x3bd2, 0x6008, 0xc0cc, 0x600a, 0x682b, 0x0000, 0x789b, + 0x000e, 0x6f14, 0x6817, 0x0002, 0x3208, 0xa18c, 0x0300, 0x0040, + 0x35c5, 0x2009, 0x0000, 0x0078, 0x35c7, 0x2009, 0x0001, 0x1078, + 0x471a, 0xd6dc, 0x0040, 0x35cf, 0x691c, 0xc1ed, 0x691e, 0x6818, + 0xd0fc, 0x0040, 0x35de, 0x7868, 0xa08c, 0x00ff, 0x0040, 0x35dc, + 0x681b, 0x001e, 0x0078, 0x35de, 0x681b, 0x0000, 0xb284, 0x0300, + 0x00c0, 0x35e6, 0x2021, 0x4a98, 0x0078, 0x35e8, 0x2021, 0x4a58, + 0x6800, 0x2022, 0x6a3c, 0x6940, 0x6a32, 0x692e, 0x1078, 0x202a, + 0x0078, 0x2946, 0x7cd8, 0x7ddc, 0x7fd0, 0x1078, 0x34e8, 0x682b, + 0x0000, 0x789b, 0x000e, 0x6f14, 0x1078, 0x4135, 0xa08c, 0x00ff, + 0x6916, 0x6818, 0xd0fc, 0x0040, 0x3607, 0x7048, 0x681a, 0xa68c, + 0xdf00, 0x691e, 0x7067, 0x0000, 0x0078, 0x2946, 0x7000, 0xa005, + 0x00c0, 0x3614, 0x0078, 0x2946, 0xa006, 0x1078, 0x4326, 0x6817, + 0x0000, 0x681b, 0x0014, 0xa68c, 0xdf00, 0x691e, 0x682b, 0x0000, + 0x6820, 0xa084, 0x00ff, 0x6822, 0x7000, 0x0079, 0x3627, 0x2946, + 0x3634, 0x3631, 0x3636, 0x3636, 0x3636, 0x362f, 0x362f, 0x1078, + 0x28ec, 0x6008, 0xc0d4, 0x600a, 0x1078, 0x3bd2, 0x6008, 0xc0a4, + 0x600a, 0x0078, 0x3b85, 0x2300, 0x0079, 0x363e, 0x3641, 0x3643, + 0x369f, 0x1078, 0x28ec, 0xd6fc, 0x00c0, 0x3686, 0x7000, 0xa00d, + 0x0079, 0x364a, 0x2946, 0x3654, 0x3654, 0x3678, 0x3654, 0x3683, + 0x3652, 0x3652, 0x1078, 0x28ec, 0xa684, 0x0060, 0xa086, 0x0060, + 0x00c0, 0x3675, 0xc6ac, 0xc6f4, 0xc6ed, 0x7e5a, 0x681c, 0xc0ac, + 0x681e, 0xa186, 0x0002, 0x0040, 0x3667, 0x1078, 0x4326, 0x1078, + 0x45f7, 0x781b, 0x0076, 0x71d4, 0xd1b4, 0x00c0, 0x2942, 0x70a4, + 0xa086, 0x0001, 0x00c0, 0x2989, 0x007c, 0xd6ec, 0x0040, 0x365c, + 0x6818, 0xd0fc, 0x0040, 0x3683, 0x681b, 0x0015, 0xd6f4, 0x0040, + 0x3683, 0x681b, 0x0007, 0x1078, 0x40d5, 0x007c, 0xc6fc, 0x7e5a, + 0x7adc, 0x79d8, 0x78d0, 0x801b, 0x00c8, 0x368f, 0x8000, 0xa084, + 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, + 0x6b94, 0x2200, 0xa303, 0x68ae, 0x781b, 0x0076, 0x007c, 0x1078, + 0x28ec, 0x2300, 0x0079, 0x36a4, 0x36a9, 0x36c5, 0x3719, 0x1078, + 0x28ec, 0x7000, 0x0079, 0x36ac, 0x36b4, 0x36b6, 0x36b6, 0x36b4, + 0x36b4, 0x36b4, 0x36b4, 0x36b4, 0x1078, 0x28ec, 0x1078, 0x45f7, + 0x681c, 0xc0b4, 0x681e, 0x70d4, 0xd0b4, 0x00c0, 0x2942, 0x70a4, + 0xa086, 0x0001, 0x00c0, 0x2989, 0x007c, 0xd6fc, 0x00c0, 0x3709, + 0x7000, 0xa00d, 0x0079, 0x36cc, 0x2946, 0x36dc, 0x36d6, 0x3700, + 0x36dc, 0x3706, 0x36d4, 0x36d4, 0x1078, 0x28ec, 0x6894, 0x78d6, + 0x78de, 0x6898, 0x78d2, 0x78da, 0xa684, 0x0060, 0xa086, 0x0060, + 0x00c0, 0x36fd, 0xa6b4, 0xbfbf, 0xc6ed, 0x7e5a, 0xa186, 0x0002, + 0x0040, 0x36ec, 0x1078, 0x4326, 0x1078, 0x45f7, 0x781b, 0x0076, + 0x681c, 0xc0b4, 0x681e, 0x71d4, 0xd1b4, 0x00c0, 0x2942, 0x70a4, + 0xa086, 0x0001, 0x00c0, 0x2989, 0x007c, 0xd6ec, 0x0040, 0x36e4, + 0x6818, 0xd0fc, 0x0040, 0x3706, 0x681b, 0x0007, 0x781b, 0x00f0, + 0x007c, 0xc6fc, 0x7e5a, 0x7adc, 0x79d8, 0x6b98, 0x2100, 0xa302, + 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x79d2, 0x781b, 0x0076, + 0x007c, 0xd6dc, 0x0040, 0x3722, 0x782b, 0x3009, 0x781b, 0x0076, + 0x0078, 0x2942, 0x7884, 0xc0ac, 0x7886, 0x78e4, 0xa084, 0x0008, + 0x00c0, 0x3735, 0xa484, 0x0200, 0x0040, 0x372f, 0xc6f5, 0xc6dd, + 0x7e5a, 0x781b, 0x0076, 0x0078, 0x2942, 0x6820, 0xc095, 0x6822, + 0x1078, 0x4062, 0xc6dd, 0x1078, 0x3eae, 0x781b, 0x0075, 0x0078, + 0x2942, 0x2300, 0x0079, 0x3744, 0x3747, 0x3749, 0x374b, 0x1078, + 0x28ec, 0x0078, 0x3ea7, 0xd6d4, 0x00c0, 0x3771, 0x79e4, 0xd1ac, + 0x0040, 0x3759, 0x78ec, 0xa084, 0x0003, 0x0040, 0x3759, 0x782b, + 0x3009, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, + 0x79e4, 0xd1ac, 0x0040, 0x3769, 0x78ec, 0xa084, 0x0003, 0x00c0, + 0x376d, 0x2001, 0x0014, 0x0078, 0x3304, 0xa184, 0x0007, 0x0079, + 0x37a7, 0x7a90, 0xa294, 0x0007, 0x789b, 0x0060, 0x79a8, 0x81ff, + 0x0040, 0x37a5, 0x789b, 0x0010, 0x7ba8, 0xa384, 0x0001, 0x00c0, + 0x3798, 0x7ba8, 0x7ba8, 0xa386, 0x0001, 0x00c0, 0x378b, 0x2009, + 0xfff7, 0x0078, 0x3791, 0xa386, 0x0003, 0x00c0, 0x3798, 0x2009, + 0xffef, 0x0c7e, 0x7058, 0x2060, 0x6004, 0xa104, 0x6006, 0x0c7f, + 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x782b, + 0x3009, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078, 0x40c9, 0x2fae, + 0x2fb8, 0x37b1, 0x37b7, 0x37af, 0x37af, 0x40c9, 0x40c9, 0x1078, + 0x28ec, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078, 0x40cf, 0x6920, + 0xa18c, 0xfcff, 0x6922, 0x0078, 0x40c9, 0x79e4, 0xa184, 0x0030, + 0x0040, 0x37c7, 0x78ec, 0xa084, 0x0003, 0x00c0, 0x37f1, 0x7000, + 0xa086, 0x0004, 0x00c0, 0x37e1, 0x7064, 0xa086, 0x0002, 0x00c0, + 0x37d7, 0x2011, 0x0002, 0x2019, 0x0000, 0x0078, 0x2e43, 0x7064, + 0xa086, 0x0006, 0x0040, 0x37d1, 0x7064, 0xa086, 0x0004, 0x0040, + 0x37d1, 0x7000, 0xa086, 0x0000, 0x0040, 0x2942, 0x6820, 0xd0ac, + 0x00c0, 0x37ed, 0x6818, 0xc0fd, 0x681a, 0x2001, 0x0014, 0x0078, + 0x3304, 0xa184, 0x0007, 0x0079, 0x37f5, 0x40c9, 0x40c9, 0x37fd, + 0x40c9, 0x4111, 0x4111, 0x40c9, 0x40c9, 0xd6bc, 0x0040, 0x383f, + 0x7184, 0x81ff, 0x0040, 0x383f, 0xa182, 0x000d, 0x00d0, 0x380c, + 0x7087, 0x0000, 0x0078, 0x3811, 0xa182, 0x000c, 0x7086, 0x2009, + 0x000c, 0x789b, 0x0061, 0x79aa, 0x157e, 0x137e, 0x147e, 0x7088, + 0x8114, 0xa210, 0x728a, 0xa080, 0x000b, 0xad00, 0x2098, 0xb284, + 0x0300, 0x0040, 0x3833, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, + 0x007f, 0x0040, 0x382f, 0x20a1, 0x012b, 0x0078, 0x3835, 0x20a1, + 0x022b, 0x0078, 0x3835, 0x20a1, 0x012b, 0x789b, 0x0000, 0x8108, + 0x81ac, 0x53a6, 0x147f, 0x137f, 0x157f, 0x0078, 0x40cf, 0xd6d4, + 0x00c0, 0x3893, 0x6820, 0xd084, 0x0040, 0x40cf, 0xa68c, 0x0060, + 0xa684, 0x0060, 0x0040, 0x3851, 0xa086, 0x0060, 0x00c0, 0x3851, + 0xc1f5, 0xc194, 0x795a, 0x69b6, 0x789b, 0x0060, 0x78ab, 0x0000, + 0x789b, 0x0061, 0x6818, 0xc0fd, 0x681a, 0x78aa, 0x8008, 0x810c, + 0x0040, 0x3beb, 0xa18c, 0x00f8, 0x00c0, 0x3beb, 0x157e, 0x137e, + 0x147e, 0x017e, 0x3208, 0xa18c, 0x0300, 0x0040, 0x387f, 0x007e, + 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x387b, 0x20a1, + 0x012b, 0x0078, 0x3881, 0x20a1, 0x022b, 0x0078, 0x3881, 0x20a1, + 0x012b, 0x017f, 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, + 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f, 0x6814, 0xc0fc, 0x8007, + 0x7882, 0x0078, 0x40cf, 0x6818, 0xd0fc, 0x0040, 0x3899, 0x681b, + 0x0008, 0x6820, 0xc0ad, 0x6822, 0x1078, 0x3eb6, 0x781b, 0x00e1, + 0x007c, 0x2300, 0x0079, 0x38a4, 0x38a9, 0x397b, 0x38a7, 0x1078, + 0x28ec, 0x7cd8, 0x7ddc, 0x7fd0, 0x82ff, 0x00c0, 0x38d1, 0x7200, + 0xa286, 0x0003, 0x0040, 0x32d2, 0x71d4, 0xd1b4, 0x0078, 0x38d4, + 0x0040, 0x38d4, 0x0d7e, 0x783b, 0x8800, 0x781b, 0x004c, 0x70bc, + 0xa06d, 0x68b4, 0xc0a5, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, + 0x78d2, 0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x0d7f, 0x0078, + 0x38d8, 0x7200, 0x0078, 0x38d8, 0x783b, 0x1800, 0x781b, 0x004a, + 0xa284, 0x000f, 0x0079, 0x38dc, 0x3966, 0x391a, 0x38e6, 0x3300, + 0x38e4, 0x3966, 0x38e4, 0x38e4, 0x1078, 0x28ec, 0x681c, 0xd0ec, + 0x0040, 0x38ed, 0x6008, 0xc08d, 0x600a, 0x6920, 0xc185, 0x6922, + 0x6800, 0x6006, 0xa005, 0x00c0, 0x38f6, 0x6002, 0x6008, 0xc0d4, + 0x600a, 0x681c, 0xa084, 0x000e, 0x00c0, 0x390a, 0xb284, 0x0300, + 0x0040, 0x3906, 0x2009, 0x90c0, 0x0078, 0x390f, 0x2009, 0x91d0, + 0x0078, 0x390f, 0x7030, 0x68ba, 0x7140, 0x70cc, 0xa108, 0x2104, + 0x6802, 0x2d0a, 0x715e, 0xd6dc, 0x00c0, 0x391a, 0xc6fc, 0x6eb6, + 0x0078, 0x3966, 0x6eb6, 0xa684, 0x0060, 0x0040, 0x3966, 0xd6dc, + 0x00c0, 0x392d, 0xa684, 0x7fff, 0x68b6, 0x6894, 0x68a6, 0x6898, + 0x68aa, 0x1078, 0x4326, 0x0078, 0x3966, 0xd6ac, 0x0040, 0x3939, + 0xa006, 0x1078, 0x4326, 0x2408, 0x2510, 0x69aa, 0x6aa6, 0x0078, + 0x3949, 0x2408, 0x2510, 0x2700, 0x801b, 0x00c8, 0x3940, 0x8000, + 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x69aa, 0x6aa6, 0x1078, + 0x4326, 0xd6fc, 0x0040, 0x3966, 0xa684, 0x7fff, 0x68b6, 0x2510, + 0x2408, 0xd6ac, 0x00c0, 0x395e, 0x2700, 0x801b, 0x00c8, 0x3959, + 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, + 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x7000, 0xa086, + 0x0030, 0x00c0, 0x2946, 0x7003, 0x0002, 0x70bc, 0xa06d, 0x68bc, + 0x7042, 0x70b8, 0xa065, 0x68c0, 0x705a, 0x2d00, 0x704e, 0xad80, + 0x0009, 0x7046, 0x007c, 0xa586, 0x8800, 0x00c0, 0x3988, 0x7003, + 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084, 0xfbef, 0x600a, + 0x0078, 0x3ea7, 0x7047, 0x0000, 0xa282, 0x0006, 0x0050, 0x3992, + 0x1078, 0x28ec, 0x2300, 0x0079, 0x3995, 0x3998, 0x39cf, 0x3a01, + 0x2200, 0x0079, 0x399b, 0x39a1, 0x3ea7, 0x39a3, 0x39a1, 0x3a38, + 0x3a9b, 0x1078, 0x28ec, 0x7003, 0x0005, 0xb284, 0x0300, 0x0040, + 0x39ad, 0x2001, 0x91e0, 0x0078, 0x39af, 0x2001, 0x9212, 0x2068, + 0x704e, 0x157e, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x00f0, + 0x39b4, 0x157f, 0xb284, 0x0300, 0x0040, 0x39c2, 0x6817, 0x0000, + 0x0078, 0x39c4, 0x6817, 0x8000, 0xad80, 0x0009, 0x7046, 0x68b7, + 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x0078, 0x3e9d, 0x7000, + 0xa086, 0x0002, 0x00c0, 0x39e0, 0x1078, 0x3bd2, 0x0078, 0x39da, + 0x1078, 0x4326, 0x6008, 0xa084, 0xfbef, 0x600a, 0x0078, 0x39e5, + 0x7000, 0xa086, 0x0003, 0x0040, 0x39d8, 0x7003, 0x0005, 0xb284, + 0x0300, 0x0040, 0x39ef, 0x2001, 0x91e0, 0x0078, 0x39f1, 0x2001, + 0x9212, 0x2068, 0x704e, 0xad80, 0x0009, 0x7046, 0x2200, 0x0079, + 0x39f9, 0x3ea7, 0x39ff, 0x39ff, 0x3a38, 0x39ff, 0x3ea7, 0x1078, + 0x28ec, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3a12, 0x1078, 0x3bd2, + 0x0078, 0x3a0c, 0x1078, 0x4326, 0x6008, 0xa084, 0xfbef, 0x600a, + 0x0078, 0x3a17, 0x7000, 0xa086, 0x0003, 0x0040, 0x3a0a, 0x7003, + 0x0005, 0xb284, 0x0300, 0x0040, 0x3a21, 0x2001, 0x91e0, 0x0078, + 0x3a23, 0x2001, 0x9212, 0x2068, 0x704e, 0xad80, 0x0009, 0x7046, + 0x2200, 0x0079, 0x3a2b, 0x3a33, 0x3a31, 0x3a31, 0x3a33, 0x3a31, + 0x3a33, 0x1078, 0x28ec, 0x1078, 0x3ebe, 0x781b, 0x0075, 0x007c, + 0x7000, 0xa086, 0x0002, 0x00c0, 0x3a4a, 0x70d4, 0xc0b5, 0x70d6, + 0x2c00, 0x70ba, 0x2d00, 0x70be, 0x0078, 0x3a4f, 0x1078, 0x4326, + 0x0078, 0x3a4f, 0x7000, 0xa086, 0x0003, 0x0040, 0x3a46, 0x7003, + 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484, + 0x001f, 0xa215, 0x2069, 0x90c0, 0xb284, 0x0300, 0x00c0, 0x3a63, + 0xc2fd, 0x2069, 0x91d0, 0x2d04, 0x2d08, 0x715e, 0xa06d, 0x0040, + 0x3a70, 0x6814, 0xa206, 0x0040, 0x3a90, 0x6800, 0x0078, 0x3a64, + 0x7003, 0x0005, 0xd2fc, 0x00c0, 0x3a79, 0x2001, 0x91e0, 0x0078, + 0x3a7b, 0x2001, 0x9212, 0x2068, 0x704e, 0x157e, 0x20a9, 0x0032, + 0x2003, 0x0000, 0x8000, 0x00f0, 0x3a80, 0x157f, 0xad80, 0x0009, + 0x7046, 0x6a16, 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, + 0x6eb4, 0x7e5a, 0x6820, 0xa084, 0x0c00, 0x0040, 0x3b10, 0x1078, + 0x3eb6, 0x0078, 0x3b10, 0x7200, 0xa286, 0x0002, 0x00c0, 0x3aad, + 0x70d4, 0xc0b5, 0x70d6, 0x2c00, 0x70ba, 0x2d00, 0x70be, 0x0078, + 0x3ab1, 0x1078, 0x4326, 0x0078, 0x3ab1, 0xa286, 0x0003, 0x0040, + 0x3aa9, 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, + 0x7ca8, 0xa484, 0x001f, 0xa215, 0xb284, 0x0300, 0x00c0, 0x3ac1, + 0xc2fd, 0x79a8, 0x79a8, 0xa18c, 0x00ff, 0x70cc, 0xa168, 0x2d04, + 0x2d08, 0x715e, 0xa06d, 0x0040, 0x3ad4, 0x6814, 0xa206, 0x0040, + 0x3afd, 0x6800, 0x0078, 0x3ac8, 0x7003, 0x0005, 0xb284, 0x0300, + 0x0040, 0x3ade, 0x2001, 0x91e0, 0x0078, 0x3ae0, 0x2001, 0x9212, + 0x2068, 0x704e, 0x157e, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, + 0x00f0, 0x3ae5, 0x157f, 0xb284, 0x0300, 0x0040, 0x3af2, 0xc2fc, + 0x0078, 0x3af3, 0xc2fd, 0x6a16, 0xad80, 0x0009, 0x7046, 0x68b7, + 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4, 0x6820, 0xa084, + 0x0c00, 0x0040, 0x3b10, 0xd0dc, 0x0040, 0x3b0a, 0x1078, 0x3eba, + 0x0078, 0x3b10, 0x1078, 0x3eb6, 0x707f, 0x0000, 0x0078, 0x3b10, + 0xa6ac, 0x0060, 0x0040, 0x3b4e, 0x6b98, 0x6c94, 0x69ac, 0x68b0, + 0xa105, 0x00c0, 0x3b33, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa6b4, + 0xb7ff, 0xa586, 0x0060, 0x0040, 0x3b4e, 0xc6ed, 0x7e5a, 0x2009, + 0x0076, 0xd69c, 0x0040, 0x3b2e, 0x2009, 0x0075, 0x791a, 0x1078, + 0x45f7, 0x0078, 0x3b57, 0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400, + 0xa305, 0x0040, 0x3b4e, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0x68b0, + 0xc6f4, 0x7e5a, 0x2011, 0x0076, 0xd69c, 0x0040, 0x3b49, 0x2011, + 0x0075, 0x7a1a, 0x1078, 0x462d, 0x0078, 0x3b57, 0x7e5a, 0x2009, + 0x0076, 0xd69c, 0x0040, 0x3b56, 0x2009, 0x0075, 0x791a, 0x68c0, + 0x705a, 0x2d00, 0x704e, 0x68c4, 0x2060, 0x71d4, 0xd1b4, 0x00c0, + 0x2942, 0x2300, 0xa405, 0x0040, 0x2942, 0x70a4, 0xa086, 0x0001, + 0x00c0, 0x2989, 0x007c, 0x6020, 0xa005, 0x0040, 0x3b79, 0x8001, + 0x6022, 0x6008, 0xa085, 0x0008, 0x600a, 0x700f, 0x0100, 0x702c, + 0x6026, 0x007c, 0xa006, 0x1078, 0x4326, 0x6817, 0x0000, 0x681b, + 0x0001, 0x6823, 0x0040, 0x681f, 0x0100, 0x7000, 0xa084, 0x000f, + 0x0079, 0x3b8a, 0x2946, 0x3b94, 0x3b94, 0x3bb1, 0x3b9c, 0x2946, + 0x3b92, 0x3b92, 0x1078, 0x28ec, 0x1078, 0x3bbc, 0x1078, 0x3bb5, + 0x1078, 0x202a, 0x0078, 0x2946, 0x7064, 0x7067, 0x0000, 0x7083, + 0x0000, 0x0079, 0x3ba3, 0x3bad, 0x3bad, 0x3bab, 0x3bab, 0x3bab, + 0x3bad, 0x3bab, 0x3bad, 0x0079, 0x2e5c, 0x7067, 0x0000, 0x0078, + 0x2946, 0x681b, 0x0000, 0x0078, 0x35ae, 0x6800, 0xa005, 0x00c0, + 0x3bba, 0x6002, 0x6006, 0x007c, 0x6410, 0x84ff, 0x0040, 0x3bce, + 0x2009, 0x4a02, 0x2104, 0x8001, 0x200a, 0x8421, 0x6412, 0x00c0, + 0x3bce, 0x2021, 0x4a04, 0x2404, 0xc0a5, 0x2022, 0x6008, 0xc0a4, + 0x600a, 0x007c, 0x6018, 0xa005, 0x0040, 0x3bd8, 0x8001, 0x601a, + 0x007c, 0x1078, 0x4131, 0x681b, 0x0018, 0x0078, 0x3c1a, 0x1078, + 0x4131, 0x681b, 0x0019, 0x0078, 0x3c1a, 0x1078, 0x4131, 0x681b, + 0x001a, 0x0078, 0x3c1a, 0x1078, 0x4131, 0x681b, 0x0003, 0x0078, + 0x3c1a, 0x7774, 0x1078, 0x3fe1, 0x7178, 0xa18c, 0x00ff, 0x3210, + 0xa294, 0x0300, 0x0040, 0x3c00, 0xa1e8, 0x8fc0, 0x0078, 0x3c02, + 0xa1e8, 0x90d0, 0x2d04, 0x2d08, 0x2068, 0xa005, 0x00c0, 0x3c0a, + 0x0078, 0x2946, 0x6814, 0xc0fc, 0x7274, 0xc2fc, 0xa206, 0x0040, + 0x3c14, 0x6800, 0x0078, 0x3c03, 0x6800, 0x200a, 0x681b, 0x0005, + 0x707f, 0x0000, 0x1078, 0x3bbc, 0x6820, 0xd084, 0x00c0, 0x3c22, + 0x1078, 0x3bb5, 0x1078, 0x3bd2, 0x681f, 0x0000, 0x6823, 0x0020, + 0x1078, 0x202a, 0x0078, 0x2946, 0xa282, 0x0003, 0x00c0, 0x3e9d, + 0x7da8, 0xa5ac, 0x00ff, 0x7ea8, 0xa6b4, 0x00ff, 0x6920, 0xc1bd, + 0x6922, 0xd1c4, 0x0040, 0x3c86, 0xc1c4, 0x6922, 0xa6b4, 0x00ff, + 0x0040, 0x3c73, 0xa682, 0x000c, 0x0048, 0x3c4a, 0x0040, 0x3c4a, + 0x2031, 0x000c, 0x2500, 0xa086, 0x000a, 0x0040, 0x3c51, 0x852b, + 0x852b, 0x1078, 0x3f73, 0x0040, 0x3c59, 0x1078, 0x3d55, 0x0078, + 0x3c7c, 0x1078, 0x3f2e, 0x0c7e, 0x2960, 0x6004, 0xa084, 0xfff5, + 0x6006, 0x1078, 0x3d8a, 0x0c7f, 0x6920, 0xc1c5, 0x6922, 0x7e58, + 0xc695, 0x7e5a, 0xd6d4, 0x00c0, 0x3c70, 0x781b, 0x0061, 0x007c, + 0x781b, 0x0075, 0x007c, 0x0c7e, 0x2960, 0x6004, 0xa084, 0xfff5, + 0x6006, 0x1078, 0x3d8a, 0x0c7f, 0x7e58, 0xd6d4, 0x00c0, 0x3c83, + 0x781b, 0x0064, 0x007c, 0x781b, 0x0076, 0x007c, 0x0c7e, 0x7058, + 0x2060, 0x6100, 0xd1e4, 0x0040, 0x3ccf, 0x6208, 0x8217, 0xa294, + 0x00ff, 0xa282, 0x000c, 0x0048, 0x3c99, 0x0040, 0x3c99, 0x2011, + 0x000c, 0x2600, 0xa202, 0x00c8, 0x3c9e, 0x2230, 0x6208, 0xa294, + 0x00ff, 0x2001, 0x4a05, 0x2004, 0xd0e4, 0x00c0, 0x3cb3, 0x78ec, + 0xd0e4, 0x0040, 0x3cb3, 0xa282, 0x000a, 0x00c8, 0x3cb9, 0x2011, + 0x000a, 0x0078, 0x3cb9, 0xa282, 0x000c, 0x00c8, 0x3cb9, 0x2011, + 0x000c, 0x2200, 0xa502, 0x00c8, 0x3cbe, 0x2228, 0x1078, 0x3f32, + 0x2500, 0xa086, 0x000a, 0x0040, 0x3cc7, 0x852b, 0x852b, 0x1078, + 0x3f73, 0x0040, 0x3ccf, 0x1078, 0x3d55, 0x0078, 0x3cd3, 0x1078, + 0x3f2e, 0x1078, 0x3d8a, 0x7858, 0xc095, 0x785a, 0x0c7f, 0x781b, + 0x0075, 0x007c, 0x0c7e, 0x2960, 0x6000, 0xd0e4, 0x00c0, 0x3cf1, + 0x6010, 0xa084, 0x000f, 0x00c0, 0x3ceb, 0x6104, 0xa18c, 0xfff5, + 0x6106, 0x0c7f, 0x007c, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078, + 0x3d1c, 0x68a0, 0xd0cc, 0x00c0, 0x3ceb, 0x6208, 0xa294, 0x00ff, + 0x2001, 0x4a05, 0x2004, 0xd0e4, 0x00c0, 0x3d0a, 0x78ec, 0xd0e4, + 0x0040, 0x3d0a, 0xa282, 0x000a, 0x00c0, 0x3d0a, 0x2011, 0x000a, + 0x0078, 0x3d10, 0xa282, 0x000c, 0x00c8, 0x3d10, 0x2011, 0x000c, + 0x6308, 0x831f, 0xa39c, 0x00ff, 0xa382, 0x000c, 0x0048, 0x3d1c, + 0x0040, 0x3d1c, 0x2019, 0x000c, 0x78ab, 0x0001, 0x78ab, 0x0003, + 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xc0c5, + 0x6822, 0x70d4, 0xd0b4, 0x0040, 0x3d38, 0xc0b4, 0x70d6, 0x70b8, + 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, + 0x0c7f, 0x007c, 0x0c7e, 0x2960, 0x6104, 0xa18c, 0xfff5, 0x6106, + 0x2011, 0x0032, 0x2019, 0x0000, 0x0078, 0x3d46, 0x78ab, 0x0001, + 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, + 0x6820, 0xc0c5, 0x6822, 0x0c7f, 0x007c, 0x0c7e, 0x7158, 0x2160, + 0x2018, 0xa08c, 0x0020, 0x0040, 0x3d5e, 0xc0ac, 0x2008, 0xa084, + 0xfff0, 0xa635, 0x7e86, 0x6018, 0x789a, 0x7eae, 0x6612, 0x78a4, + 0xa084, 0xfff0, 0xa18c, 0x000f, 0xa105, 0xa39c, 0x0020, 0x0040, + 0x3d73, 0xa085, 0x4000, 0xc0fc, 0xd0b4, 0x00c0, 0x3d78, 0xc0fd, + 0x78a6, 0x6016, 0x788a, 0xa6b4, 0x000f, 0x8637, 0x8204, 0x8004, + 0xa084, 0x00ff, 0xa605, 0x600e, 0x6004, 0xa084, 0xfff5, 0x6006, + 0x0c7f, 0x007c, 0x0c7e, 0x7058, 0x2060, 0x6018, 0x789a, 0x78a4, + 0xa084, 0xfff0, 0x78a6, 0x6012, 0x7884, 0xa084, 0xfff0, 0x7886, + 0x600c, 0xa084, 0x00ff, 0x600e, 0x0c7f, 0x007c, 0xa282, 0x0002, + 0x00c0, 0x3e9d, 0x7aa8, 0x6920, 0xc1bd, 0x6922, 0xd1cc, 0x0040, + 0x3dd9, 0xc1cc, 0x6922, 0xa294, 0x00ff, 0xa282, 0x0002, 0x00c8, + 0x3e9d, 0x1078, 0x3e2a, 0x1078, 0x3d8a, 0xa980, 0x0001, 0x200c, + 0x1078, 0x3fdd, 0x1078, 0x3cda, 0x88ff, 0x0040, 0x3dcf, 0x789b, + 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x00c0, + 0x3dcc, 0x781b, 0x0061, 0x007c, 0x781b, 0x0075, 0x007c, 0x7e58, + 0xd6d4, 0x00c0, 0x3dd6, 0x781b, 0x0064, 0x007c, 0x781b, 0x0076, + 0x007c, 0xa282, 0x0002, 0x00c8, 0x3de1, 0xa284, 0x0001, 0x0040, + 0x3dea, 0x7158, 0xa188, 0x0000, 0x210c, 0xd1ec, 0x00c0, 0x3dea, + 0x2011, 0x0000, 0x1078, 0x3f0f, 0x1078, 0x3e2a, 0x1078, 0x3d8a, + 0x7858, 0xc095, 0x785a, 0x781b, 0x0075, 0x007c, 0x0c7e, 0x027e, + 0x2960, 0x6000, 0x2011, 0x0001, 0xd0ec, 0x00c0, 0x3e0b, 0x6014, + 0xa084, 0x0040, 0x00c0, 0x3e09, 0xc1a4, 0x6106, 0xa006, 0x0078, + 0x3e27, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, + 0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x70d4, 0xd0b4, 0x0040, 0x3e23, + 0xc0b4, 0x70d6, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, + 0x6018, 0x8001, 0x601a, 0x6820, 0xa085, 0x0200, 0x6822, 0x027f, + 0x0c7f, 0x007c, 0x0c7e, 0x7058, 0x2060, 0x82ff, 0x0040, 0x3e32, + 0x2011, 0x0040, 0x6018, 0xa080, 0x0002, 0x789a, 0x78a4, 0xa084, + 0xffbf, 0xa205, 0xc0fc, 0xd0b4, 0x00c0, 0x3e3f, 0xc0fd, 0x78a6, + 0x6016, 0x788a, 0x6004, 0xc0a4, 0x6006, 0x0c7f, 0x007c, 0x007e, + 0x7000, 0xa086, 0x0003, 0x0040, 0x3e50, 0x007f, 0x0078, 0x3e53, + 0x007f, 0x0078, 0x3e9a, 0xd6ac, 0x0040, 0x3e9a, 0x7888, 0xa084, + 0x0040, 0x0040, 0x3e9a, 0x7bb8, 0xa384, 0x003f, 0x831b, 0x00c8, + 0x3e62, 0x8000, 0xa005, 0x0040, 0x3e77, 0x831b, 0x00c8, 0x3e6b, + 0x8001, 0x0040, 0x3e97, 0xd6f4, 0x0040, 0x3e77, 0x78b8, 0x801b, + 0x00c8, 0x3e73, 0x8000, 0xa084, 0x003f, 0x00c0, 0x3e97, 0xc6f4, + 0x7e5a, 0x79d8, 0x7adc, 0x2001, 0x0001, 0xa108, 0x00c8, 0x3e82, + 0xa291, 0x0000, 0x79d2, 0x79da, 0x7ad6, 0x7ade, 0x1078, 0x46e5, + 0x781b, 0x0073, 0xb284, 0x0300, 0x0040, 0x3e92, 0x2001, 0x0000, + 0x0078, 0x3e94, 0x2001, 0x0001, 0x1078, 0x4585, 0x007c, 0x781b, + 0x0073, 0x007c, 0x781b, 0x0076, 0x007c, 0x1078, 0x3ec2, 0x781b, + 0x0075, 0x007c, 0x1078, 0x3eae, 0x781b, 0x0075, 0x007c, 0x6827, + 0x0002, 0x1078, 0x3eb6, 0x781b, 0x0075, 0x007c, 0x2001, 0x0005, + 0x0078, 0x3ec4, 0x2001, 0x000c, 0x0078, 0x3ec4, 0x2001, 0x0006, + 0x0078, 0x3ec4, 0x2001, 0x000d, 0x0078, 0x3ec4, 0x2001, 0x0009, + 0x0078, 0x3ec4, 0x2001, 0x0007, 0x789b, 0x007e, 0x78aa, 0xc69d, + 0x7e5a, 0x70d4, 0xd0b4, 0x0040, 0x3eda, 0xc0b4, 0x70d6, 0x0c7e, + 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, + 0x601a, 0x0c7f, 0x007c, 0x077e, 0x873f, 0xa7bc, 0x000f, 0x873b, + 0x873b, 0x8703, 0x017e, 0xb28c, 0x0300, 0x0040, 0x3eeb, 0xa0e0, + 0x4ec0, 0x0078, 0x3eed, 0xa0e0, 0x4f40, 0x017f, 0xa7b8, 0x0020, + 0x7f9a, 0x79a4, 0xa184, 0x000f, 0x0040, 0x3efd, 0xa184, 0xfff0, + 0x78a6, 0x6012, 0x6004, 0xc09d, 0x6006, 0x8738, 0x8738, 0x7f9a, + 0x79a4, 0xa184, 0x0040, 0x0040, 0x3f0d, 0xa184, 0xffbf, 0xc0fd, + 0x78a6, 0x6016, 0x6004, 0xc0a5, 0x6006, 0x077f, 0x007c, 0x789b, + 0x0010, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, + 0x789b, 0x0060, 0x78ab, 0x0004, 0x70d4, 0xd0b4, 0x0040, 0x3f2d, + 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, + 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x007c, 0x2031, 0x0000, + 0x2029, 0x0032, 0x789b, 0x0010, 0x78ab, 0x0001, 0x78ab, 0x0003, + 0x78ab, 0x0001, 0x7daa, 0x7eaa, 0x789b, 0x0060, 0x78ab, 0x0005, + 0x70d4, 0xd0b4, 0x0040, 0x3f51, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, + 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, + 0x0c7f, 0x007c, 0x157e, 0x8007, 0xa084, 0x00ff, 0x8003, 0x8003, + 0xa080, 0x0020, 0x789a, 0x79a4, 0xa18c, 0xfff0, 0x2021, 0x3fc6, + 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011, 0x0032, 0x2404, 0xa084, + 0xfff0, 0xa106, 0x0040, 0x3f71, 0x8420, 0x2300, 0xa210, 0x00f0, + 0x3f66, 0x157f, 0x007c, 0x157e, 0x2001, 0x4a05, 0x2004, 0xd0e4, + 0x00c0, 0x3fa4, 0x2021, 0x3fd4, 0x20a9, 0x0009, 0x2011, 0x0028, + 0xa582, 0x0019, 0x0040, 0x3fba, 0x0048, 0x3fba, 0x8420, 0x95a9, + 0x2011, 0x0032, 0xa582, 0x0032, 0x0040, 0x3fba, 0x0048, 0x3fba, + 0x8420, 0x95a9, 0x2019, 0x000a, 0x2011, 0x0064, 0x2200, 0xa502, + 0x0040, 0x3fba, 0x0048, 0x3fba, 0x8420, 0x2300, 0xa210, 0x00f0, + 0x3f96, 0x157f, 0x0078, 0x3fb8, 0x2021, 0x3fc6, 0x2019, 0x0011, + 0x20a9, 0x000e, 0x2011, 0x0032, 0x2200, 0xa502, 0x0040, 0x3fba, + 0x0048, 0x3fba, 0x8420, 0x2300, 0xa210, 0x00f0, 0x3fac, 0x157f, + 0xa006, 0x007c, 0x157f, 0xa582, 0x0064, 0x00c8, 0x3fc3, 0x7808, + 0xa085, 0x0070, 0x780a, 0x2404, 0xa005, 0x007c, 0x1209, 0x3002, + 0x3202, 0x4203, 0x4403, 0x5404, 0x5604, 0x6605, 0x6805, 0x7806, + 0x7a06, 0x0c07, 0x0c07, 0x0e07, 0x10e1, 0x330a, 0x5805, 0x5a05, + 0x6a06, 0x6c06, 0x7c07, 0x7e07, 0x0e00, 0x789b, 0x0010, 0xa046, + 0x007c, 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f, 0x8003, 0x8003, + 0x8003, 0x8003, 0xa105, 0xd7fc, 0x0040, 0x3ff2, 0xa0e0, 0x6fc0, + 0x0078, 0x3ff4, 0xa0e0, 0x4fc0, 0x007c, 0x0e7e, 0x0f7e, 0xd084, + 0x0040, 0x4002, 0x2079, 0x0100, 0x2009, 0x4a80, 0x2071, 0x4a80, + 0x0078, 0x4014, 0x2009, 0x4a40, 0x007e, 0x2001, 0x4a04, 0x2004, + 0xd0ec, 0x007f, 0x0040, 0x4010, 0x2079, 0x0100, 0x0078, 0x4014, + 0x2079, 0x0200, 0x2071, 0x4a40, 0x2091, 0x8000, 0x2104, 0xa084, + 0x000f, 0x0079, 0x401b, 0x405d, 0x4025, 0x4025, 0x4025, 0x4025, + 0x4025, 0x4023, 0x4023, 0x1078, 0x28ec, 0x784b, 0x0004, 0x7848, + 0xa084, 0x0004, 0x00c0, 0x4027, 0x784b, 0x0008, 0x7848, 0xa084, + 0x0008, 0x00c0, 0x402e, 0x68b4, 0xc0f5, 0x68b6, 0x7858, 0xc0f5, + 0x785a, 0x7830, 0xd0bc, 0x00c0, 0x405d, 0x007e, 0x2001, 0x4a04, + 0x2004, 0xd0ec, 0x007f, 0x0040, 0x4049, 0xb284, 0x0300, 0x0078, + 0x404b, 0xb284, 0x0400, 0x0040, 0x4051, 0x0018, 0x405d, 0x0078, + 0x4053, 0x0028, 0x405d, 0x681c, 0xd0ac, 0x00c0, 0x405b, 0x1078, + 0x40d5, 0x0078, 0x405d, 0x781b, 0x00f0, 0x2091, 0x8001, 0x0f7f, + 0x0e7f, 0x007c, 0x0c7e, 0x2001, 0x4a01, 0x2004, 0xd0ac, 0x00c0, + 0x40c7, 0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, + 0xb28c, 0x0300, 0x0040, 0x4078, 0xa0e0, 0x4ec0, 0x0078, 0x407a, + 0xa0e0, 0x4f40, 0x6004, 0xa084, 0x000a, 0x00c0, 0x40c7, 0x6108, + 0xa194, 0xff00, 0x0040, 0x40c7, 0xa18c, 0x00ff, 0x2001, 0x000a, + 0xa106, 0x0040, 0x40a6, 0x2001, 0x000c, 0xa106, 0x0040, 0x40aa, + 0x2001, 0x0012, 0xa106, 0x0040, 0x40ae, 0x2001, 0x0014, 0xa106, + 0x0040, 0x40b2, 0x2001, 0x0019, 0xa106, 0x0040, 0x40b6, 0x2001, + 0x0032, 0xa106, 0x0040, 0x40ba, 0x0078, 0x40be, 0x2009, 0x000c, + 0x0078, 0x40c0, 0x2009, 0x0012, 0x0078, 0x40c0, 0x2009, 0x0014, + 0x0078, 0x40c0, 0x2009, 0x0019, 0x0078, 0x40c0, 0x2009, 0x0020, + 0x0078, 0x40c0, 0x2009, 0x003f, 0x0078, 0x40c0, 0x2011, 0x0000, + 0x2100, 0xa205, 0x600a, 0x6004, 0xa085, 0x0002, 0x6006, 0x0c7f, + 0x007c, 0x781b, 0x0076, 0x007c, 0x781b, 0x0075, 0x007c, 0x781b, + 0x0064, 0x007c, 0x781b, 0x0061, 0x007c, 0x2009, 0x4a19, 0x210c, + 0xa186, 0x0000, 0x0040, 0x40e7, 0xa186, 0x0001, 0x0040, 0x40ea, + 0x701f, 0x000b, 0x7067, 0x0001, 0x781b, 0x0047, 0x007c, 0x781b, + 0x00e7, 0x007c, 0x701f, 0x000a, 0x007c, 0x2009, 0x4a19, 0x210c, + 0xa186, 0x0000, 0x0040, 0x4102, 0xa186, 0x0001, 0x0040, 0x40ff, + 0x701f, 0x000b, 0x7067, 0x0001, 0x781b, 0x0047, 0x007c, 0x701f, + 0x000a, 0x007c, 0x781b, 0x00e6, 0x007c, 0x781b, 0x00f0, 0x007c, + 0x781b, 0x00ef, 0x007c, 0x781b, 0x00c0, 0x007c, 0x781b, 0x00bf, + 0x007c, 0x6818, 0xd0fc, 0x0040, 0x4117, 0x681b, 0x001d, 0x7067, + 0x0001, 0x781b, 0x0047, 0x007c, 0x7830, 0xa084, 0x00c0, 0x00c0, + 0x4130, 0x7808, 0xc08c, 0x780a, 0x0005, 0x0005, 0x0005, 0x0005, + 0x78ec, 0xa084, 0x0021, 0x0040, 0x4130, 0x7808, 0xc08d, 0x780a, + 0x007c, 0x7808, 0xc08d, 0x780a, 0x007c, 0x7830, 0xa084, 0x0040, + 0x00c0, 0x4135, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x0040, 0x4144, + 0xb284, 0x0300, 0x0078, 0x4146, 0xb284, 0x0400, 0x0040, 0x414c, + 0x0098, 0x4150, 0x0078, 0x414e, 0x00a8, 0x4150, 0x78ac, 0x007c, + 0x7808, 0xa084, 0xfffd, 0x780a, 0x0005, 0x0005, 0x0005, 0x0005, + 0x78ec, 0xa084, 0x0021, 0x0040, 0x4173, 0x007e, 0x2001, 0x4a04, + 0x2004, 0xd0ec, 0x007f, 0x0040, 0x4169, 0xb284, 0x0300, 0x0078, + 0x416b, 0xb284, 0x0400, 0x0040, 0x4171, 0x0098, 0x416d, 0x0078, + 0x4173, 0x00a8, 0x4171, 0x78ac, 0x007e, 0x7808, 0xa085, 0x0002, + 0x780a, 0x007f, 0x007c, 0xa784, 0x0001, 0x00c0, 0x360e, 0xa784, + 0x0070, 0x0040, 0x418b, 0x0c7e, 0x2d60, 0x2f68, 0x1078, 0x2881, + 0x2d78, 0x2c68, 0x0c7f, 0xa784, 0x0008, 0x0040, 0x4198, 0x784b, + 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2946, 0x0078, 0x40c9, + 0xa784, 0x0004, 0x0040, 0x41c7, 0x78b8, 0xa084, 0x4001, 0x0040, + 0x41c7, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2946, + 0x78e4, 0xa084, 0x0007, 0xa086, 0x0001, 0x00c0, 0x41c7, 0x78c0, + 0xa685, 0x4800, 0x2030, 0x7e5a, 0x781b, 0x00f0, 0x007c, 0x784b, + 0x0008, 0x6818, 0xd0fc, 0x0040, 0x41c4, 0x681b, 0x0015, 0xd6f4, + 0x0040, 0x41c4, 0x681b, 0x0007, 0x1078, 0x40d5, 0x007c, 0x681b, + 0x0003, 0x7858, 0xa084, 0x3f00, 0x681e, 0x682f, 0x0000, 0x6833, + 0x0000, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2f84, + 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x41e4, + 0xb284, 0x0300, 0x0078, 0x41e6, 0xb284, 0x0400, 0x0040, 0x41ec, + 0x0018, 0x2942, 0x0078, 0x41ee, 0x0028, 0x2942, 0x0078, 0x3ea2, + 0x6b14, 0x8307, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xd3fc, + 0x0040, 0x41fe, 0xa080, 0x4f40, 0x0078, 0x4200, 0xa080, 0x4ec0, + 0x2060, 0x2048, 0x705a, 0x2a60, 0x007c, 0x0020, 0x0020, 0x0000, + 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, + 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, + 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, + 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0062, + 0x0009, 0x0014, 0x0014, 0x9848, 0x0014, 0x0014, 0x9906, 0x98f4, + 0x0014, 0x0014, 0x0080, 0x00f1, 0x0100, 0x0402, 0x2008, 0xf880, + 0x0018, 0xa20a, 0x0014, 0x300b, 0xa20c, 0x0014, 0x2500, 0x0013, + 0x2500, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, + 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0xa200, + 0x3806, 0x8839, 0x20c4, 0x0864, 0xa850, 0x3008, 0x28c1, 0x9d0d, + 0xa201, 0x300c, 0x2847, 0x8161, 0x846a, 0x8000, 0x84a4, 0x1856, + 0x883a, 0xa808, 0x28e2, 0x9cc2, 0xa8f3, 0x0864, 0xa83e, 0x300c, + 0xa801, 0x3008, 0x28e1, 0x9cc2, 0x2021, 0xa81b, 0xa205, 0x870c, + 0xd8de, 0x64a0, 0x6de0, 0x6fc0, 0x63a4, 0x6c80, 0x0212, 0xa205, + 0x883d, 0x9d25, 0x882b, 0x1814, 0x883b, 0x9d2b, 0x883b, 0x7027, + 0x85f2, 0xa737, 0xa532, 0xf003, 0x8576, 0x8677, 0xa812, 0x883e, + 0xa810, 0x280c, 0xa204, 0x64c0, 0x6de0, 0x67a0, 0x6fc0, 0x9d25, + 0x1814, 0x9d2b, 0x883b, 0x7023, 0x8576, 0x8677, 0xa802, 0x7861, + 0x883e, 0x206b, 0x28c1, 0x9d0d, 0x2044, 0x2103, 0x20a2, 0x2081, + 0xa8c9, 0xa207, 0x2901, 0xa80a, 0x0014, 0xa203, 0x8000, 0x85a4, + 0x1872, 0x879a, 0x883c, 0x1fe2, 0xf601, 0xa208, 0x856e, 0x866f, + 0x7161, 0x0014, 0x0704, 0x3008, 0x9cc2, 0x0014, 0xa202, 0x8000, + 0x85a4, 0x3009, 0x84a8, 0x19e2, 0xf844, 0x856e, 0x883f, 0x08e6, + 0xa8f5, 0xf861, 0xa8ea, 0xf801, 0x0014, 0xf881, 0x0016, 0x85b2, + 0x80f0, 0x9532, 0xfaa2, 0x1de2, 0x0014, 0x8532, 0xf221, 0x0014, + 0x1de2, 0x84a8, 0xd6e0, 0x1fe6, 0x0014, 0x3008, 0x8000, 0x284a, + 0x1011, 0xa8fc, 0x3008, 0x9d25, 0x8000, 0xa000, 0x2802, 0x1011, + 0xa8fd, 0x9d2b, 0xa887, 0x3008, 0x9d25, 0x283b, 0x1011, 0xa8fd, + 0xa209, 0x0017, 0x300c, 0x8000, 0x85a4, 0x1de2, 0xdac1, 0x0014, + 0x0210, 0xa801, 0x0014, 0x26e0, 0x873a, 0xfaa3, 0x19f2, 0x26e0, + 0x18f2, 0x0014, 0xa20b, 0x0014, 0xa20d, 0x3806, 0x0210, 0x9d17, + 0x0704, 0xa206, 0x6865, 0x817e, 0x842a, 0x1dc1, 0x8823, 0x0016, + 0x6042, 0x8008, 0xa8fa, 0x8000, 0x84a4, 0x8160, 0x842a, 0xf021, + 0x3008, 0x84a8, 0x11d6, 0x7042, 0x20dd, 0x0011, 0x20d4, 0x8822, + 0x0016, 0x7944, 0x8421, 0xa020, 0xa532, 0x84a1, 0x0016, 0x7944, + 0x8421, 0xa0df, 0x9532, 0x84a1, 0x0016, 0x0000, 0x127e, 0x70d4, + 0xa084, 0x4600, 0x8004, 0x2090, 0x7204, 0x7008, 0xc09c, 0xa205, + 0x00c0, 0x4342, 0x720c, 0x82ff, 0x0040, 0x433d, 0x8aff, 0x00c0, + 0x4342, 0x7200, 0xd284, 0x00c0, 0x4342, 0x7003, 0x0008, 0x127f, + 0x2000, 0x007c, 0x7000, 0xa084, 0x0003, 0x7002, 0xc69c, 0xd084, + 0x0040, 0x4374, 0x2001, 0x4a05, 0x2004, 0xd0ec, 0x00c0, 0x43a5, + 0xd0e4, 0x00c0, 0x435a, 0x2001, 0x04fd, 0x2004, 0xa086, 0x0003, + 0x0040, 0x43a5, 0x0e7e, 0x2071, 0x0010, 0x2009, 0x0007, 0x7008, + 0xa084, 0x3000, 0x00c0, 0x435d, 0x8109, 0x00c0, 0x435f, 0x0e7f, + 0x2009, 0x0007, 0x7008, 0xa084, 0x3000, 0x00c0, 0x435a, 0x8109, + 0x00c0, 0x436a, 0x0078, 0x43a5, 0x7108, 0xd1fc, 0x0040, 0x437f, + 0x1078, 0x44ba, 0x8aff, 0x0040, 0x432c, 0x0078, 0x4374, 0x700c, + 0xa08c, 0x03ff, 0x0040, 0x43aa, 0x7004, 0xd084, 0x0040, 0x439c, + 0x7014, 0xa005, 0x00c0, 0x4398, 0x7010, 0x7310, 0xa306, 0x00c0, + 0x438c, 0x2300, 0xa005, 0x0040, 0x439c, 0xa102, 0x00c8, 0x4374, + 0x7007, 0x0010, 0x0078, 0x43a5, 0x8aff, 0x0040, 0x43aa, 0x1078, + 0x46a3, 0x00c0, 0x439f, 0x0040, 0x4374, 0x1078, 0x4443, 0x127f, + 0x2000, 0x007c, 0x7204, 0x7108, 0xc19c, 0x8103, 0x00c8, 0x43b9, + 0x1078, 0x44ba, 0x0078, 0x43aa, 0x7003, 0x0008, 0x127f, 0x2000, + 0x007c, 0xa205, 0x00c0, 0x43a5, 0x7003, 0x0008, 0x127f, 0x2000, + 0x007c, 0x6428, 0x84ff, 0x0040, 0x43ed, 0x2c70, 0x7004, 0xa0bc, + 0x000f, 0xa7b8, 0x43fd, 0x273c, 0x87fb, 0x00c0, 0x43db, 0x0048, + 0x43d3, 0x1078, 0x28ec, 0x609c, 0xa075, 0x0040, 0x43ed, 0x0078, + 0x43c6, 0x2039, 0x43f2, 0x2704, 0xae68, 0x6808, 0xa630, 0x680c, + 0xa529, 0x8421, 0x0040, 0x43ed, 0x8738, 0x2704, 0xa005, 0x00c0, + 0x43dc, 0x709c, 0xa075, 0x00c0, 0x43c6, 0x007c, 0x0000, 0x0005, + 0x0009, 0x000d, 0x0011, 0x0015, 0x0019, 0x001d, 0x0000, 0x0003, + 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0000, 0x43f2, 0x43ef, + 0x0000, 0x0000, 0x8000, 0x0000, 0x43f2, 0x0000, 0x43fa, 0x43f7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x43fa, 0x0000, 0x43f5, 0x43f5, + 0x0000, 0x0000, 0x8000, 0x0000, 0x43f5, 0x0000, 0x43fb, 0x43fb, + 0x0000, 0x0000, 0x0000, 0x0000, 0x43fb, 0x2079, 0x4a00, 0x2071, + 0x0010, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0001, 0x7810, + 0xd0ec, 0x0040, 0x4431, 0x2009, 0x0001, 0x2071, 0x0020, 0x0078, + 0x4435, 0x2009, 0x0002, 0x2071, 0x0050, 0x7007, 0x000a, 0x7007, + 0x0002, 0x7003, 0x0000, 0x8109, 0x0040, 0x4442, 0x2071, 0x0020, + 0x0078, 0x4435, 0x007c, 0x7004, 0x8004, 0x00c8, 0x44a6, 0x7007, + 0x0012, 0x2019, 0x0000, 0x7108, 0x7008, 0xa106, 0x00c0, 0x444b, + 0xa184, 0x01e0, 0x0040, 0x4456, 0x1078, 0x28ec, 0x7810, 0xd0ec, + 0x0040, 0x4470, 0x2001, 0x04fd, 0x2004, 0xa086, 0x0003, 0x00c0, + 0x4474, 0xa184, 0x4000, 0x0040, 0x4478, 0xa382, 0x0003, 0x00c8, + 0x4478, 0xa184, 0x0004, 0x0040, 0x444b, 0x8318, 0x0078, 0x444b, + 0x7814, 0xd0ec, 0x00c0, 0x4478, 0xa184, 0x4000, 0x00c0, 0x444b, + 0xa19c, 0x300c, 0xa386, 0x2004, 0x0040, 0x4486, 0xa386, 0x0008, + 0x0040, 0x4491, 0xa386, 0x200c, 0x00c0, 0x444b, 0x7200, 0x8204, + 0x0048, 0x4491, 0x730c, 0xa384, 0x03ff, 0x0040, 0x4491, 0x1078, + 0x28ec, 0x7007, 0x0012, 0x7000, 0xd084, 0x00c0, 0x44a6, 0x7008, + 0xa084, 0x01e0, 0x00c0, 0x44a6, 0x7310, 0x7014, 0xa305, 0x0040, + 0x44a6, 0x710c, 0xa184, 0x03ff, 0x00c0, 0x4443, 0x7007, 0x0012, + 0x7007, 0x0008, 0x7004, 0xd09c, 0x00c0, 0x44aa, 0x7007, 0x0012, + 0x7108, 0x8103, 0x0048, 0x44ae, 0x7003, 0x0008, 0x007c, 0x7108, + 0x0078, 0x44ba, 0xa184, 0x01e0, 0x00c0, 0x44ee, 0x7108, 0xa184, + 0x01e0, 0x00c0, 0x44ee, 0xa184, 0x0007, 0x0079, 0x44c7, 0x44d1, + 0x44e1, 0x44cf, 0x44e1, 0x44cf, 0x4533, 0x44cf, 0x4531, 0x1078, + 0x28ec, 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff, 0x00c0, + 0x44dc, 0x2049, 0x0000, 0x007c, 0x1078, 0x46a3, 0x00c0, 0x44dc, + 0x007c, 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff, 0x0040, + 0x44ed, 0x1078, 0x46a3, 0x00c0, 0x44e9, 0x007c, 0x7007, 0x0012, + 0x7108, 0x00e0, 0x44f1, 0x2091, 0x6000, 0x00e0, 0x44f5, 0x2091, + 0x6000, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xd09c, 0x00c0, + 0x44fd, 0x7007, 0x0012, 0x7108, 0xd1fc, 0x00c0, 0x4501, 0x7003, + 0x0000, 0x7000, 0xa005, 0x00c0, 0x4515, 0x7004, 0xa005, 0x00c0, + 0x4515, 0x700c, 0xa005, 0x0040, 0x4517, 0x0078, 0x44f9, 0x2049, + 0x0000, 0xb284, 0x0100, 0x0040, 0x4521, 0x2001, 0x0000, 0x0078, + 0x4523, 0x2001, 0x0001, 0x1078, 0x3ff5, 0x6818, 0xa084, 0x8000, + 0x0040, 0x452c, 0x681b, 0x0002, 0x007c, 0x1078, 0x28ec, 0x1078, + 0x28ec, 0x1078, 0x4570, 0x7210, 0x7114, 0x700c, 0xa09c, 0x03ff, + 0x2800, 0xa300, 0xa211, 0xa189, 0x0000, 0x1078, 0x4570, 0x2704, + 0x2c58, 0xac60, 0x6308, 0x2200, 0xa322, 0x630c, 0x2100, 0xa31b, + 0x2400, 0xa305, 0x0040, 0x4556, 0x00c8, 0x4556, 0x8412, 0x8210, + 0x830a, 0xa189, 0x0000, 0x2b60, 0x0078, 0x453d, 0x2b60, 0x8a07, + 0x007e, 0x6004, 0xa084, 0x0008, 0x0040, 0x4562, 0xa7ba, 0x43f7, + 0x0078, 0x4564, 0xa7ba, 0x43ef, 0x007f, 0xa73d, 0x2c00, 0x6886, + 0x6f8a, 0x6c92, 0x6b8e, 0x7007, 0x0012, 0x1078, 0x4443, 0x007c, + 0x8a50, 0x8739, 0x2704, 0xa004, 0x00c0, 0x4584, 0x6000, 0xa064, + 0x00c0, 0x457b, 0x2d60, 0x6004, 0xa084, 0x000f, 0xa080, 0x440d, + 0x203c, 0x87fb, 0x1040, 0x28ec, 0x007c, 0x127e, 0x0d7e, 0x70d4, + 0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x6884, 0x2060, 0x6888, + 0x6b8c, 0x6c90, 0x8057, 0xaad4, 0x00ff, 0xa084, 0x00ff, 0x007e, + 0x6804, 0xa084, 0x0008, 0x007f, 0x0040, 0x45a2, 0xa0b8, 0x43f7, + 0x0078, 0x45a4, 0xa0b8, 0x43ef, 0xb284, 0x0100, 0x0040, 0x45ab, + 0x7e20, 0x0078, 0x45ac, 0x7e24, 0xa6b5, 0x000c, 0x681c, 0xd0b4, + 0x0040, 0x45b3, 0xc685, 0x2400, 0xa305, 0x0040, 0x45dd, 0x2c58, + 0x2704, 0x6104, 0xac60, 0x6000, 0xa400, 0x701a, 0x6004, 0xa301, + 0x701e, 0xa184, 0x0008, 0x0040, 0x45cd, 0x6010, 0xa081, 0x0000, + 0x7022, 0x6014, 0xa081, 0x0000, 0x7026, 0x6208, 0x2400, 0xa202, + 0x7012, 0x620c, 0x2300, 0xa203, 0x7016, 0x7602, 0x7007, 0x0001, + 0x2b60, 0x1078, 0x46c6, 0x0078, 0x45df, 0x1078, 0x46a3, 0x00c0, + 0x45dd, 0x127f, 0x2000, 0x007c, 0x127e, 0x0d7e, 0x70d4, 0xa084, + 0x4600, 0x8004, 0x2090, 0x0d7f, 0x7007, 0x0004, 0x7004, 0xd094, + 0x00c0, 0x45ee, 0x7003, 0x0008, 0x127f, 0x2000, 0x007c, 0x127e, + 0x0d7e, 0x70d4, 0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x7e20, + 0xb284, 0x0100, 0x00c0, 0x4605, 0x7e24, 0xa6b5, 0x000c, 0x681c, + 0xd0ac, 0x00c0, 0x4610, 0xc685, 0x7003, 0x0000, 0x7007, 0x0004, + 0x6828, 0x2050, 0x2d60, 0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x43fd, + 0x273c, 0x87fb, 0x00c0, 0x4626, 0x0048, 0x4620, 0x1078, 0x28ec, + 0x689c, 0xa065, 0x0040, 0x462a, 0x0078, 0x4613, 0x1078, 0x46a3, + 0x00c0, 0x4626, 0x127f, 0x2000, 0x007c, 0x127e, 0x007e, 0x017e, + 0x0d7e, 0x70d4, 0xa084, 0x4600, 0x8004, 0x2090, 0x7e20, 0xb284, + 0x0100, 0x00c0, 0x463c, 0x7e24, 0x0d7f, 0x037f, 0x047f, 0xa6b5, + 0x000c, 0x681c, 0xd0b4, 0x0040, 0x464a, 0xc685, 0x7003, 0x0000, + 0x7007, 0x0004, 0x2049, 0x462d, 0x6828, 0xa055, 0x0040, 0x46a0, + 0x2d70, 0x2e60, 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x43fd, 0x273c, + 0x87fb, 0x00c0, 0x4666, 0x0048, 0x465f, 0x1078, 0x28ec, 0x709c, + 0xa075, 0x2060, 0x0040, 0x46a0, 0x0078, 0x4652, 0x2704, 0xae68, + 0x6808, 0xa422, 0x680c, 0xa31b, 0x0048, 0x467f, 0x8a51, 0x00c0, + 0x4673, 0x1078, 0x28ec, 0x8738, 0x2704, 0xa005, 0x00c0, 0x4667, + 0x709c, 0xa075, 0x2060, 0x0040, 0x46a0, 0x0078, 0x4652, 0x8422, + 0x8420, 0x831a, 0xa399, 0x0000, 0x6908, 0x2400, 0xa122, 0x690c, + 0x2300, 0xa11b, 0x00c8, 0x468e, 0x1078, 0x28ec, 0xb284, 0x0100, + 0x0040, 0x469c, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x00c0, 0x469c, + 0x2071, 0x0050, 0x0078, 0x469e, 0x2071, 0x0020, 0x0078, 0x45b3, + 0x127f, 0x2000, 0x007c, 0x7008, 0xa084, 0x0003, 0xa086, 0x0003, + 0x00c0, 0x46ab, 0x007c, 0x2704, 0xac78, 0x7800, 0x701a, 0x7804, + 0x701e, 0x7808, 0x7012, 0x780c, 0x7016, 0x6004, 0xa084, 0x0008, + 0x0040, 0x46be, 0x7810, 0x7022, 0x7814, 0x7026, 0x7602, 0x7004, + 0xa084, 0x0010, 0xc085, 0x7006, 0x2079, 0x4a00, 0x8a51, 0x0040, + 0x46e1, 0x8738, 0x2704, 0xa005, 0x00c0, 0x46dc, 0x609c, 0xa005, + 0x0040, 0x46e2, 0x2060, 0x6004, 0xa084, 0x000f, 0xa080, 0x43fd, + 0x203c, 0x87fb, 0x1040, 0x28ec, 0x7008, 0xa084, 0x0003, 0xa086, + 0x0003, 0x007c, 0x2051, 0x0000, 0x007c, 0x127e, 0x007e, 0x0d7e, + 0x70d4, 0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x087f, 0x7108, + 0xa184, 0x0003, 0x00c0, 0x46fa, 0x6828, 0xa005, 0x0040, 0x470a, + 0x0078, 0x4342, 0x7108, 0xd1fc, 0x0040, 0x4702, 0x1078, 0x44ba, + 0x0078, 0x46ef, 0x7007, 0x0010, 0x7108, 0xd1fc, 0x0040, 0x4704, + 0x1078, 0x44ba, 0x7008, 0xa086, 0x0008, 0x00c0, 0x46ef, 0x7000, + 0xa005, 0x00c0, 0x46ef, 0x7003, 0x0000, 0x2049, 0x0000, 0x127f, + 0x2000, 0x007c, 0x127e, 0x147e, 0x137e, 0x157e, 0x0c7e, 0x0d7e, + 0x70d4, 0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x2049, 0x471a, + 0xad80, 0x0011, 0x20a0, 0xb284, 0x0100, 0x0040, 0x473d, 0x2001, + 0x4a04, 0x2004, 0xd0ec, 0x0040, 0x4739, 0x2099, 0x0031, 0x0078, + 0x473f, 0x2099, 0x0032, 0x0078, 0x473f, 0x2099, 0x0031, 0x700c, + 0xa084, 0x03ff, 0x682a, 0x7007, 0x0008, 0x7007, 0x0002, 0x7003, + 0x0001, 0x0040, 0x474e, 0x8000, 0x80ac, 0x53a5, 0x700c, 0xa084, + 0x03ff, 0x0040, 0x475a, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, + 0x00c0, 0x4755, 0x0c7f, 0x2049, 0x0000, 0x7003, 0x0000, 0x157f, + 0x137f, 0x147f, 0x127f, 0x2000, 0x007c, 0x2091, 0x8000, 0x2091, + 0x6000, 0x78ac, 0xa005, 0x00c0, 0x477c, 0x7974, 0x70d0, 0xa106, + 0x00c0, 0x477c, 0x781c, 0xa005, 0x0040, 0x477c, 0x781f, 0x0000, + 0x0068, 0x477c, 0x2091, 0x4080, 0x7830, 0x8001, 0x7832, 0x00c0, + 0x4804, 0x7834, 0x7832, 0x7810, 0xd0ec, 0x00c0, 0x47fd, 0x2061, + 0x6fc0, 0x2069, 0x4a80, 0xc7fd, 0x68d0, 0xa005, 0x0040, 0x4796, + 0x8001, 0x68d2, 0x00c0, 0x4796, 0x1078, 0x4998, 0x6800, 0xa084, + 0x000f, 0x0040, 0x47ab, 0xa086, 0x0001, 0x0040, 0x47ab, 0x6844, + 0xa00d, 0x0040, 0x47ab, 0x2104, 0xa005, 0x0040, 0x47ab, 0x8001, + 0x200a, 0x0040, 0x4909, 0x6814, 0xa005, 0x0040, 0x47d0, 0x8001, + 0x6816, 0x00c0, 0x47d0, 0x68a7, 0x0001, 0x0f7e, 0xd7fc, 0x00c0, + 0x47c5, 0x7810, 0xd0ec, 0x0040, 0x47c1, 0x2079, 0x0100, 0x0078, + 0x47c7, 0x2079, 0x0200, 0x0078, 0x47c7, 0x2079, 0x0100, 0x1078, + 0x4131, 0x0f7f, 0x6864, 0xa005, 0x0040, 0x47d0, 0x1078, 0x25de, + 0x6880, 0xa005, 0x0040, 0x47dd, 0x8001, 0x6882, 0x00c0, 0x47dd, + 0x6867, 0x0000, 0x68d4, 0xc0dd, 0x68d6, 0x68d4, 0xd0fc, 0x0040, + 0x47fa, 0xc0fc, 0x68d6, 0x20a9, 0x0200, 0x603c, 0xa005, 0x0040, + 0x47f6, 0x8001, 0x603e, 0x68d4, 0xc0fd, 0x68d6, 0x00c0, 0x47f6, + 0x6010, 0xa005, 0x0040, 0x47f6, 0x1078, 0x25de, 0xace0, 0x0010, + 0x00f0, 0x47e5, 0xd7fc, 0x0040, 0x4804, 0x2061, 0x4fc0, 0x2069, + 0x4a40, 0xc7fc, 0x0078, 0x478c, 0x1078, 0x4840, 0x7838, 0x8001, + 0x783a, 0x00c0, 0x4826, 0x783c, 0x783a, 0x2061, 0x4fc0, 0x2069, + 0x4a40, 0xc7fc, 0x680c, 0xa005, 0x0040, 0x4818, 0x1078, 0x487f, + 0xd7fc, 0x00c0, 0x4826, 0x7810, 0xd0ec, 0x00c0, 0x4826, 0x2061, + 0x6fc0, 0x2069, 0x4a80, 0xc7fd, 0x0078, 0x4812, 0x7814, 0xd0e4, + 0x00c0, 0x482a, 0x7810, 0xd0cc, 0x0040, 0x483d, 0xd0ac, 0x00c0, + 0x4836, 0xd0a4, 0x0040, 0x483d, 0xc0ad, 0x7812, 0x2091, 0x8001, + 0x0068, 0x483c, 0x1078, 0x2368, 0x007c, 0x2091, 0x8001, 0x007c, + 0x7840, 0x8001, 0x7842, 0x00c0, 0x487e, 0x7844, 0x7842, 0x2091, + 0x8000, 0x2061, 0x4fc0, 0x2069, 0x4a40, 0xc7fc, 0x6810, 0xa005, + 0x00c0, 0x4854, 0x2001, 0x0101, 0x8001, 0x6812, 0xd7fc, 0x0040, + 0x485d, 0xa080, 0x90d0, 0x0078, 0x485f, 0xa080, 0x8fc0, 0x2040, + 0x2004, 0xa065, 0x0040, 0x4870, 0x6024, 0xa005, 0x0040, 0x486c, + 0x8001, 0x6026, 0x0040, 0x48ad, 0x6000, 0x2c40, 0x0078, 0x4861, + 0xd7fc, 0x00c0, 0x487e, 0x7810, 0xd0ec, 0x00c0, 0x487e, 0x2061, + 0x6fc0, 0x2069, 0x4a80, 0xc7fd, 0x0078, 0x484e, 0x007c, 0x2009, + 0x0000, 0x20a9, 0x0200, 0x6008, 0xd09c, 0x0040, 0x4899, 0x6024, + 0xa005, 0x0040, 0x488f, 0x8001, 0x6026, 0x0078, 0x4897, 0x6008, + 0xc09c, 0xc0bd, 0x600a, 0xa18d, 0x0001, 0x0078, 0x4899, 0xa18d, + 0x0100, 0xace0, 0x0010, 0x00f0, 0x4883, 0xa184, 0x0001, 0x0040, + 0x48a8, 0xa18c, 0xfffe, 0x690e, 0x1078, 0x25de, 0x0078, 0x48a9, + 0x690e, 0x007c, 0x00c0, 0x48a9, 0x786c, 0x6800, 0xa005, 0x0040, + 0x48b5, 0x684c, 0xac06, 0x0040, 0x4909, 0x6864, 0xa005, 0x0040, + 0x48bd, 0x6027, 0x0001, 0x0078, 0x4906, 0x2c00, 0x687e, 0x601b, + 0x0006, 0x60b4, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, + 0xa085, 0x0060, 0x6022, 0x6000, 0x2042, 0x6714, 0x6f76, 0x1078, + 0x1e02, 0x6818, 0xa005, 0x0040, 0x48d7, 0x8001, 0x681a, 0x6808, + 0xc0a4, 0x680a, 0x6810, 0x7908, 0x8109, 0x790a, 0x8001, 0x00d0, + 0x48e3, 0x1078, 0x28ec, 0x6812, 0x00c0, 0x48e9, 0x7910, 0xc1a5, + 0x7912, 0x602f, 0x0000, 0x6033, 0x0000, 0x2c68, 0x1078, 0x202a, + 0xd7fc, 0x00c0, 0x48f7, 0x2069, 0x4a40, 0x0078, 0x48f9, 0x2069, + 0x4a80, 0x6910, 0xa184, 0x0100, 0x2001, 0x0006, 0x00c0, 0x4903, + 0x697a, 0x2001, 0x0004, 0x2708, 0x1078, 0x25d1, 0x2091, 0x8001, + 0x007c, 0x0d7e, 0x694c, 0x2160, 0xd7fc, 0x00c0, 0x491b, 0x7810, + 0xd0ec, 0x0040, 0x4917, 0x2069, 0x0100, 0x0078, 0x491d, 0x2069, + 0x0200, 0x0078, 0x491d, 0x2069, 0x0100, 0x1078, 0x2881, 0x601b, + 0x0006, 0x6858, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, + 0xa085, 0x0048, 0x6022, 0x602f, 0x0000, 0x6033, 0x0000, 0x6830, + 0xd0b4, 0x0040, 0x494b, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, + 0xd094, 0x0040, 0x493d, 0x00f0, 0x4937, 0x684b, 0x0009, 0x20a9, + 0x0014, 0x6848, 0xd084, 0x0040, 0x4947, 0x00f0, 0x4941, 0x20a9, + 0x00fa, 0x00f0, 0x4949, 0x6808, 0xa084, 0xfffd, 0x680a, 0x681b, + 0x0047, 0x0d7f, 0x6867, 0x0007, 0x2091, 0x8001, 0x007c, 0x2079, + 0x4a00, 0x1078, 0x498b, 0x1078, 0x4971, 0x1078, 0x497e, 0x2009, + 0x0002, 0x2069, 0x4a80, 0x680f, 0x0000, 0x6813, 0x0000, 0x6817, + 0x0000, 0x8109, 0x0040, 0x4970, 0x2069, 0x4a40, 0x0078, 0x4963, + 0x007c, 0x7810, 0xd0ec, 0x0040, 0x4979, 0x2019, 0x00cc, 0x0078, + 0x497b, 0x2019, 0x007b, 0x7b3a, 0x7b3e, 0x007c, 0x7814, 0xd0e4, + 0x00c0, 0x4986, 0x2019, 0x0040, 0x0078, 0x4988, 0x2019, 0x0026, + 0x7b42, 0x7b46, 0x007c, 0x7814, 0xd0e4, 0x00c0, 0x4993, 0x2019, + 0x3f94, 0x0078, 0x4995, 0x2019, 0x2624, 0x7b32, 0x7b36, 0x007c, + 0x6950, 0xa185, 0x0000, 0x0040, 0x49ad, 0x0c7e, 0x6ac0, 0x2264, + 0x602b, 0x0000, 0x602f, 0x0000, 0x6008, 0xc0b5, 0x600a, 0x8210, + 0x8109, 0x00c0, 0x499f, 0x6952, 0x0c7f, 0x007c, 0x70ec, 0xd0dc, + 0x00c0, 0x49b7, 0xd0d4, 0x0040, 0x49d6, 0x0078, 0x49d9, 0x7810, + 0xd0ec, 0x0040, 0x49c2, 0xc0f5, 0x7812, 0xd0ec, 0x0040, 0x49dd, + 0x0078, 0x49d9, 0xae8e, 0x0100, 0x0040, 0x49ce, 0x7814, 0xc0f5, + 0x7816, 0xd0d4, 0x00c0, 0x49dd, 0x0078, 0x49d9, 0x7814, 0xc0fd, + 0x7816, 0xd0d4, 0x00c0, 0x49dd, 0x0078, 0x49d9, 0xd0e4, 0x0040, + 0x49df, 0x7804, 0xd08c, 0x0040, 0x49df, 0x681f, 0x000c, 0x70a0, + 0x70a2, 0x007c, 0x699a +}; +unsigned short ql12_risc_code_length01 = 0x39e3; + diff -Naur linux.2210/drivers/scsi/qla1280.c linux.2210.vw/drivers/scsi/qla1280.c --- linux.2210/drivers/scsi/qla1280.c Wed Dec 31 16:00:00 1969 +++ linux.2210.vw/drivers/scsi/qla1280.c Thu Jul 15 04:48:08 1999 @@ -0,0 +1,6514 @@ +/*************************************************************************** + * QLogic ISP1280 device driver for Linux 2.0.36 (redhat 5.2). + * + * COPYRIGHT (C) 1996-1999 QLOGIC CORPORATION + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. + * + *****************************************************************************/ +/**************************************************************************** + Revision History: + Rev. 2.00 June 8, 1999 D Grigsby + Changes to support RedHat release 6.0 (kernel 2.2.5). + - Added SCSI exclusive access lock (io_request_lock) when accessing the adapter. + - Added changes for the new LINUX interface template. Some new error handling + routines have been added to the template, but for now we will use the old ones. + + - Initial Beta Release. +*****************************************************************************/ + + +#include /* for CONFIG_PCI */ +#include /* for KERNEL_VERSION */ +#ifdef MODULE +#include +#endif + +#ifndef KERNEL_VERSION +# define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) +# include +#endif +#include "sd.h" +#include "scsi.h" +#include "hosts.h" +#include "qla1280.h" +#include "qla1280host.h" +#include "isp_fw.h" /* ISP RISC code */ + +#include +#include /* for kmalloc() */ + + + +/* + * Compile time Options: + * 0 - Disable and 1 - Enable + */ +#define QLA1280_64BIT_SUPPORT 0 /* 64-bit Support */ +#define QL1280_TARGET_MODE_SUPPORT 0 /* Target mode support */ +#define WATCHDOGTIMER 0 +#define MEMORY_MAPPED_IO 0 +#define DEBUG_QLA1280_INTR 0 +#define USE_NVRAM_DEFAULTS 0 +#define DEBUG_PRINT_NVRAM 0 +#define LOADING_RISC_ACTIVITY 0 +#define AUTO_ESCALATE_RESET 0 /* Automatically escalate resets */ +#define AUTO_ESCALATE_ABORT 0 /* Automatically escalate aborts */ +#define STOP_ON_ERROR 0 /* Stop on aborts and resets */ +#define STOP_ON_RESET 0 +#define STOP_ON_ABORT 0 + +#define DEBUG_QLA1280 0 /* Debugging */ + +/* + * These macros to assist programming + */ + +#define BZERO(ptr, amt) memset(ptr, 0, amt) +#define BCOPY(src, dst, amt) memcpy(dst, src, amt) +#define KMALLOC(siz) kmalloc((siz), GFP_ATOMIC) +#define KMFREE(ip,siz) kfree((ip)) +#define SYS_DELAY(x) udelay(x);barrier() +#define QLA1280_DELAY(sec) mdelay(sec * 1000) +#define VIRT_TO_BUS(a) (unsigned int)virt_to_bus((void *)(a)) +#if QLA1280_64BIT_SUPPORT +#define VIRT_TO_BUS_LOW(a) (unsigned int)(0xffffffff & virt_to_bus((void *)(a))) +#define VIRT_TO_BUS_HIGH(a) (unsigned int)(0xffffffff & (virt_to_bus((void *)(a))>>32)) +#endif /* QLA1280_64BIT_SUPPORT */ + +#define STATIC + +#define NVRAM_DELAY() udelay(500) /* 2 microsecond delay */ + +#if 0 /* XXX BH */ +/* + * Linux - SCSI Driver Interface Function Prototypes. + */ +int qla1280_proc_info ( char *, char **, off_t, int, int, int); +const char * qla1280_info(struct Scsi_Host *host); +int qla1280_detect(Scsi_Host_Template *); +int qla1280_release(struct Scsi_Host *); +const char * qla1280_info(struct Scsi_Host *); +int qla1280_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *)); +int qla1280_abort(Scsi_Cmnd *); +int qla1280_reset(Scsi_Cmnd *, unsigned int); +int qla1280_biosparam(Disk *, kdev_t, int[]); +void qla1280_intr_handler(int, void *, struct pt_regs *); +void qla1280_setup(char *s, int *dummy); +#endif +STATIC void qla1280_device_queue_depth(scsi_qla_host_t *, Scsi_Device *); + +/* + * QLogic Driver Support Function Prototypes. + */ +STATIC void qla1280_done(scsi_qla_host_t *, srb_t **, srb_t **); +STATIC void qla1280_next(scsi_qla_host_t *, scsi_lu_t *, uint8_t); +STATIC void qla1280_putq_t(scsi_lu_t *, srb_t *); +STATIC void qla1280_done_q_put(srb_t *, srb_t **, srb_t **); +STATIC void qla1280_select_queue_depth(struct Scsi_Host *, Scsi_Device *); +#ifdef QLA1280_UNUSED +static void qla1280_dump_regs(struct Scsi_Host *host); +#endif +#if STOP_ON_ERROR +static void qla1280_panic(char *, struct Scsi_Host *host); +#endif +void qla1280_print_scsi_cmd(Scsi_Cmnd *cmd); +STATIC void qla1280_abort_queue_single(scsi_qla_host_t *,uint32_t,uint32_t,uint32_t,uint32_t); + +STATIC int qla1280_return_status( sts_entry_t *sts, Scsi_Cmnd *cp); +STATIC void qla1280_removeq(scsi_lu_t *q, srb_t *sp); +STATIC void qla1280_mem_free(scsi_qla_host_t *ha); +void qla1280_do_dpc(void *p); +#ifdef QLA1280_UNUSED +static void qla1280_set_flags(char * s); +#endif +static char *qla1280_get_token(char *, char *); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) +STATIC inline void mdelay(int); +#endif + +/* + * QLogic ISP1280 Hardware Support Function Prototypes. + */ +STATIC uint8_t qla1280_initialize_adapter(struct scsi_qla_host *ha); +STATIC uint8_t qla1280_enable_tgt(scsi_qla_host_t *, uint8_t); +STATIC uint8_t qla1280_isp_firmware(scsi_qla_host_t *); +STATIC uint8_t qla1280_pci_config(scsi_qla_host_t *); +STATIC uint8_t qla1280_chip_diag(scsi_qla_host_t *); +STATIC uint8_t qla1280_setup_chip(scsi_qla_host_t *); +STATIC uint8_t qla1280_init_rings(scsi_qla_host_t *); +STATIC uint8_t qla1280_nvram_config(scsi_qla_host_t *); +STATIC uint8_t qla1280_mailbox_command(scsi_qla_host_t *, uint8_t, uint16_t *); +STATIC uint8_t qla1280_bus_reset(scsi_qla_host_t *, uint8_t); +STATIC uint8_t qla1280_device_reset(scsi_qla_host_t *, uint8_t, uint32_t); +STATIC uint8_t qla1280_abort_device(scsi_qla_host_t *, uint8_t, uint32_t, uint32_t); +STATIC uint8_t qla1280_abort_command(scsi_qla_host_t *, srb_t *), +#if QLA1280_64BIT_SUPPORT + qla1280_64bit_start_scsi(scsi_qla_host_t *, srb_t *), +#endif + qla1280_32bit_start_scsi(scsi_qla_host_t *, srb_t *), + qla1280_abort_isp(scsi_qla_host_t *); +STATIC void qla1280_nv_write(scsi_qla_host_t *, uint16_t), + qla1280_nv_delay(scsi_qla_host_t *), + qla1280_poll(scsi_qla_host_t *), + qla1280_reset_adapter(scsi_qla_host_t *), + qla1280_marker(scsi_qla_host_t *, uint8_t, uint32_t, uint32_t, uint8_t), + qla1280_isp_cmd(scsi_qla_host_t *), + qla1280_isr(scsi_qla_host_t *, srb_t **, srb_t **), + qla1280_rst_aen(scsi_qla_host_t *), + qla1280_status_entry(scsi_qla_host_t *, sts_entry_t *, srb_t **, + srb_t **), + qla1280_error_entry(scsi_qla_host_t *, response_t *, srb_t **, + srb_t **), + qla1280_restart_queues(scsi_qla_host_t *), + qla1280_abort_queues(scsi_qla_host_t *); +STATIC uint16_t qla1280_get_nvram_word(scsi_qla_host_t *, uint32_t), + qla1280_nvram_request(scsi_qla_host_t *, uint32_t), + qla1280_debounce_register(volatile uint16_t *); +STATIC request_t *qla1280_req_pkt(scsi_qla_host_t *); +int qla1280_check_for_dead_scsi_bus(scsi_qla_host_t *ha, srb_t *sp); + +#if QL1280_TARGET_MODE_SUPPORT + qla1280_enable_lun(scsi_qla_host_t *, uint8_t, uint32_t), + qla1280_notify_ack(scsi_qla_host_t *, notify_entry_t *), + qla1280_immed_notify(scsi_qla_host_t *, notify_entry_t *), + qla1280_accept_io(scsi_qla_host_t *, ctio_ret_entry_t *), +#if QLA1280_64BIT_SUPPORT + qla1280_64bit_continue_io(scsi_qla_host_t *, atio_entry_t *, uint32_t, + paddr32_t *), +#endif + qla1280_32bit_continue_io(scsi_qla_host_t *, atio_entry_t *, uint32_t, + paddr32_t *), + qla1280_atio_entry(scsi_qla_host_t *, atio_entry_t *), + qla1280_notify_entry(scsi_qla_host_t *, notify_entry_t *), + +#endif /* QLA1280_TARGET_MODE_SUPPORT */ + +#ifdef QL_DEBUG_ROUTINES +/* + * Driver Debug Function Prototypes. + */ +STATIC uint8_t qla1280_getbyte(uint8_t *); +STATIC uint16_t qla1280_getword(uint16_t *); +STATIC uint32_t qla1280_getdword(uint32_t *); +STATIC void qla1280_putbyte(uint8_t *, uint8_t), + qla1280_putword(uint16_t *, uint16_t), + qla1280_putdword(uint32_t *, uint32_t), + qla1280_print(caddr_t), + qla1280_output_number(uint32_t, uint8_t), + qla1280_putc(uint8_t), + qla1280_dump_buffer(caddr_t, uint32_t); + +char debug_buff[80]; +#if DEBUG_QLA1280 +STATIC uint8_t ql_debug_print = 1; +#else +STATIC uint8_t ql_debug_print = 0; +#endif +#endif + +/* + * insmod needs to find the variable and make it point to something + */ +#ifdef MODULE +static char *options = NULL; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,18) + +/* insmod qla1280 options=verbose" */ +MODULE_PARM(options, "s"); +#endif +/* + * Just in case someone uses commas to separate items on the insmod + * command line, we define a dummy buffer here to avoid having insmod + * write wild stuff into our code segment + */ +static char dummy_buffer[60] = "Please don't add commas in your insmod command!!\n"; + +#endif + +#if defined(__386__) +# define QLA1280_BIOSPARAM qla1280_biosparam +#else +# define QLA1280_BIOSPARAM NULL +#endif + +/* + * Scsi_Host_template (see hosts.h) + * Device driver Interfaces to mid-level SCSI driver. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) +/* This interface is now obsolete !!! */ +#define QLA1280_LINUX_TEMPLATE { \ + next: NULL, \ + usage_count: NULL, \ + proc_dir: NULL, \ + proc_info: NULL, \ + name: "Qlogic ISP 1280", \ + detect: qla1280_detect, \ + release: qla1280_release, \ + info: qla1280_info, \ + command: NULL, \ + queuecommand: qla1280_queuecommand, \ + abort: qla1280_abort, \ + reset: qla1280_reset, \ + slave_attach: NULL, \ + bios_param: QLA1280_BIOSPARAM, \ + can_queue: 255, /* MAX_OUTSTANDING_COMMANDS */ \ + this_id: -1, /* scsi id of host adapter */ \ + sg_tablesize: SG_ALL, \ + cmd_per_lun: 3, /* max commands per lun */ \ + present: 0, /* number of 1280s present */ \ + unchecked_isa_dma: 0, /* no memeory DMA restrictions */ \ + use_clustering: ENABLE_CLUSTERING \ +} +#else + +#if 0 /* XXX BH */ +#define QLA1280_LINUX_TEMPLATE { \ + next: NULL, \ + module: NULL, \ + proc_dir: NULL, \ + proc_info: qla1280_proc_info, \ + name: "Qlogic ISP 1280\1080", \ + detect: qla1280_detect, \ + release: qla1280_release, \ + info: qla1280_info, \ + ioctl: NULL, \ + command: NULL, \ + queuecommand: qla1280_queuecommand, \ + eh_strategy_handler: NULL, \ + eh_abort_handler: NULL, \ + eh_device_reset_handler: NULL, \ + eh_bus_reset_handler: NULL, \ + eh_host_reset_handler: NULL, \ + abort: qla1280_abort, \ + reset: qla1280_reset, \ + slave_attach: NULL, \ + bios_param: QLA1280_BIOSPARAM, \ + can_queue: 255, /* max simultaneous cmds */\ + this_id: -1, /* scsi id of host adapter */\ + sg_tablesize: SG_ALL, /* max scatter-gather cmds */\ + cmd_per_lun: 3, /* cmds per lun (linked cmds) */\ + present: 0, /* number of 7xxx's present */\ + unchecked_isa_dma: 0, /* no memory DMA restrictions */\ + use_clustering: ENABLE_CLUSTERING, \ + use_new_eh_code: 0, \ + emulated: 0 \ +} +#endif +#endif + + +/* + * Our directory Entry in /proc/scsi for the user to + * access the driver. + */ + +/* Need to add in proc_fs.h PROC_SCSI_QL1280 */ +#define PROC_SCSI_QL1280 PROC_SCSI_QLOGICISP + +struct proc_dir_entry proc_scsi_qla1280 = { + PROC_SCSI_QL1280, 7, "qla1280", + S_IFDIR | S_IRUGO | S_IXUGO, 2, + 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +/* We use the Scsi_Pointer structure that's included with each command + * SCSI_Cmnd as a scratchpad for our SRB. + * + * SCp will always point to the SRB structure (defined in qla1280.h). + * It is define as follows: + * - SCp.ptr -- > pointer back to the cmd + * - SCp.this_residual --> used as forward pointer to next srb + * - SCp.buffer --> used as backward pointer to next srb + * - SCp.buffers_residual --> used as flags field + * - SCp.have_data_in --> not used + * - SCp.sent_command --> not used + * - SCp.phase --> not used + */ + +#define CMD_SP(Cmnd) (&(Cmnd)->SCp) +#define CMD_XFRLEN(Cmnd) (Cmnd)->request_bufflen +#define CMD_CDBLEN(Cmnd) (Cmnd)->cmd_len +#define CMD_CDBP(Cmnd) (Cmnd)->cmnd +#define CMD_SNSP(Cmnd) (Cmnd)->sense_buffer +#define CMD_SNSLEN(Cmnd) (sizeof (Cmnd)->sense_buffer) +#define CMD_RESULT(Cmnd) ((Cmnd)->result) +#define CMD_HANDLE(Cmnd) ((Cmnd)->host_scribble) + +/*****************************************/ +/* ISP Boards supported by this driver */ +/*****************************************/ +#define QLA1280_VENDOR_ID 0x1077 +#define QLA1080_DEVICE_ID 0x1080 +#define QLA1240_DEVICE_ID 0x1240 +#define QLA1280_DEVICE_ID 0x1280 +#define NUM_OF_ISP_DEVICES 4 + +#define QLA1280_VERSION " 1.20-Beta" +typedef struct _qlaboards +{ + unsigned char bdName[9]; + unsigned long device_id; + int numPorts; +} qla_boards_t; + +struct _qlaboards QLBoardTbl[NUM_OF_ISP_DEVICES] = +{ + /* Name , Board PCI Device ID, Number of ports */ + {"QLA1080 ", QLA1080_DEVICE_ID, 1}, + {"QLA1240 ", QLA1240_DEVICE_ID, 2}, + {"QLA1280 ", QLA1280_DEVICE_ID, 2}, + {" ", 0, 0} +}; + +static unsigned long qla1280_verbose = 1L; +static scsi_qla_host_t *qla1280_hostlist = NULL; +static int qla1280_buffer_size = 0; +static char *qla1280_buffer = NULL; + +#ifdef QL_DEBUG_LEVEL_3 +#define ENTER(x) sprintf(debug_buff,"qla1280 : Entering %s()\n\r", x); \ + qla1280_print(debug_buff); +#define LEAVE(x) sprintf(debug_buff,"qla1280 : Leaving %s()\n\r", x); \ + qla1280_print(debug_buff); +#define ENTER_INTR(x) sprintf(debug_buff,"qla1280 : Entering %s()\n\r", x); \ + qla1280_print(debug_buff); +#define LEAVE_INTR(x) sprintf(debug_buff,"qla1280 : Leaving %s()\n\r", x); \ + qla1280_print(debug_buff); +#define DEBUG3(x) x +#else +#define ENTER(x) +#define LEAVE(x) +#define ENTER_INTR(x) +#define LEAVE_INTR(x) +#define DEBUG3(x) +#endif + +#if DEBUG_QLA1280 +#define COMTRACE(x) +/* #define COMTRACE(x) qla1280_putc(x); */ +#define DEBUG(x) x +#else +#define DEBUG(x) +#define COMTRACE(x) +#endif + +#ifdef QL_DEBUG_LEVEL_2 +#define DEBUG2(x) x +#else +#define DEBUG2(x) +#endif + +#define OFFSET(w) (((uint32_t) &w) & 0xFFFF) /* 256 byte offsets */ + +#define SCSI_BUS_32(scp) ((scp)->channel) +#define SCSI_TCN_32(scp) ((scp)->target) +#define SCSI_LUN_32(scp) ((scp)->lun) + +/****************************************************************************/ +/* LINUX - Loadable Module Functions. */ +/****************************************************************************/ + + +/************************************************************************* + * qla1280_set_info + * + * Description: + * Set parameters for the driver from the /proc filesystem. + * + * Returns: + *************************************************************************/ +int +qla1280_set_info(char *buffer, int length, struct Scsi_Host *HBAptr) +{ + return (-ENOSYS); /* Currently this is a no-op */ +} + +/************************************************************************* + * qla1280_proc_info + * + * Description: + * Return information to handle /proc support for the driver. + * + * buffer - ptrs to a page buffer + * + * Returns: + *************************************************************************/ +#define PROC_BUF (&qla1280_buffer[size]) +#define LUN_ID (targ_lun>>(MAX_T_BITS+MAX_L_BITS)),((targ_lun>>MAX_L_BITS)&0xf), targ_lun&0x7 +int +qla1280_proc_info ( char *buffer, char **start, off_t offset, int length, + int hostno, int inout) +{ + struct Scsi_Host *host; + scsi_qla_host_t *ha; + int size = 0; + int targ_lun; + scsi_lu_t *up; + int no_devices; + + printk("Entering proc_info 0x%x,0x%lx,0x%x,0x%x\n",(int)buffer,offset,length,hostno); + host = NULL; + /* find the host they want to look at */ + for(ha=qla1280_hostlist; (ha != NULL) && ha->host->host_no != hostno; ha=ha->next) + ; + + if (!ha) + { + size += sprintf(buffer, "Can't find adapter for host number %d\n", hostno); + if (size > length) + { + return (size); + } + else + { + return (length); + } + } + + host = ha->host; + if (inout == TRUE) /* Has data been written to the file? */ + { + return (qla1280_set_info(buffer, length, host)); + } + + /* compute number of active devices */ + no_devices = 0; + for (targ_lun = 0; targ_lun < MAX_EQ; targ_lun++) + { + if( (up = ha->dev[targ_lun]) == NULL ) + continue; + no_devices++; + } + /* size = 112 * no_devices; */ + size = 4096; + /* round up to the next page */ + + /* + * if our old buffer is the right size use it otherwise + * allocate a new one. + */ + if (qla1280_buffer_size != size) + { + /* deallocate this buffer and get a new one */ + if (qla1280_buffer != NULL) + { + kfree(qla1280_buffer); + qla1280_buffer_size = 0; + } + qla1280_buffer = kmalloc(size, GFP_KERNEL); + } + if (qla1280_buffer == NULL) + { + size = sprintf(buffer, "qla1280 - kmalloc error at line %d\n", + __LINE__); + return size; + } + qla1280_buffer_size = size; + + size = 0; + size += sprintf(PROC_BUF, "Qlogic 1280/1080 SCSI driver version: "); /* 43 bytes */ + size += sprintf(PROC_BUF, "%5s, ", QLA1280_VERSION); /* 5 */ + size += sprintf(PROC_BUF, "Qlogic Firmware version: "); /* 25 */ + size += sprintf(PROC_BUF, "%2d.%2d.%2d",ql12_firmware_version[0], /* 8 */ + ql12_firmware_version[1], + ql12_firmware_version[2]); + size += sprintf(PROC_BUF, "\n"); /* 1 */ + + size += sprintf(PROC_BUF, "SCSI Host Adapter Information: %s\n", QLBoardTbl[ha->devnum].bdName); + size += sprintf(PROC_BUF, "Request Queue = 0x%lx, Response Queue = 0x%lx\n", + ha->request_dma, + ha->response_dma); + size += sprintf(PROC_BUF, "Request Queue count= 0x%x, Response Queue count= 0x%x\n", + REQUEST_ENTRY_CNT, + RESPONSE_ENTRY_CNT); + size += sprintf(PROC_BUF,"Number of pending commands = 0x%lx\n", ha->actthreads); + size += sprintf(PROC_BUF,"Number of queued commands = 0x%lx\n", ha->qthreads); + size += sprintf(PROC_BUF,"Number of free request entries = %d\n",ha->req_q_cnt); + size += sprintf(PROC_BUF, "\n"); /* 1 */ + + size += sprintf(PROC_BUF, "Attached devices:\n"); + /* scan for all equipment stats */ + for (targ_lun = 0; targ_lun < MAX_EQ; targ_lun++) + { + if( (up = ha->dev[targ_lun]) == NULL ) + continue; + if( up->io_cnt == 0 ) + { + size += sprintf(PROC_BUF,"(%2d:%2d:%2d) No stats\n",LUN_ID); + continue; + } + /* total reads since boot */ + /* total writes since boot */ + /* total requests since boot */ + size += sprintf(PROC_BUF, "Total requests %ld,",up->io_cnt); + /* current number of pending requests */ + size += sprintf(PROC_BUF, "(%2d:%2d:%2d) pending requests %d,",LUN_ID,up->q_outcnt); + /* avg response time */ + size += sprintf(PROC_BUF, "Avg response time %ld%%,",(up->resp_time/up->io_cnt)*100); + + /* avg active time */ + size += sprintf(PROC_BUF, "Avg active time %ld%%\n",(up->act_time/up->io_cnt)*100); + } + + if (size >= qla1280_buffer_size) + { + printk(KERN_WARNING "qla1280: Overflow buffer in qla1280_proc.c\n"); + } + + if (offset > size - 1) + { + kfree(qla1280_buffer); + qla1280_buffer = NULL; + qla1280_buffer_size = length = 0; + *start = NULL; + } + else + { + *start = &qla1280_buffer[offset]; /* Start of wanted data */ + if (size - offset < length) + { + length = size - offset; + } + } + + return (length); +} + + +/************************************************************************** + * qla1280_detect + * This routine will probe for Qlogic 1280 SCSI host adapters. + * It returns the number of host adapters of a particular + * type that were found. It also initialize all data necessary for + * the driver. It is passed-in the host number, so that it + * knows where its first entry is in the scsi_hosts[] array. + * + * Input: + * template - pointer to SCSI template + * + * Returns: + * num - number of host adapters found. + **************************************************************************/ +int +qla1280_detect(Scsi_Host_Template *template) +{ + int num_hosts = 0; + struct Scsi_Host *host; + scsi_qla_host_t *ha, *cur_ha; + struct _qlaboards *bdp; + int i, index, j; + unsigned int piobase; + unsigned char pci_bus, pci_devfn, pci_irq; + config_reg_t *cfgp = 0; + device_reg_t *reg; + char *cp; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95) + struct pci_dev *pdev = NULL; +#endif + + ENTER("qla1280_detect"); + +#ifdef CHECKSRBSIZE + if (sizeof(srb_t) > sizeof(Scsi_Pointer) ) + { + printk("Redefine SRB - its too big"); + return 0; + } +#endif + +#ifdef MODULE + /* + * If we are called as a module, the qla1280 pointer may not be null + * and it would point to our bootup string, just like on the lilo + * command line. IF not NULL, then process this config string with + * qla1280_setup + * + * Boot time Options + * To add options at boot time add a line to your lilo.conf file like: + * append="qla1280=verbose,max_tags:{{255,255,255,255},{255,255,255,255}}" + * which will result in the first four devices on the first two + * controllers being set to a tagged queue depth of 32. + */ + if(options) + qla1280_setup(options, NULL); + if(dummy_buffer[0] != 'P') + printk(KERN_WARNING "qla1280: Please read the file /usr/src/linux/drivers" + "/scsi/README.qla1280\n" + "qla1280: to see the proper way to specify options to the qla1280 " + "module\n" + "qla1280: Specifically, don't use any commas when passing arguments to\n" + "qla1280: insmod or else it might trash certain memory areas.\n"); +#endif + + if ((int) pcibios_present()) + { + bdp = &QLBoardTbl[0]; + qla1280_hostlist = NULL; + template->proc_dir = &proc_scsi_qla1280; + for( i=0; bdp->device_id != 0 && i < NUM_OF_ISP_DEVICES; i++, bdp++ ) + { + /* Try and find each different type of adapter we support */ + index = 0; + while (!(pcibios_find_device(QLA1280_VENDOR_ID, + bdp->device_id, + index++, &pci_bus, &pci_devfn)) ) + { /* found a adapter */ + host = scsi_register(template, sizeof(scsi_qla_host_t)); + ha = (scsi_qla_host_t *) host->hostdata; + for( j =0, cp = (char *)ha; j < sizeof(scsi_qla_host_t); j++) + *cp = 0; + /* Sanitize the information from PCI BIOS. */ +#if 0 + pcibios_read_config_byte(pci_bus, pci_devfn, OFFSET(cfgp->interrupt_line), &pci_irq); +#else + pdev = pci_find_slot(pci_bus, pci_devfn); + pci_irq = pdev->irq; +#endif + pcibios_read_config_dword(pci_bus, pci_devfn, OFFSET(cfgp->base_port), &piobase); + ha->pci_bus = pci_bus; + ha->pci_device_fn = pci_devfn; + ha->devnum = i; + + host->io_port = (unsigned int) piobase; + host->io_port &= PCI_BASE_ADDRESS_IO_MASK; + host->irq = pci_irq; + ha->request_ring = &ha->req[0]; + ha->request_dma = VIRT_TO_BUS(&ha->req[0]); + ha->response_ring = &ha->res[0]; + ha->response_dma = VIRT_TO_BUS(&ha->res[0]); + ha->ports = bdp->numPorts; + if( qla1280_verbose ) + { + printk("(scsi): Found a %s @ bus %2d, device %2d, irq %2d, iobase 0x%lx\n", + bdp->bdName,pci_bus, (pci_devfn & 0xf8) >> 3, host->irq,host->io_port); + printk("(scsi): Initializing Adapter; Please wait ...\n"); + } + + ha->iobase = (device_reg_t *) host->io_port; + ha->host = host; + ha->host_no = host->host_no; + + /* load the F/W, read paramaters, and init the H/W */ + if (qla1280_initialize_adapter(ha)) + { + + printk(KERN_INFO "qla1280: Failed to initialized adapter\n"); + qla1280_mem_free(ha); + scsi_unregister(host); + continue; + } + host->can_queue = 0xfffff; /* unlimited */ + host->cmd_per_lun = 1; + host->select_queue_depths = qla1280_select_queue_depth; + host->n_io_port = 0xFF; + host->base = (unsigned char *) ha->mmpbase; + host->max_id = MAX_TARGETS; + host->max_channel = bdp->numPorts-1; + host->max_lun = MAX_LUNS-1; + ha->instance = num_hosts; + host->unique_id = ha->instance; + ha->next = NULL; + + /* set our host ID (need to do something about our two IDs) */ + host->this_id = ha->bus_settings[0].id; + + /* Register the IRQ with Linux (sharable) */ + if ( request_irq(host->irq, qla1280_intr_handler, SA_INTERRUPT| SA_SHIRQ, "qla1280", ha)) + { + printk("qla1280 : Failed to reserved interrupt %d already in use\n", host->irq); + qla1280_mem_free(ha); + scsi_unregister(host); + continue; + } + + /* Register the I/O space with Linux */ + if (check_region(host->io_port, 0xff)) + { + printk("qla1280 : Failed to reserved i/o region 0x%04lx-0x%04lx already in use\n", + host->io_port, host->io_port + 0xff); + free_irq(host->irq, NULL); + qla1280_mem_free(ha); + scsi_unregister(host); + continue; + } + + request_region(host->io_port, 0xff, "qla1280"); + + reg = ha->iobase; + /* Disable ISP interrupts. */ + WRT_REG_WORD(®->ictrl, 0); + + /* Insure mailbox registers are free. */ + WRT_REG_WORD(®->semaphore, 0); + WRT_REG_WORD(®->host_cmd, HC_CLR_RISC_INT); + WRT_REG_WORD(®->host_cmd, HC_CLR_HOST_INT); + + /* Enable chip interrupts. */ + WRT_REG_WORD(®->ictrl, ISP_EN_INT + ISP_EN_RISC); + /* Insert new entry into the list of adapters */ + ha->next = NULL; + if( qla1280_hostlist == NULL ) + { + cur_ha = qla1280_hostlist = ha; + } + else + { + cur_ha = qla1280_hostlist; + while( cur_ha->next != NULL ) + cur_ha = cur_ha->next; + cur_ha->next = ha; + } + num_hosts++; + } /* end of WHILE */ + } /* end of FOR */ + } /* end of IF */ + + LEAVE("qla1280_detect"); + return num_hosts; +} + + +/************************************************************************** + * qla1280_release + * Free the passed in Scsi_Host memory structures prior to unloading the + * module. + **************************************************************************/ +int +qla1280_release(struct Scsi_Host *host) +{ + scsi_qla_host_t *ha = (scsi_qla_host_t *) host->hostdata; + + ENTER("qla1280_release"); + + if( !ha->flags.online ) + return(0); + + /* turn-off interrupts on the card */ + WRT_REG_WORD(&ha->iobase->ictrl, 0); + + /* Detach interrupts */ + if(host->irq) + free_irq(host->irq, ha); + + /* release io space registers */ + if( host->io_port ) + release_region(host->io_port, 0xff); + +#if MEMORY_MAPPED_IO + if(ha->mmpbase) + { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) + vfree((void *) (((unsigned long) ha->mmpbase) & PAGE_MASK)); +#else + iounmap((void *) (((unsigned long) ha->mmpbase) & PAGE_MASK)); +#endif + } +#endif /* MEMORY_MAPPED_IO */ + qla1280_mem_free(ha); + + ENTER("qla1280_release"); + return(0); +} + +/************************************************************************** + * qla1280_info + * Return a string describing the driver. + **************************************************************************/ +const char * +qla1280_info(struct Scsi_Host *host) +{ + static char qla1280_buffer[125]; + char *bp; + scsi_qla_host_t *ha; + qla_boards_t *bdp; + + bp = &qla1280_buffer[0]; + ha = (scsi_qla_host_t *)host->hostdata; + bdp = &QLBoardTbl[ha->devnum]; + memset(bp, 0, sizeof(qla1280_buffer)); + sprintf(bp, + "QLogic %sPCI to SCSI Host Adapter: bus %d device %d irq %d\n" + " Version: %s, Firmware version: %s", + (char *)&bdp->bdName[0], ha->pci_bus, (ha->pci_device_fn & 0xf8) >> 3, host->irq, + QLA1280_VERSION, + QL12_FW_VERSION_STRING); + return(bp); +} + +/************************************************************************** + * qla1200_queuecommand + * Queue a command to the controller. + * + * Note: + * The mid-level driver tries to ensures that queuecommand never gets invoked + * concurrently with itself or the interrupt handler (although the + * interrupt handler may call this routine as part of request-completion + * handling). Unfortunely, it sometimes calls the scheduler in interrupt + * context which is a big NO! NO!. + **************************************************************************/ +int +qla1280_queuecommand(Scsi_Cmnd *cmd, void (*fn)(Scsi_Cmnd *)) +{ + scsi_qla_host_t *ha; + srb_t *sp; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) + unsigned long cpu_flags = 0; +#endif + struct Scsi_Host *host; + uint32_t b, t, l; + scsi_lu_t *q; + u_long handle; + + ENTER("qla1280_queuecommand"); + COMTRACE('C') + + host = cmd->host; + ha = (scsi_qla_host_t *) host->hostdata; + + /* send command to adapter */ + sp = (srb_t *) CMD_SP(cmd); + sp->cmd = cmd; + cmd->scsi_done = fn; + if (cmd->flags == 0) /* new command */ + { + sp->flags = 0; + } + + +#if DEBUG_QLA1280 + DEBUG3(qla1280_print_scsi_cmd(cmd)); +#endif /* DEBUG_QLA1280 */ + + /* Generate LU queue on bus, target, LUN */ + b = SCSI_BUS_32(cmd); + t = SCSI_TCN_32(cmd); + l = SCSI_LUN_32(cmd); + if((q = LU_Q(ha, b, t, l)) == NULL ) + { + DRIVER_LOCK + if( (q = (scsi_lu_t *)KMALLOC(sizeof(struct scsi_lu))) ) + { + LU_Q(ha, b, t, l) = q; + BZERO(q,sizeof(struct scsi_lu)); + DEBUG(sprintf(debug_buff,"Allocate new device queue 0x%x\n",q)); + DEBUG(qla1280_print(debug_buff)); + DRIVER_UNLOCK + } + else + { + CMD_RESULT(cmd) = (int) (DID_BUS_BUSY << 16); + qla1280_done_q_put(sp, &ha->done_q_first, &ha->done_q_last); + queue_task(&ha->run_qla_bh,&tq_scheduler); + ha->flags.dpc_sched = TRUE; + DRIVER_UNLOCK + return(0); + } + } + + handle = MAX_OUTSTANDING_COMMANDS+1; + CMD_HANDLE(cmd) = (unsigned char *)handle; + + sp->r_start = jiffies; /* bookkeeping information */ + ha->qthreads++; + qla1280_putq_t(q,sp); + + DEBUG(sprintf(debug_buff,"qla1280: queueing SP=(0x%x), handle=(0x%x)\n\r",sp,handle)); + DEBUG(qla1280_print(debug_buff)); + /* we can take an unlimited number of SG elements */ + host->sg_tablesize = SG_ALL; + + + /* kick off a command */ + DRIVER_LOCK + if (q->q_outcnt == 0) + qla1280_restart_queues(ha); + DRIVER_UNLOCK + + LEAVE("qla1280_queuecommand"); + return (0); +} + +/************************************************************************** + * qla1200_abort + * Abort the speciifed SCSI command(s). + **************************************************************************/ +int +qla1280_abort(Scsi_Cmnd *cmd) +{ + scsi_qla_host_t *ha; + srb_t *sp; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) + unsigned long cpu_flags = 0; +#endif + struct Scsi_Host *host; + uint32_t b, t, l; + scsi_lu_t *q; + int return_status = SCSI_ABORT_SUCCESS; + int found = 0; + int i; + u_long handle; + u_short data; + + ENTER("qla1280_abort"); + COMTRACE('A') + ha = (scsi_qla_host_t *) cmd->host->hostdata; + host = cmd->host; + DRIVER_LOCK + + sp = (srb_t *) CMD_SP(cmd); + handle = (u_long) CMD_HANDLE(cmd); + if (qla1280_verbose) + printk("scsi(%d): ABORT Command=0x%x, handle=0x%lx\n",(int)ha->host_no,(int)cmd,handle); + + /* Check for pending interrupts. */ + if( handle == 0L ) + { + COMTRACE('a') + /* we never got this command */ + printk(KERN_INFO "qla1280: Aborting a NULL handle\n"); + DRIVER_UNLOCK + return(SCSI_ABORT_NOT_RUNNING); /* no action - we don't have command */ + } + data = qla1280_debounce_register(&ha->iobase->istatus); + if( !(ha->flags.in_isr) && (data & RISC_INT) ) + { + /* put any pending command in done queue */ + qla1280_isr(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last); + } + + handle = (u_long) CMD_HANDLE(cmd); + + /* Generate LU queue on bus, target, LUN */ + b = SCSI_BUS_32(cmd); + t = SCSI_TCN_32(cmd); + l = SCSI_LUN_32(cmd); + if((q = LU_Q(ha, b, t, l)) == NULL ) + { + COMTRACE('a') + /* No lun queue -- command must not be active */ + DRIVER_UNLOCK + printk(KERN_WARNING "qla1280 (%d:%d:%d): No LUN queue for the specified device\n",(int)b,(int)t,(int)l); + return(SCSI_ABORT_NOT_RUNNING); /* no action - we don't have command */ + } + +#if AUTO_ESCALATE_ABORT + if ( (sp->flags & SRB_ABORTED) ) + { + DRIVER_UNLOCK + DEBUG(qla1280_print("qla1280_abort: Abort escalayted - returning SCSI_ABORT_SNOOZE.\n\r")); + return(SCSI_ABORT_SNOOZE); + } +#endif + + if ( (sp->flags & SRB_ABORT_PENDING) ) + { + COMTRACE('a') + DRIVER_UNLOCK + if( qla1280_verbose ) + printk("scsi(): Command has a pending abort message - ABORT_PENDING.\n"); + DEBUG(qla1280_print("qla1280: Command has a pending abort message - ABORT_PENDING.\n\r")); + return(SCSI_ABORT_PENDING); + } + +#if STOP_ON_ABORT + printk("Scsi layer issued a ABORT command= 0x%x\n",(int)cmd); + DEBUG2(qla1280_print_scsi_cmd(cmd)); +#endif + + ha->flags.in_abort = TRUE; + /* + * Normally, would would need to search our queue for the specified command + * but; since our sp contains the cmd ptr, we can just remove it from our + * LUN queue. + */ + if( !(sp->flags&SRB_SENT) ) + { + found++; + if( qla1280_verbose ) + printk("scsi(): Command returned from queue aborted.\n"); + DEBUG(qla1280_print("qla1280: Command returned from queue aborted.\n\r")); + /* Remove srb from SCSI LU queue. */ + qla1280_removeq(q, sp); + sp->flags |= SRB_ABORTED; + CMD_RESULT(cmd) = DID_ABORT << 16; + qla1280_done_q_put(sp, &ha->done_q_first, &ha->done_q_last); + return_status = SCSI_ABORT_SUCCESS; + } + else + { /* find the command in our active list */ + for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) + { + if( sp == ha->outstanding_cmds[i] ) + { + found++; + DEBUG(qla1280_print("qla1280: RISC aborting command.\n\r")); + qla1280_abort_command(ha,sp); + return_status = SCSI_ABORT_PENDING; + break; + } + } + } + +#if STOP_ON_ABORT + qla1280_panic("qla1280_abort",ha->host); +#endif + if ( found == 0 ) + return_status = SCSI_ABORT_NOT_RUNNING; /* no action - we don't have command */ + + DEBUG(sprintf(debug_buff, "qla1280_abort: Aborted status returned = 0x%x.\n\r",return_status)); + DEBUG(qla1280_print(debug_buff)); + + if( ha->done_q_first ) + qla1280_done(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last); + if ( found ) + { + qla1280_restart_queues(ha); + } + ha->flags.in_abort = FALSE; + DRIVER_UNLOCK + + LEAVE("qla1280_abort"); + COMTRACE('a') + return(return_status); +} + +/************************************************************************** + * qla1200_reset + * The reset function will reset the SCSI bus and abort any executing + * commands. + * + * Input: + * cmd = Linux SCSI command packet of the command that cause the + * bus reset. + * flags = SCSI bus reset option flags (see scsi.h) + * + * Returns: + * DID_RESET in cmd.host_byte of aborted command(s) + * + * Note: + * Resetting the bus always succeeds - is has to, otherwise the + * kernel will panic! Try a surgical technique - sending a BUS + * DEVICE RESET message - on the offending target before pulling + * the SCSI bus reset line. + **************************************************************************/ +int +qla1280_reset(Scsi_Cmnd *cmd, unsigned int flags) +{ + scsi_qla_host_t *ha; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) + unsigned long cpu_flags = 0; +#endif + uint32_t b, t, l; + srb_t *sp; + typedef enum + { + ABORT_DEVICE = 1, + DEVICE_RESET = 2, + BUS_RESET = 3, + ADAPTER_RESET= 4, + RESET_DELAYED= 5, + FAIL = 6 + } action_t; + action_t action = ADAPTER_RESET; + u_short data; + scsi_lu_t *q; + int result; + + + ENTER("qla1280_reset"); + COMTRACE('R') + if (qla1280_verbose) + printk("scsi(): Resetting Cmnd=0x%x, Handle=0x%lx, flags=0x%x\n",(int)cmd,(long)CMD_HANDLE(cmd),flags); + if ( cmd == NULL ) + { + printk(KERN_WARNING "(scsi?:?:?:?) Reset called with NULL Scsi_Cmnd " + "pointer, failing.\n"); + return(SCSI_RESET_SNOOZE); + } + ha = (scsi_qla_host_t *) cmd->host->hostdata; + sp = (srb_t *) CMD_SP(cmd); + +#if STOP_ON_RESET + qla1280_panic("qla1280_reset",ha->host); +#endif + + DRIVER_LOCK + /* Check for pending interrupts. */ + data = qla1280_debounce_register(&ha->iobase->istatus); + if( !(ha->flags.in_isr) && (data & RISC_INT) ) + { + qla1280_isr(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last); + } + DRIVER_UNLOCK + + /* + * Determine the suggested action that the mid-level driver wants + * us to perform. + */ + if( CMD_HANDLE(cmd) == (unsigned char *) 0 ) + { + /* + * if mid-level driver called reset with a orphan SCSI_Cmnd + * (i.e. a command that's not pending ), so perform the + * function specified. + */ + if( (flags & SCSI_RESET_SUGGEST_HOST_RESET) ) + action = ADAPTER_RESET; + else + action = BUS_RESET; + } + else + { /* + * Mid-level driver has called reset with this SCSI_Cmnd and + * its pending. + */ + if( flags & SCSI_RESET_SUGGEST_HOST_RESET ) + action = ADAPTER_RESET; + else if( flags & SCSI_RESET_SUGGEST_BUS_RESET ) + action = BUS_RESET; + else + action = DEVICE_RESET; + } + + b = SCSI_BUS_32(cmd); + t = SCSI_TCN_32(cmd); + l = SCSI_LUN_32(cmd); + q = LU_Q(ha, b, t, l); + +#if AUTO_ESCALATE_RESET + if ( (action & DEVICE_RESET) && (q->q_flag & QLA1280_QRESET) ) + { + printk(KERN_INFO "qla1280(%d): Bus device reset already sent to " "device, escalating.\n", (int)ha->host_no); + action = BUS_RESET; + } + if ( (action & DEVICE_RESET) && (sp->flags & SRB_ABORT_PENDING) ) + { + printk(KERN_INFO "qla1280(%d):Have already attempted to reach " "device with abort device\n", (int)ha->host_no); + printk(KERN_INFO "qla1280(%d):message, will escalate to BUS " "RESET.\n",(int) ha->host_no); + action = BUS_RESET; + } +#endif + + /* + * By this point, we want to already know what we are going to do, + * so we only need to perform the course of action. + */ + DRIVER_LOCK + result = SCSI_RESET_ERROR; + switch (action) + { + case FAIL: + break; + + case RESET_DELAYED: + result = SCSI_RESET_PENDING; + break; + + case ABORT_DEVICE: + ha->flags.in_reset = TRUE; + if (qla1280_verbose) + printk(KERN_INFO "scsi(%d:%d:%d:%d): Queueing abort device command.\n", (int)ha->host_no,(int)b,(int)t,(int)l); + qla1280_abort_queue_single(ha,b,t,l,DID_ABORT); + if( qla1280_abort_device(ha, b, t, l) == 0) + result = SCSI_RESET_PENDING; + break; + + case DEVICE_RESET: + if (qla1280_verbose) + printk(KERN_INFO "scsi(%d:%d:%d:%d): Queueing device reset command.\n",(int) ha->host_no,(int)b,(int)t,(int)l); + ha->flags.in_reset = TRUE; + for (l = 0; l < MAX_LUNS; l++) + qla1280_abort_queue_single(ha,b,t,l,DID_ABORT); + if( qla1280_device_reset(ha, b, t) == 0 ) + result = SCSI_RESET_PENDING; + q->q_flag |= QLA1280_QRESET; + break; + + case BUS_RESET: + if (qla1280_verbose) + printk(KERN_INFO "qla1280(%d:%d:%d:%d): Issuing BUS DEVICE RESET.\n",(int) ha->host_no,(int)b,(int)t,(int)l); + ha->flags.in_reset = TRUE; + for (t = 0; t < MAX_TARGETS; t++) + for (l = 0; l < MAX_LUNS; l++) + qla1280_abort_queue_single(ha,b,t,l,DID_RESET); + qla1280_bus_reset(ha, b); + /* + * The bus reset routine returns all the outstanding commands back + * with "DID_RESET" in the status field after a short delay + * by the firmware. If the mid-level time out the SCSI reset before + * our delay we may need to ignore it. + */ + /* result = SCSI_RESET_PENDING | SCSI_RESET_BUS_RESET; */ + result = SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET; + mdelay(4 * 1000); barrier(); + if( flags & SCSI_RESET_SYNCHRONOUS ) + { + CMD_RESULT(cmd) = (int) (DID_BUS_BUSY << 16); + (*(cmd)->scsi_done)(cmd); + } + /* ha->reset_start = jiffies; */ + break; + + case ADAPTER_RESET: + default: + if (qla1280_verbose) + { + printk(KERN_INFO "scsi(%d:%d:%d:%d): Issued an ADAPTER RESET.\n",(int) ha->host_no,(int)b,(int)t,(int)l); + printk(KERN_INFO "scsi(%d:%d:%d:%d): I/O processing will continue automatically.\n",(int) ha->host_no,(int)b,(int)t,(int)l); + } + ha->flags.reset_active = TRUE; + /* + * We restarted all of the commands automatically, so the mid-level code can expect + * completions momentitarily. + */ + if( qla1280_abort_isp(ha) == 0 ) + result = SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET; + + ha->flags.reset_active = FALSE; + } + + if( ha->done_q_first ) + qla1280_done(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last); + qla1280_restart_queues(ha); + ha->flags.in_reset = FALSE; + +DRIVER_UNLOCK + DEBUG(printk("RESET returning %d\n", result)); + + COMTRACE('r') + LEAVE("qla1280_reset"); + return( result ); +} + +/************************************************************************** + * qla1200_biosparam + * Return the disk geometry for the given SCSI device. + **************************************************************************/ +int +qla1280_biosparam(Disk *disk, kdev_t dev, int geom[]) +{ + int heads, sectors, cylinders; + + heads = 64; + sectors = 32; + cylinders = disk->capacity / (heads * sectors); + if (cylinders > 1024) + { + heads = 255; + sectors = 63; + cylinders = disk->capacity / (heads * sectors); + /* if (cylinders > 1023) + cylinders = 1023; */ + } + + geom[0] = heads; + geom[1] = sectors; + geom[2] = cylinders; + + return (0); +} +/************************************************************************** + * qla1280_intr_handler + * Handles the H/W interrupt + **************************************************************************/ +void qla1280_intr_handler(int irq, void *dev_id, struct pt_regs *regs) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,95) + unsigned long cpu_flags = 0; +#endif + scsi_qla_host_t *ha; + u_short data; + device_reg_t *reg; + + ENTER_INTR("qla1280_intr_handler"); + COMTRACE('I') + ha = (scsi_qla_host_t *) dev_id; + if(!ha) + { + printk(KERN_INFO "scsi(): Interrupt with NULL host ptr\n"); + COMTRACE('X') + return; + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,95) + spin_lock_irqsave(&io_request_lock, cpu_flags); + if(test_and_set_bit(QLA1280_IN_ISR_BIT, &ha->flags)) + { + COMTRACE('X') + return; + } + ha->isr_count++; + reg = ha->iobase; + /* disable our interrupt. */ + WRT_REG_WORD(®->ictrl, 0); + data = qla1280_debounce_register(®->istatus); + /* Check for pending interrupts. */ + if ( !(data & RISC_INT) ) + { + /* spurious interrupts can happen legally */ + DEBUG(printk("scsi(%d): Spurious interrupt - ignoring\n",(int)ha->host_no)); + COMTRACE('X') + } + else + qla1280_isr(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last); + if (ha->done_q_first) + qla1280_done(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last); + + clear_bit(QLA1280_IN_ISR_BIT, &ha->flags); + spin_unlock_irqrestore(&io_request_lock, cpu_flags); +#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) */ + + if( test_bit(QLA1280_IN_ISR_BIT, (int *)&ha->flags) ) + { + COMTRACE('X') + printk(KERN_INFO "scsi(%d): Already in interrupt - returning \n", (int)ha->host_no); + return; + } + set_bit(QLA1280_IN_ISR_BIT, (int *)&ha->flags); + ha->isr_count++; + reg = ha->iobase; + /* disable our interrupt. */ + WRT_REG_WORD(®->ictrl, 0); + + data = qla1280_debounce_register(®->istatus); + /* Check for pending interrupts. */ + if ( !(data & RISC_INT) ) + { + /* spurious interrupts can happen legally */ + DEBUG(printk("scsi(%d): Spurious interrupt - ignoring\n",(int)ha->host_no)); + COMTRACE('X') + } + else + qla1280_isr(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last); + + /* if no work to do then call the SCSI mid-level right away */ + if( ha->done_q_first ) + qla1280_done(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last); + + /* Schedule the DPC routine */ + if (ha->flags.isp_abort_needed || ha->flags.reset_marker || + ha->done_q_first ) + { + ha->run_qla_bh.data = (void *) ha; + ha->run_qla_bh.routine = qla1280_do_dpc; + + COMTRACE('P') + queue_task_irq(&ha->run_qla_bh,&tq_scheduler); + ha->flags.dpc_sched = TRUE; + } + clear_bit(QLA1280_IN_ISR_BIT, (int *)&ha->flags); +#endif + /* enable our interrupt. */ + WRT_REG_WORD(®->ictrl, ISP_EN_INT + ISP_EN_RISC); + + COMTRACE('i') + LEAVE_INTR("qla1280_intr_handler"); +} + +/************************************************************************** + * qla1280_do_dpc + * + * Description: + * This routine is a task that is schedule by the interrupt handler + * to perform the background processing for interrupts. We put it + * on a task queue that is consumed whenever the scheduler runs; that's + * so you can do anything (i.e. put the process to sleep etc). In fact, the + * mid-level tries to sleep when it reaches the driver threshold + * "host->can_queue". This can cause a panic if we were in our interrupt + * code . + **************************************************************************/ +void qla1280_do_dpc(void *p) +{ + scsi_qla_host_t *ha = (scsi_qla_host_t *) p; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95) + unsigned long cpu_flags = 0; +#endif + + COMTRACE('p') +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95) + spin_lock_irqsave(&io_request_lock, cpu_flags); +#endif + if (ha->flags.isp_abort_needed) + qla1280_abort_isp(ha); + + if (ha->flags.reset_marker) + qla1280_rst_aen(ha); + + if (ha->done_q_first) + qla1280_done(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last); + ha->flags.dpc_sched = FALSE; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95) + spin_unlock_irqrestore(&io_request_lock, cpu_flags); +#endif +} + +/************************************************************************** + * qla1280_device_queue_depth + * + * Description: + * Determines the queue depth for a given device. There are two ways + * a queue depth can be obtained for a tagged queueing device. One + * way is the default queue depth which is determined by whether + * If it is defined, then it is used + * as the default queue depth. Otherwise, we use either 4 or 8 as the + * default queue depth (dependent on the number of hardware SCBs). + **************************************************************************/ +STATIC void qla1280_device_queue_depth(scsi_qla_host_t *p, Scsi_Device *device) +{ + int default_depth = 3; + int bus = device->channel; + int target = device->id; + + device->queue_depth = default_depth; + + if (device->tagged_supported && + (p->bus_settings[bus].qtag_enables & (BIT_0 << target)) ) + { + device->tagged_queue = 1; + device->current_tag = 0; + device->queue_depth = p->bus_settings[bus].hiwat; + /* device->queue_depth = 20; */ + printk(KERN_INFO "scsi(%d:%d:%d:%d): Enabled tagged queuing, queue depth %d.\n", + (int)p->host_no, device->channel, device->id, + device->lun, device->queue_depth); + } + +} + +/************************************************************************** + * qla1280_select_queue_depth + * + * Sets the queue depth for each SCSI device hanging off the input + * host adapter. We use a queue depth of 2 for devices that do not + * support tagged queueing. + **************************************************************************/ +STATIC void +qla1280_select_queue_depth(struct Scsi_Host *host, Scsi_Device *scsi_devs) +{ + Scsi_Device *device; + scsi_qla_host_t *p = (scsi_qla_host_t *) host->hostdata; + + ENTER("qla1280_select_queue_depth"); + for (device = scsi_devs; device != NULL; device = device->next) + { + if (device->host == host) + qla1280_device_queue_depth(p, device); + } + LEAVE("qla1280_select_queue_depth"); +} + +/*--------------------------** +** Driver Support Routines ** +**--------------------------*/ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) +/* + * mdelay + * Delay in milliseconds + * + * Input: + * milliseconds = delay + */ +STATIC inline void mdelay(int milliseconds) +{ + int i; + + for(i=0; is_next)) + *done_q_last = NULL; + else + (*done_q_first)->s_prev = NULL; + cmd = sp->cmd; + b = SCSI_BUS_32(cmd); + t = SCSI_TCN_32(cmd); + l = SCSI_LUN_32(cmd); + q = LU_Q(ha, b, t, l); + + /* Decrement outstanding commands on device. */ + if (q->q_outcnt) + q->q_outcnt--; + if (q->q_outcnt < ha->bus_settings[b].hiwat) + { + q->q_flag &= ~QLA1280_QBUSY; + } + + q->resp_time += jiffies - sp->r_start; /* Lun bookkeeping information */ + q->act_time += jiffies - sp->u_start; + q->io_cnt++; + if( sp->dir & BIT_5 ) + q->r_cnt++; + else + q->w_cnt++; + + switch ( (CMD_RESULT(cmd)>>16)) + { + case DID_RESET: + q->q_flag &= ~QLA1280_QRESET; + /* Issue marker command. */ + qla1280_marker(ha, b, t, 0, MK_SYNC_ID); + break; + case DID_ABORT: + sp->flags &= ~SRB_ABORT_PENDING; + sp->flags |= SRB_ABORTED; + if (sp->flags & SRB_TIMEOUT) + CMD_RESULT(sp->cmd)= DID_TIME_OUT << 16; + break; + default: + break; + } + + /* Call the mid-level driver interrupt handler */ + CMD_HANDLE(sp->cmd) = (unsigned char *) 0; + ha->actthreads--; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) + sti(); + (*(cmd)->scsi_done)(cmd); + cli(); +#else + (*(cmd)->scsi_done)(cmd); +#endif + qla1280_next(ha, q, b); + } + DRIVER_UNLOCK + + + COMTRACE('d') + LEAVE("qla1280_done"); +} + +/* + * Translates a ISP error to a Linux SCSI error + */ +STATIC int qla1280_return_status( sts_entry_t *sts, Scsi_Cmnd *cp) +{ + int host_status = DID_ERROR; +#if DEBUG_QLA1280_INTR + STATIC char *reason[] = + { + "DID_OK", + "DID_NO_CONNECT", + "DID_BUS_BUSY", + "DID_TIME_OUT", + "DID_BAD_TARGET", + "DID_ABORT", + "DID_PARITY", + "DID_ERROR", + "DID_RESET", + "DID_BAD_INTR" + }; +#endif /* DEBUG_QLA1280_INTR */ + + ENTER("qla1280_return_status"); + +#if DEBUG_QLA1280_INTR + /* + DEBUG(printk("qla1280_return_status: compl status = 0x%04x\n", sts->comp_status)); + */ +#endif + switch(sts->comp_status) + { + case CS_COMPLETE: + host_status = DID_OK; + break; + case CS_INCOMPLETE: + if (!(sts->state_flags & SF_GOT_BUS)) + host_status = DID_NO_CONNECT; + else if (!(sts->state_flags & SF_GOT_TARGET)) + host_status = DID_BAD_TARGET; + else if (!(sts->state_flags & SF_SENT_CDB)) + host_status = DID_ERROR; + else if (!(sts->state_flags & SF_TRANSFERRED_DATA)) + host_status = DID_ERROR; + else if (!(sts->state_flags & SF_GOT_STATUS)) + host_status = DID_ERROR; + else if (!(sts->state_flags & SF_GOT_SENSE)) + host_status = DID_ERROR; + break; + case CS_RESET: + host_status = DID_RESET; + break; + case CS_ABORTED: + host_status = DID_ABORT; + break; + case CS_TIMEOUT: + host_status = DID_TIME_OUT; + break; + case CS_DATA_OVERRUN: +#ifdef QL_DEBUG_LEVEL_2 + printk("Data overrun 0x%x\n",(int)sts->residual_length); + qla1280_print( + "\n\rqla1280_isr: response packet data\n\r"); + qla1280_dump_buffer((caddr_t)sts, + RESPONSE_ENTRY_SIZE); +#endif + host_status = DID_ERROR; + break; + case CS_DATA_UNDERRUN: + if ( (CMD_XFRLEN(cp) - sts->residual_length) < cp->underflow) + { + printk("scsi: Underflow detected - retrying command.\n"); + host_status = DID_ERROR; + } + else + host_status = DID_OK; + break; + default: + host_status = DID_ERROR; + break; + } + +#if DEBUG_QLA1280_INTR + sprintf(debug_buff, "qla1280 ISP status: host status (%s) scsi status %x\n\r", reason[host_status], sts->scsi_status); + qla1280_print(debug_buff); +#endif + + LEAVE("qla1280_return_status"); + + return (sts->scsi_status & 0xff) | (host_status << 16); +} + +/* + * qla1280_done_q_put + * Place SRB command on done queue. + * + * Input: + * sp = srb pointer. + * done_q_first = done queue first pointer. + * done_q_last = done queue last pointer. + */ +STATIC void +qla1280_done_q_put(srb_t *sp, srb_t **done_q_first, srb_t **done_q_last) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) + unsigned long cpu_flags = 0; +#endif +#ifdef QL_DEBUG_LEVEL_3 + ENTER("qla1280_put_done_q"); +#endif + /* Place block on done queue */ + DRIVER_LOCK + sp->s_next = NULL; + sp->s_prev = *done_q_last; + if (!*done_q_first) + *done_q_first = sp; + else + (*done_q_last)->s_next = sp; + *done_q_last = sp; + + DRIVER_UNLOCK +#ifdef QL_DEBUG_LEVEL_3 + LEAVE("qla1280_put_done_q"); +#endif +} + +/* + * qla1280_next + * Retrieve and process next job in the queue. + * + * Input: + * ha = adapter block pointer. + * q = SCSI LU pointer. + * b = SCSI bus number. + * SCSI_LU_Q lock must be already obtained and no other locks. + * + * Output: + * Releases SCSI_LU_Q upon exit. + */ +STATIC void +qla1280_next(scsi_qla_host_t *ha, scsi_lu_t *q, uint8_t b) +{ + srb_t *sp; + uint32_t cnt; + uint8_t status; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) + unsigned long cpu_flags = 0; +#endif + + ENTER("qla1280_next"); + + DRIVER_LOCK + while ( ((sp = q->q_first) != NULL) && /* we have a queue pending */ + !(q->q_flag & QLA1280_QBUSY) && /* device not busy */ + !ha->flags.abort_isp_active && /* not resetting the adapter */ + !(q->q_flag & QLA1280_QSUSP) ) /* device not suspended */ + { + /* Remove srb from SCSI LU queue. */ + qla1280_removeq(q, sp); + + DEBUG(sprintf(debug_buff,"starting request 0x%x<-(0x%x)\n\r",q,sp)); + DEBUG(qla1280_print(debug_buff)); + { + /* Set busy flag if reached high water mark. */ + q->q_outcnt++; + if (q->q_outcnt >= ha->bus_settings[b].hiwat) + q->q_flag |= QLA1280_QBUSY; + +#if QLA1280_64BIT_SUPPORT + if (ha->flags.enable_64bit_addressing) + status = qla1280_64bit_start_scsi(ha, sp); + else +#endif + status = qla1280_32bit_start_scsi(ha, sp); + + if (status) /* if couldn't start the request */ + { + if (q->q_outcnt == 1) + { + /* Release SCSI LU queue specific lock */ + QLA1280_SCSILU_UNLOCK(q); + + /* Wait for 30 sec for command to be accepted. */ + for (cnt = 6000000; cnt; cnt--) + { +#if QLA1280_64BIT_SUPPORT + if (ha->flags.enable_64bit_addressing) + status = qla1280_64bit_start_scsi(ha, sp); + else +#endif + status = qla1280_32bit_start_scsi(ha, sp); + + if (!status) + { + break; + } + + /* Go check for pending interrupts. */ + qla1280_poll(ha); + + SYS_DELAY(5); /* 10 */ + } + if (!cnt) + { + /* Set timeout status */ + CMD_RESULT(sp->cmd) = DID_TIME_OUT << 16; + +#if WATCHDOGTIMER + /* Remove command from watchdog queue. */ + if (sp->flags & SRB_WATCHDOG) + qla1280_timeout_remove(ha, sp); +#endif + COMTRACE('M') + CMD_HANDLE(sp->cmd) = (unsigned char *) 0; + + /* Call the mid-level driver interrupt handler */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) + sti(); + (*(sp->cmd)->scsi_done)(sp->cmd); + cli(); +#else + (*(sp->cmd)->scsi_done)(sp->cmd); +#endif + + /* Acquire LU queue specific lock */ + QLA1280_SCSILU_LOCK(q); + + if (q->q_outcnt) + q->q_outcnt--; + } + else + /* Acquire LU queue specific lock */ + QLA1280_SCSILU_LOCK(q); + } + else + { /* Place request back on top of device queue. */ + qla1280_putq_t(q, sp); + + if (q->q_outcnt) + q->q_outcnt--; + if (q->q_outcnt < ha->bus_settings[b].hiwat) + q->q_flag &= ~QLA1280_QBUSY; + break; + } + } + } + } + DRIVER_UNLOCK + + /* Release SCSI LU queue specific lock */ + QLA1280_SCSILU_UNLOCK(q); + + LEAVE("qla1280_next"); +} + +/* + * qla1280_putq_t + * Add the standard SCB job to the top of standard SCB commands. + * + * Input: + * q = SCSI LU pointer. + * sp = srb pointer. + * SCSI_LU_Q lock must be already obtained. + */ +STATIC void +qla1280_putq_t(scsi_lu_t *q, srb_t *sp) +{ + srb_t *srb_p; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) + unsigned long cpu_flags = 0; +#endif + +#ifdef QL_DEBUG_LEVEL_3 + ENTER("qla1280_putq_t"); +#endif + DRIVER_LOCK + DEBUG(sprintf(debug_buff,"Adding to device 0x%x<-(0x%x)\n\r",q,sp)); + DEBUG(qla1280_print(debug_buff)); + sp->s_next = NULL; + if (!q->q_first) /* If queue empty */ + { + sp->s_prev = NULL; + q->q_first = sp; + q->q_last = sp; + } + else + { + srb_p = q->q_first; + while (srb_p ) + srb_p = srb_p->s_next; + + if (srb_p) + { + sp->s_prev = srb_p->s_prev; + if (srb_p->s_prev) + srb_p->s_prev->s_next = sp; + else + q->q_first = sp; + srb_p->s_prev = sp; + sp->s_next = srb_p; + } + else + { + sp->s_prev = q->q_last; + q->q_last->s_next = sp; + q->q_last = sp; + } + } + + DRIVER_UNLOCK +#ifdef QL_DEBUG_LEVEL_3 + LEAVE("qla1280_putq_t"); +#endif +} + +/* + * qla1280_removeq + * Function used to remove a command block from the + * LU queue. + * + * Input: + * q = SCSI LU pointer. + * sp = srb pointer. + * SCSI_LU_Q lock must be already obtained. + */ +STATIC void +qla1280_removeq(scsi_lu_t *q, srb_t *sp) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) + unsigned long cpu_flags = 0; +#endif + DEBUG(sprintf(debug_buff,"Removing from device_q (0x%x)->(0x%x)\n\r",q,sp)); + DEBUG(qla1280_print(debug_buff)); + DRIVER_LOCK + if (sp->s_prev) + { + if ((sp->s_prev->s_next = sp->s_next) != NULL) + sp->s_next->s_prev = sp->s_prev; + else + q->q_last = sp->s_prev; + } + else if (!(q->q_first = sp->s_next)) + q->q_last = NULL; + else + q->q_first->s_prev = NULL; + DRIVER_UNLOCK +} + +/* + * qlc1280_mem_free + * Frees adapter allocated memory. + * + * Input: + * ha = adapter block pointer. + */ +STATIC void +qla1280_mem_free(scsi_qla_host_t *ha) +{ + scsi_lu_t *q; + uint32_t b, t, l; + + ENTER("qlc1280_mem_free"); + if (ha) + { + /* Free device queues. */ + for (b = 0; b < MAX_BUSES; b++) + { + q = LU_Q(ha, b, ha->bus_settings[b].id, 0); + for (t = 0; t < MAX_TARGETS; t++) + for (l = 0; l < MAX_LUNS; l++) + if (LU_Q(ha, b, t, l) != NULL && LU_Q(ha, b, t, l) != q) + KMFREE(LU_Q(ha, b, t, l),sizeof(struct scsi_lu)); + KMFREE(q, sizeof(struct scsi_lu)); + } + for( b =0; b < MAX_EQ; b++ ) + ha->dev[b] = (scsi_lu_t *)NULL; + } + + LEAVE("qlc1280_mem_free"); +} + + + + +/****************************************************************************/ +/* QLogic ISP1280 Hardware Support Functions. */ +/****************************************************************************/ + +/* + * qla1280_initialize_adapter + * Initialize board. + * + * Input: + * ha = adapter block pointer. + * + * Returns: + * 0 = success + */ +STATIC uint8_t +qla1280_initialize_adapter(scsi_qla_host_t *ha) +{ + device_reg_t *reg; + uint8_t status; + /* uint8_t cnt; */ + uint8_t b; + +#ifdef QL_DEBUG_LEVEL_3 + ENTER("qla1280_initialize_adapter"); +#endif + + /* Clear adapter flags. */ + ha->flags.online = FALSE; + ha->flags.isp_abort_needed = FALSE; + ha->flags.disable_host_adapter = FALSE; + ha->flags.reset_active = FALSE; + ha->flags.abort_isp_active = FALSE; + ha->flags.watchdog_enabled = FALSE; + + DEBUG(printk("Configure PCI space for adapter...\n")); + if (!(status = qla1280_pci_config(ha))) + { + reg = ha->iobase; + + /* Disable ISP interrupts. */ + WRT_REG_WORD(®->ictrl, 0); + + /* Insure mailbox registers are free. */ + WRT_REG_WORD(®->semaphore, 0); + WRT_REG_WORD(®->host_cmd, HC_CLR_RISC_INT); + WRT_REG_WORD(®->host_cmd, HC_CLR_HOST_INT); + + /* If firmware needs to be loaded */ + if (qla1280_verbose) + printk("scsi(%d): Determining if RISC is loaded...\n",(int)ha->host_no); + if (qla1280_isp_firmware(ha)) + { + if (qla1280_verbose) + printk("scsi(%d): Verifying chip...\n",(int)ha->host_no); + if (!(status = qla1280_chip_diag(ha))) + { + status = qla1280_setup_chip(ha); + } + } + + if (!status) + { + /* Setup adapter based on NVRAM parameters. */ + if (qla1280_verbose) + printk("scsi(%d): Configure NVRAM parameters...\n",(int)ha->host_no); + qla1280_nvram_config(ha); + + if (!ha->flags.disable_host_adapter && + !qla1280_init_rings(ha)) + { + /* Issue SCSI reset. */ + for (b = 0; b < ha->ports; b++) + if (!ha->bus_settings[b].disable_scsi_reset) + { + /* dg 03/13 if we can't reset twice then bus is dead */ + if( qla1280_bus_reset(ha, b) ) + if( qla1280_bus_reset(ha, b) ) + { + ha->bus_settings[b].scsi_bus_dead = TRUE; + } + } + + do + { + /* Issue marker command. */ + ha->flags.reset_marker = FALSE; + for (b = 0; b < ha->ports; b++) + { + ha->bus_settings[b].reset_marker = FALSE; + qla1280_marker(ha, b, 0, 0, MK_SYNC_ALL); + } + }while (ha->flags.reset_marker); + + ha->flags.online = TRUE; + + /* Enable host adapter target mode. */ + for (b = 0; b < ha->ports; b++) + { + if (!(status = qla1280_enable_tgt(ha, b))) + { + /* for (cnt = 0; cnt < MAX_LUNS; cnt++) + { + qla1280_enable_lun(ha, b, cnt); + qla1280_poll(ha); + }*/ + } + else + break; + } + } + else + status = 1; + } + } + +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + if (status) + qla1280_print("qla1280_initialize_adapter: **** FAILED ****\n\r"); +#endif +#ifdef QL_DEBUG_LEVEL_3 + else + LEAVE("qla1280_initialize_adapter"); +#endif + return(status); +} + +/* + * qla1280_enable_tgt + * Enable target mode. + * + * Input: + * ha = adapter block pointer. + * b = SCSI bus number. + * + * Returns: + * 0 = success. + */ +STATIC uint8_t +qla1280_enable_tgt(scsi_qla_host_t *ha, uint8_t b) +{ + uint8_t status = 0; + /* uint16_t mb[MAILBOX_REGISTER_COUNT]; */ + +#ifdef QL_DEBUG_LEVEL_3 + qla1280_print("qla1280_enable_tgt: entered\n\r"); +#endif + + /* Enable target mode. */ + /* + mb[0] = MBC_ENABLE_TARGET_MODE; + mb[1] = BIT_15; + mb[2] = (uint16_t)(b << 15); + status = qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0, &mb[0]); + */ +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + if (status) + qla1280_print("qla1280_enable_tgt: **** FAILED ****\n\r"); +#endif +#ifdef QL_DEBUG_LEVEL_3 + else + qla1280_print("qla1280_enable_tgt: exiting normally\n\r"); +#endif + return(status); +} + +/* + * ISP Firmware Test + * Checks if present version of RISC firmware is older than + * driver firmware. + * + * Input: + * ha = adapter block pointer. + * + * Returns: + * 0 = firmware does not need to be loaded. + */ +STATIC uint8_t +qla1280_isp_firmware(scsi_qla_host_t *ha) +{ + nvram_t *nv = (nvram_t *)ha->response_ring; + uint16_t *wptr; + uint8_t chksum; + uint8_t cnt; + uint8_t status = 0; /* dg 2/27 always loads RISC */ + uint16_t mb[MAILBOX_REGISTER_COUNT]; + + ENTER("qla1280_isp_firmware"); + + /* Verify valid NVRAM checksum. */ + wptr = (uint16_t *)ha->response_ring; + DEBUG(printk("qla1280_isp_firmware: Reading NVRAM\n")); + chksum = 0; + for (cnt = 0; cnt < sizeof(nvram_t)/2; cnt++) + { + *wptr = qla1280_get_nvram_word(ha, cnt); + /* + *wptr = (u_short) qla1280_read_nvram_word(ha->host, (u_short) cnt); + */ + chksum += (uint8_t)*wptr; + chksum += (uint8_t)(*wptr >> 8); + wptr++; + } + DEBUG(printk("qla1280_isp_firmware: Completed Reading NVRAM\n")); + +#if defined(QL_DEBUG_LEVEL_3) + sprintf(debug_buff,"qla1280_isp_firmware: NVRAM Magic ID= %c %c %c\n\r",(char *) nv->id[0],nv->id[1],nv->id[2]); + qla1280_print(debug_buff); +#endif + + /* Bad NVRAM data, load RISC code. */ + if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' || + nv->id[2] != 'P' || nv->id[3] != ' ' || nv->version < 1) + { + printk(KERN_INFO "qla1280_isp_firmware: Bad checksum or magic number or version in NVRAM.\n"); + ha->flags.disable_risc_code_load = FALSE; + } + else + ha->flags.disable_risc_code_load = nv->cntr_flags_1.disable_loading_risc_code; + + if (ha->flags.disable_risc_code_load) + { +#if defined(QL_DEBUG_LEVEL_3) + qla1280_print("qla1280_isp_firmware: Telling RISC to verify checksum of loaded BIOS code.\n\r"); +#endif + /* Verify checksum of loaded RISC code. */ + mb[0] = MBC_VERIFY_CHECKSUM; + mb[1] = ql12_risc_code_addr01; + if (!(status = qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]))) + { + /* Start firmware execution. */ +#if defined(QL_DEBUG_LEVEL_3) + qla1280_print("qla1280_isp_firmware: Startng F/W execution.\n\r"); +#endif + mb[0] = MBC_EXECUTE_FIRMWARE; + mb[1] = ql12_risc_code_addr01; + qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]); + } + else + printk(KERN_INFO "qla1280: RISC checksum failed.\n"); + } + else + { + DEBUG(printk("qla1280: NVRAM configured to load RISC load.\n")); + status = 1; + } + +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + if (status) + qla1280_print( + "qla1280_isp_firmware: **** Load RISC code ****\n\r"); +#endif + LEAVE("qla1280_isp_firmware"); + return(status); +} + +/* + * PCI configuration + * Setup device PCI configuration registers. + * + * Input: + * ha = adapter block pointer. + * + * Returns: + * 0 = success. + */ +STATIC uint8_t +qla1280_pci_config(scsi_qla_host_t *ha) +{ + uint8_t status = 1; + uint32_t command; +#if MEMORY_MAPPED_IO + uint32_t page_offset, base; + uint32_t mmapbase; +#endif + config_reg_t *creg = 0; + uint16_t buf_wd; + + ENTER("qla1280_pci_config"); + + /* Get command register. */ + if (pcibios_read_config_word(ha->pci_bus,ha->pci_device_fn, OFFSET(creg->command), &buf_wd) == PCIBIOS_SUCCESSFUL) + { + command = buf_wd; + /* + * Set Bus Master Enable, Memory Address Space Enable and + * reset any error bits. + */ + buf_wd &= ~0x7; +#if MEMORY_MAPPED_IO + DEBUG(printk("qla1280: MEMORY MAPPED IO is enabled.\n")); + buf_wd |= BIT_2 + BIT_1 + BIT_0; +#else + buf_wd |= BIT_2 + BIT_0; +#endif + if( pcibios_write_config_word(ha->pci_bus,ha->pci_device_fn, OFFSET(creg->command), buf_wd) ) + { + printk(KERN_WARNING "qla1280: Could not write config word.\n"); + } + /* Get expansion ROM address. */ + if (pcibios_read_config_word(ha->pci_bus,ha->pci_device_fn, OFFSET(creg->expansion_rom), &buf_wd) == PCIBIOS_SUCCESSFUL) + { + /* Reset expansion ROM address decode enable. */ + buf_wd &= ~BIT_0; + if (pcibios_write_config_word(ha->pci_bus,ha->pci_device_fn, OFFSET(creg->expansion_rom), buf_wd) == PCIBIOS_SUCCESSFUL) + { +#if MEMORY_MAPPED_IO + /* Get memory mapped I/O address. */ + pcibios_read_config_dword(ha->pci_bus, ha->pci_device_fn,OFFSET(cfgp->mem_base_addr), &mmapbase); + mmapbase &= PCI_BASE_ADDRESS_MEM_MASK; + + /* Find proper memory chunk for memory map I/O reg. */ + base = mmapbase & PAGE_MASK; + page_offset = mmapbase - base; + /* Get virtual address for I/O registers. */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) + ha->mmpbase = ioremap_nocache(base, page_offset + 256); +#else + ha->mmpbase = vremap(base,page_offset + 256); +#endif + if( ha->mmpbase ) + { + ha->mmpbase += page_offset; + /* ha->iobase = ha->mmpbase; */ + status = 0; + } +#else /* MEMORY_MAPPED_IO */ + status = 0; +#endif /* MEMORY_MAPPED_IO */ + } + } + } + + LEAVE("qla1280_pci_config"); + return(status); +} + +/* + * Chip diagnostics + * Test chip for proper operation. + * + * Input: + * ha = adapter block pointer. + * + * Returns: + * 0 = success. + */ +STATIC uint8_t +qla1280_chip_diag(scsi_qla_host_t *ha) +{ + device_reg_t *reg = ha->iobase; + uint8_t status = 0; + uint16_t data; + uint32_t cnt; + uint16_t mb[MAILBOX_REGISTER_COUNT]; + +#ifdef QL_DEBUG_LEVEL_3 + sprintf(debug_buff, "qla1280_chip_diag: testing device at 0x%x \n\r",®->id_l); + qla1280_print(debug_buff); +#endif + + /* Soft reset chip and wait for it to finish. */ + WRT_REG_WORD(®->ictrl, ISP_RESET); + data = qla1280_debounce_register(®->ictrl); + for (cnt = 6000000; cnt && data & ISP_RESET; cnt--) + { + SYS_DELAY(5); + data = RD_REG_WORD(®->ictrl); + } + if (cnt) + { + /* Reset register not cleared by chip reset. */ +#if defined(QL_DEBUG_LEVEL_3) + qla1280_print("qla1280_chip_diag: reset register cleared by chip reset\n\r"); +#endif + WRT_REG_WORD(®->cfg_1, 0); + + /* Reset RISC and disable BIOS which + allows RISC to execute out of RAM. */ + WRT_REG_WORD(®->host_cmd, HC_RESET_RISC); + WRT_REG_WORD(®->host_cmd, HC_RELEASE_RISC); + WRT_REG_WORD(®->host_cmd, HC_DISABLE_BIOS); + data = qla1280_debounce_register(®->mailbox0); + for (cnt = 6000000; cnt && data == MBS_BUSY; cnt--) + { + SYS_DELAY(5); + data = RD_REG_WORD(®->mailbox0); + } + + if (cnt) + { + /* Check product ID of chip */ +#if defined(QL_DEBUG_LEVEL_3) + qla1280_print("qla1280_chip_diag: Checking product ID of chip\n\r"); +#endif + if (RD_REG_WORD(®->mailbox1) != PROD_ID_1 || + (RD_REG_WORD(®->mailbox2) != PROD_ID_2 && + RD_REG_WORD(®->mailbox2) != PROD_ID_2a) || + RD_REG_WORD(®->mailbox3) != PROD_ID_3 || + RD_REG_WORD(®->mailbox4) != PROD_ID_4) + { + printk(KERN_INFO "qla1280: Wrong product ID = 0x%x,0x%x,0x%x,0x%x\n", + RD_REG_WORD(®->mailbox1), + RD_REG_WORD(®->mailbox2), + RD_REG_WORD(®->mailbox3), + RD_REG_WORD(®->mailbox4) ); + status = 1; + } + else + { + DEBUG(printk("qla1280_chip_diag: Checking mailboxes of chip\n")); + /* Wrap Incoming Mailboxes Test. */ + mb[0] = MBC_MAILBOX_REGISTER_TEST; + mb[1] = 0xAAAA; + mb[2] = 0x5555; + mb[3] = 0xAA55; + mb[4] = 0x55AA; + mb[5] = 0xA5A5; + mb[6] = 0x5A5A; + mb[7] = 0x2525; + if (!(status = qla1280_mailbox_command(ha, + (BIT_7|BIT_6|BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0), + &mb[0]))) + { + if (mb[1] != 0xAAAA || mb[2] != 0x5555 || + mb[3] != 0xAA55 || mb[4] != 0x55AA) + status = 1; + if (mb[5] != 0xA5A5 || mb[6] != 0x5A5A || + mb[7] != 0x2525) + status = 1; + if( status == 1 ) + printk(KERN_INFO "qla1280: Failed mailbox check\n"); + } + } + } + else + status = 1; + } + else + status = 1; + +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + if (status) + qla1280_print("qla1280_chip_diag: **** FAILED ****\n\r"); +#endif +#ifdef QL_DEBUG_LEVEL_3 + else + qla1280_print("qla1280_chip_diag: exiting normally\n\r"); +#endif + return(status); +} + +/* + * Setup chip + * Load and start RISC firmware. + * + * Input: + * ha = adapter block pointer. + * + * Returns: + * 0 = success. + */ +STATIC uint8_t +qla1280_setup_chip(scsi_qla_host_t *ha) +{ + uint8_t status = 0; + uint16_t risc_address; + uint16_t *risc_code_address; + long risc_code_size; + uint16_t mb[MAILBOX_REGISTER_COUNT]; +#ifdef QLA1280_UNUSED + int i; +#endif + uint16_t cnt; + int num; + +#ifdef QL_DEBUG_LEVEL_3 + ENTER("qla1280_setup_chip"); +#endif + + /* Load RISC code. */ + risc_address = ql12_risc_code_addr01; + risc_code_address = &ql12_risc_code01[0]; + risc_code_size = ql12_risc_code_length01; + + DEBUG(printk("qla1280: DMAing RISC code (%d) words.\n",(int)risc_code_size)); + DEBUG(sprintf(debug_buff,"qla1280_setup_chip: Loading RISC code size =(%d).\n\r",risc_code_size);) + DEBUG(qla1280_print(debug_buff)); + num =0; + while (risc_code_size > 0 && !status) + { + cnt = 2000 >> 1; + + if ( cnt > risc_code_size ) + cnt = risc_code_size; + + DEBUG(sprintf(debug_buff,"qla1280_setup_chip: loading risc @ =(0x%x),%d,%d(0x%x).\n\r",risc_code_address,cnt,num,risc_address);) + DEBUG(qla1280_print(debug_buff)); + BCOPY((caddr_t) risc_code_address,(caddr_t) ha->request_ring, (cnt <<1)); + mb[0] = MBC_LOAD_RAM; + mb[1] = risc_address; + mb[3] = (uint16_t) (ha->request_dma & 0xffff); + mb[2] = (uint16_t) (ha->request_dma >> 16) & 0xffff; + mb[4] = cnt; + if( (status = qla1280_mailbox_command(ha, BIT_4|BIT_3|BIT_2|BIT_1|BIT_0, + &mb[0])) ) + { + printk("Failed to load partial segment of f/w\n"); + break; + } + + risc_address += cnt; + risc_code_size = risc_code_size - cnt; + risc_code_address = risc_code_address + cnt; + num++; + } +#ifdef QLA1280_UNUSED + DEBUG(ql_debug_print = 0;) + { + for (i = 0; i < ql12_risc_code_length01; i++) + { + mb[0] = 0x4; + mb[1] = ql12_risc_code_addr01 + i; + mb[2] = ql12_risc_code01[i]; + + status = qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0, + &mb[0]); + if (status) + { + printk("qla1280 : firmware load failure\n"); + break; + } + + mb[0] = 0x5; + mb[1] = ql12_risc_code_addr01 + i; + mb[2] = 0; + + status = qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0, + &mb[0]); + if (status) + { + printk("qla1280 : firmware dump failure\n"); + break; + } + if( mb[2] != ql12_risc_code01[i] ) + printk("qla1280 : firmware compare error @ (0x%x)\n",ql12_risc_code_addr01+i); + } + } + DEBUG(ql_debug_print = 1;) +#endif + + /* Verify checksum of loaded RISC code. */ + if (!status) + { + DEBUG(printk("qla1280_setup_chip: Verifying checksum of loaded RISC code.\n");) + mb[0] = MBC_VERIFY_CHECKSUM; + mb[1] = ql12_risc_code_addr01; + if (!(status = qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]))) + { + /* Start firmware execution. */ + DEBUG(qla1280_print("qla1280_setup_chip: start firmware running.\n\r");) + mb[0] = MBC_EXECUTE_FIRMWARE; + mb[1] = ql12_risc_code_addr01; + qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]); + } +#if defined(QL_DEBUG_LEVEL_2) + else + qla1280_print("qla1280_setup_chip: Failed checksum.\n"); +#endif + } + +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + if (status) + qla1280_print("qla1280_setup_chip: **** FAILED ****\n\r"); +#endif +#ifdef QL_DEBUG_LEVEL_3 + else + LEAVE("qla1280_setup_chip"); +#endif + return(status); +} + +/* + * Initialize rings + * + * Input: + * ha = adapter block pointer. + * ha->request_ring = request ring virtual address + * ha->response_ring = response ring virtual address + * ha->request_dma = request ring physical address + * ha->response_dma = response ring physical address + * + * Returns: + * 0 = success. + */ +STATIC uint8_t +qla1280_init_rings(scsi_qla_host_t *ha) +{ + uint8_t status = 0; + uint16_t cnt; + uint16_t mb[MAILBOX_REGISTER_COUNT]; + +#ifdef QL_DEBUG_LEVEL_3 + ENTER("qla1280_init_rings"); +#endif + /* Clear outstanding commands array. */ + for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) + ha->outstanding_cmds[cnt] = 0; + + /* Initialize request queue. */ + ha->request_ring_ptr = ha->request_ring; + ha->req_ring_index = 0; + ha->req_q_cnt = REQUEST_ENTRY_CNT; + mb[0] = MBC_INIT_REQUEST_QUEUE; + mb[1] = REQUEST_ENTRY_CNT; + mb[3] = (uint16_t)ha->request_dma; + mb[2] = (uint16_t)(ha->request_dma >> 16); + mb[4] = 0; + mb[7] = 0; + mb[6] = 0; + if (!(status = qla1280_mailbox_command(ha, + BIT_7|BIT_6|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0, + &mb[0]))) + { + /* Initialize response queue. */ + ha->response_ring_ptr = ha->response_ring; + ha->rsp_ring_index = 0; + mb[0] = MBC_INIT_RESPONSE_QUEUE; + mb[1] = RESPONSE_ENTRY_CNT; + mb[3] = (uint16_t)ha->response_dma; + mb[2] = (uint16_t)(ha->response_dma >> 16); + mb[5] = 0; + mb[7] = 0; + mb[6] = 0; + status = qla1280_mailbox_command(ha, + BIT_7|BIT_6|BIT_5|BIT_3|BIT_2|BIT_1|BIT_0, + &mb[0]); + } + +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + if (status) + qla1280_print("qla1280_init_rings: **** FAILED ****\n\r"); +#endif +#ifdef QL_DEBUG_LEVEL_3 + else + LEAVE("qla1280_init_rings"); +#endif + return(status); +} + +/* + * NVRAM configuration. + * + * Input: + * ha = adapter block pointer. + * ha->request_ring = request ring virtual address + * + * Output: + * host adapters parameters in host adapter block + * + * Returns: + * 0 = success. + */ +STATIC uint8_t +qla1280_nvram_config(scsi_qla_host_t *ha) +{ + device_reg_t *reg = ha->iobase; + nvram_t *nv = (nvram_t *)ha->response_ring; + uint8_t status = 0; + uint32_t b, t, l; + uint16_t *wptr; + uint16_t mb[MAILBOX_REGISTER_COUNT]; + uint8_t cnt; + uint8_t chksum; + +#if defined(QL_DEBUG_ROUTINES) && !defined(QL_DEBUG_LEVEL_4) + uint8_t saved_print_status = ql_debug_print; +#endif + ENTER("qla1280_nvram_config"); +#if defined(QL_DEBUG_ROUTINES) && !defined(QL_DEBUG_LEVEL_4) + ql_debug_print = FALSE; +#endif + + /* Verify valid NVRAM checksum. */ +#if USE_NVRAM_DEFAULTS + chksum = 1; +#else + wptr = (uint16_t *)ha->response_ring; + chksum = 0; + for (cnt = 0; cnt < sizeof(nvram_t)/2; cnt++) + { + *wptr = qla1280_get_nvram_word(ha, cnt); + chksum += (uint8_t)*wptr; + chksum += (uint8_t)(*wptr >> 8); + wptr++; + } +#endif + + + /* Bad NVRAM data, set defaults parameters. */ + if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' || + nv->id[2] != 'P' || nv->id[3] != ' ' || nv->version < 1) + { +#if USE_NVRAM_DEFAULTS + DEBUG(printk("Using defaults for NVRAM\n")); +#else + DEBUG(printk("Using defaults for NVRAM: \n")); + DEBUG(printk("checksum=0x%x, Id=%c, version=0x%x\n",chksum,nv->id[0],nv->version)); +#if defined(QL_DEBUG_LEVEL_3) + /* ql_debug_print = 1; + qla1280_dump_buffer((caddr_t)ha->response_ring, REQUEST_ENTRY_SIZE); + ql_debug_print = 0; */ +#endif + wptr = (uint16_t *)ha->response_ring; + for (cnt = 0; cnt < sizeof(nvram_t)/2; cnt++) + *wptr++ = 0; +#endif + + + /* nv->cntr_flags_1.disable_loading_risc_code = 1; */ + nv->firmware_feature.w = BIT_0; + nv->termination.f.scsi_bus_0_control = 3; + nv->termination.f.scsi_bus_1_control = 3; + nv->termination.f.auto_term_support = 1; + + for (b = 0; b < MAX_BUSES; b++) + { + nv->bus[b].config_1.initiator_id = 7; + nv->bus[b].bus_reset_delay = 5; + nv->bus[b].config_2.async_data_setup_time = 9; + nv->bus[b].config_2.req_ack_active_negation = 1; + nv->bus[b].config_2.data_line_active_negation = 1; + nv->bus[b].selection_timeout = 250; + nv->bus[b].max_queue_depth = 256; + + for (t = 0; t < MAX_TARGETS; t++) + { + nv->bus[b].target[t].parameter.f.auto_request_sense = 1; + nv->bus[b].target[t].parameter.f.disconnect_allowed = 1; + nv->bus[b].target[t].parameter.f.tag_queuing = 1; + nv->bus[b].target[t].flags.device_enable = 1; + } + } + +#if USE_NVRAM_DEFAULTS + status = 0; +#else + status = 1; +#endif + } + else + { + /* Always force AUTO sense for LINUX SCSI */ + for (b = 0; b < MAX_BUSES; b++) + for (t = 0; t < MAX_TARGETS; t++) + { + nv->bus[b].target[t].parameter.f.auto_request_sense = 1; + } + } +#if DEBUG_PRINT_NVRAM + ql_debug_print = 1; + sprintf(debug_buff,"qla1280 : initiator scsi id bus[0]=%d\n\r", + nv->bus[0].config_1.initiator_id); + qla1280_print(debug_buff); + sprintf(debug_buff,"qla1280 : initiator scsi id bus[1]=%d\n\r", + nv->bus[1].config_1.initiator_id); + qla1280_print(debug_buff); + + sprintf(debug_buff,"qla1280 : bus reset delay[0]=%d\n\r", + nv->bus[0].bus_reset_delay); + qla1280_print(debug_buff); + sprintf(debug_buff,"qla1280 : bus reset delay[1]=%d\n\r", + nv->bus[1].bus_reset_delay); + qla1280_print(debug_buff); + + sprintf(debug_buff,"qla1280 : retry count[0]=%d\n\r", + nv->bus[0].retry_count); + qla1280_print(debug_buff); + sprintf(debug_buff,"qla1280 : retry delay[0]=%d\n\r", + nv->bus[0].retry_delay); + qla1280_print(debug_buff); + sprintf(debug_buff,"qla1280 : retry count[1]=%d\n\r", + nv->bus[1].retry_count); + qla1280_print(debug_buff); + sprintf(debug_buff,"qla1280 : retry delay[1]=%d\n\r", + nv->bus[1].retry_delay); + qla1280_print(debug_buff); + + sprintf(debug_buff,"qla1280 : async data setup time[0]=%d\n\r", + nv->bus[0].config_2.async_data_setup_time); + qla1280_print(debug_buff); + sprintf(debug_buff,"qla1280 : async data setup time[1]=%d\n\r", + nv->bus[1].config_2.async_data_setup_time); + qla1280_print(debug_buff); + + sprintf(debug_buff,"qla1280 : req/ack active negation[0]=%d\n\r", + nv->bus[0].config_2.req_ack_active_negation); + qla1280_print(debug_buff); + sprintf(debug_buff,"qla1280 : req/ack active negation[1]=%d\n\r", + nv->bus[1].config_2.req_ack_active_negation); + qla1280_print(debug_buff); + + sprintf(debug_buff,"qla1280 : data line active negation[0]=%d\n\r", + nv->bus[0].config_2.data_line_active_negation); + qla1280_print(debug_buff); + sprintf(debug_buff,"qla1280 : data line active negation[1]=%d\n\r", + nv->bus[1].config_2.data_line_active_negation); + qla1280_print(debug_buff); + + + sprintf(debug_buff,"qla1280 : disable loading risc code=%d\n\r", + nv->cntr_flags_1.disable_loading_risc_code); + qla1280_print(debug_buff); + + sprintf(debug_buff,"qla1280 : enable 64bit addressing=%d\n\r", + nv->cntr_flags_1.enable_64bit_addressing); + qla1280_print(debug_buff); + + sprintf(debug_buff,"qla1280 : selection timeout limit[0]=%d\n\r", + nv->bus[0].selection_timeout); + qla1280_print(debug_buff); + sprintf(debug_buff,"qla1280 : selection timeout limit[1]=%d\n\r", + nv->bus[1].selection_timeout); + + qla1280_print(debug_buff); + sprintf(debug_buff,"qla1280 : max queue depth[0]=%d\n\r", + nv->bus[0].max_queue_depth); + qla1280_print(debug_buff); + sprintf(debug_buff,"qla1280 : max queue depth[1]=%d\n\r", + nv->bus[1].max_queue_depth); + qla1280_print(debug_buff); +#endif + + DEBUG(ql_debug_print = 0;) + + /* Disable RISC load of firmware. */ + ha->flags.disable_risc_code_load = + nv->cntr_flags_1.disable_loading_risc_code; + /* Enable 64bit addressing. */ + ha->flags.enable_64bit_addressing = + nv->cntr_flags_1.enable_64bit_addressing; + + /* Set ISP hardware DMA burst */ + mb[0] = nv->isp_config.c; + WRT_REG_WORD(®->cfg_1, mb[0]); + + /* Set SCSI termination. */ + WRT_REG_WORD(®->gpio_enable, (BIT_3 + BIT_2 + BIT_1 + BIT_0)); + mb[0] = nv->termination.c & (BIT_3 + BIT_2 + BIT_1 + BIT_0); + WRT_REG_WORD(®->gpio_data, mb[0]); + + /* ISP parameter word. */ + mb[0] = MBC_SET_SYSTEM_PARAMETER; + mb[1] = nv->isp_parameter; + status |= qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]); + + /* Firmware feature word. */ + mb[0] = MBC_SET_FIRMWARE_FEATURES; + mb[1] = nv->firmware_feature.w & (BIT_1|BIT_0); + status |= qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]); + + /* Retry count and delay. */ + mb[0] = MBC_SET_RETRY_COUNT; + mb[1] = nv->bus[0].retry_count; + mb[2] = nv->bus[0].retry_delay; + mb[6] = nv->bus[1].retry_count; + mb[7] = nv->bus[1].retry_delay; + status |= qla1280_mailbox_command(ha, BIT_7|BIT_6|BIT_2|BIT_1|BIT_0, &mb[0]); + + /* ASYNC data setup time. */ + mb[0] = MBC_SET_ASYNC_DATA_SETUP; + mb[1] = nv->bus[0].config_2.async_data_setup_time; + mb[2] = nv->bus[1].config_2.async_data_setup_time; + status |= qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0, &mb[0]); + + /* Active negation states. */ + mb[0] = MBC_SET_ACTIVE_NEGATION; + mb[1] = 0; + if (nv->bus[0].config_2.req_ack_active_negation) + mb[1] |= BIT_5; + if (nv->bus[0].config_2.data_line_active_negation) + mb[1] |= BIT_4; + mb[2] = 0; + if (nv->bus[1].config_2.req_ack_active_negation) + mb[2] |= BIT_5; + if (nv->bus[1].config_2.data_line_active_negation) + mb[2] |= BIT_4; + status |= qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0, &mb[0]); + + /* Selection timeout. */ + mb[0] = MBC_SET_SELECTION_TIMEOUT; + mb[1] = nv->bus[0].selection_timeout; + mb[2] = nv->bus[1].selection_timeout; + status |= qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0, &mb[0]); + + for (b = 0; b < ha->ports; b++) + { + /* SCSI Reset Disable. */ + ha->bus_settings[b].disable_scsi_reset = nv->bus[b].config_1.scsi_reset_disable; + + /* Initiator ID. */ + ha->bus_settings[b].id = nv->bus[b].config_1.initiator_id; + mb[0] = MBC_SET_INITIATOR_ID; + mb[1] = b ? ha->bus_settings[b].id | BIT_7 : ha->bus_settings[b].id; + status |= qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]); + + /* Reset Delay. */ + ha->bus_settings[b].bus_reset_delay = nv->bus[b].bus_reset_delay; + + /* Command queue depth per device. */ + ha->bus_settings[b].hiwat = nv->bus[b].max_queue_depth - 1; + + /* Set target parameters. */ + for (t = 0; t < MAX_TARGETS; t++) + { + /* Set Target Parameters. */ + mb[0] = MBC_SET_TARGET_PARAMETERS; + mb[1] = (uint16_t)(b ? t | BIT_7 :t); + mb[1] <<= 8; + mb[2] = nv->bus[b].target[t].parameter.c << 8; + mb[2] |= TP_AUTO_REQUEST_SENSE; + mb[2] &= ~TP_STOP_QUEUE; + mb[3] = nv->bus[b].target[t].flags.sync_offset << 8; + mb[3] |= nv->bus[b].target[t].sync_period; + status |= qla1280_mailbox_command(ha, BIT_3|BIT_2|BIT_1|BIT_0, + &mb[0]); + + /* Save Tag queuing enable flag. */ + mb[0] = BIT_0 << t; + if (nv->bus[b].target[t].parameter.f.tag_queuing) + ha->bus_settings[b].qtag_enables |= mb[0]; + + /* Save Device enable flag. */ + if (nv->bus[b].target[t].flags.device_enable) + ha->bus_settings[b].device_enables |= mb[0]; + + /* Save LUN disable flag. */ + if (nv->bus[b].target[t].flags.lun_disable) + ha->bus_settings[b].lun_disables |= mb[0]; + + /* Set Device Queue Parameters. */ + for (l = 0; l < MAX_LUNS; l++) + { + mb[0] = MBC_SET_DEVICE_QUEUE; + mb[1] = (uint16_t)(b ? t | BIT_7 :t); + mb[1] = mb[1] << 8 | l; + mb[2] = nv->bus[b].max_queue_depth; + mb[3] = nv->bus[b].target[t].execution_throttle; + status |= qla1280_mailbox_command(ha, BIT_3|BIT_2|BIT_1|BIT_0, + &mb[0]); + } + } + } + DEBUG(ql_debug_print = 0;) + +#if defined(QL_DEBUG_ROUTINES) && !defined(QL_DEBUG_LEVEL_4) + ql_debug_print = saved_print_status; +#endif + +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + DEBUG(if (status)) + DEBUG(qla1280_print("qla1280_nvram_config: **** FAILED ****\n\r");) +#endif + LEAVE("qla1280_nvram_config"); + return(status); +} + +/* + * Get NVRAM data word + * Calculates word position in NVRAM and calls request routine to + * get the word from NVRAM. + * + * Input: + * ha = adapter block pointer. + * address = NVRAM word address. + * + * Returns: + * data word. + */ +STATIC uint16_t +qla1280_get_nvram_word(scsi_qla_host_t *ha, uint32_t address) +{ + uint32_t nv_cmd; + uint16_t data; + +#ifdef QL_DEBUG_ROUTINES + uint8_t saved_print_status = ql_debug_print; +#endif +#ifdef QL_DEBUG_LEVEL_4 + ENTER("qla1280_get_nvram_word"); +#endif + + nv_cmd = address << 16; + nv_cmd |= NV_READ_OP; + +#ifdef QL_DEBUG_ROUTINES + ql_debug_print = FALSE; +#endif + data = qla1280_nvram_request(ha, nv_cmd); +#ifdef QL_DEBUG_ROUTINES + ql_debug_print = saved_print_status; +#endif + +#ifdef QL_DEBUG_LEVEL_4 + qla1280_print("qla1280_get_nvram_word: exiting normally NVRAM data = "); + qla1280_output_number((uint32_t)data, 16); + qla1280_print("\n\r"); +#endif + return(data); +} + +/* + * NVRAM request + * Sends read command to NVRAM and gets data from NVRAM. + * + * Input: + * ha = adapter block pointer. + * nv_cmd = Bit 26 = start bit + * Bit 25, 24 = opcode + * Bit 23-16 = address + * Bit 15-0 = write data + * + * Returns: + * data word. + */ +STATIC uint16_t +qla1280_nvram_request(scsi_qla_host_t *ha, uint32_t nv_cmd) +{ + uint8_t cnt; + device_reg_t *reg = ha->iobase; + uint16_t data = 0; + uint16_t reg_data; + + /* Send command to NVRAM. */ + + nv_cmd <<= 5; + for (cnt = 0; cnt < 11; cnt++) + { + if (nv_cmd & BIT_31) + qla1280_nv_write(ha, NV_DATA_OUT); + else + qla1280_nv_write(ha, 0); + nv_cmd <<= 1; + } + + /* Read data from NVRAM. */ + + for (cnt = 0; cnt < 16; cnt++) + { + WRT_REG_WORD(®->nvram, NV_SELECT+NV_CLOCK); + /* qla1280_nv_delay(ha); */ + NVRAM_DELAY(); + data <<= 1; + reg_data = RD_REG_WORD(®->nvram); + if (reg_data & NV_DATA_IN) + data |= BIT_0; + WRT_REG_WORD(®->nvram, NV_SELECT); + /* qla1280_nv_delay(ha); */ + NVRAM_DELAY(); + } + + /* Deselect chip. */ + + WRT_REG_WORD(®->nvram, NV_DESELECT); + /* qla1280_nv_delay(ha); */ + NVRAM_DELAY(); + + return(data); +} + +STATIC void +qla1280_nv_write(scsi_qla_host_t *ha, uint16_t data) +{ + device_reg_t *reg = ha->iobase; + + WRT_REG_WORD(®->nvram, data | NV_SELECT); + NVRAM_DELAY(); + /* qla1280_nv_delay(ha); */ + WRT_REG_WORD(®->nvram, data | NV_SELECT | NV_CLOCK); + /* qla1280_nv_delay(ha); */ + NVRAM_DELAY(); + WRT_REG_WORD(®->nvram, data | NV_SELECT); + /* qla1280_nv_delay(ha); */ + NVRAM_DELAY(); +} + +STATIC void +qla1280_nv_delay(scsi_qla_host_t *ha) +{ + device_reg_t *reg = ha->iobase; + int cnt = NV_DELAY_COUNT; + uint16_t data = 0; + + while (cnt--) + data |= RD_REG_WORD(®->nvram); +} + +/* + * Mailbox Command + * Issue mailbox command and waits for completion. + * + * Input: + * ha = adapter block pointer. + * mr = mailbox registers to load. + * mb = data pointer for mailbox registers. + * + * Output: + * mb[MAILBOX_REGISTER_COUNT] = returned mailbox data. + * + * Returns: + * 0 = success + */ +STATIC uint8_t +qla1280_mailbox_command(scsi_qla_host_t *ha, uint8_t mr, uint16_t *mb) +{ + device_reg_t *reg = ha->iobase; + uint8_t status = 0; + uint32_t cnt; + uint16_t *optr, *iptr; + uint16_t data; + srb_t *done_q_first = 0; + srb_t *done_q_last = 0; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) + unsigned long cpu_flags = 0; +#endif + +#ifdef QL_DEBUG_LEVEL_3 + ENTER("qla1280_mailbox_command"); +#endif + + /* Acquire interrupt specific lock */ + QLA1280_INTR_LOCK(ha); + DRIVER_LOCK + ha->flags.mbox_busy = TRUE; + + /* Load mailbox registers. */ + optr = (uint16_t *)®->mailbox0; + iptr = mb; + for (cnt = 0; cnt < MAILBOX_REGISTER_COUNT; cnt++) + { + if (mr & BIT_0) + { + WRT_REG_WORD(optr, (*iptr)); + } + + mr >>= 1; + optr++; + iptr++; + } + /* Issue set host interrupt command. */ + ha->flags.mbox_int = FALSE; + WRT_REG_WORD(®->host_cmd, HC_SET_HOST_INT); + data = qla1280_debounce_register(®->istatus); + + /* Wait for 30 seconds for command to finish. */ + for (cnt = 30000000; cnt > 0 && !ha->flags.mbox_int; cnt--) + { + /* Check for pending interrupts. */ + if (data & RISC_INT) + { + qla1280_isr(ha, (srb_t **)&done_q_first, (srb_t **)&done_q_last); + } + SYS_DELAY(1); + data = RD_REG_WORD(®->istatus); + } + + /* Check for mailbox command timeout. */ + if ( !cnt ) + { +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print( + "qla1280_mailbox_command: **** Command Timeout, mailbox0 = "); + qla1280_output_number((uint32_t)mb[0], 16); + qla1280_print(" ****\n\r"); +#endif + ha->flags.isp_abort_needed = TRUE; + status = 1; + } + else if (ha->mailbox_out[0] != MBS_CMD_CMP) + status = 1; + + /* Load return mailbox registers. */ + optr = mb; + iptr = (uint16_t *)&ha->mailbox_out[0]; + mr = MAILBOX_REGISTER_COUNT; + while (mr--) + *optr++ = *iptr++; + + /* Go check for any response interrupts pending. */ + ha->flags.mbox_busy = FALSE; + qla1280_isr(ha, (srb_t **)&done_q_first, (srb_t **)&done_q_last); + + /* Release interrupt specific lock */ + QLA1280_INTR_UNLOCK(ha); + DRIVER_UNLOCK + + if (ha->flags.isp_abort_needed) + qla1280_abort_isp(ha); + + if (ha->flags.reset_marker) + qla1280_rst_aen(ha); + + if (done_q_first) + qla1280_done(ha, (srb_t **)&done_q_first, (srb_t **)&done_q_last); + +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + if (status) + { + qla1280_print("qla1280_mailbox_command: **** FAILED, mailbox0 = "); + qla1280_output_number((uint32_t)mb[0], 16); + qla1280_print(" ****\n\r"); + } +#endif +#ifdef QL_DEBUG_LEVEL_3 + else + LEAVE("qla1280_mailbox_command"); +#endif + return(status); +} + +/* + * qla1280_poll + * Polls ISP for interrupts. + * + * Input: + * ha = adapter block pointer. + */ +STATIC void +qla1280_poll(scsi_qla_host_t *ha) +{ + device_reg_t *reg = ha->iobase; + uint16_t data; + srb_t *done_q_first = 0; + srb_t *done_q_last = 0; + +#ifdef QL_DEBUG_LEVEL_3 + /* ENTER("qla1280_poll"); */ +#endif + + /* Acquire interrupt specific lock */ + QLA1280_INTR_LOCK(ha); + + /* Check for pending interrupts. */ + data = RD_REG_WORD(®->istatus); + if (data & RISC_INT) + qla1280_isr(ha, (srb_t **)&done_q_first, (srb_t **)&done_q_last); + + /* Release interrupt specific lock */ + QLA1280_INTR_UNLOCK(ha); + + if (!ha->flags.mbox_busy) + { + if (ha->flags.isp_abort_needed) + qla1280_abort_isp(ha); + if (ha->flags.reset_marker) + qla1280_rst_aen(ha); + } + + if (done_q_first) + qla1280_done(ha, (srb_t **)&done_q_first, (srb_t **)&done_q_last); + +#ifdef QL_DEBUG_LEVEL_3 + /* LEAVE("qla1280_poll"); */ +#endif +} + +/* + * qla1280_bus_reset + * Issue SCSI bus reset. + * + * Input: + * ha = adapter block pointer. + * b = SCSI bus number. + * + * Returns: + * 0 = success + */ +STATIC uint8_t +qla1280_bus_reset(scsi_qla_host_t *ha, uint8_t b) +{ + uint8_t status; + uint16_t mb[MAILBOX_REGISTER_COUNT]; + +#ifdef QL_DEBUG_LEVEL_3 + qla1280_print("qla1280_bus_reset: entered\n\r"); +#endif + if( qla1280_verbose ) + { + printk("scsi(%d): Resetting SCSI BUS (%d)\n",(int)ha->host_no,b); + } + + mb[0] = MBC_BUS_RESET; + mb[1] = ha->bus_settings[b].bus_reset_delay; + mb[2] = (uint16_t)b; + status = qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0, &mb[0]); + + if (status) + { + if (ha->bus_settings[b].failed_reset_count > 2) /* dg - 03/13/99 */ + ha->bus_settings[b].scsi_bus_dead = TRUE; + ha->bus_settings[b].failed_reset_count++; + } + else + { + QLA1280_DELAY(4); + ha->bus_settings[b].scsi_bus_dead = FALSE; /* dg - 03/13/99 */ + ha->bus_settings[b].failed_reset_count = 0; + /* Issue marker command. */ + qla1280_marker(ha, b, 0, 0, MK_SYNC_ALL); + } +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + if (status) + qla1280_print("qla1280_bus_reset: **** FAILED ****\n\r"); +#endif +#ifdef QL_DEBUG_LEVEL_3 + else + qla1280_print("qla1280_bus_reset: exiting normally\n\r"); +#endif + return(status); +} + +/* + * qla1280_device_reset + * Issue bus device reset message to the target. + * + * Input: + * ha = adapter block pointer. + * b = SCSI BUS number. + * t = SCSI ID. + * + * Returns: + * 0 = success + */ +STATIC uint8_t +qla1280_device_reset(scsi_qla_host_t *ha, uint8_t b, uint32_t t) +{ + uint8_t status; + uint16_t mb[MAILBOX_REGISTER_COUNT]; + +#ifdef QL_DEBUG_LEVEL_3 + ENTER("qla1280_device_reset"); +#endif + + mb[0] = MBC_ABORT_TARGET; + mb[1] = (b ? (t | BIT_7) : t) << 8; + mb[2] = 1; + status = qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0, &mb[0]); + + /* Issue marker command. */ + qla1280_marker(ha, b, t, 0, MK_SYNC_ID); + +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + if (status) + qla1280_print("qla1280_device_reset: **** FAILED ****\n\r"); +#endif +#ifdef QL_DEBUG_LEVEL_3 + else + LEAVE("qla1280_device_reset"); +#endif + return(status); +} + +/* + * qla1280_abort_device + * Issue an abort message to the device + * + * Input: + * ha = adapter block pointer. + * b = SCSI BUS. + * t = SCSI ID. + * l = SCSI LUN. + * + * Returns: + * 0 = success + */ +STATIC uint8_t +qla1280_abort_device(scsi_qla_host_t *ha, uint8_t b, uint32_t t, uint32_t l) +{ + uint8_t status; + uint16_t mb[MAILBOX_REGISTER_COUNT]; + +#ifdef QL_DEBUG_LEVEL_3 + ENTER("qla1280_abort_device"); +#endif + + mb[0] = MBC_ABORT_DEVICE; + mb[1] = (b ? t | BIT_7 : t) << 8 | l; + status = qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]); + + /* Issue marker command. */ + qla1280_marker(ha, b, t, l, MK_SYNC_ID_LUN); + +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + if (status) + qla1280_print("qla1280_abort_device: **** FAILED ****\n\r"); +#endif +#ifdef QL_DEBUG_LEVEL_3 + else + LEAVE("qla1280_abort_device"); +#endif + return(status); +} + +/* + * qla1280_abort_command + * Abort command aborts a specified IOCB. + * + * Input: + * ha = adapter block pointer. + * sp = SB structure pointer. + * + * Returns: + * 0 = success + */ +STATIC uint8_t +qla1280_abort_command(scsi_qla_host_t *ha, srb_t *sp) +{ + uint8_t status; + uint16_t mb[MAILBOX_REGISTER_COUNT]; + uint32_t b, t, l; + uint32_t handle; + +#ifdef QL_DEBUG_LEVEL_3 + ENTER("qla1280_abort_command"); +#endif + + /* Locate handle number. */ + for (handle = 0; handle < MAX_OUTSTANDING_COMMANDS; handle++) + if (ha->outstanding_cmds[handle] == sp) + break; + + b = SCSI_BUS_32(sp->cmd); + t = SCSI_TCN_32(sp->cmd); + l = SCSI_LUN_32(sp->cmd); + + mb[0] = MBC_ABORT_COMMAND; + mb[1] = (b ? t | BIT_7 : t) << 8 | l; + mb[2] = handle >> 16; + mb[3] = (uint16_t)handle; + status = qla1280_mailbox_command(ha, BIT_3|BIT_2|BIT_1|BIT_0, &mb[0]); + +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + if (status) + qla1280_print("qla1280_abort_command: **** FAILED ****\n\r"); +#endif + sp->flags |= SRB_ABORT_PENDING; + + LEAVE("qla1280_abort_command"); + return(status); +} + +/* + * qla1280_reset_adapter + * Reset adapter. + * + * Input: + * ha = adapter block pointer. + */ +STATIC void +qla1280_reset_adapter(scsi_qla_host_t *ha) +{ + device_reg_t *reg = ha->iobase; + +#ifdef QL_DEBUG_LEVEL_3 + ENTER("qla1280_reset_adapter"); +#endif + + /* Disable ISP chip */ + ha->flags.online = FALSE; + WRT_REG_WORD(®->ictrl, ISP_RESET); + WRT_REG_WORD(®->host_cmd, HC_RESET_RISC); + WRT_REG_WORD(®->host_cmd, HC_RELEASE_RISC); + WRT_REG_WORD(®->host_cmd, HC_DISABLE_BIOS); + +#ifdef QL_DEBUG_LEVEL_3 + LEAVE("qla1280_reset_adapter"); +#endif +} + +/* + * Issue marker command. + * Function issues marker IOCB. + * + * Input: + * ha = adapter block pointer. + * b = SCSI BUS number + * t = SCSI ID + * l = SCSI LUN + * type = marker modifier + */ +STATIC void +qla1280_marker(scsi_qla_host_t *ha, uint8_t b, uint32_t t, uint32_t l, uint8_t type) +{ + mrk_entry_t *pkt; + +#ifdef QL_DEBUG_LEVEL_3 + ENTER("qla1280_marker"); +#endif + + /* Get request packet. */ + if ( (pkt = (mrk_entry_t *)qla1280_req_pkt(ha)) ) + { + pkt->entry_type = MARKER_TYPE; + pkt->lun = (uint8_t)l; + pkt->target = (uint8_t)(b ? (t | BIT_7) : t); + pkt->modifier = type; + + /* Issue command to ISP */ + qla1280_isp_cmd(ha); + } + +#ifdef QL_DEBUG_LEVEL_3 + LEAVE("qla1280_marker"); +#endif +} + +#if QLA1280_64BIT_SUPPORT +/* + * qla1280_64bit_start_scsi + * The start SCSI is responsible for building request packets on + * request ring and modifying ISP input pointer. + * + * Input: + * ha = adapter block pointer. + * sp = SB structure pointer. + * + * Returns: + * 0 = success, was able to issue command. + */ +STATIC uint8_t +qla1280_64bit_start_scsi(scsi_qla_host_t *ha, srb_t *sp) +{ + device_reg_t *reg = ha->iobase; + uint8_t status = 0; + Scsi_Cmnd *cmd = sp->cmd; + uint32_t cnt; + cmd_entry_t *pkt; + uint16_t req_cnt; + uint16_t seg_cnt; + struct scatterlist *sg = (struct scatterlist *) NULL; + paddr32_t *addr32p; + caddr_t data_ptr; + uint32_t *dword_ptr; + uint32_t timeout; + +#ifdef QL_DEBUG_LEVEL_3 + ENTER("qla1280_64bit_start_scsi:"); +#endif + + if( qla1280_check_for_dead_scsi_bus(ha, sp) ) + { + return(0); + } + + /* Calculate number of entries and segments required. */ + seg_cnt = 0; + req_cnt = 1; + if (cmd->use_sg) + { + seg_cnt = cmd->use_sg; + sg = (struct scatterlist *) cmd->request_buffer; + + if (seg_cnt > 2) + { + req_cnt += (uint16_t)(seg_cnt - 2) / 5; + if ((uint16_t)(seg_cnt - 2) % 5) + req_cnt++; + } + } + else if (cmd->request_bufflen) /* If data transfer. */ + { + DEBUG(printk("Single data transfer (0x%x)\n",cmd->request_bufflen)); + seg_cnt = 1; + } + + /* Acquire ring specific lock */ + QLA1280_RING_LOCK(ha); + + if ((uint16_t)(req_cnt + 2) >= ha->req_q_cnt) + { + /* Calculate number of free request entries. */ + cnt = RD_REG_WORD(®->mailbox4); + if (ha->req_ring_index < cnt) + ha->req_q_cnt = cnt - ha->req_ring_index; + else + ha->req_q_cnt = REQUEST_ENTRY_CNT - (ha->req_ring_index - cnt); + } + + /* If room for request in request ring. */ + if ((uint16_t)(req_cnt + 2) < ha->req_q_cnt) + { + /* Check for room in outstanding command list. */ + for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS && + ha->outstanding_cmds[cnt] != 0; cnt++) + ; + + if (cnt < MAX_OUTSTANDING_COMMANDS) + { + ha->outstanding_cmds[cnt] = sp; + ha->req_q_cnt -= req_cnt; + CMD_HANDLE(sp->cmd) = (unsigned char *) cnt; + + /* + * Build command packet. + */ + pkt = ha->request_ring_ptr; + + pkt->entry_type = COMMAND_A64_TYPE; + pkt->entry_count = (uint8_t)req_cnt; + pkt->sys_define = (uint8_t)ha->req_ring_index; + pkt->handle = (uint32_t)cnt; + + /* Zero out remaining portion of packet. */ + dword_ptr = (uint32_t *)pkt + 2; + for (cnt = 2; cnt < REQUEST_ENTRY_SIZE/4; cnt++) + *dword_ptr++ = 0; + + /* Set ISP command timeout. */ + pkt->timeout = (uint16_t)30; + + /* Set device target ID and LUN */ + pkt->lun = SCSI_LUN_32(cmd); + pkt->target = SCSI_BUS_32(cmd) ? + (SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd); + + /* Enable simple tag queuing if device supports it. */ + if (cmd->device->tagged_queue ) + pkt->control_flags |= BIT_3; + + /* Load SCSI command packet. */ + pkt->cdb_len = (uint16_t)CMD_CDBLEN(cmd); + data_ptr = (uint8_t *) &(CMD_CDBP(cmd)); + for (cnt = 0; cnt < pkt->cdb_len; cnt++) + pkt->scsi_cdb[cnt] = *data_ptr++; + + /* + * Load data segments. + */ + if (seg_cnt) /* If data transfer. */ + { + /* Set transfer direction. */ + if ( (cmd->data_cmnd[0] == WRITE_6) ) + pkt->control_flags |= BIT_6; + else + pkt->control_flags |= (BIT_5|BIT_6); + + sp->dir = pkt->control_flags & (BIT_5|BIT_6); + + /* Set total data segment count. */ + pkt->dseg_count = seg_cnt; + + /* Setup packet address segment pointer. */ + dword_ptr = (uint32_t *)&pkt->dseg_0_address; + + if (cmd->use_sg) /* If scatter gather */ + { + /* Load command entry data segments. */ + for (cnt = 0; cnt < 2 && seg_cnt; cnt++, seg_cnt--) + { + *dword_ptr++ = (uint32_t) cpu_to_le32(VIRT_TO_BUS_LOW(sg->address)); + *dword_ptr++ = (uint32_t) cpu_to_le32(VIRT_TO_BUS_HIGH(sg->address)); + *dword_ptr++ = sg->length; + sg++; + } +#ifdef QL_DEBUG_LEVEL_5 + qla1280_print( + "qla1280_64bit_start_scsi: Scatter/gather command packet data - "); + qla1280_print("b"); + qla1280_output_number((uint32_t)SCSI_BUS_32(cmd), 10); + qla1280_print("t"); + qla1280_output_number((uint32_t)SCSI_TCN_32(cmd), 10); + qla1280_print("d"); + qla1280_output_number((uint32_t)SCSI_LUN_32(cmd), 10); + qla1280_print("\n\r"); + qla1280_dump_buffer((caddr_t)pkt, REQUEST_ENTRY_SIZE); +#endif + /* + * Build continuation packets. + */ + while (seg_cnt > 0) + { + /* Adjust ring index. */ + ha->req_ring_index++; + if (ha->req_ring_index == REQUEST_ENTRY_CNT) + { + ha->req_ring_index = 0; + ha->request_ring_ptr = ha->request_ring; + } + else + ha->request_ring_ptr++; + + pkt = ha->request_ring_ptr; + + /* Zero out packet. */ + dword_ptr = (uint32_t *)pkt; + for (cnt = 0;cnt < REQUEST_ENTRY_SIZE/4; cnt++) + *dword_ptr++ = 0; + + /* Load packet defaults. */ + ((cont_a64_entry_t *)pkt)->entry_type = + CONTINUE_A64_TYPE; + ((cont_a64_entry_t *)pkt)->entry_count = 1; + ((cont_a64_entry_t *)pkt)->sys_define = (uint8_t) + ha->req_ring_index; + + /* Setup packet address segment pointer. */ + dword_ptr = (uint32_t *) + &((cont_a64_entry_t *)pkt)->dseg_0_address; + + /* Load continuation entry data segments. */ + for (cnt = 0; cnt < 5 && seg_cnt; cnt++, seg_cnt--) + { + *dword_ptr++ = (uint32_t) cpu_to_le32(VIRT_TO_BUS_LOW(sg->address)); + *dword_ptr++ = (uint32_t) cpu_to_le32(VIRT_TO_BUS_HIGH(sg->address)); + *dword_ptr++ = sg->length; + sg++; + } +#ifdef QL_DEBUG_LEVEL_5 + qla1280_print( + "qla1280_64bit_start_scsi: continuation packet data - c"); + qla1280_print("b"); + qla1280_output_number((uint32_t)SCSI_BUS_32(cmd), 10); + + qla1280_print("t"); + qla1280_output_number((uint32_t)SCSI_TCN_32(cmd), 10); + qla1280_print("d"); + qla1280_output_number((uint32_t)SCSI_LUN_32(cmd), 10); + qla1280_print("\n\r"); + qla1280_dump_buffer((caddr_t)pkt, REQUEST_ENTRY_SIZE); +#endif + } + } + else /* No scatter gather data transfer */ + { + *dword_ptr++ = (uint32_t) cpu_to_le32(VIRT_TO_BUS_LOW(cmd->request_buffer)); + *dword_ptr++ = (uint32_t) cpu_to_le32(VIRT_TO_BUS_HIGH(cmd->request_buffer)); + *dword_ptr = (uint32_t) cmd->request_bufflen; +#ifdef QL_DEBUG_LEVEL_5 + qla1280_print( + "qla1280_64bit_start_scsi: No scatter/gather command packet data - c"); + qla1280_print("b"); + qla1280_output_number((uint32_t)SCSI_BUS_32(cmd), 10); + qla1280_print("t"); + qla1280_output_number((uint32_t)SCSI_TCN_32(cmd), 10); + qla1280_print("d"); + qla1280_output_number((uint32_t)SCSI_LUN_32(cmd), 10); + qla1280_print("\n\r"); + qla1280_dump_buffer((caddr_t)pkt, REQUEST_ENTRY_SIZE); +#endif + } + } +#ifdef QL_DEBUG_LEVEL_5 + else /* No data transfer */ + { + *dword_ptr++ = (uint32_t) 0; + *dword_ptr++ = (uint32_t) 0; + *dword_ptr = (uint32_t) 0; + qla1280_print( + "qla1280_64bit_start_scsi: No data, command packet data - c"); + qla1280_print("b"); + qla1280_output_number((uint32_t)SDI_BUS_32(cmd), 10); + qla1280_print("t"); + qla1280_output_number((uint32_t)SDI_TCN_32(cmd), 10); + qla1280_print("d"); + qla1280_output_number((uint32_t)SDI_LUN_32(cmd), 10); + qla1280_print("\n\r"); + qla1280_dump_buffer((caddr_t)pkt, REQUEST_ENTRY_SIZE); + } +#endif + /* Adjust ring index. */ + ha->req_ring_index++; + if (ha->req_ring_index == REQUEST_ENTRY_CNT) + { + ha->req_ring_index = 0; + ha->request_ring_ptr = ha->request_ring; + } + else + ha->request_ring_ptr++; + + /* Set chip new ring index. */ + WRT_REG_WORD(®->mailbox4, ha->req_ring_index); + } + else + { + status = 1; +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print( + "qla1280_64bit_start_scsi: NO ROOM IN OUTSTANDING ARRAY\n\r"); + qla1280_print(" req_q_cnt="); + qla1280_output_number((uint32_t)ha->req_q_cnt, 16); +#endif + } + } + else + { + status = 1; +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print("qla1280_64bit_start_scsi: in-ptr="); + qla1280_output_number((uint32_t)ha->req_ring_index, 16); + qla1280_print(" req_q_cnt="); + qla1280_output_number((uint32_t)ha->req_q_cnt, 16); + qla1280_print(" req_cnt="); + qla1280_output_number((uint32_t)req_cnt, 16); + qla1280_print("\n\r"); +#endif + } + + /* Release ring specific lock */ + QLA1280_RING_UNLOCK(ha); + +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + if (status) + qla1280_print("qla1280_64bit_start_scsi: **** FAILED ****\n\r"); +#endif +#ifdef QL_DEBUG_LEVEL_3 + else + qla1280_print("qla1280_64bit_start_scsi: exiting normally\n\r"); +#endif + return(status); +} +#endif /* QLA1280_64BIT_SUPPORT */ + +/* + * qla1280_32bit_start_scsi + * The start SCSI is responsible for building request packets on + * request ring and modifying ISP input pointer. + * + * The Qlogic firmware interface allows every queue slot to have a SCSI + * command and up to 4 scatter/gather (SG) entries. If we need more + * than 4 SG entries, then continuation entries are used that can + * hold another 7 entries each. The start routine determines if there + * is eought empty slots then build the combination of requests to + * fulfill the OS request. + * + * Input: + * ha = adapter block pointer. + * sp = SCSI Request Block structure pointer. + * + * Returns: + * 0 = success, was able to issue command. + */ +STATIC uint8_t +qla1280_32bit_start_scsi(scsi_qla_host_t *ha, srb_t *sp) +{ + device_reg_t *reg = ha->iobase; + uint8_t status = 0; + Scsi_Cmnd *cmd = sp->cmd; + uint32_t cnt; + cmd_entry_t *pkt; + uint16_t req_cnt; + uint16_t seg_cnt; + struct scatterlist *sg = (struct scatterlist *) NULL; + uint8_t *data_ptr; + uint32_t *dword_ptr; + + ENTER("qla1280_32bit_start_scsi"); + + + if( qla1280_check_for_dead_scsi_bus(ha, sp) ) + { + return(0); + } + + /* Calculate number of entries and segments required. */ + req_cnt = 1; + if (cmd->use_sg) + { + /* + * We must build an SG list in adapter format, as the kernel's SG list + * cannot be used directly because of data field size (__alpha__) + * differences and the kernel SG list uses virtual addresses where + * we need physical addresses. + */ + seg_cnt = cmd->use_sg; + sg = (struct scatterlist *) cmd->request_buffer; + /* + * if greater than four sg entries then we need to allocate + * continuation entries + */ + if (seg_cnt > 4) + { + req_cnt += (uint16_t)(seg_cnt - 4) / 7; + if ((uint16_t)(seg_cnt - 4) % 7) + req_cnt++; + } + DEBUG(sprintf(debug_buff,"S/G for data transfer -num segs(%d), req blk cnt(%d)\n\r",seg_cnt,req_cnt)); + DEBUG(qla1280_print(debug_buff)); + } + else if (cmd->request_bufflen) /* If data transfer. */ + { + DEBUG(printk("Single data transfer (0x%x)\n",cmd->request_bufflen)); + seg_cnt = 1; + } + else + { + DEBUG(printk("No data transfer \n")); + seg_cnt = 0; + } + + /* Acquire ring specific lock */ + QLA1280_RING_LOCK(ha); + + if ((uint16_t)(req_cnt + 2) >= ha->req_q_cnt) + { + /* Calculate number of free request entries. */ + cnt = RD_REG_WORD(®->mailbox4); + if (ha->req_ring_index < cnt) + ha->req_q_cnt = cnt - ha->req_ring_index; + else + ha->req_q_cnt = REQUEST_ENTRY_CNT - (ha->req_ring_index - cnt); + } + + DEBUG(sprintf(debug_buff,"Number of free entries = (%d)\n\r",ha->req_q_cnt)); + DEBUG(qla1280_print(debug_buff)); + /* If room for request in request ring. */ + if ((uint16_t)(req_cnt + 2) < ha->req_q_cnt) + { + /* Check for empty slot in outstanding command list. */ + for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS && + (ha->outstanding_cmds[cnt] != 0); cnt++) + ; + + if (cnt < MAX_OUTSTANDING_COMMANDS) + { + CMD_HANDLE(sp->cmd) = (unsigned char *) cnt; + ha->outstanding_cmds[cnt] = sp; + ha->req_q_cnt -= req_cnt; + + /* + * Build command packet. + */ + pkt = (cmd_entry_t *)ha->request_ring_ptr; + + pkt->entry_type = COMMAND_TYPE; + pkt->entry_count = (uint8_t)req_cnt; + pkt->sys_define = (uint8_t)ha->req_ring_index; + pkt->handle = (uint32_t)cnt; + + /* Zero out remaining portion of packet. */ + dword_ptr = (uint32_t *)pkt + 2; + for (cnt = 2; cnt < REQUEST_ENTRY_SIZE/4; cnt++) + *dword_ptr++ = 0; + + /* Set ISP command timeout. */ + pkt->timeout = (uint16_t)30; + + /* Set device target ID and LUN */ + pkt->lun = SCSI_LUN_32(cmd); + pkt->target = SCSI_BUS_32(cmd) ? + (SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd); + + /* Enable simple tag queuing if device supports it. */ + if (cmd->device->tagged_queue ) + pkt->control_flags |= BIT_3; + + /* Load SCSI command packet. */ + pkt->cdb_len = (uint16_t)CMD_CDBLEN(cmd); + data_ptr = (uint8_t *) &(CMD_CDBP(cmd)); + for (cnt = 0; cnt < pkt->cdb_len; cnt++) + pkt->scsi_cdb[cnt] = *data_ptr++; + DEBUG(printk("Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0])); + /* + * Load data segments. + */ + if (seg_cnt) + { + DEBUG(printk("loading data segments..\n")); + /* Set transfer direction (READ and WRITE) */ + /* Linux doesn't tell us */ + + /* + * 3/10 dg - Normally, we should need this check with our F/W + * but because of a small issue with it we do. + * + * For block devices, cmd->request.cmd has the operation + * For character devices, this isn't always set properly, so + * we need to check data_cmnd[0]. This catches the conditions + * for st.c, but not sg. Generic commands are pass down to us. + */ + if ( (cmd->data_cmnd[0] == WRITE_6) ) + pkt->control_flags |= BIT_6; + else + pkt->control_flags |= (BIT_5|BIT_6); + + sp->dir = pkt->control_flags & (BIT_5|BIT_6); + + /* Set total data segment count. */ + pkt->dseg_count = seg_cnt; + + /* Setup packet address segment pointer. */ + dword_ptr = (uint32_t *)&pkt->dseg_0_address; + + if (cmd->use_sg) /* If scatter gather */ + { + DEBUG(qla1280_print("Building S/G data segments..\n\r")); + DEBUG(qla1280_dump_buffer((caddr_t)sg, 4*16 )); + /* Load command entry data segments. */ + for (cnt = 0; cnt < 4 && seg_cnt; cnt++, seg_cnt--) + { + *dword_ptr++ = (uint32_t) cpu_to_le32(VIRT_TO_BUS(sg->address)); + *dword_ptr++ = sg->length; + DEBUG(sprintf(debug_buff,"SG Segment ap=0x%x, len=0x%x\n\r",sg->address,sg->length)); + DEBUG(qla1280_print(debug_buff)); + sg++; + } + /* + * Build continuation packets. + */ + while (seg_cnt > 0) + { + /* Adjust ring index. */ + ha->req_ring_index++; + if (ha->req_ring_index == REQUEST_ENTRY_CNT) + { + ha->req_ring_index = 0; + ha->request_ring_ptr = ha->request_ring; + } + else + ha->request_ring_ptr++; + + pkt = (cmd_entry_t *)ha->request_ring_ptr; + + /* Zero out packet. */ + dword_ptr = (uint32_t *)pkt; + for (cnt = 0;cnt < REQUEST_ENTRY_SIZE/4; cnt++) + *dword_ptr++ = 0; + + /* Load packet defaults. */ + ((cont_entry_t *)pkt)->entry_type = + CONTINUE_TYPE; + ((cont_entry_t *)pkt)->entry_count = 1; + + ((cont_entry_t *)pkt)->sys_define = (uint8_t) + ha->req_ring_index; + + /* Setup packet address segment pointer. */ + dword_ptr = (uint32_t *) + &((cont_entry_t *)pkt)->dseg_0_address; + + /* Load continuation entry data segments. */ + for (cnt = 0; cnt < 7 && seg_cnt; cnt++, seg_cnt--) + { + *dword_ptr++ = (u_int) cpu_to_le32(VIRT_TO_BUS(sg->address)); + *dword_ptr++ = sg->length; + sg++; + } +#ifdef QL_DEBUG_LEVEL_5 + qla1280_print( + "qla1280_32bit_start_scsi: continuation packet data - scsi("); + qla1280_output_number((uint32_t)SCSI_BUS_32(cmd), 10); + qla1280_print(":"); + qla1280_output_number((uint32_t)SCSI_TCN_32(cmd), 10); + qla1280_print(":"); + qla1280_output_number((uint32_t)SCSI_LUN_32(cmd), 10); + qla1280_print(")\n\r"); + qla1280_dump_buffer((caddr_t)pkt, REQUEST_ENTRY_SIZE); +#endif + } + } + else /* No scatter gather data transfer */ + { + *dword_ptr++ = (uint32_t) cpu_to_le32(VIRT_TO_BUS(cmd->request_buffer)); + *dword_ptr = (uint32_t) cmd->request_bufflen; + DEBUG(printk("Single Segment ap=0x%x, len=0x%x\n",cmd->request_buffer,cmd->request_bufflen)); + } + } + else /* No data transfer */ + { + *dword_ptr++ = (uint32_t) 0; + *dword_ptr = (uint32_t) 0; +#ifdef QL_DEBUG_LEVEL_5 + qla1280_print( + "qla1280_32bit_start_scsi: No data, command packet data - "); + qla1280_print("\n\r"); + qla1280_dump_buffer((caddr_t)pkt, REQUEST_ENTRY_SIZE); +#endif + } +#ifdef QL_DEBUG_LEVEL_5 + qla1280_print("qla1280_32bit_start_scsi: First IOCB block:\n\r"); + qla1280_dump_buffer((caddr_t)ha->request_ring_ptr, REQUEST_ENTRY_SIZE); +#endif + /* Adjust ring index. */ + ha->req_ring_index++; + if (ha->req_ring_index == REQUEST_ENTRY_CNT) + { + ha->req_ring_index = 0; + ha->request_ring_ptr = ha->request_ring; + } + else + ha->request_ring_ptr++; + + /* Set chip new ring index. */ + DEBUG(qla1280_print("qla1280_32bit_start_scsi: Wakeup RISC for pending command\n\r")); + ha->qthreads--; + sp->u_start = jiffies; + sp->flags |= SRB_SENT; + ha->actthreads++; + /* qla1280_output_number((uint32_t)ha->actthreads++, 16); */ + WRT_REG_WORD(®->mailbox4, ha->req_ring_index); + } + else + { + status = 1; +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print( + "qla1280_32bit_start_scsi: NO ROOM IN OUTSTANDING ARRAY\n\r"); + qla1280_print(" req_q_cnt="); + qla1280_output_number((uint32_t)ha->req_q_cnt, 16); + qla1280_print("\n\r"); +#endif + } + } + else + { + status = 1; +#ifdef QL_DEBUG_LEVEL_2 + /* qla1280_print("qla1280_32bit_start_scsi: in-ptr="); + qla1280_output_number((uint32_t)ha->req_ring_index, 16); + qla1280_print(" req_q_cnt="); + qla1280_output_number((uint32_t)ha->req_q_cnt, 16); + qla1280_print(" req_cnt="); + qla1280_output_number((uint32_t)req_cnt, 16); + qla1280_print("\n\r"); */ +#endif + } + + /* Release ring specific lock */ + QLA1280_RING_UNLOCK(ha); + +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + /* if (status) + qla1280_print("qla1280_32bit_start_scsi: **** FAILED ****\n\r"); */ +#endif +#ifdef QL_DEBUG_LEVEL_3 + LEAVE("qla1280_32bit_start_scsi"); +#endif + return(status); +} + +/* + * qla1280_req_pkt + * Function is responsible for locking ring and + * getting a zeroed out request packet. + * + * Input: + * ha = adapter block pointer. + * + * Returns: + * 0 = failed to get slot. + */ +STATIC request_t * +qla1280_req_pkt(scsi_qla_host_t *ha) +{ + device_reg_t *reg = ha->iobase; + request_t *pkt = 0; + uint16_t cnt; + uint32_t *dword_ptr; + uint32_t timer; + +#ifdef QL_DEBUG_LEVEL_3 + ENTER("qla1280_req_pkt"); +#endif + + /* Wait for 30 seconds for slot. */ + for (timer = 15000000; timer; timer--) + { + /* Acquire ring specific lock */ + QLA1280_RING_LOCK(ha); + + if (ha->req_q_cnt > 0) + { + /* Calculate number of free request entries. */ + cnt = RD_REG_WORD(®->mailbox4); + if (ha->req_ring_index < cnt) + ha->req_q_cnt = cnt - ha->req_ring_index; + else + ha->req_q_cnt = REQUEST_ENTRY_CNT - (ha->req_ring_index - cnt); + } + + /* Found empty request ring slot? */ + if (ha->req_q_cnt > 0) + { + ha->req_q_cnt--; + pkt = ha->request_ring_ptr; + + /* Zero out packet. */ + dword_ptr = (uint32_t *)pkt; + for (cnt = 0; cnt < REQUEST_ENTRY_SIZE/4; cnt++) + *dword_ptr++ = 0; + + /* Set system defined field. */ + pkt->sys_define = (uint8_t)ha->req_ring_index; + + /* Set entry count. */ + pkt->entry_count = 1; + + break; + } + + /* Release ring specific lock */ + QLA1280_RING_UNLOCK(ha); + + SYS_DELAY(2); /* 10 */ + + /* Check for pending interrupts. */ + qla1280_poll(ha); + } + +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + if (!pkt) + qla1280_print("qla1280_req_pkt: **** FAILED ****\n\r"); +#endif +#ifdef QL_DEBUG_LEVEL_3 + else + qla1280_print("qla1280_req_pkt: exiting normally\n\r"); +#endif + return(pkt); +} + +/* + * qla1280_isp_cmd + * Function is responsible for modifying ISP input pointer. + * Releases ring lock. + * + * Input: + * ha = adapter block pointer. + */ +STATIC void +qla1280_isp_cmd(scsi_qla_host_t *ha) +{ + device_reg_t *reg = ha->iobase; + +#ifdef QL_DEBUG_LEVEL_3 + ENTER("qla1280_isp_cmd"); +#endif + +#ifdef QL_DEBUG_LEVEL_5 + qla1280_print("qla1280_isp_cmd: IOCB data:\n\r"); + qla1280_dump_buffer((caddr_t)ha->request_ring_ptr, REQUEST_ENTRY_SIZE); +#endif + + /* Adjust ring index. */ + ha->req_ring_index++; + if (ha->req_ring_index == REQUEST_ENTRY_CNT) + { + ha->req_ring_index = 0; + ha->request_ring_ptr = ha->request_ring; + } + else + ha->request_ring_ptr++; + + /* Set chip new ring index. */ + WRT_REG_WORD(®->mailbox4, ha->req_ring_index); + + /* Release ring specific lock */ + QLA1280_RING_UNLOCK(ha); + +#ifdef QL_DEBUG_LEVEL_3 + LEAVE("qla1280_isp_cmd"); +#endif +} + +/* + * qla1280_enable_lun + * Issue enable LUN entry IOCB. + * + * Input: + * ha = adapter block pointer. + * b = SCSI BUS number. + * l = LUN number. + */ +STATIC void +qla1280_enable_lun(scsi_qla_host_t *ha, uint8_t b, uint32_t l) +{ + elun_entry_t *pkt; + +#ifdef QL_DEBUG_LEVEL_3 + qla1280_print("qla1280_enable_lun: entered\n\r"); +#endif + + /* Get request packet. */ + /* + if (pkt = (elun_entry_t *)qla1280_req_pkt(ha)) + { + pkt->entry_type = ENABLE_LUN_TYPE; + pkt->lun = (uint16_t)(b ? l | BIT_15 : l); + pkt->command_count = 32; + pkt->immed_notify_count = 1; + pkt->group_6_length = MAX_CMDSZ; + pkt->group_7_length = MAX_CMDSZ; + pkt->timeout = 0x30; + + qla1280_isp_cmd(ha); + } + */ + pkt = (elun_entry_t *)1; + +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + if (!pkt) + qla1280_print("qla1280_enable_lun: **** FAILED ****\n\r"); +#endif +#ifdef QL_DEBUG_LEVEL_3 + else + qla1280_print("qla1280_enable_lun: exiting normally\n\r"); +#endif +} + +#if QL1280_TARGET_MODE_SUPPORT +/****************************************************************************/ +/* Target Mode Support Functions. */ +/****************************************************************************/ + +/* + * qla1280_notify_ack + * Issue notify acknowledge IOCB. + * If sequence ID is zero, acknowledgement of + * SCSI bus reset or bus device reset is assumed. + * + * Input: + * ha = adapter block pointer. + * inotify = immediate notify entry pointer. + */ +STATIC void +qla1280_notify_ack(scsi_qla_host_t *ha, notify_entry_t *inotify) +{ + nack_entry_t *pkt; + +#ifdef QL_DEBUG_LEVEL_3 + qla1280_print("qla1280_notify_ack: entered\n\r"); +#endif + + /* Get request packet. */ + if (pkt = (nack_entry_t *)qla1280_req_pkt(ha)) + { + pkt->entry_type = NOTIFY_ACK_TYPE; + pkt->lun = inotify->lun; + pkt->initiator_id = inotify->initiator_id; + pkt->target_id = inotify->target_id; + if (inotify->seq_id == 0) + pkt->event = BIT_7; + else + pkt->seq_id = inotify->seq_id; + + /* Issue command to ISP */ + qla1280_isp_cmd(ha); + } + +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + if (!pkt) + qla1280_print("qla1280_notify_ack: **** FAILED ****\n\r"); +#endif +#ifdef QL_DEBUG_LEVEL_3 + else + qla1280_print("qla1280_notify_ack: exiting normally\n\r"); +#endif +} + +/* + * qla1280_immed_notify + * Issue immediate notify IOCB for LUN 0. + * + * Input: + * ha = adapter block pointer. + * inotify = immediate notify entry pointer. + */ +STATIC void +qla1280_immed_notify(scsi_qla_host_t *ha, notify_entry_t *inotify) +{ + notify_entry_t *pkt; + +#ifdef QL_DEBUG_LEVEL_3 + qla1280_print("qla1280_immed_notify: entered\n\r"); +#endif + + /* Get request packet. */ + if (pkt = (notify_entry_t *)qla1280_req_pkt(ha)) + { + pkt->entry_type = IMMED_NOTIFY_TYPE; + pkt->lun = inotify->lun; + pkt->initiator_id = inotify->initiator_id; + pkt->target_id = inotify->target_id; + pkt->status = 1; + + /* Issue command to ISP */ + qla1280_isp_cmd(ha); + } + +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + if (!pkt) + qla1280_print("qla1280_immed_notify: **** FAILED ****\n\r"); +#endif +#ifdef QL_DEBUG_LEVEL_3 + else + qla1280_print("qla1280_immed_notify: exiting normally\n\r"); +#endif +} + +/* + * qla1280_accept_io + * Issue accept target I/O IOCB for LUN 0. + * + * Input: + * ha = adapter block pointer. + * ctio = ctio returned entry pointer. + */ +STATIC void +qla1280_accept_io(scsi_qla_host_t *ha, ctio_ret_entry_t *ctio) +{ + atio_entry_t *pkt; + +#ifdef QL_DEBUG_LEVEL_3 + qla1280_print("qla1280_accept_io: entered\n\r"); +#endif + + /* Get request packet. */ + if (pkt = (atio_entry_t *)qla1280_req_pkt(ha)) + { + pkt->entry_type = ACCEPT_TGT_IO_TYPE; + pkt->lun = ctio->lun; + pkt->initiator_id = ctio->initiator_id; + pkt->target_id = ctio->target_id; + pkt->tag_value = ctio->tag_value; + pkt->status = 1; + + /* Issue command to ISP */ + qla1280_isp_cmd(ha); + } + +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + if (!pkt) + qla1280_print("qla1280_accept_io: **** FAILED ****\n\r"); +#endif +#ifdef QL_DEBUG_LEVEL_3 + else + qla1280_print("qla1280_accept_io: exiting normally\n\r"); +#endif +} + +/* + * qla1280_64bit_continue_io + * Issue continue target I/O IOCB. + * + * Input: + * ha = adapter block pointer. + * atio = atio pointer. + * len = total bytecount. + * addr = physical address pointer. + */ +STATIC void +qla1280_64bit_continue_io(scsi_qla_host_t *ha, atio_entry_t *atio, uint32_t len, + paddr32_t *addr) +{ + ctio_a64_entry_t *pkt; + uint32_t *dword_ptr; + +#ifdef QL_DEBUG_LEVEL_3 + qla1280_print("qla1280_64bit_continue_io: entered\n\r"); +#endif + + /* Get request packet. */ + if (pkt = (ctio_a64_entry_t *)qla1280_req_pkt(ha)) + { + pkt->entry_type = CTIO_A64_TYPE; + pkt->lun = atio->lun; + pkt->initiator_id = atio->initiator_id; + pkt->target_id = atio->target_id; + pkt->option_flags = atio->option_flags; + pkt->tag_value = atio->tag_value; + pkt->scsi_status = atio->scsi_status; + + if (len) + { + pkt->dseg_count = 1; + pkt->transfer_length = len; + pkt->dseg_0_length = len; + dword_ptr = (uint32_t *)addr; + pkt->dseg_0_address[0] = *dword_ptr++; + pkt->dseg_0_address[1] = *dword_ptr; + } + + /* Issue command to ISP */ + qla1280_isp_cmd(ha); + } + +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + if (!pkt) + qla1280_print("qla1280_64bit_continue_io: **** FAILED ****\n\r"); +#endif +#ifdef QL_DEBUG_LEVEL_3 + else + qla1280_print("qla1280_64bit_continue_io: exiting normally\n\r"); +#endif +} + +/* + * qla1280_32bit_continue_io + * Issue continue target I/O IOCB. + * + * Input: + * ha = adapter block pointer. + * atio = atio pointer. + * len = total bytecount. + * addr = physical address pointer. + */ +STATIC void +qla1280_32bit_continue_io(scsi_qla_host_t *ha, atio_entry_t *atio, uint32_t len, + paddr32_t *addr) +{ + ctio_entry_t *pkt; + uint32_t *dword_ptr; + +#ifdef QL_DEBUG_LEVEL_3 + qla1280_print("qla1280_32bit_continue_io: entered\n\r"); +#endif + + /* Get request packet. */ + if (pkt = (ctio_entry_t *)qla1280_req_pkt(ha)) + { + pkt->entry_type = CONTINUE_TGT_IO_TYPE; + pkt->lun = atio->lun; + pkt->initiator_id = atio->initiator_id; + pkt->target_id = atio->target_id; + pkt->option_flags = atio->option_flags; + pkt->tag_value = atio->tag_value; + pkt->scsi_status = atio->scsi_status; + + if (len) + { + pkt->dseg_count = 1; + pkt->transfer_length = len; + pkt->dseg_0_length = len; + dword_ptr = (uint32_t *)addr; + pkt->dseg_0_address = *dword_ptr; + } + + /* Issue command to ISP */ + qla1280_isp_cmd(ha); + } + +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + if (!pkt) + qla1280_print("qla1280_32bit_continue_io: **** FAILED ****\n\r"); +#endif +#ifdef QL_DEBUG_LEVEL_3 + else + qla1280_print("qla1280_32bit_continue_io: exiting normally\n\r"); +#endif +} +#endif /* QL1280_TARGET_MODE_SUPPORT */ + +/****************************************************************************/ +/* Interrupt Service Routine. */ +/****************************************************************************/ + +/**************************************************************************** + * qla1280_isr + * Calls I/O done on command completion. + * + * Input: + * ha = adapter block pointer. + * done_q_first = done queue first pointer. + * done_q_last = done queue last pointer. + * INTR_LOCK must be already obtained. + ****************************************************************************/ +STATIC void +qla1280_isr(scsi_qla_host_t *ha, srb_t **done_q_first, srb_t **done_q_last) +{ + device_reg_t *reg = ha->iobase; + response_t *pkt; + srb_t *sp; + uint16_t mailbox[MAILBOX_REGISTER_COUNT]; + uint16_t *wptr; + uint32_t index; + + ENTER("qla1280_isr"); + + + /* Save mailbox register 5 */ + mailbox[5] = RD_REG_WORD(®->mailbox5); + + /* Check for mailbox interrupt. */ + + mailbox[0] = RD_REG_WORD(®->semaphore); + if (mailbox[0] & BIT_0) + { + /* Get mailbox data. */ + + wptr = &mailbox[0]; + *wptr++ = RD_REG_WORD(®->mailbox0); + *wptr++ = RD_REG_WORD(®->mailbox1); + *wptr = RD_REG_WORD(®->mailbox2); + if (mailbox[0] != MBA_SCSI_COMPLETION) + { + wptr++; + *wptr++ = RD_REG_WORD(®->mailbox3); + *wptr++ = RD_REG_WORD(®->mailbox4); + wptr++; + *wptr++ = RD_REG_WORD(®->mailbox6); + *wptr = RD_REG_WORD(®->mailbox7); + } + + /* Release mailbox registers. */ + + WRT_REG_WORD(®->semaphore, 0); + WRT_REG_WORD(®->host_cmd, HC_CLR_RISC_INT); + +#ifdef QL_DEBUG_LEVEL_5 + qla1280_print("qla1280_isr: mailbox interrupt mailbox[0] = "); + qla1280_output_number((uint32_t)mailbox[0], 16); + qla1280_print("\n\r"); +#endif + + /* Handle asynchronous event */ + + switch (mailbox[0]) + { + case MBA_SCSI_COMPLETION: /* Response completion */ +#ifdef QL_DEBUG_LEVEL_5 + qla1280_print("qla1280_isr: mailbox response completion\n\r"); +#endif + if (ha->flags.online) + { + /* Get outstanding command index. */ + index = (uint32_t)(mailbox[2] << 16 | mailbox[1]); + + /* Validate handle. */ + if (index < MAX_OUTSTANDING_COMMANDS) + sp = ha->outstanding_cmds[index]; + else + sp = 0; + + if (sp) + { + /* Free outstanding command slot. */ + ha->outstanding_cmds[index] = 0; + + /* Save ISP completion status */ + CMD_RESULT(sp->cmd) = 0; + + /* Place block on done queue */ + sp->s_next = NULL; + sp->s_prev = *done_q_last; + if (!*done_q_first) + *done_q_first = sp; + else + (*done_q_last)->s_next = sp; + *done_q_last = sp; + } + else + { +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print("qla1280_isr: ISP invalid handle\n\r"); +#endif + printk(KERN_WARNING "qla1280: ISP invalid handle"); + ha->flags.isp_abort_needed = TRUE; + } + } + break; + case MBA_BUS_RESET: /* SCSI Bus Reset */ +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print("qla1280_isr: asynchronous BUS_RESET\n\r"); +#endif + ha->flags.reset_marker = TRUE; + index = mailbox[6] & BIT_0; + ha->bus_settings[index].reset_marker = TRUE; + break; + case MBA_SYSTEM_ERR: /* System Error */ +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print("qla1280_isr: ISP System Error - mbx1="); + qla1280_output_number((uint32_t)mailbox[1], 16); + qla1280_print(", mbx2="); + qla1280_output_number((uint32_t)mailbox[2], 16); + qla1280_print(", mbx3="); + qla1280_output_number((uint32_t)mailbox[3], 16); + qla1280_print("\n\r"); +#endif + printk(KERN_WARNING + "qla1280: ISP System Error - mbx1=%xh, mbx2=%xh, mbx3=%xh\n", + mailbox[1], mailbox[2], mailbox[3]); + ha->flags.isp_abort_needed = TRUE; + break; + case MBA_REQ_TRANSFER_ERR: /* Request Transfer Error */ +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print("qla1280_isr: ISP Request Transfer Error\n\r"); +#endif + printk(KERN_WARNING "qla1280: ISP Request Transfer Error\n"); + ha->flags.isp_abort_needed = TRUE; + break; + case MBA_RSP_TRANSFER_ERR: /* Response Transfer Error */ +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print("qla1280_isr: ISP Response Transfer Error\n\r"); +#endif + printk(KERN_WARNING "qla1280: ISP Response Transfer Error\n"); + ha->flags.isp_abort_needed = TRUE; + break; + case MBA_WAKEUP_THRES: /* Request Queue Wake-up */ +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print("qla1280_isr: asynchronous WAKEUP_THRES\n\r"); +#endif + break; + case MBA_TIMEOUT_RESET: /* Execution Timeout Reset */ +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print("qla1280_isr: asynchronous TIMEOUT_RESET\n\r"); +#endif + break; + case MBA_DEVICE_RESET: /* Bus Device Reset */ +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print( + "qla1280_isr: asynchronous BUS_DEVICE_RESET\n\r"); +#endif + ha->flags.reset_marker = TRUE; + index = mailbox[6] & BIT_0; + ha->bus_settings[index].reset_marker = TRUE; + break; + case MBA_BUS_MODE_CHANGE: +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print( + "qla1280_isr: asynchronous BUS_MODE_CHANGE\n\r"); +#endif + break; + default: + if (mailbox[0] < MBA_ASYNC_EVENT) + { + wptr = &mailbox[0]; + ha->mailbox_out[0] = *wptr++; + ha->mailbox_out[1] = *wptr++; + ha->mailbox_out[2] = *wptr++; + ha->mailbox_out[3] = *wptr++; + ha->mailbox_out[4] = *wptr++; + ha->mailbox_out[5] = *wptr++; + ha->mailbox_out[6] = *wptr++; + ha->mailbox_out[7] = *wptr; + ha->flags.mbox_int = TRUE; + } + break; + } + } + else + WRT_REG_WORD(®->host_cmd, HC_CLR_RISC_INT); + + /* + * Response ring + */ + if (ha->flags.online && !ha->flags.mbox_busy) + { + if (mailbox[5] < RESPONSE_ENTRY_CNT) + { + while (ha->rsp_ring_index != mailbox[5]) + { + pkt = ha->response_ring_ptr; + +#ifdef QL_DEBUG_LEVEL_5 + qla1280_print("qla1280_isr: ha->rsp_ring_index = "); + qla1280_output_number((uint32_t)ha->rsp_ring_index, 16); + qla1280_print(" mailbox[5] = "); + qla1280_output_number((uint32_t)mailbox[5], 16); + qla1280_print("\n\rqla1280_isr: response packet data\n\r"); + qla1280_dump_buffer((caddr_t)pkt, RESPONSE_ENTRY_SIZE); +#endif + +#if defined(QL_DEBUG_LEVEL_2) && !defined(QL_DEBUG_LEVEL_5) + if (pkt->entry_type == STATUS_TYPE) + { + if ((uint8_t)(pkt->scsi_status) || pkt->comp_status || + pkt->entry_status) + { + DEBUG(qla1280_print("qla1280_isr: ha->rsp_ring_index = ");) + DEBUG(qla1280_output_number((uint32_t)ha->rsp_ring_index, + 16);) + DEBUG(qla1280_print(" mailbox[5] = ");) + DEBUG(qla1280_output_number((uint32_t)mailbox[5], 16);) + DEBUG(qla1280_print( "\n\r comp_status = ");) + DEBUG(qla1280_output_number((uint32_t)pkt->comp_status,16);) + DEBUG(qla1280_print( ", ");) + DEBUG(qla1280_print( " scsi_status = ");) + DEBUG(qla1280_output_number((uint32_t)pkt->scsi_status,16);) + DEBUG(qla1280_print( "\n\r");) + /* qla1280_print( + "\n\rqla1280_isr: response packet data\n\r"); + qla1280_dump_buffer((caddr_t)pkt, + RESPONSE_ENTRY_SIZE); */ + } + } + else + { + qla1280_print("qla1280_isr: ha->rsp_ring_index = "); + qla1280_output_number((uint32_t)ha->rsp_ring_index, 16); + qla1280_print(" mailbox[5] = "); + qla1280_output_number((uint32_t)mailbox[5], 16); + qla1280_print( + "\n\rqla1280_isr: response packet data\n\r"); + qla1280_dump_buffer((caddr_t)pkt, RESPONSE_ENTRY_SIZE); + } +#endif + if (pkt->entry_type == STATUS_TYPE || pkt->entry_status) + { + if (pkt->entry_type == STATUS_TYPE) + qla1280_status_entry(ha, (sts_entry_t *)pkt, + done_q_first, done_q_last); + else + qla1280_error_entry(ha, pkt, + done_q_first, done_q_last); + + /* Adjust ring index. */ + ha->rsp_ring_index++; + if (ha->rsp_ring_index == RESPONSE_ENTRY_CNT) + { + ha->rsp_ring_index = 0; + ha->response_ring_ptr = ha->response_ring; + } + else + ha->response_ring_ptr++; + WRT_REG_WORD(®->mailbox5, ha->rsp_ring_index); + } +#if QLA1280_TARGET_MODE_SUPPORT + else + { + pkt = &response_entry; + + /* Copy packet. */ + dptr1 = (uint32_t *)ha->response_ring_ptr; + dptr2 = (uint32_t *)pkt; + for (index = 0; index < RESPONSE_ENTRY_SIZE/4; index++) + *dptr2++ = *dptr1++; + + /* Adjust ring index. */ + ha->rsp_ring_index++; + if (ha->rsp_ring_index == RESPONSE_ENTRY_CNT) + { + ha->rsp_ring_index = 0; + ha->response_ring_ptr = ha->response_ring; + } + else + ha->response_ring_ptr++; + WRT_REG_WORD(®->mailbox5, ha->rsp_ring_index); + + /* Release interrupt specific lock */ + QLA1280_INTR_UNLOCK(ha); + + switch (pkt->entry_type) + { + case ACCEPT_TGT_IO_TYPE: + qla1280_atio_entry(ha, (atio_entry_t *)pkt); + break; + case IMMED_NOTIFY_TYPE: + qla1280_notify_entry(ha, (notify_entry_t *)pkt); + break; + case CTIO_RET_TYPE: + qla1280_accept_io(ha, (ctio_ret_entry_t *)pkt); + break; + default: + break; + } + + /* Acquire interrupt specific lock */ + QLA1280_INTR_LOCK(ha); + } +#endif + } + } + else + { + ha->flags.isp_abort_needed = TRUE; +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print("qla1280_isr: Response pointer Error\n"); +#endif + } + } + + LEAVE("qla1280_isr"); +} + +/* + * qla1280_rst_aen + * Processes asynchronous reset. + * + * Input: + * ha = adapter block pointer. + */ +STATIC void +qla1280_rst_aen(scsi_qla_host_t *ha) +{ +#if QL1280_TARGET_MODE_SUPPORT + notify_entry_t nentry; +#endif + uint8_t b; + +#ifdef QL_DEBUG_LEVEL_3 + ENTER("qla1280_rst_aen"); +#endif + + if (ha->flags.online && !ha->flags.reset_active && + !ha->flags.abort_isp_active) + { + ha->flags.reset_active = TRUE; + while (ha->flags.reset_marker) + { + /* Issue marker command. */ + ha->flags.reset_marker = FALSE; + for (b = 0; b < ha->ports && !ha->flags.reset_marker; b++) + { + if (ha->bus_settings[b].reset_marker) + { + ha->bus_settings[b].reset_marker = FALSE; + qla1280_marker(ha, b, 0, 0, MK_SYNC_ALL); + + if (!ha->flags.reset_marker) + { +#if QL1280_TARGET_MODE_SUPPORT + /* Issue notify acknowledgement command. */ + bzero((caddr_t)&nentry, sizeof(notify_entry_t)); + + nentry.initiator_id = nentry.target_id = b ? + ha->bus_settings[b].id | BIT_7 : + ha->bus_settings[b].id; + qla1280_notify_entry(ha, &nentry); +#endif + + /* Asynchronous event notification */ + } + } + } + } + } + +#ifdef QL_DEBUG_LEVEL_3 + LEAVE("qla1280_rst_aen"); +#endif +} + +#if QL1280_TARGET_MODE_SUPPORT +/* + * qla1280_atio_entry + * Processes received ISP accept target I/O entry. + * + * Input: + * ha = adapter block pointer. + * pkt = entry pointer. + */ +STATIC void +qla1280_atio_entry(scsi_qla_host_t *ha, atio_entry_t *pkt) +{ + uint64_t *a64; + uint64_t *end_a64; + paddr32_t phy_addr[2]; + paddr32_t end_addr[2]; + uint32_t len; + uint32_t offset; + uint8_t t; + uint8_t *sense_ptr; + +#ifdef QL_DEBUG_LEVEL_3 + qla1280_print("qla1280_atio_entry: entered\n\r"); +#endif + + t = pkt->initiator_id; + sense_ptr = ha->tsense + t * TARGET_SENSE_SIZE; + a64 = (uint64_t *)&phy_addr[0]; + end_a64 = (uint64_t *)&end_addr[0]; + + switch (pkt->status & ~BIT_7) + { + case 7: /* Path invalid */ +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + qla1280_print("qla1280_atio_entry: Path invalid\n\r"); +#endif + break; + case 0x14: /* Target Bus Phase Sequence Failure */ +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + qla1280_print( + "qla1280_atio_entry: Target Bus Phase Sequence Failure\n\r"); +#endif + if (pkt->status & BIT_7) + { + BCOPY((caddr_t)&pkt->sense_data, sense_ptr,TARGET_SENSE_SIZE); + } + else + { + bzero(sense_ptr, TARGET_SENSE_SIZE); + *sense_ptr = 0x70; + *(sense_ptr+2) = SD_HARDERR; + *(sense_ptr+7) = TARGET_SENSE_SIZE-8; + *(sense_ptr+12) = SC_SELFAIL; + } + pkt->scsi_status = S_CKCON; + pkt->option_flags |= (uint32_t)OF_SSTS | (uint32_t)OF_NO_DATA; + if (ha->flags.enable_64bit_addressing) + qla1280_64bit_continue_io(ha, pkt, 0, 0); + else + qla1280_32bit_continue_io(ha, pkt, 0, 0); + break; + case 0x16: /* Requested Capability Not Available */ +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + qla1280_print( + "qla1280_atio_entry: Target Bus Phase Sequence Failure\n\r"); +#endif + break; + case 0x17: /* Bus Device Reset Message Received */ +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + qla1280_print( + "qla1280_atio_entry: Target Bus Phase Sequence Failure\n\r"); +#endif + break; + case 0x3D: /* CDB Received */ + + /* Check for invalid LUN */ + if (pkt->lun && pkt->cdb[0] != SS_INQUIR && + pkt->cdb[0] != SS_REQSEN) + pkt->cdb[0] = SS_TEST; + + switch (pkt->cdb[0]) + { + case SS_TEST: +#ifdef QL_DEBUG_LEVEL_3 + qla1280_print("qla1280_atio_entry: SS_TEST\n\r"); +#endif + bzero(sense_ptr, TARGET_SENSE_SIZE); + len = 0; + if (pkt->lun == 0) + pkt->scsi_status = S_GOOD; + else + { + *sense_ptr = 0x70; + *(sense_ptr+2) = SD_ILLREQ; + *(sense_ptr+7) = TARGET_SENSE_SIZE-8; + *(sense_ptr+12) = SC_INVLUN; + pkt->scsi_status = S_CKCON; + } + + pkt->option_flags |= (uint32_t)OF_SSTS | + (uint32_t)OF_NO_DATA; + break; + case SS_REQSEN: +#ifdef QL_DEBUG_LEVEL_3 + qla1280_print("qla1280_atio_entry: SS_REQSEN\n\r"); +#endif + phy_addr[0] = ha->tsense_dma; + phy_addr[1] = 0; + *a64 += t * TARGET_SENSE_SIZE; + if (pkt->cdb[4] > TARGET_SENSE_SIZE) + len = TARGET_SENSE_SIZE; + else + len = pkt->cdb[4]; + pkt->scsi_status = S_GOOD; + pkt->option_flags |= (uint32_t)OF_SSTS | + (uint32_t)OF_DATA_IN; + break; + case SS_INQUIR: +#ifdef QL_DEBUG_LEVEL_3 + qla1280_print("qla1280_atio_entry: SS_INQUIR\n\r"); +#endif + bzero(sense_ptr, TARGET_SENSE_SIZE); + phy_addr[0] = ha->tbuf_dma; + phy_addr[1] = 0; + *a64 += TARGET_INQ_OFFSET; + + if (pkt->lun == 0) + { + ha->tbuf->inq.id_type = ID_PROCESOR; + ha->tbuf->inq.id_pqual = ID_QOK; + } + else + { + ha->tbuf->inq.id_type = ID_NODEV; + ha->tbuf->inq.id_pqual = ID_QNOLU; + } + + if (pkt->cdb[4] > sizeof(struct ident)) + len = sizeof(struct ident); + else + len = pkt->cdb[4]; + pkt->scsi_status = S_GOOD; + pkt->option_flags |= (uint32_t)OF_SSTS | + (uint32_t)OF_DATA_IN; + break; + case SM_WRDB: + bzero(sense_ptr, TARGET_SENSE_SIZE); + offset = pkt->cdb[5]; + offset |= pkt->cdb[4] << 8; + offset |= pkt->cdb[3] << 16; + len = pkt->cdb[8]; + len |= pkt->cdb[7] << 8; + len |= pkt->cdb[6] << 16; + end_addr[0] = phy_addr[0] = ha->tbuf_dma; + end_addr[1] = phy_addr[1] = 0; + *end_a64 += TARGET_DATA_OFFSET + TARGET_DATA_SIZE; + switch (pkt->cdb[1] & 7) + { + case RW_BUF_HDATA: +#ifdef QL_DEBUG_LEVEL_3 + qla1280_print("qla1280_atio_entry: SM_WRDB, RW_BUF_HDATA\n\r"); +#endif + if (len > TARGET_DATA_SIZE + 4) + { +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print("qla1280_atio_entry: SM_WRDB, length > buffer size\n\r"); +#endif + *sense_ptr = 0x70; + *(sense_ptr+2) = SD_ILLREQ; + *(sense_ptr+7) = TARGET_SENSE_SIZE-8; + *(sense_ptr+12) = SC_ILLCDB; + pkt->scsi_status = S_CKCON; + pkt->option_flags |= (uint32_t)OF_SSTS | + (uint32_t)OF_NO_DATA; + len = 0; + } + else if (len) + { + pkt->scsi_status = S_GOOD; + pkt->option_flags |= (uint32_t)OF_SSTS | + (uint32_t)OF_DATA_OUT; +#ifdef QL_DEBUG_LEVEL_3 + qla1280_print("qla1280_atio_entry: Issuing SDI_TARMOD_WRCOMP\n\r"); +#endif + sdi_xaen(SDI_TARMOD_WRCOMP, ha->cntlr, + pkt->target_id, pkt->lun, 0, offset); + } + else + { +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print("qla1280_atio_entry: SM_WRDB, zero length\n\r"); +#endif + pkt->scsi_status = S_GOOD; + pkt->option_flags |= (uint32_t)OF_SSTS | + (uint32_t)OF_NO_DATA; + } + + break; + case RW_BUF_DATA: +#ifdef QL_DEBUG_LEVEL_3 + qla1280_print("qla1280_atio_entry: SM_WRDB, RW_BUF_DATA\n\r"); +#endif + *a64 += offset + TARGET_DATA_OFFSET; + if (pkt->cdb[2] != 0 || *a64 >= *end_a64 || + *a64 + len > *end_a64) + { +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print("qla1280_atio_entry: SM_WRDB, RW_BUF_DATA BAD\n\r"); + qla1280_print("buf_id="); + qla1280_output_number((uint32_t)pkt->cdb[2], 16); + qla1280_print(", offset="); + qla1280_output_number((uint32_t)offset, 16); + qla1280_print(", length="); + qla1280_output_number((uint32_t)len, 16); + qla1280_print("\n\r"); +#endif + *sense_ptr = 0x70; + *(sense_ptr+2) = SD_ILLREQ; + *(sense_ptr+7) = TARGET_SENSE_SIZE-8; + *(sense_ptr+12) = SC_ILLCDB; + len = 0; + pkt->scsi_status = S_CKCON; + pkt->option_flags |= (uint32_t)OF_SSTS | + (uint32_t)OF_NO_DATA; + } + else if (len) + { + pkt->scsi_status = S_GOOD; + pkt->option_flags |= (uint32_t)OF_SSTS | + (uint32_t)OF_DATA_OUT; +#ifdef QL_DEBUG_LEVEL_3 + qla1280_print("qla1280_atio_entry: Issuing SDI_TARMOD_WRCOMP\n\r"); +#endif + sdi_xaen(SDI_TARMOD_WRCOMP, ha->cntlr, + pkt->target_id, pkt->lun, 0, offset); + } + else + { +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print("qla1280_atio_entry: SM_WRDB, zero length\n\r"); +#endif + pkt->scsi_status = S_GOOD; + pkt->option_flags |= (uint32_t)OF_SSTS | + (uint32_t)OF_NO_DATA; + } + break; + default: +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print("qla1280_atio_entry: SM_WRDB unknown mode\n\r"); +#endif + *sense_ptr = 0x70; + *(sense_ptr+2) = SD_ILLREQ; + *(sense_ptr+7) = TARGET_SENSE_SIZE-8; + *(sense_ptr+12) = SC_ILLCDB; + len = 0; + pkt->scsi_status = S_CKCON; + pkt->option_flags |= (uint32_t)OF_SSTS | + (uint32_t)OF_NO_DATA; + break; + } + break; + case SM_RDDB: + bzero(sense_ptr, TARGET_SENSE_SIZE); + offset = pkt->cdb[5]; + offset |= pkt->cdb[4] << 8; + offset |= pkt->cdb[3] << 16; + len = pkt->cdb[8]; + len |= pkt->cdb[7] << 8; + len |= pkt->cdb[6] << 16; + end_addr[0] = phy_addr[0] = ha->tbuf_dma; + end_addr[1] = phy_addr[1] = 0; + *end_a64 += TARGET_DATA_OFFSET + TARGET_DATA_SIZE; + switch (pkt->cdb[1] & 7) + { + case RW_BUF_HDATA: +#ifdef QL_DEBUG_LEVEL_3 + qla1280_print("qla1280_atio_entry: SM_RDDB, RW_BUF_HDATA\n\r"); +#endif + if (len) + { + ha->tbuf->hdr[0] = 0; + ha->tbuf->hdr[1] = + (uint8_t)(TARGET_DATA_SIZE >> 16); + ha->tbuf->hdr[2] = + (uint8_t)(TARGET_DATA_SIZE >> 8); + ha->tbuf->hdr[3] = (uint8_t)TARGET_DATA_SIZE; + if (len > TARGET_DATA_SIZE + 4) + len = TARGET_DATA_SIZE + 4; + pkt->scsi_status = S_GOOD; + pkt->option_flags |= (uint32_t)OF_SSTS | + (uint32_t)OF_DATA_IN; + } + else + { +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print("qla1280_atio_entry: SM_RDDB, zero length\n\r"); +#endif + pkt->scsi_status = S_GOOD; + pkt->option_flags |= (uint32_t)OF_SSTS | + (uint32_t)OF_NO_DATA; + } + break; + case RW_BUF_DATA: +#ifdef QL_DEBUG_LEVEL_3 + qla1280_print("qla1280_atio_entry: SM_RDDB, RW_BUF_DATA\n\r"); +#endif + *a64 += offset + TARGET_DATA_OFFSET; + if (pkt->cdb[2] != 0 || *a64 >= *end_a64) + { +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print("qla1280_atio_entry: SM_RDDB, RW_BUF_DATA BAD\n\r"); + qla1280_print("buf_id="); + qla1280_output_number((uint32_t)pkt->cdb[2], 16); + qla1280_print(", offset="); + qla1280_output_number((uint32_t)offset, 16); + qla1280_print("\n\r"); +#endif + *sense_ptr = 0x70; + *(sense_ptr+2) = SD_ILLREQ; + *(sense_ptr+7) = TARGET_SENSE_SIZE-8; + *(sense_ptr+12) = SC_ILLCDB; + len = 0; + pkt->scsi_status = S_CKCON; + pkt->option_flags |= (uint32_t)OF_SSTS | + (uint32_t)OF_NO_DATA; + } + else + { + if (*a64 + len > *end_a64) + len = *end_a64 - *a64; + if (len) + { + pkt->scsi_status = S_GOOD; + pkt->option_flags |= (uint32_t)OF_SSTS | + (uint32_t)OF_DATA_IN; + } + else + { +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print("qla1280_atio_entry: SM_RDDB, zero length\n\r"); +#endif + pkt->scsi_status = S_GOOD; + pkt->option_flags |= (uint32_t)OF_SSTS | + (uint32_t)OF_NO_DATA; + } + } + break; + case RW_BUF_DESC: +#ifdef QL_DEBUG_LEVEL_3 + qla1280_print("qla1280_atio_entry: SM_RDDB, RW_BUF_DESC\n\r"); +#endif + if (len) + { + if (len > 4) + len = 4; + + ha->tbuf->hdr[0] = 0; + if (pkt->cdb[2] != 0) + { + ha->tbuf->hdr[1] = 0; + ha->tbuf->hdr[2] = 0; + ha->tbuf->hdr[3] = 0; + } + else + { + ha->tbuf->hdr[1] = + (uint8_t)(TARGET_DATA_SIZE >> 16); + ha->tbuf->hdr[2] = + (uint8_t)(TARGET_DATA_SIZE >> 8); + ha->tbuf->hdr[3] = + (uint8_t)TARGET_DATA_SIZE; + } + pkt->scsi_status = S_GOOD; + pkt->option_flags |= (uint32_t)OF_SSTS | + (uint32_t)OF_DATA_IN; + } + else + { +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print("qla1280_atio_entry: SM_RDDB, zero length\n\r"); +#endif + pkt->scsi_status = S_GOOD; + pkt->option_flags |= (uint32_t)OF_SSTS | + (uint32_t)OF_NO_DATA; + } + break; + default: +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print("qla1280_atio_entry: SM_RDDB unknown mode\n\r"); +#endif + *sense_ptr = 0x70; + *(sense_ptr+2) = SD_ILLREQ; + *(sense_ptr+7) = TARGET_SENSE_SIZE-8; + *(sense_ptr+12) = SC_ILLCDB; + len = 0; + pkt->scsi_status = S_CKCON; + pkt->option_flags |= (uint32_t)OF_SSTS | + (uint32_t)OF_NO_DATA; + break; + } + break; + default: +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print("qla1280_atio_entry: Unknown SCSI command\n\r"); + qla1280_dump_buffer((caddr_t)&pkt->cdb[0], pkt->cdb_len); +#endif + bzero(sense_ptr, TARGET_SENSE_SIZE); + *sense_ptr = 0x70; + *(sense_ptr+2) = SD_ILLREQ; + *(sense_ptr+7) = TARGET_SENSE_SIZE-8; + *(sense_ptr+12) = SC_INVOPCODE; + len = 0; + pkt->scsi_status = S_CKCON; + pkt->option_flags |= (uint32_t)OF_SSTS | + (uint32_t)OF_NO_DATA; + break; + } + if (ha->flags.enable_64bit_addressing) + qla1280_64bit_continue_io(ha, pkt, len, (paddr32_t *)&phy_addr); + else + qla1280_32bit_continue_io(ha, pkt, len, (paddr32_t *)&phy_addr); + break; + default: + break; + } + +#ifdef QL_DEBUG_LEVEL_3 + qla1280_print("qla1280_atio_entry: exiting normally\n\r"); +#endif +} + +/* + * qla1280_notify_entry + * Processes received ISP immediate notify entry. + * + * Input: + * ha = adapter block pointer. + * pkt = entry pointer. + */ +STATIC void +qla1280_notify_entry(scsi_qla_host_t *ha, notify_entry_t *pkt) +{ +#ifdef QL_DEBUG_LEVEL_3 + qla1280_print("qla1280_notify_entry: entered\n\r"); +#endif + + /* Acknowledge immediate notify */ + qla1280_notify_ack(ha, pkt); + + /* Issue notify entry to increment resource count */ + qla1280_immed_notify(ha, pkt); + +#ifdef QL_DEBUG_LEVEL_3 + qla1280_print("qla1280_notify_entry: exiting normally\n\r"); +#endif +} + +#endif /* QLA1280_TARGET_MODE_SUPPORT */ +/* + * qla1280_status_entry + * Processes received ISP status entry. + * + * Input: + * ha = adapter block pointer. + * pkt = entry pointer. + * done_q_first = done queue first pointer. + * done_q_last = done queue last pointer. + */ +STATIC void +qla1280_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt, srb_t **done_q_first, + srb_t **done_q_last) +{ + uint32_t b, t, l; + uint8_t sense_sz = 0; + srb_t *sp; + scsi_lu_t *q; + Scsi_Cmnd *cp; + +#ifdef QL_DEBUG_LEVEL_3 + ENTER("qla1280_status_entry"); +#endif + + /* Validate handle. */ + if (pkt->handle < MAX_OUTSTANDING_COMMANDS) + sp = ha->outstanding_cmds[pkt->handle]; + else + sp = 0; + + if (sp) + { + /* Free outstanding command slot. */ + ha->outstanding_cmds[pkt->handle] = 0; + + cp = sp->cmd; + /* Generate LU queue on cntrl, target, LUN */ + b = SCSI_BUS_32(cp); + t = SCSI_TCN_32(cp); + l = SCSI_LUN_32(cp); + q = LU_Q(ha, b, t, l); + if( pkt->comp_status || pkt->scsi_status ) + { + DEBUG(qla1280_print( "scsi: comp_status = ");) + DEBUG(qla1280_output_number((uint32_t)pkt->comp_status,16);) + DEBUG(qla1280_print( ", ");) + DEBUG(qla1280_print( " scsi_status = ");) + DEBUG(qla1280_output_number((uint32_t)pkt->scsi_status,16);) + DEBUG(qla1280_print( "\n\r");) + DEBUG(qla1280_print(", handle = ");) + DEBUG(qla1280_output_number((uint32_t)pkt->handle, 16);) + DEBUG(qla1280_print("\n\r");) + } + + /* Target busy */ + if ( pkt->scsi_status & SS_BUSY_CONDITION && + pkt->scsi_status != SS_RESERVE_CONFLICT ) + { + CMD_RESULT(cp) = (int) (DID_BUS_BUSY << 16) | + (pkt->scsi_status & 0xff); + } + else + { + + /* Save ISP completion status */ + CMD_RESULT(cp) = qla1280_return_status( pkt, cp ); + + if (pkt->scsi_status & SS_CHECK_CONDITION) + { + BZERO(cp->sense_buffer, CMD_SNSLEN(cp)); + if (pkt->comp_status != CS_ARS_FAILED) + { + if ( pkt->req_sense_length < CMD_SNSLEN(cp) ) + sense_sz = pkt->req_sense_length; + else + sense_sz = CMD_SNSLEN(cp) - 1; + + BCOPY((caddr_t)&pkt->req_sense_data, cp->sense_buffer, sense_sz); + + } +#ifdef QL_DEBUG_LEVEL_2 + DEBUG(qla1280_print( + "qla1280_status_entry: Check condition Sense data, b");) + DEBUG(qla1280_output_number((uint32_t)b, 10);) + DEBUG(qla1280_print("t");) + DEBUG(qla1280_output_number((uint32_t)t, 10);) + DEBUG(qla1280_print("d");) + DEBUG(qla1280_output_number((uint32_t)l, 10);) + DEBUG(qla1280_print("\n\r");) + DEBUG(if (sense_sz)) + DEBUG(qla1280_dump_buffer(cp->sense_buffer, sense_sz);) +#endif + } + } + /* Place command on done queue. */ + qla1280_done_q_put(sp, done_q_first, done_q_last); + } + else + { +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print("qla1280_status_entry: ISP Invalid handle\n\r"); +#endif + printk(KERN_WARNING "qla1280: Status Entry invalid handle\n"); + ha->flags.isp_abort_needed = TRUE; + } +#ifdef QL_DEBUG_LEVEL_3 + LEAVE("qla1280_status_entry"); +#endif +} + +/* + * qla1280_error_entry + * Processes error entry. + * + * Input: + * ha = adapter block pointer. + * pkt = entry pointer. + * done_q_first = done queue first pointer. + * done_q_last = done queue last pointer. + */ +STATIC void +qla1280_error_entry(scsi_qla_host_t *ha, response_t *pkt, srb_t **done_q_first, + srb_t **done_q_last) +{ + srb_t *sp; + +#ifdef QL_DEBUG_LEVEL_3 + ENTER("qla1280_error_entry"); +#endif + +#ifdef QL_DEBUG_LEVEL_2 + if (pkt->entry_status & BIT_3) + qla1280_print("qla1280_error_entry: BAD PAYLOAD flag error\n\r"); + else if (pkt->entry_status & BIT_2) + qla1280_print("qla1280_error_entry: BAD HEADER flag error\n\r"); + else if (pkt->entry_status & BIT_1) + qla1280_print("qla1280_error_entry: FULL flag error\n\r"); + else + qla1280_print("qla1280_error_entry: UNKNOWN flag error\n\r"); +#endif + + /* Validate handle. */ + if (pkt->handle < MAX_OUTSTANDING_COMMANDS) + sp = ha->outstanding_cmds[pkt->handle]; + else + sp = 0; + + if (sp) + { + /* Free outstanding command slot. */ + ha->outstanding_cmds[pkt->handle] = 0; + + /* Bad payload or header */ + if (pkt->entry_status & (BIT_3 + BIT_2)) + { + /* Bad payload or header, set error status. */ + /* CMD_RESULT(sp->cmd) = CS_BAD_PAYLOAD; */ + CMD_RESULT(sp->cmd) = (int) DID_ERROR << 16; + } + else if (pkt->entry_status & BIT_1 ) /* FULL flag */ + { + CMD_RESULT(sp->cmd) = (int) DID_BUS_BUSY << 16; + } + else + { + /* Set error status. */ + CMD_RESULT(sp->cmd) =(int) DID_ERROR << 16; + } + /* Place command on done queue. */ + qla1280_done_q_put(sp, done_q_first, done_q_last); + } +#if QLA1280_64BIT_SUPPORT + else if (pkt->entry_type == COMMAND_A64_TYPE) + { +#ifdef QL_DEBUG_LEVEL_2 + qla1280_print("qla1280_error_entry: ISP Invalid handle\n\r"); +#endif + printk(KERN_WARNING, "!qla1280: Error Entry invalid handle"); + ha->flags.isp_abort_needed = TRUE; + } +#endif + +#ifdef QL_DEBUG_LEVEL_3 + LEAVE("qla1280_error_entry"); +#endif +} + +/* + * qla1280_abort_isp + * Resets ISP and aborts all outstanding commands. + * + * Input: + * ha = adapter block pointer. + * + * Returns: + * 0 = success + */ +STATIC uint8_t +qla1280_abort_isp(scsi_qla_host_t *ha) +{ + device_reg_t *reg = ha->iobase; + uint8_t status = 0; + uint16_t cnt; + srb_t *sp; + scsi_lu_t *q; + uint32_t b, t, l; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) + unsigned long cpu_flags = 0; +#endif + +#ifdef QL_DEBUG_LEVEL_3 + ENTER("qla1280_abort_isp"); +#endif + + DRIVER_LOCK + ha->flags.isp_abort_needed = FALSE; + if (!ha->flags.abort_isp_active && ha->flags.online) + { + ha->flags.abort_isp_active = TRUE; + + /* Disable ISP interrupts. */ + WRT_REG_WORD(®->ictrl, 0); + + /* Dequeue all commands in outstanding command list. */ + for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) + { + sp = ha->outstanding_cmds[cnt]; + if (sp) + { + ha->outstanding_cmds[cnt] = 0; + + /* Generate LU queue on controller, target, LUN */ + b = SCSI_BUS_32(sp->cmd); + t = SCSI_TCN_32(sp->cmd); + l = SCSI_LUN_32(sp->cmd); + + q = (scsi_lu_t *)LU_Q(ha, b, t, l); + + /* Reset outstanding command count. */ + q->q_outcnt = 0; + q->q_flag &= ~QLA1280_QBUSY; + q->q_flag = 0; + + /* Adjust watchdog timer for command. */ + /* if (sp->flags & SRB_WATCHDOG) + sp->timeout += 2; */ + + /* Place request back on top of device queue. */ + sp->flags &= ~(SRB_SENT | SRB_TIMEOUT); + sp->flags = 0; + qla1280_putq_t(q, sp); + } + } + + /* If firmware needs to be loaded */ + if (qla1280_isp_firmware(ha)) + { + if (!(status = qla1280_chip_diag(ha))) + status = qla1280_setup_chip(ha); + } + + if (!status) + { + /* Setup adapter based on NVRAM parameters. */ + qla1280_nvram_config(ha); + + if (!(status = qla1280_init_rings(ha))) + { + /* Issue SCSI reset. */ + for (b = 0; b < ha->ports; b++) + { + qla1280_bus_reset(ha, b); + } + do + { + /* Issue marker command. */ + ha->flags.reset_marker = FALSE; + for (b = 0; b < ha->ports; b++) + { + ha->bus_settings[b].reset_marker = FALSE; + qla1280_marker(ha, b, 0, 0, MK_SYNC_ALL); + } + }while (ha->flags.reset_marker); + + /* Enable host adapter target mode. */ + for (b = 0; b < ha->ports; b++) + { + if (!(status = qla1280_enable_tgt(ha, b))) + { + for (cnt = 0; cnt < MAX_LUNS; cnt++) + { + /* qla1280_enable_lun(ha, b, cnt); */ + qla1280_poll(ha); + } + } + else + break; + } + + if (!status) + { + /* Enable ISP interrupts. */ + WRT_REG_WORD(®->ictrl, ISP_EN_INT + ISP_EN_RISC); + ha->flags.abort_isp_active = FALSE; + /* Restart queues that may have been stopped. */ + qla1280_restart_queues(ha); + } + } + } + } + + if (status) + { + printk(KERN_WARNING + "qla1280: ISP error recovery failed, board disabled"); + qla1280_reset_adapter(ha); + qla1280_abort_queues(ha); + +#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) + qla1280_print("qla1280_abort_isp: **** FAILED ****\n\r"); +#endif + } +#ifdef QL_DEBUG_LEVEL_3 + else + LEAVE("qla1280_abort_isp"); +#endif + DRIVER_UNLOCK + + return(status); +} + +/* + * qla1280_restart_queues + * Restart all device queues. + * + * Input: + * ha = adapter block pointer. + */ +STATIC void +qla1280_restart_queues(scsi_qla_host_t *ha) +{ + scsi_lu_t *q; + uint32_t b, t, l; + +#ifdef QL_DEBUG_LEVEL_3 + ENTER("qla1280_restart_queues"); +#endif + + for (b = 0; b < ha->ports; b++) + for (t = 0; t < MAX_TARGETS; t++) + for (l = 0; l < MAX_LUNS; l++) + { + q = (scsi_lu_t *) LU_Q(ha, b, t, l); + if (q != NULL) + { + /* Acquire LU queue specific lock */ + QLA1280_SCSILU_LOCK(q); + + if (q->q_first) + qla1280_next(ha, q, b); + else + /* Release LU queue specific lock */ + QLA1280_SCSILU_UNLOCK(q); + } + } +#ifdef QL_DEBUG_LEVEL_3 + qla1280_print("qla1280_restart_queues: exiting normally\n"); +#endif +} + +/* + * qla1280_abort_queue_single + * Abort all commands on a device queues. + * + * Input: + * ha = adapter block pointer. + */ +STATIC void qla1280_abort_queue_single(scsi_qla_host_t *ha,uint32_t b,uint32_t t,uint32_t l,uint32_t stat) +{ + scsi_lu_t *q; + srb_t *sp, *sp_next; + + ENTER("qla1280_abort_queue_single"); + q = (scsi_lu_t * )LU_Q(ha, b, t, l); + if (q != NULL) + { + /* Acquire LU queue specific lock */ + QLA1280_SCSILU_LOCK(q); + + sp = q->q_first; + q->q_first = q->q_last = NULL; + + QLA1280_SCSILU_UNLOCK(q); + + while (sp) + { + sp_next = sp->s_next; + CMD_RESULT(sp->cmd) = stat; + qla1280_done_q_put(sp, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last); + sp = sp_next; + } + } + LEAVE("qla1280_abort_queue_single"); +} + +/* + * qla1280_abort_queues + * Abort all commands on device queues. + * + * Input: + * ha = adapter block pointer. + */ +STATIC void +qla1280_abort_queues(scsi_qla_host_t *ha) +{ + uint32_t b, t, l; + + ENTER("qla1280_abort_queues"); + + for (b = 0; b < ha->ports; b++) + for (t = 0; t < MAX_TARGETS; t++) + for (l = 0; l < MAX_LUNS; l++) + qla1280_abort_queue_single(ha,b,t,l,DID_RESET); + + LEAVE("qla1280_abort_queues"); +} + +/* + * qla1280_debounce_register + * Debounce register. + * + * Input: + * port = register address. + * + * Returns: + * register value. + */ +STATIC uint16_t +qla1280_debounce_register(volatile uint16_t *addr) +{ + volatile uint16_t ret; + volatile uint16_t ret2; + + do + { + ret = RD_REG_WORD(addr); + ret2 = RD_REG_WORD(addr); + }while (ret != ret2); + + return(ret); +} + + +/* + * Declarations for load module + */ +#ifdef MODULE +Scsi_Host_Template driver_template = QLA1280_LINUX_TEMPLATE; + +#include "scsi_module.c" +#endif + +/************************************************************************ + * qla1280_check_for_dead_scsi_bus * + * * + * This routine checks for a dead SCSI bus * + ************************************************************************/ +#define SET_SXP_BANK 0x0100 +#define SCSI_PHASE_INVALID 0x87FF +int qla1280_check_for_dead_scsi_bus(scsi_qla_host_t *ha, srb_t *sp) +{ + uint16_t config_reg, scsi_control; + device_reg_t *reg = ha->iobase; + uint32_t b; + Scsi_Cmnd *cp; + + /* + * If SCSI Bus is Dead because of bad termination, + * we will return a status of Selection timeout. + */ + + cp = sp->cmd; + b = SCSI_BUS_32(cp); + if (ha->bus_settings[b].scsi_bus_dead) + { + WRT_REG_WORD(®->host_cmd, HC_PAUSE_RISC); + config_reg = RD_REG_WORD(®->cfg_1); + WRT_REG_WORD(®->cfg_1,SET_SXP_BANK); + scsi_control = RD_REG_WORD(®->scsiControlPins); + WRT_REG_WORD(®->cfg_1,config_reg); + WRT_REG_WORD(®->host_cmd, HC_RELEASE_RISC); + + if (scsi_control == SCSI_PHASE_INVALID) + { + CMD_RESULT(cp) = DID_NO_CONNECT << 16; + CMD_HANDLE(cp) = (unsigned char *) 0; + /* ha->actthreads--; */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) + sti(); + (*(cp)->scsi_done)(cp); + cli(); +#else + (*(cp)->scsi_done)(cp); +#endif + return(TRUE); /* bus is dead */ + } + else + { + ha->bus_settings[b].scsi_bus_dead = FALSE; + ha->bus_settings[b].failed_reset_count= 0; + } + } + return(FALSE); /* bus is not dead */ +} + + + +#ifdef QL_DEBUG_ROUTINES +/****************************************************************************/ +/* Driver Debug Functions. */ +/****************************************************************************/ + +/* + * Get byte from I/O port + */ +STATIC uint8_t +qla1280_getbyte(uint8_t *port) +{ + uint8_t ret; + +#if MEMORY_MAPPED_IO + ret = *port; +#else + ret = inb((int)port); +#endif + + if (ql_debug_print) + { + qla1280_print("qla1280_getbyte: address = "); + qla1280_output_number((uint32_t)port, 16); + qla1280_print(" data = 0x"); + qla1280_output_number((uint32_t)ret, 16); + qla1280_print("\n\r"); + } + + return(ret); +} + +/* + * Get word from I/O port + */ +STATIC uint16_t +qla1280_getword(uint16_t *port) +{ + uint16_t ret; + +#if MEMORY_MAPPED_IO + ret = *port; +#else + ret = inw((int)port); +#endif + + if (ql_debug_print) + { + qla1280_print("qla1280_getword: address = "); + qla1280_output_number((uint32_t)port, 16); + qla1280_print(" data = 0x"); + qla1280_output_number((uint32_t)ret, 16); + qla1280_print("\n\r"); + } + + return(ret); +} + +/* + * Get double word from I/O port + */ +STATIC uint32_t +qla1280_getdword(uint32_t *port) +{ + uint32_t ret; + +#if MEMORY_MAPPED_IO + ret = *port; +#else + ret = inl((int)port); +#endif + + if (ql_debug_print) + { + qla1280_print("qla1280_getdword: address = "); + qla1280_output_number((uint32_t)port, 16); + qla1280_print(" data = 0x"); + qla1280_output_number((uint32_t)ret, 16); + qla1280_print("\n\r"); + } + + return(ret); +} + +/* + * Send byte to I/O port + */ +STATIC void +qla1280_putbyte(uint8_t *port, uint8_t data) +{ +#if MEMORY_MAPPED_IO + *port = data; +#else + outb(data, (int)port); +#endif + + if (ql_debug_print) + { + qla1280_print("qla1280_putbyte: address = "); + qla1280_output_number((uint32_t)port, 16); + qla1280_print(" data = 0x"); + qla1280_output_number((uint32_t)data, 16); + qla1280_print("\n\r"); + } +} + +/* + * Send word to I/O port + */ +STATIC void +qla1280_putword(uint16_t *port, uint16_t data) +{ +#if MEMORY_MAPPED_IO + *port = data; +#else +#ifdef _LINUX_IOPORTS + outw(data, (int)port); +#else + outw((int)port, data); +#endif +#endif + + if (ql_debug_print) + { + qla1280_print("qla1280_putword: address = "); + qla1280_output_number((uint32_t)port, 16); + qla1280_print(" data = 0x"); + qla1280_output_number((uint32_t)data, 16); + qla1280_print("\n\r"); + } +} + +/* + * Send double word to I/O port + */ +STATIC void +qla1280_putdword(uint32_t *port, uint32_t data) +{ +#if MEMORY_MAPPED_IO + *port = data; +#else +#ifdef _LINUX_IOPORTS + outl(data,(int)port); +#else + outl((int)port, data); +#endif +#endif + + if (ql_debug_print) + { + qla1280_print("qla1280_putdword: address = "); + qla1280_output_number((uint32_t)port, 16); + qla1280_print(" data = 0x"); + qla1280_output_number((uint32_t)data, 16); + qla1280_print("\n\r"); + } +} + +/* + * Dummy function to prevent warnings for + * declared and unused debug functions + */ +void +qla1280_debug(void) +{ + qla1280_getbyte(0); + qla1280_getword(0); + qla1280_getdword(0); + qla1280_putbyte(0, 0); + qla1280_putword(0, 0); + qla1280_putdword(0, 0); +} + +/* + * Out character to COM2 port. + * PORT must be at standard address for COM2 = 0x2F8, + * or COM1 = 0x3F8 + */ +#define OUTB(addr,data) outb((data),(addr)) + +STATIC void +qla1280_putc(uint8_t c) +{ +#ifdef QL_DEBUG_CONSOLE + printk("%c", c); +#else + int com_addr = 0x2f8; + int hardware_flow_control = 1; + int software_flow_control = 0; + uint8_t data; + + /* Wait for transmitter holding and shift registers for empty. */ + do + { + data = inb(com_addr+5); + }while (!(data & BIT_6)); + + /* + * Set BAUD rate for COM2 to 19200 (0x6) + */ + + /* Select rate divisor. */ + OUTB(com_addr+3, 0x83); + + /* BAUD rate divisor LSB. */ + OUTB(com_addr, 0xc); /* 0xC = 9600 baud */ + + /* BAUD rate divisor MSB. */ + OUTB(com_addr+1, 0); + + /* Set No parity, 8 bits, 1 stop bit and + select interrupt enable register. */ + OUTB(com_addr+3, 3); + + /* Disable interrupts. */ + OUTB(com_addr+1, 0); + + /* Set data terminal ready and request to send */ + OUTB(com_addr+4,3); + + if (hardware_flow_control) + { + /* Wait for clear-to-send and data-set-ready */ + do + { + data = inb(com_addr+6) & (BIT_5 + BIT_4); + }while (data != (BIT_5 + BIT_4)); + } + else if (software_flow_control) + { + /* Test for data ready. */ + data = inb(com_addr+5); + if (data & BIT_0) + { + /* If XOFF */ + data = inb(com_addr); + if (data == '\023') + { + /* Wait for XON */ + do + { + /* Wait for char */ + do + { + data = inb(com_addr+5); + }while (!(data & BIT_0)); + data = inb(com_addr); + }while (data != '\021'); + } + } + } + + /* Output character. */ + OUTB(com_addr, c); +#endif +} + +/* + * Out NULL terminated string to COM port. + */ +STATIC void +qla1280_print(caddr_t s) +{ + if (ql_debug_print) + { +#ifdef QL_DEBUG_CONSOLE + printk("%s",s); +#else + /* Output string. */ + while (*s) + qla1280_putc(*s++); +#endif + } +} + +/* + * Output long number to COM port. + */ +STATIC void +qla1280_output_number(uint32_t n, uint8_t base) +{ + int8_t str[12]; + int8_t *s = &str[11]; + int8_t output = 0; + int8_t hex = FALSE; + + if (ql_debug_print) + { + if (base == 10 || base == 16) + { + if (base == 16 && n > 9) + hex = TRUE; + + *s = 0; + do + { + s--; + *s = n % base; + if (*s > 9) + *s += 55; + else + *s += '0'; + n /= base; + }while (n); + + for (; *s; s++) + { + if (*s != '0') + output = 1; + if (output) + qla1280_putc(*s); + } + if (!output) + qla1280_putc(*--s); + + if (hex) + qla1280_putc('h'); + } + } +} + +STATIC void +qla1280_dump_buffer(caddr_t b, uint32_t size) +{ + uint32_t cnt; + uint8_t c; + + if (ql_debug_print) + { + qla1280_print( + " 0 1 2 3 4 5 6 7 8 9 Ah Bh Ch Dh Eh Fh\n\r"); + qla1280_print( + "---------------------------------------------------------------\n\r"); + + for (cnt = 0; cnt < size; ) + { + c = *b++; + if (c < 16) + qla1280_putc(' '); + qla1280_output_number((uint32_t)c, 16); + cnt++; + if (!(cnt % 16)) + qla1280_print("\n\r"); + else if (c < 10) + qla1280_print(" "); + else + qla1280_putc(' '); + } + if (cnt % 16) + qla1280_print("\n\r"); + } +} +/************************************************************************** + * ql1280_print_scsi_cmd + * + **************************************************************************/ +void qla1280_print_scsi_cmd(Scsi_Cmnd *cmd) +{ + scsi_qla_host_t *ha; + struct Scsi_Host *host = cmd->host; + srb_t *sp; + /* struct scatterlist *sg; */ + + int i; + ha = (scsi_qla_host_t *) host->hostdata; + + ql_debug_print = 1; + sp = (srb_t *) CMD_SP(cmd); + sprintf(debug_buff,"SCSI Command @= 0x%08x, Handle=0x%08x\n\r", (int)cmd,(int) (int)CMD_HANDLE(cmd)); + qla1280_print(debug_buff); + sprintf(debug_buff," chan=%d, target = 0x%02x, lun = 0x%02x, cmd_len = 0x%02x\n\r", + cmd->channel, cmd->target, cmd->lun, cmd->cmd_len); + qla1280_print(debug_buff); + qla1280_print(" CDB = "); + for (i = 0; i < cmd->cmd_len; i++) + { + sprintf(debug_buff,"0x%02x ", cmd->cmnd[i]); + qla1280_print(debug_buff); + } + sprintf(debug_buff," seg_cnt =%d\n\r",cmd->use_sg); + qla1280_print(debug_buff); + sprintf(debug_buff," request buffer=0x%x, request buffer len=0x%x\n\r",(int)cmd->request_buffer,cmd->request_bufflen); + qla1280_print(debug_buff); + /* if( cmd->use_sg ) + { + sg = (struct scatterlist *) cmd->request_buffer; + qla1280_print(" SG buffer: \n\r"); + qla1280_dump_buffer((caddr_t)sg, (cmd->use_sg*sizeof(struct scatterlist)) ); + } */ + sprintf(debug_buff," tag=%d, flags=0x%x, transfersize=0x%x \n\r", + cmd->tag, cmd->flags,cmd->transfersize ); + qla1280_print(debug_buff); + sprintf(debug_buff," Pid=%d, SP=0x%x\n\r", (int)cmd->pid, (int)CMD_SP(cmd)); + qla1280_print(debug_buff); + sprintf(debug_buff," r_start=0x%lx, u_start=0x%lx\n\r",sp->r_start,sp->u_start); + qla1280_print(debug_buff); + sprintf(debug_buff," underflow size = 0x%lx, direction=0x%x, req.cmd=0x%x \n\r", cmd->underflow, sp->dir,cmd->request.cmd); + qla1280_print(debug_buff); +} +/************************************************************************** + * ql1280_dump_device + * + **************************************************************************/ +void +ql1280_dump_device(scsi_qla_host_t *ha) +{ + + Scsi_Cmnd *cp; + srb_t *sp; + int i; + qla1280_print("Outstanding Commands on controller:\n\r"); + for ( i=0; i < MAX_OUTSTANDING_COMMANDS; i++ ) + { + if( (sp = ha->outstanding_cmds[i]) == NULL ) + continue; + if( (cp = sp->cmd) == NULL ) + continue; + qla1280_print_scsi_cmd(cp); + } + +} +#endif + +#ifdef QLA1280_UNUSED +/************************************************************************** + * ql1280_dump_regs + * + **************************************************************************/ +static void qla1280_dump_regs(struct Scsi_Host *host) +{ + printk("Mailbox registers:\n"); + printk("qla1280 : mbox 0 0x%04x \n", inw(host->io_port + 0x70)); + printk("qla1280 : mbox 1 0x%04x \n", inw(host->io_port + 0x72)); + printk("qla1280 : mbox 2 0x%04x \n", inw(host->io_port + 0x74)); + printk("qla1280 : mbox 3 0x%04x \n", inw(host->io_port + 0x76)); + printk("qla1280 : mbox 4 0x%04x \n", inw(host->io_port + 0x78)); + printk("qla1280 : mbox 5 0x%04x \n", inw(host->io_port + 0x7a)); +} +#endif + + + +#if STOP_ON_ERROR +/************************************************************************** + * ql1280_panic + * + **************************************************************************/ +static void qla1280_panic(char *cp, struct Scsi_Host *host) +{ + scsi_qla_host_t *ha; + long *fp; + + ha = (scsi_qla_host_t *) host->hostdata; + printk("qla1280 - PANIC: %s\n",cp); + printk("Current time=0x%lx\n", jiffies); + printk("Number of pending commands =0x%lx\n", ha->actthreads); + printk("Number of SCSI queued commands =0x%lx\n", ha->qthreads); + printk("Number of free entries = (%d)\n",ha->req_q_cnt); + printk("Request Queue @ 0x%lx, Response Queue @ 0x%lx\n", + ha->request_dma, + ha->response_dma); + printk("Request In Ptr %d\n", ha->req_ring_index ); + fp = (long *) &ha->flags; + printk("HA flags =0x%lx\n", *fp); + DEBUG2(ql_debug_print = 1;) + /* DEBUG2(ql1280_dump_device((scsi_qla_host_t *) host->hostdata)); */ +#ifdef QLA1280_UNUSED + qla1280_dump_regs(host); +#endif + sti(); + panic("Ooops"); + /* cli(); + for(;;) + { + barrier(); + sti(); + } + */ +} +#endif + +#ifdef QLA1280_UNUSED +static void qla1280_set_flags(char * s) +{ +} +#endif + +/************************************************************************** + * qla1280_setup + * + * Handle Linux boot parameters. This routine allows for assigning a value + * to a parameter with a ':' between the parameter and the value. + * ie. qla1280=max_reqs:0x0A,verbose + **************************************************************************/ +void +qla1280_setup(char *s, int *dummy) +{ + char *end, *str, *cp; + +#ifdef QLA1280_UNUSED + static struct + { + const char *name; + int siz; + void (*func)(); + int arg; + } options[] = + { + { "dump_regs", 9, &qla1280_dump_regs, 0 + }, + { "verbose", 7, &qla1280_set_flags, 0x1 + }, + { "", 0, NULL, 0 + } + }; +#endif + + printk("scsi: Processing Option str = %s\n", s); + end = strchr(s, '\0'); + /* locate command */ + str = s; + for( cp = s; *cp && cp != end; cp++ ) + { + cp = qla1280_get_token(cp, str); + printk("scsi: token str = %s\n", str); + /* if found execute routine */ + + } + +} + +static char *qla1280_get_token(char *cmdline, char *str ) +{ + register char *cp = cmdline; + + /* skip preceeding spaces */ + while(strchr(cp,' ')) + ++cp; + /* symbol starts here */ + str = cp; + /* skip char if not a space or : */ + while (*cp && !( strchr(cp,' ') || strchr(cp,':')) ) + cp++; + *cp = '\0'; + return( cp ); +} + +/* + * Overrides for Emacs so that we almost follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-indent-level: 2 + * c-brace-imaginary-offset: 0 + * c-brace-offset: -2 + * c-argdecl-indent: 2 + * c-label-offset: -2 + * c-continued-statement-offset: 2 + * c-continued-brace-offset: 0 + * indent-tabs-mode: nil + * tab-width: 8 + * End: + */ + diff -Naur linux.2210/drivers/scsi/qla1280.h linux.2210.vw/drivers/scsi/qla1280.h --- linux.2210/drivers/scsi/qla1280.h Wed Dec 31 16:00:00 1969 +++ linux.2210.vw/drivers/scsi/qla1280.h Thu Jul 15 05:01:44 1999 @@ -0,0 +1,1334 @@ +/* + * QLogic ISP1280 Linux Driver + * Host Bus Adapter driver include file. + */ + +/************************************************************************* +** ** +** NOTICE ** +** COPYRIGHT (C) 1999 QLOGIC CORPORATION ** +** ALL RIGHTS RESERVED ** +** ** +** This computer program is CONFIDENTIAL and contains TRADE SECRETS of ** +** QLOGIC CORPORATION. The receipt or possession of this program does ** +** not convey any rights to reproduce or disclose its contents, or to ** +** manufacture, use, or sell anything that it may describe, in whole or ** +** in part, without the specific written consent of QLOGIC CORPORATION. ** +** Any reproduction of this program without the express written consent ** +** of QLOGIC CORPORATION is a violation of the copyright laws and may ** +** subject you to civil liability and criminal prosecution. ** +** ** +*************************************************************************/ + +#ifndef _IO_HBA_QLA1280_H /* wrapper symbol for kernel use */ +#define _IO_HBA_QLA1280_H /* subject to change without notice */ + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * Enable define statement to ignore Data Underrun Errors, + * remove define statement to enable detection. + */ +/* #define DATA_UNDERRUN_ERROR_DISABLE */ + +/* + * Driver debug definitions. + */ +/* #define QL_DEBUG_LEVEL_1 */ /* Output register accesses to COM2. */ +/* #define QL_DEBUG_LEVEL_2 */ /* Output error msgs to COM2. */ +/* #define QL_DEBUG_LEVEL_3 */ /* Output function trace msgs to COM2. */ +/* #define QL_DEBUG_LEVEL_4 */ /* Output NVRAM trace msgs to COM2. */ +/* #define QL_DEBUG_LEVEL_5 */ /* Output ring trace msgs to COM2. */ +/* #define QL_DEBUG_LEVEL_6 */ /* Output WATCHDOG timer trace to COM2. */ +/* #define QL_DEBUG_LEVEL_7 */ /* Output RISC load trace msgs to COM2. */ + +#define QL_DEBUG_CONSOLE /* Output to console instead of COM2. */ + +#ifndef TRUE +# define TRUE 1 +#endif +#ifndef FALSE +# define FALSE 0 +#endif + + +#ifndef KERNEL_VERSION +# define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) +#endif + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,1,92) +# if defined(__sparc_v9__) || defined(__powerpc__) +# error "PPC and Sparc platforms are only support under 2.1.92 and above" +# endif +#endif + + +/* + * Locking + */ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0) +# include +# include +# define cpuid smp_processor_id() +# if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) +# define DRIVER_LOCK_INIT \ + spin_lock_init(&ha->spin_lock); +# define DRIVER_LOCK \ + if(!ha->cpu_lock_count[cpuid]) { \ + spin_lock_irqsave(&ha->spin_lock, cpu_flags); \ + ha->cpu_lock_count[cpuid]++; \ + } else { \ + ha->cpu_lock_count[cpuid]++; \ + } +# define DRIVER_UNLOCK \ + if(--ha->cpu_lock_count[cpuid] == 0) \ + spin_unlock_irqrestore(&ha->spin_lock, cpu_flags); +# else +# define DRIVER_LOCK_INIT +# define DRIVER_LOCK +# define DRIVER_UNLOCK +# endif +#else +# define cpuid 0 +# define DRIVER_LOCK_INIT +# define DRIVER_LOCK \ + save_flags(cpu_flags); \ + cli(); +# define DRIVER_UNLOCK \ + restore_flags(cpu_flags); +# define le32_to_cpu(x) (x) +# define cpu_to_le32(x) (x) +#endif + +/* + * Data bit definitions. + */ +#define BIT_0 0x1 +#define BIT_1 0x2 +#define BIT_2 0x4 +#define BIT_3 0x8 +#define BIT_4 0x10 +#define BIT_5 0x20 +#define BIT_6 0x40 +#define BIT_7 0x80 +#define BIT_8 0x100 +#define BIT_9 0x200 +#define BIT_10 0x400 +#define BIT_11 0x800 +#define BIT_12 0x1000 +#define BIT_13 0x2000 +#define BIT_14 0x4000 +#define BIT_15 0x8000 +#define BIT_16 0x10000 +#define BIT_17 0x20000 +#define BIT_18 0x40000 +#define BIT_19 0x80000 +#define BIT_20 0x100000 +#define BIT_21 0x200000 +#define BIT_22 0x400000 +#define BIT_23 0x800000 +#define BIT_24 0x1000000 +#define BIT_25 0x2000000 +#define BIT_26 0x4000000 +#define BIT_27 0x8000000 +#define BIT_28 0x10000000 +#define BIT_29 0x20000000 +#define BIT_30 0x40000000 +#define BIT_31 0x80000000 + +/* + * Common size type definitions + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; +typedef char int8_t; +typedef short int16_t; +typedef long int32_t; +#endif + +/* + * Local Macro Definitions. + */ +#if defined(QL_DEBUG_LEVEL_1) || defined(QL_DEBUG_LEVEL_2) || \ + defined(QL_DEBUG_LEVEL_3) || defined(QL_DEBUG_LEVEL_4) || \ + defined(QL_DEBUG_LEVEL_5) || defined(QL_DEBUG_LEVEL_6) || \ + defined(QL_DEBUG_LEVEL_7) + #define QL_DEBUG_ROUTINES +#endif + +/* + * I/O port macros +*/ +#define LINUX_IOPORTS /* Linux in/out routines are define*/ + /* differently from other OSs */ +/* #define MEMORY_MAPPED_IO */ /* Enable memory mapped I/O */ +#undef MEMORY_MAPPED_IO /* Disable memory mapped I/O */ + +#ifdef QL_DEBUG_LEVEL_1 +#define RD_REG_BYTE(addr) qla1280_getbyte((uint8_t *)addr) +#define RD_REG_WORD(addr) qla1280_getword((uint16_t *)addr) +#define RD_REG_DWORD(addr) qla1280_getdword((uint32_t *)addr) +#define WRT_REG_BYTE(addr, data) qla1280_putbyte((uint8_t *)addr, data) +#define WRT_REG_WORD(addr, data) qla1280_putword((uint16_t *)addr, data) +#define WRT_REG_DWORD(addr, data) qla1280_putdword((uint32_t *)addr, data) +#else /* QL_DEBUG_LEVEL_1 */ +#ifdef MEMORY_MAPPED_IO + #define RD_REG_BYTE(addr) (*((volatile uint8_t *)addr)) + #define RD_REG_WORD(addr) (*((volatile uint16_t *)addr)) + #define RD_REG_DWORD(addr) (*((volatile uint32_t *)addr)) + #define WRT_REG_BYTE(addr, data) (*((volatile uint8_t *)addr) = data) + #define WRT_REG_WORD(addr, data) (*((volatile uint16_t *)addr) = data) + #define WRT_REG_DWORD(addr, data) (*((volatile uint32_t *)addr) = data) +#else /* MEMORY_MAPPED_IO */ +#define RD_REG_BYTE(addr) (inb((int)addr)) +#define RD_REG_WORD(addr) (inw((int)addr)) +#define RD_REG_DWORD(addr) (inl((int)addr)) +#ifdef LINUX_IOPORTS +/* Parameters are reversed in Linux */ +#define WRT_REG_BYTE(addr, data) (outb(data,(int)addr)) +#define WRT_REG_WORD(addr, data) (outw(data,(int)addr)) +#define WRT_REG_DWORD(addr, data) (outl(data,(int)addr)) +#else +#define WRT_REG_BYTE(addr, data) (outb((int)addr, data)) +#define WRT_REG_WORD(addr, data) (outw((int)addr, data)) +#define WRT_REG_DWORD(addr, data) (outl((int)addr, data)) +#endif +#endif /* MEMORY_MAPPED_IO */ +#endif /* QL_DEBUG_LEVEL_1 */ + +/* + * Host adapter default definitions. + */ +#define MAX_BUSES 2 /* 2 */ +#define MAX_B_BITS 1 + +#define MAX_TARGETS 16 /* 16 */ +#define MAX_T_BITS 4 /* 4 */ + +#define MAX_LUNS 8 /* 32 */ +#define MAX_L_BITS 3 /* 5 */ + +/* + * Watchdog time quantum + */ +#define QLA1280_WDG_TIME_QUANTUM 5 /* In seconds */ + +/* Command retry count (0-65535) */ +#define COMMAND_RETRY_COUNT 255 + +/* Maximum outstanding commands in ISP queues (1-65535) */ +#define MAX_OUTSTANDING_COMMANDS 512 + +/* ISP request and response entry counts (37-65535) */ +#define REQUEST_ENTRY_CNT 256 /* Number of request entries. */ +#define RESPONSE_ENTRY_CNT 16 /* Number of response entries. */ + +/* Maximum equipage per controller */ +#define MAX_EQ (MAX_BUSES * MAX_TARGETS * MAX_LUNS) + +/* Number of segments 1 - 65535 */ +#define SG_SEGMENTS 32 /* Cmd entry + 6 continuations */ + + +typedef struct timer_list timer_t; /* timer */ + +/* + * SCSI Request Block structure + */ +typedef struct srb +{ + Scsi_Cmnd *cmd; /* (4) SCSI command block */ + struct srb *s_next; /* (4) Next block on LU queue */ + struct srb *s_prev; /* (4) Previous block on LU queue */ + uint8_t flags; /* (1) Status flags. */ + uint8_t dir; /* direction of transfer */ + uint8_t unused[2]; + u_long r_start; /* jiffies at start of request */ + u_long u_start; /* jiffies when sent to F/W */ +}srb_t; + +/* + * SRB flag definitions + */ +#define SRB_TIMEOUT BIT_0 /* Command timed out */ +#define SRB_SENT BIT_1 /* Command sent to ISP */ +#define SRB_ABORT_PENDING BIT_2 /* Command abort sent to device */ +#define SRB_ABORTED BIT_3 /* Command aborted command already */ + + +/* + * Logical Unit Queue structure + */ +typedef struct scsi_lu +{ + srb_t *q_first; /* First block on LU queue */ + srb_t *q_last; /* Last block on LU queue */ + uint8_t q_flag; /* LU queue state flags */ + uint8_t q_sense[16]; /* sense data */ + u_long io_cnt; /* total xfer count */ + u_long resp_time; /* total response time (start - finish) */ + u_long act_time; /* total actived time (minus queuing time) */ + u_long w_cnt; /* total writes */ + u_long r_cnt; /* total reads */ + uint16_t q_outcnt; /* Pending jobs for this LU */ +#if QL1280_TARGET_MODE_SUPPORT + void (*q_func)(); /* Target driver event handler */ + int32_t q_param; /* Target driver event param */ + uint8_t q_lock; /* Device Queue Lock */ +#endif +}scsi_lu_t; + +/* + * Logical Unit flags + */ +#define QLA1280_QBUSY BIT_0 +#define QLA1280_QWAIT BIT_1 +#define QLA1280_QSUSP BIT_2 +#define QLA1280_QSENSE BIT_3 /* Sense data cache valid */ +#define QLA1280_QRESET BIT_4 +#define QLA1280_QHBA BIT_5 +#define QLA1280_BSUSP BIT_6 /* controller is suspended */ +#define QLA1280_BREM BIT_7 /* controller is removed */ + +/* + * ISP PCI Configuration Register Set + */ +typedef volatile struct +{ + uint16_t vendor_id; /* 0x0 */ + uint16_t device_id; /* 0x2 */ + uint16_t command; /* 0x4 */ + uint16_t status; /* 0x6 */ + uint8_t revision_id; /* 0x8 */ + uint8_t programming_interface; /* 0x9 */ + uint8_t sub_class; /* 0xa */ + uint8_t base_class; /* 0xb */ + uint8_t cache_line; /* 0xc */ + uint8_t latency_timer; /* 0xd */ + uint8_t header_type; /* 0xe */ + uint8_t bist; /* 0xf */ + uint32_t base_port; /* 0x10 */ + uint32_t mem_base_addr; /* 0x14 */ + uint32_t base_addr[4]; /* 0x18-0x24 */ + uint32_t reserved_1[2]; /* 0x28-0x2c */ + uint16_t expansion_rom; /* 0x30 */ + uint32_t reserved_2[2]; /* 0x34-0x38 */ + uint8_t interrupt_line; /* 0x3c */ + uint8_t interrupt_pin; /* 0x3d */ + uint8_t min_grant; /* 0x3e */ + uint8_t max_latency; /* 0x3f */ +}config_reg_t; + +/* + * ISP I/O Register Set structure definitions. + */ +typedef volatile struct +{ + uint16_t id_l; /* ID low */ + uint16_t id_h; /* ID high */ + uint16_t cfg_0; /* Configuration 0 */ + uint16_t cfg_1; /* Configuration 1 */ + uint16_t ictrl; /* Interface control */ + #define ISP_RESET BIT_0 /* ISP soft reset */ + #define ISP_EN_INT BIT_1 /* ISP enable interrupts. */ + #define ISP_EN_RISC BIT_2 /* ISP enable RISC interrupts. */ + uint16_t istatus; /* Interface status */ + #define PCI_64BIT_SLOT BIT_14 /* PCI 64-bit slot indicator. */ + #define RISC_INT BIT_2 /* RISC interrupt */ + #define PCI_INT BIT_1 /* PCI interrupt */ + uint16_t semaphore; /* Semaphore */ + uint16_t nvram; /* NVRAM register. */ + #define NV_DESELECT 0 + #define NV_CLOCK BIT_0 + #define NV_SELECT BIT_1 + #define NV_DATA_OUT BIT_2 + #define NV_DATA_IN BIT_3 + uint16_t flash_data; /* Flash BIOS data */ + uint16_t flash_address; /* Flash BIOS address */ + + uint16_t unused_1[0x2e]; /* 0x14-0x6f Gap */ + + uint16_t mailbox0; /* Mailbox 0 */ + uint16_t mailbox1; /* Mailbox 1 */ + uint16_t mailbox2; /* Mailbox 2 */ + uint16_t mailbox3; /* Mailbox 3 */ + uint16_t mailbox4; /* Mailbox 4 */ + uint16_t mailbox5; /* Mailbox 5 */ + uint16_t mailbox6; /* Mailbox 6 */ + uint16_t mailbox7; /* Mailbox 7 */ + + uint16_t unused_2[0x20]; /* 0x80-0xbf Gap */ + + uint16_t host_cmd; /* Host command and control */ + #define HOST_INT BIT_7 /* host interrupt bit */ + #define BIOS_ENABLE BIT_0 + + uint16_t unused_6[0x5]; /* 0xc2-0xcb Gap */ + + uint16_t gpio_data; + uint16_t gpio_enable; + + uint16_t unused_7[0x11]; /* d0-f0 */ + uint16_t scsiControlPins; /* f2 */ + +}device_reg_t; + +#define MAILBOX_REGISTER_COUNT 8 + +/* + * ISP product identification definitions in mailboxes after reset. + */ +#define PROD_ID_1 0x4953 +#define PROD_ID_2 0x0000 +#define PROD_ID_2a 0x5020 +#define PROD_ID_3 0x2020 +#define PROD_ID_4 0x1 + +/* + * ISP host command and control register command definitions + */ +#define HC_RESET_RISC 0x1000 /* Reset RISC */ +#define HC_PAUSE_RISC 0x2000 /* Pause RISC */ +#define HC_RELEASE_RISC 0x3000 /* Release RISC from reset. */ +#define HC_SET_HOST_INT 0x5000 /* Set host interrupt */ +#define HC_CLR_HOST_INT 0x6000 /* Clear HOST interrupt */ +#define HC_CLR_RISC_INT 0x7000 /* Clear RISC interrupt */ +#define HC_DISABLE_BIOS 0x9000 /* Disable BIOS. */ + +/* + * ISP mailbox Self-Test status codes + */ +#define MBS_FRM_ALIVE 0 /* Firmware Alive. */ +#define MBS_CHKSUM_ERR 1 /* Checksum Error. */ +#define MBS_SHADOW_LD_ERR 2 /* Shadow Load Error. */ +#define MBS_BUSY 4 /* Busy. */ + +/* + * ISP mailbox command complete status codes + */ +#define MBS_CMD_CMP 0x4000 /* Command Complete. */ +#define MBS_INV_CMD 0x4001 /* Invalid Command. */ +#define MBS_HOST_INF_ERR 0x4002 /* Host Interface Error. */ +#define MBS_TEST_FAILED 0x4003 /* Test Failed. */ +#define MBS_CMD_ERR 0x4005 /* Command Error. */ +#define MBS_CMD_PARAM_ERR 0x4006 /* Command Parameter Error. */ + +/* + * ISP mailbox asynchronous event status codes + */ +#define MBA_ASYNC_EVENT 0x8000 /* Asynchronous event. */ +#define MBA_BUS_RESET 0x8001 /* SCSI Bus Reset. */ +#define MBA_SYSTEM_ERR 0x8002 /* System Error. */ +#define MBA_REQ_TRANSFER_ERR 0x8003 /* Request Transfer Error. */ +#define MBA_RSP_TRANSFER_ERR 0x8004 /* Response Transfer Error. */ +#define MBA_WAKEUP_THRES 0x8005 /* Request Queue Wake-up. */ +#define MBA_TIMEOUT_RESET 0x8006 /* Execution Timeout Reset. */ +#define MBA_DEVICE_RESET 0x8007 /* Bus Device Reset. */ +#define MBA_BUS_MODE_CHANGE 0x800E /* SCSI bus mode transition. */ +#define MBA_SCSI_COMPLETION 0x8020 /* Completion response. */ + +/* + * ISP mailbox commands + */ +#define MBC_NOP 0 /* No Operation. */ +#define MBC_LOAD_RAM 1 /* Load RAM. */ +#define MBC_EXECUTE_FIRMWARE 2 /* Execute firmware. */ +#define MBC_WRITE_RAM_WORD 4 /* Write ram word. */ +#define MBC_READ_RAM_WORD 5 /* Read ram word. */ +#define MBC_MAILBOX_REGISTER_TEST 6 /* Wrap incoming mailboxes */ +#define MBC_VERIFY_CHECKSUM 7 /* Verify checksum. */ +#define MBC_ABOUT_FIRMWARE 8 /* Get firmware revision. */ +#define MBC_INIT_REQUEST_QUEUE 0x10 /* Initialize request queue. */ +#define MBC_INIT_RESPONSE_QUEUE 0x11 /* Initialize response queue. */ +#define MBC_EXECUTE_IOCB 0x12 /* Execute IOCB command. */ +#define MBC_ABORT_COMMAND 0x15 /* Abort IOCB command. */ +#define MBC_ABORT_DEVICE 0x16 /* Abort device (ID/LUN). */ +#define MBC_ABORT_TARGET 0x17 /* Abort target (ID). */ +#define MBC_BUS_RESET 0x18 /* SCSI bus reset. */ +#define MBC_GET_RETRY_COUNT 0x22 /* Get retry count and delay. */ +#define MBC_GET_TARGET_PARAMETERS 0x28 /* Get target parameters. */ +#define MBC_SET_INITIATOR_ID 0x30 /* Set initiator SCSI ID. */ +#define MBC_SET_SELECTION_TIMEOUT 0x31 /* Set selection timeout. */ +#define MBC_SET_RETRY_COUNT 0x32 /* Set retry count and delay. */ +#define MBC_SET_TAG_AGE_LIMIT 0x33 /* Set tag age limit. */ +#define MBC_SET_CLOCK_RATE 0x34 /* Set clock rate. */ +#define MBC_SET_ACTIVE_NEGATION 0x35 /* Set active negation state. */ +#define MBC_SET_ASYNC_DATA_SETUP 0x36 /* Set async data setup time. */ +#define MBC_SET_PCI_CONTROL 0x37 /* Set BUS control parameters. */ +#define MBC_SET_TARGET_PARAMETERS 0x38 /* Set target parameters. */ +#define MBC_SET_DEVICE_QUEUE 0x39 /* Set device queue parameters */ +#define MBC_SET_SYSTEM_PARAMETER 0x45 /* Set system parameter word. */ +#define MBC_SET_FIRMWARE_FEATURES 0x4A /* Set firmware feature word. */ +#define MBC_INIT_REQUEST_QUEUE_A64 0x52 /* Initialize request queue A64 */ +#define MBC_INIT_RESPONSE_QUEUE_A64 0x53 /* Initialize response q A64. */ +#define MBC_ENABLE_TARGET_MODE 0x55 /* Enable target mode. */ + +/* + * ISP Get/Set Target Parameters mailbox command control flags. + */ +#define TP_RENEGOTIATE BIT_8 /* Renegotiate on error. */ +#define TP_STOP_QUEUE BIT_9 /* Stop que on check condition */ +#define TP_AUTO_REQUEST_SENSE BIT_10 /* Automatic request sense. */ +#define TP_TAGGED_QUEUE BIT_11 /* Tagged queuing. */ +#define TP_SYNC BIT_12 /* Synchronous data transfers. */ +#define TP_WIDE BIT_13 /* Wide data transfers. */ +#define TP_PARITY BIT_14 /* Parity checking. */ +#define TP_DISCONNECT BIT_15 /* Disconnect privilege. */ + +/* + * NVRAM Command values. + */ +#define NV_START_BIT BIT_2 +#define NV_WRITE_OP (BIT_26+BIT_24) +#define NV_READ_OP (BIT_26+BIT_25) +#define NV_ERASE_OP (BIT_26+BIT_25+BIT_24) +#define NV_MASK_OP (BIT_26+BIT_25+BIT_24) +#define NV_DELAY_COUNT 10 + +/* + * QLogic ISP1280 NVRAM structure definition. + */ +typedef struct +{ + uint8_t id[4]; /* 0, 1, 2, 3 */ + uint8_t version; /* 4 */ + + struct + { + uint8_t bios_configuration_mode :2; + uint8_t bios_disable :1; + uint8_t selectable_scsi_boot_enable :1; + uint8_t cd_rom_boot_enable :1; + uint8_t disable_loading_risc_code :1; + uint8_t enable_64bit_addressing :1; + uint8_t unused_7 :1; + }cntr_flags_1; /* 5 */ + + struct + { + uint8_t boot_lun_number :5; + uint8_t scsi_bus_number :1; + uint8_t unused_6 :1; + uint8_t unused_7 :1; + uint8_t boot_target_number :4; + uint8_t unused_12 :1; + uint8_t unused_13 :1; + uint8_t unused_14 :1; + uint8_t unused_15 :1; + }cntr_flags_2; /* 6, 7 */ + + uint16_t unused_8; /* 8, 9 */ + uint16_t unused_10; /* 10, 11 */ + uint16_t unused_12; /* 12, 13 */ + uint16_t unused_14; /* 14, 15 */ + + union + { + uint8_t c; + struct + { + uint8_t reserved :2; + uint8_t burst_enable :1; + uint8_t reserved_1 :1; + uint8_t fifo_threshold :4; + }f; + }isp_config; /* 16 */ + + /* Termination + * 0 = Disable, 1 = high only, 3 = Auto term + */ + union + { + uint8_t c; + struct + { + uint8_t scsi_bus_1_control :2; + uint8_t scsi_bus_0_control :2; + uint8_t unused_0 :1; + uint8_t unused_1 :1; + uint8_t unused_2 :1; + uint8_t auto_term_support :1; + }f; + }termination; /* 17 */ + + uint16_t isp_parameter; /* 18, 19 */ + + union + { + uint16_t w; + struct + { + uint8_t enable_fast_posting :1; + uint8_t report_lvd_bus_transition :1; + uint8_t unused_2 :1; + uint8_t unused_3 :1; + uint8_t unused_4 :1; + uint8_t unused_5 :1; + uint8_t unused_6 :1; + uint8_t unused_7 :1; + uint8_t unused_8 :1; + uint8_t unused_9 :1; + uint8_t unused_10 :1; + uint8_t unused_11 :1; + uint8_t unused_12 :1; + uint8_t unused_13 :1; + uint8_t unused_14 :1; + uint8_t unused_15 :1; + }f; + }firmware_feature; /* 20, 21 */ + + uint16_t unused_22; /* 22, 23 */ + + struct + { + struct + { + uint8_t initiator_id :4; + uint8_t scsi_reset_disable :1; + uint8_t scsi_bus_size :1; + uint8_t scsi_bus_type :1; + uint8_t unused_7 :1; + }config_1; /* 24 */ + + uint8_t bus_reset_delay; /* 25 */ + uint8_t retry_count; /* 26 */ + uint8_t retry_delay; /* 27 */ + + struct + { + uint8_t async_data_setup_time :4; + uint8_t req_ack_active_negation :1; + uint8_t data_line_active_negation :1; + uint8_t unused_6 :1; + uint8_t unused_7 :1; + }config_2; /* 28 */ + + uint8_t unused_29; /* 29 */ + + uint16_t selection_timeout; /* 30, 31 */ + uint16_t max_queue_depth; /* 32, 33 */ + + uint16_t unused_34; /* 34, 35 */ + uint16_t unused_36; /* 36, 37 */ + uint16_t unused_38; /* 38, 39 */ + + struct + { + union + { + uint8_t c; + struct + { + uint8_t renegotiate_on_error :1; + uint8_t stop_queue_on_check :1; + uint8_t auto_request_sense :1; + uint8_t tag_queuing :1; + uint8_t sync_data_transfers :1; + uint8_t wide_data_transfers :1; + uint8_t parity_checking :1; + uint8_t disconnect_allowed :1; + }f; + }parameter; /* 40 */ + + uint8_t execution_throttle; /* 41 */ + uint8_t sync_period; /* 42 */ + + struct + { + uint8_t sync_offset :4; + uint8_t device_enable :1; + uint8_t lun_disable :1; + uint8_t unused_6 :1; + uint8_t unused_7 :1; + }flags; /* 43 */ + + uint16_t unused_44; /* 44, 45 */ + }target[MAX_TARGETS]; + }bus[MAX_BUSES]; + + uint16_t unused_248; /* 248, 249 */ + + uint16_t subsystem_id[2]; /* 250, 251, 252, 253 */ + + uint8_t unused_254; /* 254 */ + + uint8_t chksum; /* 255 */ +}nvram_t; + +/* + * ISP queue - command entry structure definition. + */ +#define MAX_CMDSZ 12 /* SCSI maximum CDB size. */ +typedef struct +{ + uint8_t entry_type; /* Entry type. */ + #define COMMAND_TYPE 1 /* Command entry */ + uint8_t entry_count; /* Entry count. */ + uint8_t sys_define; /* System defined. */ + uint8_t entry_status; /* Entry Status. */ + uint32_t handle; /* System handle. */ + uint8_t lun; /* SCSI LUN */ + uint8_t target; /* SCSI ID */ + uint16_t cdb_len; /* SCSI command length. */ + uint16_t control_flags; /* Control flags. */ + uint16_t reserved; + uint16_t timeout; /* Command timeout. */ + uint16_t dseg_count; /* Data segment count. */ + uint8_t scsi_cdb[MAX_CMDSZ]; /* SCSI command words. */ + uint32_t dseg_0_address; /* Data segment 0 address. */ + uint32_t dseg_0_length; /* Data segment 0 length. */ + uint32_t dseg_1_address; /* Data segment 1 address. */ + uint32_t dseg_1_length; /* Data segment 1 length. */ + uint32_t dseg_2_address; /* Data segment 2 address. */ + uint32_t dseg_2_length; /* Data segment 2 length. */ + uint32_t dseg_3_address; /* Data segment 3 address. */ + uint32_t dseg_3_length; /* Data segment 3 length. */ +}cmd_entry_t; + +/* + * ISP queue - continuation entry structure definition. + */ +typedef struct +{ + uint8_t entry_type; /* Entry type. */ + #define CONTINUE_TYPE 2 /* Continuation entry. */ + uint8_t entry_count; /* Entry count. */ + uint8_t sys_define; /* System defined. */ + uint8_t entry_status; /* Entry Status. */ + uint32_t reserved; /* Reserved */ + uint32_t dseg_0_address; /* Data segment 0 address. */ + uint32_t dseg_0_length; /* Data segment 0 length. */ + uint32_t dseg_1_address; /* Data segment 1 address. */ + uint32_t dseg_1_length; /* Data segment 1 length. */ + uint32_t dseg_2_address; /* Data segment 2 address. */ + uint32_t dseg_2_length; /* Data segment 2 length. */ + uint32_t dseg_3_address; /* Data segment 3 address. */ + uint32_t dseg_3_length; /* Data segment 3 length. */ + uint32_t dseg_4_address; /* Data segment 4 address. */ + uint32_t dseg_4_length; /* Data segment 4 length. */ + uint32_t dseg_5_address; /* Data segment 5 address. */ + uint32_t dseg_5_length; /* Data segment 5 length. */ + uint32_t dseg_6_address; /* Data segment 6 address. */ + uint32_t dseg_6_length; /* Data segment 6 length. */ +}cont_entry_t; + +/* + * ISP queue - status entry structure definition. + */ +typedef struct +{ + uint8_t entry_type; /* Entry type. */ + #define STATUS_TYPE 3 /* Status entry. */ + uint8_t entry_count; /* Entry count. */ + uint8_t sys_define; /* System defined. */ + uint8_t entry_status; /* Entry Status. */ + #define RF_CONT BIT_0 /* Continuation. */ + #define RF_FULL BIT_1 /* Full */ + #define RF_BAD_HEADER BIT_2 /* Bad header. */ + #define RF_BAD_PAYLOAD BIT_3 /* Bad payload. */ + uint32_t handle; /* System handle. */ + uint16_t scsi_status; /* SCSI status. */ + uint16_t comp_status; /* Completion status. */ + uint16_t state_flags; /* State flags. */ + #define SF_TRANSFER_CMPL BIT_14 /* Transfer Complete. */ + #define SF_GOT_SENSE BIT_13 /* Got Sense */ + #define SF_GOT_STATUS BIT_12 /* Got Status */ + #define SF_TRANSFERRED_DATA BIT_11 /* Transferred data */ + #define SF_SENT_CDB BIT_10 /* Send CDB */ + #define SF_GOT_TARGET BIT_9 /* */ + #define SF_GOT_BUS BIT_8 /* */ + uint16_t status_flags; /* Status flags. */ + uint16_t time; /* Time. */ + uint16_t req_sense_length; /* Request sense data length. */ + uint32_t residual_length; /* Residual transfer length. */ + uint16_t reserved[4]; + uint8_t req_sense_data[32]; /* Request sense data. */ +}sts_entry_t, response_t; + +/* + * ISP queue - marker entry structure definition. + */ +typedef struct +{ + uint8_t entry_type; /* Entry type. */ + #define MARKER_TYPE 4 /* Marker entry. */ + uint8_t entry_count; /* Entry count. */ + uint8_t sys_define; /* System defined. */ + uint8_t entry_status; /* Entry Status. */ + uint32_t reserved; + uint8_t lun; /* SCSI LUN */ + uint8_t target; /* SCSI ID */ + uint8_t modifier; /* Modifier (7-0). */ + #define MK_SYNC_ID_LUN 0 /* Synchronize ID/LUN */ + #define MK_SYNC_ID 1 /* Synchronize ID */ + #define MK_SYNC_ALL 2 /* Synchronize all ID/LUN */ + uint8_t reserved_1[53]; +}mrk_entry_t; + +/* + * ISP queue - extended command entry structure definition. + */ +typedef struct +{ + uint8_t entry_type; /* Entry type. */ + #define EXTENDED_CMD_TYPE 5 /* Extended command entry. */ + uint8_t entry_count; /* Entry count. */ + uint8_t sys_define; /* System defined. */ + uint8_t entry_status; /* Entry Status. */ + uint32_t handle; /* System handle. */ + uint8_t lun; /* SCSI LUN */ + uint8_t target; /* SCSI ID */ + uint16_t cdb_len; /* SCSI command length. */ + uint16_t control_flags; /* Control flags. */ + uint16_t reserved; + uint16_t timeout; /* Command timeout. */ + uint16_t dseg_count; /* Data segment count. */ + uint8_t scsi_cdb[88]; /* SCSI command words. */ +}ecmd_entry_t; + +/* + * ISP queue - 64-Bit addressing, command entry structure definition. + */ +typedef struct +{ + uint8_t entry_type; /* Entry type. */ + #define COMMAND_A64_TYPE 9 /* Command A64 entry */ + uint8_t entry_count; /* Entry count. */ + uint8_t sys_define; /* System defined. */ + uint8_t entry_status; /* Entry Status. */ + uint32_t handle; /* System handle. */ + uint8_t lun; /* SCSI LUN */ + uint8_t target; /* SCSI ID */ + uint16_t cdb_len; /* SCSI command length. */ + uint16_t control_flags; /* Control flags. */ + uint16_t reserved; + uint16_t timeout; /* Command timeout. */ + uint16_t dseg_count; /* Data segment count. */ + uint8_t scsi_cdb[MAX_CMDSZ]; /* SCSI command words. */ + uint32_t reserved_1[2]; /* unused */ + uint32_t dseg_0_address[2]; /* Data segment 0 address. */ + uint32_t dseg_0_length; /* Data segment 0 length. */ + uint32_t dseg_1_address[2]; /* Data segment 1 address. */ + uint32_t dseg_1_length; /* Data segment 1 length. */ +}cmd_a64_entry_t, request_t; + +/* + * ISP queue - 64-Bit addressing, continuation entry structure definition. + */ +typedef struct +{ + uint8_t entry_type; /* Entry type. */ + #define CONTINUE_A64_TYPE 0xA /* Continuation A64 entry. */ + uint8_t entry_count; /* Entry count. */ + uint8_t sys_define; /* System defined. */ + uint8_t entry_status; /* Entry Status. */ + uint32_t dseg_0_address[2]; /* Data segment 0 address. */ + uint32_t dseg_0_length; /* Data segment 0 length. */ + uint32_t dseg_1_address[2]; /* Data segment 1 address. */ + uint32_t dseg_1_length; /* Data segment 1 length. */ + uint32_t dseg_2_address[2]; /* Data segment 2 address. */ + uint32_t dseg_2_length; /* Data segment 2 length. */ + uint32_t dseg_3_address[2]; /* Data segment 3 address. */ + uint32_t dseg_3_length; /* Data segment 3 length. */ + uint32_t dseg_4_address[2]; /* Data segment 4 address. */ + uint32_t dseg_4_length; /* Data segment 4 length. */ +}cont_a64_entry_t; + +/* + * ISP queue - enable LUN entry structure definition. + */ +typedef struct +{ + uint8_t entry_type; /* Entry type. */ + #define ENABLE_LUN_TYPE 0xB /* Enable LUN entry. */ + uint8_t entry_count; /* Entry count. */ + uint8_t reserved_1; + uint8_t entry_status; /* Entry Status not used. */ + uint32_t reserved_2; + uint16_t lun; /* Bit 15 is bus number. */ + uint16_t reserved_4; + uint32_t option_flags; + uint8_t status; + uint8_t reserved_5; + uint8_t command_count; /* Number of ATIOs allocated. */ + uint8_t immed_notify_count; /* Number of Immediate Notify */ + /* entries allocated. */ + uint8_t group_6_length; /* SCSI CDB length for group 6 */ + /* commands (2-26). */ + uint8_t group_7_length; /* SCSI CDB length for group 7 */ + /* commands (2-26). */ + uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */ + uint16_t reserved_6[20]; +}elun_entry_t; + +/* + * ISP queue - modify LUN entry structure definition. + */ +typedef struct +{ + uint8_t entry_type; /* Entry type. */ + #define MODIFY_LUN_TYPE 0xC /* Modify LUN entry. */ + uint8_t entry_count; /* Entry count. */ + uint8_t reserved_1; + uint8_t entry_status; /* Entry Status. */ + uint32_t reserved_2; + uint8_t lun; /* SCSI LUN */ + uint8_t reserved_3; + uint8_t operators; + uint8_t reserved_4; + uint32_t option_flags; + uint8_t status; + uint8_t reserved_5; + uint8_t command_count; /* Number of ATIOs allocated. */ + uint8_t immed_notify_count; /* Number of Immediate Notify */ + /* entries allocated. */ + uint16_t reserved_6; + uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */ + uint16_t reserved_7[20]; +}modify_lun_entry_t; + +/* + * ISP queue - immediate notify entry structure definition. + */ +typedef struct +{ + uint8_t entry_type; /* Entry type. */ + #define IMMED_NOTIFY_TYPE 0xD /* Immediate notify entry. */ + uint8_t entry_count; /* Entry count. */ + uint8_t reserved_1; + uint8_t entry_status; /* Entry Status. */ + uint32_t reserved_2; + uint8_t lun; + uint8_t initiator_id; + uint8_t reserved_3; + uint8_t target_id; + uint32_t option_flags; + uint8_t status; + uint8_t reserved_4; + uint8_t tag_value; /* Received queue tag message value */ + uint8_t tag_type; /* Received queue tag message type */ + /* entries allocated. */ + uint16_t seq_id; + uint8_t scsi_msg[8]; /* SCSI message not handled by ISP */ + uint16_t reserved_5[8]; + uint8_t sense_data[18]; +}notify_entry_t; + +/* + * ISP queue - notify acknowledge entry structure definition. + */ +typedef struct +{ + uint8_t entry_type; /* Entry type. */ + #define NOTIFY_ACK_TYPE 0xE /* Notify acknowledge entry. */ + uint8_t entry_count; /* Entry count. */ + uint8_t reserved_1; + uint8_t entry_status; /* Entry Status. */ + uint32_t reserved_2; + uint8_t lun; + uint8_t initiator_id; + uint8_t reserved_3; + uint8_t target_id; + uint32_t option_flags; + uint8_t status; + uint8_t event; + uint16_t seq_id; + uint16_t reserved_4[22]; +}nack_entry_t; + +/* + * ISP queue - Accept Target I/O (ATIO) entry structure definition. + */ +typedef struct +{ + uint8_t entry_type; /* Entry type. */ + #define ACCEPT_TGT_IO_TYPE 6 /* Accept target I/O entry. */ + uint8_t entry_count; /* Entry count. */ + uint8_t reserved_1; + uint8_t entry_status; /* Entry Status. */ + uint32_t reserved_2; + uint8_t lun; + uint8_t initiator_id; + uint8_t cdb_len; + uint8_t target_id; + uint32_t option_flags; + uint8_t status; + uint8_t scsi_status; + uint8_t tag_value; /* Received queue tag message value */ + uint8_t tag_type; /* Received queue tag message type */ + uint8_t cdb[26]; + uint8_t sense_data[18]; +}atio_entry_t; + +/* + * ISP queue - Continue Target I/O (CTIO) entry structure definition. + */ +typedef struct +{ + uint8_t entry_type; /* Entry type. */ + #define CONTINUE_TGT_IO_TYPE 7 /* CTIO entry */ + uint8_t entry_count; /* Entry count. */ + uint8_t reserved_1; + uint8_t entry_status; /* Entry Status. */ + uint32_t reserved_2; + uint8_t lun; /* SCSI LUN */ + uint8_t initiator_id; + uint8_t reserved_3; + uint8_t target_id; + uint32_t option_flags; + uint8_t status; + uint8_t scsi_status; + uint8_t tag_value; /* Received queue tag message value */ + uint8_t tag_type; /* Received queue tag message type */ + uint32_t transfer_length; + uint32_t residual; + uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */ + uint16_t dseg_count; /* Data segment count. */ + uint32_t dseg_0_address; /* Data segment 0 address. */ + uint32_t dseg_0_length; /* Data segment 0 length. */ + uint32_t dseg_1_address; /* Data segment 1 address. */ + uint32_t dseg_1_length; /* Data segment 1 length. */ + uint32_t dseg_2_address; /* Data segment 2 address. */ + uint32_t dseg_2_length; /* Data segment 2 length. */ + uint32_t dseg_3_address; /* Data segment 3 address. */ + uint32_t dseg_3_length; /* Data segment 3 length. */ +}ctio_entry_t; + +/* + * ISP queue - CTIO returned entry structure definition. + */ +typedef struct +{ + uint8_t entry_type; /* Entry type. */ + #define CTIO_RET_TYPE 7 /* CTIO return entry */ + uint8_t entry_count; /* Entry count. */ + uint8_t reserved_1; + uint8_t entry_status; /* Entry Status. */ + uint32_t reserved_2; + uint8_t lun; /* SCSI LUN */ + uint8_t initiator_id; + uint8_t reserved_3; + uint8_t target_id; + uint32_t option_flags; + uint8_t status; + uint8_t scsi_status; + uint8_t tag_value; /* Received queue tag message value */ + uint8_t tag_type; /* Received queue tag message type */ + uint32_t transfer_length; + uint32_t residual; + uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */ + uint16_t dseg_count; /* Data segment count. */ + uint32_t dseg_0_address; /* Data segment 0 address. */ + uint32_t dseg_0_length; /* Data segment 0 length. */ + uint32_t dseg_1_address; /* Data segment 1 address. */ + uint16_t dseg_1_length; /* Data segment 1 length. */ + uint8_t sense_data[18]; +}ctio_ret_entry_t; + +/* + * ISP queue - CTIO A64 entry structure definition. + */ +typedef struct +{ + uint8_t entry_type; /* Entry type. */ + #define CTIO_A64_TYPE 0xF /* CTIO A64 entry */ + uint8_t entry_count; /* Entry count. */ + uint8_t reserved_1; + uint8_t entry_status; /* Entry Status. */ + uint32_t reserved_2; + uint8_t lun; /* SCSI LUN */ + uint8_t initiator_id; + uint8_t reserved_3; + uint8_t target_id; + uint32_t option_flags; + uint8_t status; + uint8_t scsi_status; + uint8_t tag_value; /* Received queue tag message value */ + uint8_t tag_type; /* Received queue tag message type */ + uint32_t transfer_length; + uint32_t residual; + uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */ + uint16_t dseg_count; /* Data segment count. */ + uint32_t reserved_4[2]; + uint32_t dseg_0_address[2]; /* Data segment 0 address. */ + uint32_t dseg_0_length; /* Data segment 0 length. */ + uint32_t dseg_1_address[2]; /* Data segment 1 address. */ + uint32_t dseg_1_length; /* Data segment 1 length. */ +}ctio_a64_entry_t; + +/* + * ISP queue - CTIO returned entry structure definition. + */ +typedef struct +{ + uint8_t entry_type; /* Entry type. */ + #define CTIO_A64_RET_TYPE 0xF /* CTIO A64 returned entry */ + uint8_t entry_count; /* Entry count. */ + uint8_t reserved_1; + uint8_t entry_status; /* Entry Status. */ + uint32_t reserved_2; + uint8_t lun; /* SCSI LUN */ + uint8_t initiator_id; + uint8_t reserved_3; + uint8_t target_id; + uint32_t option_flags; + uint8_t status; + uint8_t scsi_status; + uint8_t tag_value; /* Received queue tag message value */ + uint8_t tag_type; /* Received queue tag message type */ + uint32_t transfer_length; + uint32_t residual; + uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */ + uint16_t dseg_count; /* Data segment count. */ + uint16_t reserved_4[7]; + uint8_t sense_data[18]; +}ctio_a64_ret_entry_t; + +/* + * ISP request and response queue entry sizes + */ +#define RESPONSE_ENTRY_SIZE (sizeof(response_t)) +#define REQUEST_ENTRY_SIZE (sizeof(request_t)) + +/* + * ISP status entry - completion status definitions. + */ +#define CS_COMPLETE 0x0 /* No errors */ +#define CS_INCOMPLETE 0x1 /* Incomplete transfer of cmd. */ +#define CS_DMA 0x2 /* A DMA direction error. */ +#define CS_TRANSPORT 0x3 /* Transport error. */ +#define CS_RESET 0x4 /* SCSI bus reset occurred */ +#define CS_ABORTED 0x5 /* System aborted command. */ +#define CS_TIMEOUT 0x6 /* Timeout error. */ +#define CS_DATA_OVERRUN 0x7 /* Data overrun. */ +#define CS_COMMAND_OVERRUN 0x8 /* Command Overrun. */ +#define CS_STATUS_OVERRUN 0x9 /* Status Overrun. */ +#define CS_BAD_MSG 0xA /* Bad msg after status phase. */ +#define CS_NO_MSG_OUT 0xB /* No msg out after selection. */ +#define CS_EXTENDED_ID 0xC /* Extended ID failed. */ +#define CS_IDE_MSG 0xD /* Target rejected IDE msg. */ +#define CS_ABORT_MSG 0xE /* Target rejected abort msg. */ +#define CS_REJECT_MSG 0xF /* Target rejected reject msg. */ +#define CS_NOP_MSG 0x10 /* Target rejected NOP msg. */ +#define CS_PARITY_MSG 0x11 /* Target rejected parity msg. */ +#define CS_DEV_RESET_MSG 0x12 /* Target rejected dev rst msg. */ +#define CS_ID_MSG 0x13 /* Target rejected ID msg. */ +#define CS_FREE 0x14 /* Unexpected bus free. */ +#define CS_DATA_UNDERRUN 0x15 /* Data Underrun. */ +#define CS_TRANACTION_1 0x18 /* Transaction error 1 */ +#define CS_TRANACTION_2 0x19 /* Transaction error 2 */ +#define CS_TRANACTION_3 0x1a /* Transaction error 3 */ +#define CS_INV_ENTRY_TYPE 0x1b /* Invalid entry type */ +#define CS_DEV_QUEUE_FULL 0x1c /* Device queue full */ +#define CS_PHASED_SKIPPED 0x1d /* SCSI phase skipped */ +#define CS_ARS_FAILED 0x1e /* ARS failed */ +#define CS_LVD_BUS_ERROR 0x21 /* LVD bus error */ +#define CS_BAD_PAYLOAD 0x80 /* Driver defined */ +#define CS_UNKNOWN 0x81 /* Driver defined */ +#define CS_RETRY 0x82 /* Driver defined */ + +/* + * ISP status entry - SCSI status byte bit definitions. + */ +#define SS_CHECK_CONDITION BIT_1 +#define SS_CONDITION_MET BIT_2 +#define SS_BUSY_CONDITION BIT_3 +#define SS_RESERVE_CONFLICT (BIT_4 | BIT_3) + +/* + * ISP target entries - Option flags bit definitions. + */ +#define OF_ENABLE_TAG BIT_1 /* Tagged queue action enable */ +#define OF_DATA_IN BIT_6 /* Data in to initiator */ + /* (data from target to initiator) */ +#define OF_DATA_OUT BIT_7 /* Data out from initiator */ + /* (data from initiator to target) */ +#define OF_NO_DATA (BIT_7 | BIT_6) +#define OF_DISC_DISABLED BIT_15 /* Disconnects disabled */ +#define OF_DISABLE_SDP BIT_24 /* Disable sending save data ptr */ +#define OF_SEND_RDP BIT_26 /* Send restore data pointers msg */ +#define OF_FORCE_DISC BIT_30 /* Disconnects mandatory */ +#define OF_SSTS BIT_31 /* Send SCSI status */ + +#if QL1280_TARGET_MODE_SUPPORT +/* + * Target Read/Write buffer structure. + */ +#define TARGET_DATA_OFFSET 4 +#define TARGET_DATA_SIZE 0x2000 /* 8K */ +#define TARGET_INQ_OFFSET (TARGET_DATA_OFFSET + TARGET_DATA_SIZE) +#define TARGET_SENSE_SIZE 18 +#define TARGET_BUF_SIZE 36 + +typedef struct +{ + uint8_t hdr[4]; + uint8_t data[TARGET_DATA_SIZE]; + struct ident inq; +}tgt_t; +#endif + +/* + * BUS parameters/settings structure + */ +typedef struct +{ + uint8_t id; /* Host adapter SCSI id */ + uint8_t bus_reset_delay; /* SCSI bus reset delay. */ + uint8_t failed_reset_count; /* number of time reset failed */ + uint8_t unused; + uint16_t device_enables; /* Device enable bits. */ + uint16_t lun_disables; /* LUN disable bits. */ + uint16_t qtag_enables; /* Tag queue enables. */ + uint16_t hiwat; /* High water mark per device. */ + uint8_t reset_marker :1; + uint8_t disable_scsi_reset :1; + uint8_t scsi_bus_dead :1; /* SCSI Bus is Dead, when 5 back to back resets failed */ + +}bus_param_t; + +/* + * Linux Host Adapter structure + */ +typedef struct scsi_qla_host +{ + /* Linux adapter configuration data */ + struct Scsi_Host *host; /* pointer to host data */ + struct scsi_qla_host *next; + device_reg_t *iobase; /* Base Memory-mapped I/O address */ + uint8_t pci_bus; + uint8_t pci_device_fn; + uint8_t devnum; + volatile unsigned char *mmpbase; /* memory mapped address */ + unsigned long host_no; + unsigned long instance; + uint8_t revision; + uint8_t ports; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0) + spinlock_t spin_lock; +#endif + volatile unsigned char cpu_lock_count[NR_CPUS]; + unsigned long actthreads; + unsigned long qthreads; + unsigned long isr_count; /* Interrupt count */ + unsigned long spurious_int; + + /* Outstandings ISP commands. */ + srb_t *outstanding_cmds[MAX_OUTSTANDING_COMMANDS]; + + /* BUS configuration data */ + bus_param_t bus_settings[MAX_BUSES]; + + /* Device LUN queues. */ + scsi_lu_t *dev[MAX_EQ]; /* Logical unit queues */ + +#ifdef UNUSED + /* Interrupt lock, and data */ + uint8_t intr_lock; /* Lock for interrupt locking */ +#endif + + /* bottom half run queue */ + struct tq_struct run_qla_bh; + + /* Received ISP mailbox data. */ + volatile uint16_t mailbox_out[MAILBOX_REGISTER_COUNT]; + +#ifdef UNUSED + /* ISP ring lock, rings, and indexes */ + uint8_t ring_lock; /* ISP ring lock */ + struct timer_list dev_timer[MAX_TARGETS]; +#endif + + request_t req[REQUEST_ENTRY_CNT+1]; + response_t res[RESPONSE_ENTRY_CNT+1]; + uint32_t request_dma; /* Physical address. */ + request_t *request_ring; /* Base virtual address */ + request_t *request_ring_ptr; /* Current address. */ + uint16_t req_ring_index; /* Current index. */ + uint16_t req_q_cnt; /* Number of available entries. */ + + uint32_t response_dma; /* Physical address. */ + response_t *response_ring; /* Base virtual address */ + response_t *response_ring_ptr; /* Current address. */ + uint16_t rsp_ring_index; /* Current index. */ + +#if QL1280_TARGET_MODE_SUPPORT + /* Target buffer and sense data. */ + uint32_t tbuf_dma; /* Physical address. */ + tgt_t *tbuf; + uint32_t tsense_dma; /* Physical address. */ + uint8_t *tsense; +#endif + +#if WATCHDOGTIMER + /* Watchdog queue, lock and total timer */ + uint8_t watchdog_q_lock; /* Lock for watchdog queue */ + srb_t *wdg_q_first; /* First job on watchdog queue */ + srb_t *wdg_q_last; /* Last job on watchdog queue */ + uint32_t total_timeout; /* Total timeout (quantum count) */ + uint32_t watchdogactive; +#endif + + srb_t *done_q_first; /* First job on done queue */ + srb_t *done_q_last; /* Last job on done queue */ + + volatile struct + { + uint32_t watchdog_enabled :1; /* 0 */ + uint32_t mbox_int :1; /* 1 */ + uint32_t mbox_busy :1; /* 2 */ + uint32_t online :1; /* 3 */ + uint32_t reset_marker :1; /* 4 */ + uint32_t isp_abort_needed :1; /* 5 */ + uint32_t pci_64bit_slot :1; /* 6 */ + uint32_t disable_host_adapter :1; /* 7 */ + uint32_t reset_active :1; /* 8 */ + uint32_t abort_isp_active :1; /* 9 */ + uint32_t disable_risc_code_load :1; /* 10 */ + uint32_t enable_64bit_addressing :1; /* 11 */ +#define QLA1280_IN_ISR_BIT 12 + uint32_t in_isr :1; /* 12 */ + uint32_t in_abort :1; /* 13 */ + uint32_t in_reset :1; /* 14 */ + uint32_t dpc :1; /* 15 */ + uint32_t dpc_sched :1; /* 16 */ + }flags; + +}scsi_qla_host_t; + +/* + * Macros to help code, maintain, etc. + */ +#define SUBDEV(b, t, l) ( (b << (MAX_T_BITS + MAX_L_BITS)) | (t << MAX_L_BITS) | l) +#define LU_Q(ha, b, t, l) (ha->dev[SUBDEV(b, t, l)]) + +/* + * Locking Macro Definitions + * + * LOCK/UNLOCK definitions are lock/unlock primitives for multi-processor + * or spl/splx for uniprocessor. + */ +#define QLA1280_HIER HBA_HIER_BASE /* Locking hierarchy base for hba */ + +#define QLA1280_WATCHDOG_Q_LOCK(ha, p) +#define QLA1280_WATCHDOG_Q_UNLOCK(ha, p) + +#define QLA1280_SCSILU_LOCK(q) +#define QLA1280_SCSILU_UNLOCK(q) + +#define QLA1280_INTR_LOCK(ha) +#define QLA1280_INTR_UNLOCK(ha) + +#define QLA1280_RING_LOCK(ha) +#define QLA1280_RING_UNLOCK(ha) + + +#if defined(__cplusplus) +} +#endif + +#endif /* _IO_HBA_QLA1280_H */ diff -Naur linux.2210/drivers/scsi/qla1280host.h linux.2210.vw/drivers/scsi/qla1280host.h --- linux.2210/drivers/scsi/qla1280host.h Wed Dec 31 16:00:00 1969 +++ linux.2210.vw/drivers/scsi/qla1280host.h Thu Jul 15 04:48:08 1999 @@ -0,0 +1,46 @@ +/* + * Linux - SCSI Driver Interface Function Prototypes. + */ +int qla1280_proc_info ( char *, char **, off_t, int, int, int); +const char * qla1280_info(struct Scsi_Host *host); +int qla1280_detect(Scsi_Host_Template *); +int qla1280_release(struct Scsi_Host *); +const char * qla1280_info(struct Scsi_Host *); +int qla1280_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *)); +int qla1280_abort(Scsi_Cmnd *); +int qla1280_reset(Scsi_Cmnd *, unsigned int); +int qla1280_biosparam(Disk *, kdev_t, int[]); /* x86 only XXX BH */ +void qla1280_intr_handler(int, void *, struct pt_regs *); +void qla1280_setup(char *s, int *dummy); + +#define QLA1280 { \ + next: NULL, \ + module: NULL, \ + proc_dir: NULL, \ + proc_info: qla1280_proc_info, \ + name: "Qlogic ISP 1280\1080", \ + detect: qla1280_detect, \ + release: qla1280_release, \ + info: qla1280_info, \ + ioctl: NULL, \ + command: NULL, \ + queuecommand: qla1280_queuecommand, \ + eh_strategy_handler: NULL, \ + eh_abort_handler: NULL, \ + eh_device_reset_handler: NULL, \ + eh_bus_reset_handler: NULL, \ + eh_host_reset_handler: NULL, \ + abort: qla1280_abort, \ + reset: qla1280_reset, \ + slave_attach: NULL, \ + bios_param: qla1280_biosparam, \ + can_queue: 255, /* max simultaneous cmds */\ + this_id: -1, /* scsi id of host adapter */\ + sg_tablesize: SG_ALL, /* max scatter-gather cmds */\ + cmd_per_lun: 3, /* cmds per lun (linked cmds) */\ + present: 0, /* number of 7xxx's present */\ + unchecked_isa_dma: 0, /* no memory DMA restrictions */\ + use_clustering: ENABLE_CLUSTERING, \ + use_new_eh_code: 0, \ + emulated: 0 \ +} diff -Naur linux.2210/drivers/usb/uhci.c linux.2210.vw/drivers/usb/uhci.c --- linux.2210/drivers/usb/uhci.c Fri Apr 30 08:20:53 1999 +++ linux.2210.vw/drivers/usb/uhci.c Thu Jul 15 04:48:08 1999 @@ -624,7 +624,9 @@ struct uhci_device *dev; unsigned short status; +#if 0 printk("uhci_connect_change: called for %d\n", nr); +#endif /* * Even if the status says we're connected, diff -Naur linux.2210/drivers/usb/usb.c linux.2210.vw/drivers/usb/usb.c --- linux.2210/drivers/usb/usb.c Fri May 7 15:16:04 1999 +++ linux.2210.vw/drivers/usb/usb.c Thu Jul 15 04:48:08 1999 @@ -124,22 +124,28 @@ if (n_len < 2 || n_len > len) { +#if 0 printk("Short descriptor.\n"); +#endif return -1; } +#if 0 printk( "Expected descriptor %02X/%02X, got %02X/%02X - skipping\n", desctype, descindex, (n_desc >> 8) & 0xFF, n_desc & 0xFF); for (i = 0 ; i < n_len; i++) printk(" %d %02x\n", i, ptr[i]); +#endif len -= n_len; ptr += n_len; parsed += n_len; } +#if 0 printk("Found %02X:%02X\n", desctype, descindex); +#endif return parsed; } @@ -154,7 +160,9 @@ if (n_len < 2 || n_len > len) { +#if 0 printk("Short descriptor.\n"); +#endif return -1; } @@ -604,8 +612,10 @@ { int addr, i; +#if 0 printk("USB new device connect, assigned device number %d\n", dev->devnum); +#endif dev->maxpacketsize = 0; /* Default to 8 byte max packet size */ diff -Naur linux.2210/drivers/video/Config.in linux.2210.vw/drivers/video/Config.in --- linux.2210/drivers/video/Config.in Tue May 11 16:30:36 1999 +++ linux.2210.vw/drivers/video/Config.in Thu Jul 15 04:48:08 1999 @@ -78,6 +78,7 @@ fi if [ "$CONFIG_VISWS" = "y" ]; then tristate 'SGI Visual Workstation framebuffer support' CONFIG_FB_SGIVW + define_bool CONFIG_BUS_I2C y fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then if [ "$CONFIG_PCI" != "n" ]; then diff -Naur linux.2210/drivers/video/Makefile linux.2210.vw/drivers/video/Makefile --- linux.2210/drivers/video/Makefile Tue May 11 16:30:36 1999 +++ linux.2210.vw/drivers/video/Makefile Thu Jul 15 04:48:08 1999 @@ -141,10 +141,10 @@ endif ifeq ($(CONFIG_FB_SGIVW),y) -L_OBJS += sgivwfb.o +LX_OBJS += sgivwfb.o else ifeq ($(CONFIG_FB_SGIVW),m) - M_OBJS += sgivwfb.o + MX_OBJS += sgivwfb.o endif endif diff -Naur linux.2210/drivers/video/sgivwfb.c linux.2210.vw/drivers/video/sgivwfb.c --- linux.2210/drivers/video/sgivwfb.c Fri Apr 16 08:20:23 1999 +++ linux.2210.vw/drivers/video/sgivwfb.c Thu Jul 15 04:48:08 1999 @@ -1,8 +1,8 @@ /* * linux/drivers/video/sgivwfb.c -- SGI DBE frame buffer device * - * Copyright (C) 1999 Silicon Graphics, Inc. - * Jeffrey Newquist, newquist@engr.sgi.som + * Copyright (C) 1999 Silicon Graphics, Inc. + * Jeffrey Newquist, newquist@engr.sgi.com * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive for @@ -25,32 +25,63 @@ #include #include #include +#include #include