]> git.neil.brown.name Git - history.git/commitdiff
Import 2.2.3pre1 2.2.3pre1
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:18:16 +0000 (15:18 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:18:16 +0000 (15:18 -0500)
136 files changed:
Documentation/Configure.help
Documentation/filesystems/fat_cvf.txt
MAINTAINERS
Makefile
arch/alpha/boot/main.c
arch/alpha/defconfig
arch/arm/defconfig
arch/i386/defconfig
arch/i386/kernel/time.c
arch/m68k/defconfig
arch/mips/defconfig
arch/ppc/apus_defconfig
arch/ppc/chrp_defconfig
arch/ppc/common_defconfig
arch/ppc/defconfig
arch/ppc/mbx_defconfig
arch/ppc/pmac_defconfig
arch/ppc/prep_defconfig
arch/sparc/defconfig
arch/sparc64/defconfig
drivers/block/genhd.c
drivers/block/hd.c
drivers/block/ide.c
drivers/block/rd.c
drivers/char/Config.in
drivers/char/Makefile
drivers/char/bttv.c
drivers/char/console.c
drivers/char/radio-aimslab.c
drivers/char/radio-typhoon.c [new file with mode: 0644]
drivers/char/radio-zoltrix.c
drivers/char/vc_screen.c
drivers/char/videodev.c
drivers/net/8390.c
drivers/net/a2065.c
drivers/net/ariadne.c
drivers/net/shaper.c
drivers/net/smc-ultra.c
drivers/scsi/Config.in
drivers/scsi/Makefile
drivers/scsi/atp870u.c
drivers/scsi/hosts.c
drivers/scsi/i60uscsi.c [new file with mode: 0644]
drivers/scsi/i60uscsi.h [new file with mode: 0644]
drivers/scsi/inia100.c [new file with mode: 0644]
drivers/scsi/inia100.h [new file with mode: 0644]
drivers/scsi/megaraid.c
drivers/scsi/megaraid.h
drivers/scsi/qlogicfc.c [new file with mode: 0644]
drivers/scsi/qlogicfc.h [new file with mode: 0644]
drivers/scsi/qlogicfc_asm.c [new file with mode: 0644]
drivers/scsi/scsi_error.c
drivers/scsi/sd_ioctl.c
drivers/scsi/sr_ioctl.c
drivers/scsi/sym53c416.c [new file with mode: 0644]
drivers/scsi/sym53c416.h [new file with mode: 0644]
drivers/video/Config.in
drivers/video/Makefile
drivers/video/atafb.c
drivers/video/atyfb.c
drivers/video/bwtwofb.c
drivers/video/cgfourteenfb.c
drivers/video/cgsixfb.c
drivers/video/cgthreefb.c
drivers/video/clgenfb.c
drivers/video/controlfb.c
drivers/video/creatorfb.c
drivers/video/cvisionppc.h
drivers/video/fbcon-afb.c
drivers/video/fbcon-cfb16.c
drivers/video/fbcon-cfb2.c
drivers/video/fbcon-cfb24.c
drivers/video/fbcon-cfb32.c
drivers/video/fbcon-cfb4.c
drivers/video/fbcon-cfb8.c
drivers/video/fbcon-ilbm.c
drivers/video/fbcon-iplan2p2.c
drivers/video/fbcon-iplan2p4.c
drivers/video/fbcon-iplan2p8.c
drivers/video/fbcon-mac.c
drivers/video/fbcon-mfb.c
drivers/video/fbcon-vga.c
drivers/video/fbcon.c
drivers/video/fbgen.c
drivers/video/fbmem.c
drivers/video/fm2fb.c [new file with mode: 0644]
drivers/video/leofb.c
drivers/video/matroxfb.c
drivers/video/mdacon.c
drivers/video/newport_con.c
drivers/video/pm2fb.c
drivers/video/pm2fb.h
drivers/video/promcon.c
drivers/video/q40fb.c [new file with mode: 0644]
drivers/video/retz3fb.c
drivers/video/skeletonfb.c
drivers/video/tcxfb.c
drivers/video/vesafb.c
drivers/video/virgefb.c
fs/dcache.c
fs/fat/cvf.c
fs/fat/file.c
fs/file_table.c
fs/lockd/host.c
fs/lockd/svcsubs.c
fs/nfs/file.c
fs/nfs/inode.c
fs/nfs/write.c
fs/vfat/namei.c
include/asm-alpha/semaphore-helper.h [new file with mode: 0644]
include/asm-alpha/semaphore.h
include/asm-alpha/vga.h
include/asm-mips/vga.h
include/asm-ppc/vga.h
include/asm-sparc64/vga.h
include/linux/console.h
include/linux/fb.h
include/linux/filter.h
include/linux/fs.h
include/linux/if_shaper.h
include/linux/nfs_fs.h
include/linux/proc_fs.h
include/linux/selection.h
include/linux/vt_buffer.h
include/linux/zorro.h
include/net/sock.h
include/video/fbcon.h
include/video/sbusfb.h
init/main.c
kernel/fork.c
mm/filemap.c
net/Config.in
net/bridge/br.c
net/sunrpc/sched.c
net/unix/garbage.c
scripts/ksymoops/oops.c

index 1c625be2c8dc31dd5295a9a86bf6dcee9670c81d..5368897871ece051b6fe1726e2bcd3e42b6c6509 100644 (file)
@@ -1089,25 +1089,6 @@ CONFIG_NET
   recommended to read the NET-3-HOWTO, available via FTP (user:
   anonymous) from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
-Network aliasing
-CONFIG_NET_ALIAS
-  If you say Y here, you will be able to set multiple network
-  addresses on the same low-level network device driver. This is
-  typically used for services that act differently based on the
-  address they listen on (e.g. "multihosting" or "virtual domains" or
-  "virtual hosting services" on the web server apache and the ftp
-  server wuftpd -- read the Virtual-Services-HOWTO, available via FTP
-  (user: anonymous) from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO)
-  or for connecting to different logical networks through the same
-  physical interface (most commonly an Ethernet networking card). See
-  Documentation/networking/alias.txt for more info.
-
-  This is the generic part, later when configuring network protocol
-  options you will be asked for protocol-specific aliasing support,
-  and you will have to say Y to at least one of them, most likely to
-  "IP: aliasing support". If you need this feature (for any protocol,
-  like IP) say Y; if unsure, say N.
-
 Socket filtering
 CONFIG_FILTER
   The Linux Socket Filter is derived from the Berkeley Packet Filter.
index 7eef569b65835e0160e927b60c149ad1530d5f44..c1cf27bd74c045cc85bfb7d9d112c15d8a2e83ad 100644 (file)
@@ -1,4 +1,4 @@
-This is the main documentation for the CVF-FAT filesystem extension.  31DEC1997
+This is the main documentation for the CVF-FAT filesystem extension.  18Nov1998
 
 
 Table of Contents:
@@ -37,14 +37,9 @@ like compression and decompression silently.
   CVF filesystems cannot do bmap. It's impossible in principle. Thus
   all actions that require bmap do not work (swapping, writable mmapping).
   Read-only mmapping works because the FAT driver has a hack for this
-  situation :) Well, with some tricks writable mmapping could work,
-  (proof: they did under old dmsdos), but..... (hint: readpage/writepage
-  interface functions) ...... but the FAT driver has to support them 
-  first without bmap :-)
-
-  We'll see. If someone points me to an application that needs this, I
-  might be persuaded to implement it :). CVF-FAT is already prepared
-  for using readpage.
+  situation :) Well, writable mmapping should now work using the readpage
+  interface function which has been hacked into the FAT driver just for 
+  CVF-FAT :)
   
 - attention, DOSEmu users 
 
@@ -66,11 +61,28 @@ driver's standard options:
 
   cvf_format=xxx
     Forces the driver to use the CVF module "xxx" instead of auto-detection.
-    This is only necessary if the CVF format is not recognized correctly
+    Without this option, the CVF-FAT interface asks all currently loaded
+    CVF modules whether they recognize the CVF. Therefore, this option is
+    only necessary if the CVF format is not recognized correctly
     because of bugs or incompatibilities in the CVF modules. (It skips
     the detect_cvf call.) "xxx" may be the text "none" (without the quotes)
     to inhibit using any of the loaded CVF modules, just in case a CVF
-    module insists on mounting plain FAT filesystems by misunderstanding :)
+    module insists on mounting plain FAT filesystems by misunderstanding.
+    "xxx" may also be the text "autoload", which has a special meaning for
+    a module loader, but does not skip auto-detection.
+
+    If the kernel supports kmod, the cvf_format=xxx option also controls
+    on-demand CVF module loading. Without this option, nothing is loaded
+    on demand. With cvf_format=xxx, a module "xxx" is requested automatically
+    before mounting the compressed filesystem (unless "xxx" is "none"). In 
+    case there is a difference between the CVF format name and the module 
+    name, setup aliases in your modules configuration. If the string "xxx" 
+    is "autoload", a non-existent module "cvf_autoload" is requested which 
+    can be used together with a special modules configuration (alias and 
+    pre-install statements) in order to load more than one CVF module, let 
+    them detect automatically which kind of CVF is to be mounted, and only 
+    keep the "right" module in memory. For examples please refer to the 
+    dmsdos documentation (ftp and http addresses see below).
 
   cvf_options=yyy
     Option string passed to the CVF module. I.e. only the "yyy" is passed
@@ -80,8 +92,8 @@ driver's standard options:
     misinterpretation by the FAT driver, which would recognize the text 
     after a comma as a FAT driver option and might get confused or print 
     strange error messages. The documentation for the CVF module should 
-    offer a different separation symbol, for example the dot ".", which
-    is only valid inside the string "yyy".
+    offer a different separation symbol, for example the dot "." or the
+    plus sign "+", which is only valid inside the string "yyy".
 
 
 4. Description of the CVF-FAT interface
@@ -120,11 +132,11 @@ It contains...
       is set, mmap is set to generic_file_mmap and readpage is caught
       and redirected to the cvf_readpage function. If it is not set,
       readpage is set to generic_readpage and mmap is caught and redirected
-      to cvf_mmap.
+      to cvf_mmap. (If you want writable mmap use the readpage interface.)
   - detect_cvf:
       A function that is called to decide whether the filesystem is a CVF of
       the type the module supports. The detect_cvf function must return 0
-      for "NO, I DON'T KNOW THIS GARBAGE" or anything !=0 for "YES, THIS IS
+      for "NO, I DON'T KNOW THIS GARBAGE" or anything >0 for "YES, THIS IS
       THE KIND OF CVF I SUPPORT". The function must maintain the module
       usage counters for safety, i.e. do MOD_INC_USE_COUNT at the beginning
       and MOD_DEC_USE_COUNT at the end. The function *must not* assume that
@@ -180,11 +192,19 @@ int unregister_cvf_format(struct cvf_format*cvf_format);
   that has not been previously registered. The code uses the version id
   to distinguish the modules, so be sure to keep it unique.
 
-5. CVS Modules
+5. CVF Modules
 ------------------------------------------------------------------------------
 
 Refer to the dmsdos module (the successor of the dmsdos filesystem) for a
 sample implementation.  It can currently be found at
 
-  ftp://fb9nt.uni-duisburg.de/pub/linux/dmsdos
+  ftp://fb9nt.uni-duisburg.de/pub/linux/dmsdos/dmsdos-x.y.z.tgz
+  ftp://sunsite.unc.edu/pub/Linux/system/Filesystems/dosfs/dmsdos-x.y.z.tgz
+  ftp://ftp.uni-stuttgart.de/pub/systems/linux/local/system/dmsdos-x.y.z.tgz
+
+(where x.y.z is to be replaced with the actual version number). Full
+documentation about dmsdos is included in the dmsdos package, but can also
+be found at
 
+  http://fb9nt.uni-duisburg.de/mitarbeiter/gockel/software/dmsdos/index.html
+  http://www.yk.rim.or.jp/~takafumi/dmsdos/index.html (in Japanese).
index 9520dc5ef9342ca018f754326100ba059e2ac023..836029aaa265da162043dd951418793899f56f84 100644 (file)
@@ -324,7 +324,7 @@ P:  Andrew J. Robinson
 M:     arobinso@nyx.net
 L:     linux-kernel@vger.rutgers.edu
 W:     http://www.nyx.net/~arobinso
-S:     Maintainted
+S:     Maintained
 
 HFS FILESYSTEM
 P:      Adrian Sun
@@ -678,9 +678,18 @@ M: alan@redhat.com
 S:     Supported
 
 SPARC:
+P:     David S. Miller
+M:     davem@dm.cobaltmicro.com
 P:     Eddie C. Dost
 M:     ecd@skynet.be
+P:     Jakub Jelinek
+M:     jj@sunsite.ms.mff.cuni.cz
+P:     Anton Blanchard
+M:     anton@jubilex.progsoc.uts.edu.au
 L:     sparclinux@vger.rutgers.edu
+L:     ultralinux@vger.rutgers.edu
+W:     http://ultra.linux.cz
+W:     http://www.geog.ubc.ca/s_linux.html
 S:     Maintained
 
 SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER
index b6a109b439fb845e2cecc1f26194842010149192..662ae0cc345c87dbd950d4bdfb4379a0858f09d4 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 2
-SUBLEVEL = 2
+SUBLEVEL = 3
 EXTRAVERSION =
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
index c2d4e657e26788d3e73323354a16faca8a342252..dd4e47ab5924345d340f24163579b99564388b63 100644 (file)
 extern int vsprintf(char *, const char *, va_list);
 extern unsigned long switch_to_osf_pal(unsigned long nr,
        struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa,
-       unsigned long vptb, unsigned long *kstk);
-
-int printk(const char * fmt, ...)
-{
-       va_list args;
-       int i, j, written, remaining, num_nl;
-       static char buf[1024];
-       char * str;
-
-       va_start(args, fmt);
-       i = vsprintf(buf, fmt, args);
-       va_end(args);
-
-       /* expand \n into \r\n: */
-
-       num_nl = 0;
-       for (j = 0; j < i; ++j) {
-           if (buf[j] == '\n')
-               ++num_nl;
-       }
-       remaining = i + num_nl;
-       for (j = i - 1; j >= 0; --j) {
-           buf[j + num_nl] = buf[j];
-           if (buf[j] == '\n') {
-               --num_nl;
-               buf[j + num_nl] = '\r';
-           }
-       }
-
-       str = buf;
-       do {
-           written = puts(str, remaining);
-           remaining -= written;
-           str += written;
-       } while (remaining > 0);
-       return i;
-}
-
-#define hwrpb (*INIT_HWRPB)
+       unsigned long *vptb);
+struct hwrpb_struct *hwrpb = INIT_HWRPB;
+static struct pcb_struct pcb_va[1];
 
 /*
  * Find a physical address of a virtual object..
  *
  * This is easy using the virtual page table address.
  */
-struct pcb_struct * find_pa(unsigned long *vptb, struct pcb_struct * pcb)
+
+static inline void *
+find_pa(unsigned long *vptb, void *ptr)
 {
-       unsigned long address = (unsigned long) pcb;
+       unsigned long address = (unsigned long) ptr;
        unsigned long result;
 
        result = vptb[address >> 13];
        result >>= 32;
        result <<= 13;
        result |= address & 0x1fff;
-       return (struct pcb_struct *) result;
+       return (void *) result;
 }      
 
 /*
@@ -88,30 +54,19 @@ struct pcb_struct * find_pa(unsigned long *vptb, struct pcb_struct * pcb)
  * code has the L1 page table identity-map itself in the second PTE
  * in the L1 page table. Thus the L1-page is virtually addressable
  * itself (through three levels) at virtual address 0x200802000.
- *
- * As we don't want it there anyway, we also move the L1 self-map
- * up as high as we can, so that the last entry in the L1 page table
- * maps the page tables.
- *
- * As a result, the OSF/1 pal-code will instead use a virtual page table
- * map located at 0xffffffe00000000.
  */
-#define pcb_va ((struct pcb_struct *) 0x20000000)
-#define old_vptb (0x0000000200000000UL)
-#define new_vptb (0xfffffffe00000000UL)
-void pal_init(void)
+
+#define VPTB   ((unsigned long *) 0x200000000)
+#define L1     ((unsigned long *) 0x200802000)
+
+void
+pal_init(void)
 {
-       unsigned long i, rev, sum;
-       unsigned long *L1, *l;
+       unsigned long i, rev;
        struct percpu_struct * percpu;
        struct pcb_struct * pcb_pa;
 
-       /* Find the level 1 page table and duplicate it in high memory */
-       L1 = (unsigned long *) 0x200802000UL; /* (1<<33 | 1<<23 | 1<<13) */
-       L1[1023] = L1[1];
-
-       percpu = (struct percpu_struct *) (hwrpb.processor_offset + (unsigned long) &hwrpb),
-               
+       /* Create the dummy PCB.  */
        pcb_va->ksp = 0;
        pcb_va->usp = 0;
        pcb_va->ptbr = L1[1] >> 32;
@@ -119,39 +74,32 @@ void pal_init(void)
        pcb_va->pcc = 0;
        pcb_va->unique = 0;
        pcb_va->flags = 1;
-       pcb_pa = find_pa((unsigned long *) old_vptb, pcb_va);
-       printk("Switching to OSF PAL-code .. ");
+       pcb_va->res1 = 0;
+       pcb_va->res2 = 0;
+       pcb_pa = find_pa(VPTB, pcb_va);
+
        /*
         * a0 = 2 (OSF)
-        * a1 = return address, but we give the asm the virtual addr of the PCB
+        * a1 = return address, but we give the asm the vaddr of the PCB
         * a2 = physical addr of PCB
         * a3 = new virtual page table pointer
-        * a4 = KSP (but we give it 0, asm sets it)
+        * a4 = KSP (but the asm sets it)
         */
-       i = switch_to_osf_pal(
-               2,
-               pcb_va,
-               pcb_pa,
-               new_vptb,
-               0);
+       srm_printk("Switching to OSF PAL-code .. ");
+
+       i = switch_to_osf_pal(2, pcb_va, pcb_pa, VPTB);
        if (i) {
-               printk("failed, code %ld\n", i);
+               srm_printk("failed, code %ld\n", i);
                halt();
        }
-       rev = percpu->pal_revision = percpu->palcode_avail[2];
 
-       hwrpb.vptb = new_vptb;
+       percpu = (struct percpu_struct *)
+               (INIT_HWRPB->processor_offset + (unsigned long) INIT_HWRPB);
+       rev = percpu->pal_revision = percpu->palcode_avail[2];
 
-       /* update checksum: */
-       sum = 0;
-       for (l = (unsigned long *) &hwrpb; l < (unsigned long *) &hwrpb.chksum; ++l)
-               sum += *l;
-       hwrpb.chksum = sum;
+       srm_printk("Ok (rev %lx)\n", rev);
 
-       printk("Ok (rev %lx)\n", rev);
-       /* remove the old virtual page-table mapping */
-       L1[1] = 0;
-       flush_tlb_all();
+       tbia(); /* do it directly in case we are SMP */
 }
 
 static inline long openboot(void)
@@ -159,15 +107,15 @@ static inline long openboot(void)
        char bootdev[256];
        long result;
 
-       result = dispatch(CCB_GET_ENV, ENV_BOOTED_DEV, bootdev, 255);
+       result = srm_dispatch(CCB_GET_ENV, ENV_BOOTED_DEV, bootdev, 255);
        if (result < 0)
                return result;
-       return dispatch(CCB_OPEN, bootdev, result & 255);
+       return srm_dispatch(CCB_OPEN, bootdev, result & 255);
 }
 
 static inline long close(long dev)
 {
-       return dispatch(CCB_CLOSE, dev);
+       return srm_dispatch(CCB_CLOSE, dev);
 }
 
 static inline long load(long dev, unsigned long addr, unsigned long count)
@@ -176,15 +124,15 @@ static inline long load(long dev, unsigned long addr, unsigned long count)
        extern char _end;
        long result, boot_size = &_end - (char *) BOOT_ADDR;
 
-       result = dispatch(CCB_GET_ENV, ENV_BOOTED_FILE, bootfile, 255);
+       result = srm_dispatch(CCB_GET_ENV, ENV_BOOTED_FILE, bootfile, 255);
        if (result < 0)
                return result;
        result &= 255;
        bootfile[result] = '\0';
        if (result)
-               printk("Boot file specification (%s) not implemented\n",
+               srm_printk("Boot file specification (%s) not implemented\n",
                       bootfile);
-       return dispatch(CCB_READ, dev, count, addr, boot_size/512 + 1);
+       return srm_dispatch(CCB_READ, dev, count, addr, boot_size/512 + 1);
 }
 
 /*
@@ -208,27 +156,27 @@ void start_kernel(void)
        int nbytes;
        char envval[256];
 
-       printk("Linux/AXP bootloader for Linux " UTS_RELEASE "\n");
-       if (hwrpb.pagesize != 8192) {
-               printk("Expected 8kB pages, got %ldkB\n", hwrpb.pagesize >> 10);
+       srm_printk("Linux/AXP bootloader for Linux " UTS_RELEASE "\n");
+       if (INIT_HWRPB->pagesize != 8192) {
+               srm_printk("Expected 8kB pages, got %ldkB\n", INIT_HWRPB->pagesize >> 10);
                return;
        }
        pal_init();
        dev = openboot();
        if (dev < 0) {
-               printk("Unable to open boot device: %016lx\n", dev);
+               srm_printk("Unable to open boot device: %016lx\n", dev);
                return;
        }
        dev &= 0xffffffff;
-       printk("Loading vmlinux ...");
+       srm_printk("Loading vmlinux ...");
        i = load(dev, START_ADDR, KERNEL_SIZE);
        close(dev);
        if (i != KERNEL_SIZE) {
-               printk("Failed (%lx)\n", i);
+               srm_printk("Failed (%lx)\n", i);
                return;
        }
 
-       nbytes = dispatch(CCB_GET_ENV, ENV_BOOTED_OSFLAGS,
+       nbytes = srm_dispatch(CCB_GET_ENV, ENV_BOOTED_OSFLAGS,
                          envval, sizeof(envval));
        if (nbytes < 0) {
                nbytes = 0;
@@ -236,7 +184,7 @@ void start_kernel(void)
        envval[nbytes] = '\0';
        strcpy((char*)ZERO_PAGE, envval);
 
-       printk(" Ok\nNow booting the kernel\n");
+       srm_printk(" Ok\nNow booting the kernel\n");
        runkernel();
        for (i = 0 ; i < 0x100000000 ; i++)
                /* nothing */;
index cfd366eb59173d2f8a90692b32270cf957edf7a3..c557d66eca964fca215d2d8675be3fea9cd3253d 100644 (file)
@@ -91,7 +91,6 @@ CONFIG_PARIDE_PARPORT=y
 # CONFIG_PACKET is not set
 # CONFIG_NETLINK is not set
 # CONFIG_FIREWALL is not set
-# CONFIG_NET_ALIAS is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
 CONFIG_INET=y
index 64fb0d7ab4219c13f7ff6b85b4df10e1e085e592..db89599be80c5b751f674f1669439f985b973b47 100644 (file)
@@ -80,7 +80,6 @@ CONFIG_BLK_DEV_PART=y
 # CONFIG_PACKET is not set
 # CONFIG_NETLINK is not set
 # CONFIG_FIREWALL is not set
-# CONFIG_NET_ALIAS is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
 CONFIG_INET=y
index 2dd06948175d52a42fc3965b2695e629f3c6de3a..696de8ddcb84909c9c94d0d82cc18c4b699ed762 100644 (file)
@@ -104,7 +104,6 @@ CONFIG_PARIDE_PARPORT=y
 CONFIG_PACKET=y
 # CONFIG_NETLINK is not set
 # CONFIG_FIREWALL is not set
-# CONFIG_NET_ALIAS is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
 CONFIG_INET=y
@@ -172,7 +171,9 @@ CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_GENERIC_NCR5380 is not set
 # CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_SYM53C416 is not set
 # CONFIG_SCSI_NCR53C7xx is not set
 CONFIG_SCSI_NCR53C8XX=y
 CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=4
@@ -186,6 +187,7 @@ CONFIG_SCSI_NCR53C8XX_SYNC=20
 # CONFIG_SCSI_PSI240I is not set
 # CONFIG_SCSI_QLOGIC_FAS is not set
 # CONFIG_SCSI_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_SEAGATE is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_T128 is not set
index ec2ea5d606f8871b403ba159a975bf753861cf1c..b556dd7911402df02668f5bc496a0fb910d442b9 100644 (file)
  *     serialize accesses to xtime/lost_ticks).
  */
 
-/* What about the "updated NTP code" stuff in 2.0 time.c? It's not in
- * 2.1, perhaps it should be ported, too.
- *
- * What about the BUGGY_NEPTUN_TIMER stuff in do_slow_gettimeoffset()?
- * Whatever it fixes, is it also fixed in the new code from the Jumbo
- * patch, so that that code can be used instead?
- *
- * The CPU Hz should probably be displayed in check_bugs() together
- * with the CPU vendor and type. Perhaps even only in MHz, though that
- * takes away some of the fun of the new code :)
- *
- * - Michael Krause */
-
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
index ab9152f5dc6733a73911387320bafbbe021bdfc0..109ce19fa86fe5bbf4ed8f465e04d30f1797266f 100644 (file)
@@ -78,7 +78,6 @@ CONFIG_BLK_DEV_INITRD=y
 CONFIG_PACKET=y
 # CONFIG_NETLINK is not set
 # CONFIG_FIREWALL is not set
-# CONFIG_NET_ALIAS is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
 CONFIG_INET=y
index 7cc98e85439e531ec465dc50242fa75f47f6a79a..08dae49b5547171e7ec5676c841be72cd69d14c6 100644 (file)
@@ -90,7 +90,6 @@ CONFIG_PARIDE_PARPORT=y
 # CONFIG_PACKET is not set
 # CONFIG_NETLINK is not set
 # CONFIG_FIREWALL is not set
-# CONFIG_NET_ALIAS is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
 CONFIG_INET=y
index c9f900cfed0d7e30be7add51b4d91da02398de49..5e75d496aee8b25f70014077bac2bcc6184de9df 100644 (file)
@@ -100,7 +100,6 @@ CONFIG_NETLINK=y
 # CONFIG_RTNETLINK is not set
 # CONFIG_NETLINK_DEV is not set
 # CONFIG_FIREWALL is not set
-CONFIG_NET_ALIAS=y
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
 CONFIG_INET=y
index 9141b2d908f5fbf85095d26de1aae35ef9bf8825..48e305f446cf943fdaa6271bac782cc1101b3f96 100644 (file)
@@ -85,7 +85,6 @@ CONFIG_PARIDE_PARPORT=y
 # CONFIG_PACKET is not set
 # CONFIG_NETLINK is not set
 # CONFIG_FIREWALL is not set
-CONFIG_NET_ALIAS=y
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
 CONFIG_INET=y
index f589657093028d66c8c92054e0a63a7d8d00512b..d0751a1036bcea6304226c24a25d2306e9717237 100644 (file)
@@ -87,7 +87,6 @@ CONFIG_PARIDE_PARPORT=y
 # CONFIG_PACKET is not set
 # CONFIG_NETLINK is not set
 # CONFIG_FIREWALL is not set
-# CONFIG_NET_ALIAS is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
 CONFIG_INET=y
index 811d599c0f6cfe88defb99aef3104b1dd4737d31..b3549490684e88341ca837fa0598e74161c32da4 100644 (file)
@@ -102,7 +102,6 @@ CONFIG_NETLINK=y
 # CONFIG_RTNETLINK is not set
 # CONFIG_NETLINK_DEV is not set
 # CONFIG_FIREWALL is not set
-CONFIG_NET_ALIAS=y
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
 CONFIG_INET=y
index 54035b866044fb12bb299e325b674529f9d3c684..8e2051e33bf48df1fc6f5b54bc7379630ed45e6b 100644 (file)
@@ -75,7 +75,6 @@ CONFIG_PARIDE_PARPORT=y
 # CONFIG_PACKET is not set
 # CONFIG_NETLINK is not set
 # CONFIG_FIREWALL is not set
-# CONFIG_NET_ALIAS is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
 CONFIG_INET=y
index 811d599c0f6cfe88defb99aef3104b1dd4737d31..b3549490684e88341ca837fa0598e74161c32da4 100644 (file)
@@ -102,7 +102,6 @@ CONFIG_NETLINK=y
 # CONFIG_RTNETLINK is not set
 # CONFIG_NETLINK_DEV is not set
 # CONFIG_FIREWALL is not set
-CONFIG_NET_ALIAS=y
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
 CONFIG_INET=y
index 14b4ea4a0ffc77141250974d4f638eff0d783789..01c314cb3cb1f0177f75d8c238816184823eb82f 100644 (file)
@@ -84,7 +84,6 @@ CONFIG_PARIDE_PARPORT=y
 # CONFIG_PACKET is not set
 # CONFIG_NETLINK is not set
 # CONFIG_FIREWALL is not set
-# CONFIG_NET_ALIAS is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
 CONFIG_INET=y
index 8e6d9e2f5ce1e5a86925fb20c706c4c6f698aaee..ef0f9d4e6a43690c508dd16ec27c21e06cf4673f 100644 (file)
@@ -101,7 +101,6 @@ CONFIG_BLK_DEV_NBD=m
 CONFIG_PACKET=y
 # CONFIG_NETLINK is not set
 # CONFIG_FIREWALL is not set
-# CONFIG_NET_ALIAS is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
 CONFIG_INET=y
index 59b3b4618fd031afcdd1e804eecf8481f2345817..233b345ff7fb6fb803f85460f311e369e0b84295 100644 (file)
@@ -128,7 +128,6 @@ CONFIG_BLK_DEV_CMD646=y
 CONFIG_PACKET=y
 # CONFIG_NETLINK is not set
 # CONFIG_FIREWALL is not set
-# CONFIG_NET_ALIAS is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
 CONFIG_INET=y
index 4cc11065a07def40f4f50fe110c92caa986fd0cd..89424cd20a6b7c3e170ca282bd4fdf5f5729e066 100644 (file)
@@ -879,7 +879,7 @@ amiga_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
        res = 0;
 
        for (blk = 0; blk < RDB_ALLOCATION_LIMIT; blk++) {
-               if(!(bh = bread(dev,blk,get_ptable_blocksize(dev)))) {
+               if(!(bh = bread(dev,blk,512))) {
                        printk("Dev %s: unable to read RDB block %d\n",
                               kdevname(dev),blk);
                        goto rdb_done;
@@ -896,7 +896,7 @@ amiga_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
                        blk = htonl(rdb->rdb_PartitionList);
                        brelse(bh);
                        for (part = 1; blk > 0 && part <= 16; part++) {
-                               if (!(bh = bread(dev,blk, get_ptable_blocksize(dev)))) {
+                               if (!(bh = bread(dev,blk, 512))) {
                                        printk("Dev %s: unable to read partition block %d\n",
                                                       kdevname(dev),blk);
                                        goto rdb_done;
index 5674e307083df68517199802e14a827929a9fe45..203c2d609acbf298b75bab452dd10065f7700fe4 100644 (file)
@@ -744,11 +744,12 @@ static void hd_geninit(struct gendisk *ignored)
                
        */
 
-               if ((cmos_disks = CMOS_READ(0x12)) & 0xf0)
+               if ((cmos_disks = CMOS_READ(0x12)) & 0xf0) {
                        if (cmos_disks & 0x0f)
                                NR_HD = 2;
                        else
                                NR_HD = 1;
+               }
        }
 #endif /* __i386__ */
        for (drive=0 ; drive < NR_HD ; drive++) {
index 456ca470fcea49edcf4e4b66b32d25b1b914d4ea..f70c55775d12303ae862560e0fc53e696ca05653 100644 (file)
@@ -2068,6 +2068,12 @@ static int ide_ioctl (struct inode *inode, struct file *file,
                                (unsigned long *) &loc->start)) return -EFAULT;
                        return 0;
                }
+               case BLKSSZGET:
+                       /* Block size of media */
+                       return put_user(blksize_size[HWIF(drive)->major]
+                                                   [minor&PARTN_MASK],
+                                                   (int *)arg);
+               
                case BLKFLSBUF:
                        if (!capable(CAP_SYS_ADMIN)) return -EACCES;
                        fsync_dev(inode->i_rdev);
index dd1933a47336eb7801d80c04b776e353f4dea7c8..1a3561d04fcbb4d685ab69029cf20da1bc118984 100644 (file)
@@ -170,14 +170,12 @@ static int rd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                        break;
                case BLKGETSIZE:   /* Return device size */
                        if (!arg)  return -EINVAL;
-                       err = verify_area(VERIFY_WRITE, (long *) arg,
-                                         sizeof(long));
-                       if (err)
-                               return err;
-                       put_user(rd_length[MINOR(inode->i_rdev)] / 512, 
+                       return put_user(rd_length[MINOR(inode->i_rdev)] / 512, 
                                 (long *) arg);
-                       return 0;
-                       
+               case BLKSSZGET:
+                       /* Block size of media */
+                       return put_user(rd_blocksizes[MINOR(inode->i_rdev)],
+                                                   (int *)arg);
                default:
                        break;
        };
index d3933e72d39e9b8138d5902022e30a3871aa110d..c0760b8877df4d210354069fb61f142e8eeea5fb 100644 (file)
@@ -139,6 +139,16 @@ if [ "$CONFIG_VIDEO_DEV" != "n" ]; then
   if [ "$CONFIG_RADIO_SF16FMI" = "y" ]; then
     hex '  SF16FMI I/O port (0x284 or 0x384)' CONFIG_RADIO_SF16FMI_PORT 284
   fi
+  dep_tristate 'Typhoon Radio (a.k.a. EcoRadio)' CONFIG_RADIO_TYPHOON $CONFIG_VIDEO_DEV
+  if [ "$CONFIG_PROC_FS" = "y" ]; then
+      if [ "$CONFIG_RADIO_TYPHOON" != "n" ]; then
+       bool '  Support for /proc/radio-typhoon' CONFIG_RADIO_TYPHOON_PROC_FS
+      fi
+  fi
+  if [ "$CONFIG_RADIO_TYPHOON" = "y" ]; then
+    hex '  Typhoon I/O port (0x316 or 0x336)' CONFIG_RADIO_TYPHOON_PORT 316
+    int '  Typhoon frequency set when muting the device (kHz)' CONFIG_RADIO_TYPHOON_MUTEFREQ 87500
+  fi
   dep_tristate 'Zoltrix Radio' CONFIG_RADIO_ZOLTRIX $CONFIG_VIDEO_DEV
   if [ "$CONFIG_RADIO_ZOLTRIX" = "y" ]; then
     hex '  ZOLTRIX I/O port (0x20c or 0x30c)' CONFIG_RADIO_ZOLTRIX_PORT 20c
index b38c4e5f14baddcc2da20abd02c9a2a7f978426c..6a627847b29ada8479a5d156992b661c4dcaf0a7 100644 (file)
@@ -364,6 +364,14 @@ else
   endif
 endif                                             
 
+ifeq ($(CONFIG_RADIO_TYPHOON),y)
+L_OBJS += radio-typhoon.o
+else
+  ifeq ($(CONFIG_RADIO_TYPHOON),m)
+  M_OBJS += radio-typhoon.o
+  endif
+endif                                             
+
 ifeq ($(CONFIG_RADIO_ZOLTRIX),y)
 L_OBJS += radio-zoltrix.o
 else
index 8cce3026db915576c176a5265112dfcff97ccbe6..caf8e5d6fe05ef12af3b4a177acbd1a08fb1a9d2 100644 (file)
@@ -1558,12 +1558,33 @@ static int bttv_open(struct video_device *dev, int flags)
 static void bttv_close(struct video_device *dev)
 {
        struct bttv *btv=(struct bttv *)dev;
-  
+       unsigned long f;
+       
        btv->user--;
        audio(btv, AUDIO_INTERN);
        btv->cap&=~3;
        bt848_set_risc_jmps(btv);
 
+       /*
+        *      A word of warning. At this point the chip
+        *      is still capturing because its FIFO hasn't emptied
+        *      and the DMA control operations are posted PCI 
+        *      operations.
+        */
+
+       btread(BT848_I2C);      /* This fixes the PCI posting delay */
+       
+       /*
+        *      This is sucky but right now I can't find a good way to
+        *      be sure its safe to free the buffer. We wait 5-6 fields
+        *      which is more than sufficient to be sure.
+        */
+        
+       schedule_timeout(HZ/10);        /* Wait 1/10th of a second */
+       
+       /*
+        *      We have allowed it to drain.
+        */
        if(btv->fbuffer)
                rvfree((void *) btv->fbuffer, 2*BTTV_MAX_FBUF);
        btv->fbuffer=0;
@@ -3037,7 +3058,7 @@ static void bt848_set_risc_jmps(struct bttv *btv)
        btv->risc_jmp[12]=BT848_RISC_JUMP;
        btv->risc_jmp[13]=virt_to_bus(btv->risc_jmp);
 
-       /* enable cpaturing and DMA */
+       /* enable capturing */
        btaor(flags, ~0x0f, BT848_CAP_CTL);
        if (flags&0x0f)
                bt848_dma(btv, 3);
@@ -3242,7 +3263,7 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
                if (astat&BT848_INT_SCERR) {
                        IDEBUG(printk ("bttv%d: IRQ_SCERR\n", btv->nr));
                        bt848_dma(btv, 0);
-                       bt848_dma(btv, 1);
+                       bt848_dma(btv, 3);
                        wake_up_interruptible(&btv->vbiq);
                        wake_up_interruptible(&btv->capq);
 
index 0499b818215a8f8152051098fd333308d4704bd4..fee7a573cf13b0f73c03547ae053569378d539f5 100644 (file)
@@ -203,7 +203,14 @@ static int scrollback_delta = 0;
 
 static inline unsigned short *screenpos(int currcons, int offset, int viewed)
 {
-       unsigned short *p = (unsigned short *)(visible_origin + offset);
+       unsigned short *p;
+       
+       if (!viewed)
+               p = (unsigned short *)(origin + offset);
+       else if (!sw->con_screen_pos)
+               p = (unsigned short *)(visible_origin + offset);
+       else
+               p = sw->con_screen_pos(vc_cons[currcons].d, offset);
        return p;
 }
 
@@ -253,16 +260,16 @@ static void do_update_region(int currcons, unsigned long start, int count)
        unsigned int xx, yy, offset;
        u16 *p;
 
-       if (start < origin) {
-               count -= origin - start;
-               start = origin;
-       }
-       if (count <= 0)
-               return;
-       offset = (start - origin) / 2;
-       xx = offset % video_num_columns;
-       yy = offset / video_num_columns;
        p = (u16 *) start;
+       if (!sw->con_getxy) {
+               offset = (start - origin) / 2;
+               xx = offset % video_num_columns;
+               yy = offset / video_num_columns;
+       } else {
+               int nxx, nyy;
+               start = sw->con_getxy(vc_cons[currcons].d, start, &nxx, &nyy);
+               xx = nxx; yy = nyy;
+       }
        for(;;) {
                u16 attrib = scr_readw(p) & 0xff00;
                int startx = xx;
@@ -285,6 +292,10 @@ static void do_update_region(int currcons, unsigned long start, int count)
                        break;
                xx = 0;
                yy++;
+               if (sw->con_getxy) {
+                       p = (u16 *)start;
+                       start = sw->con_getxy(vc_cons[currcons].d, start, NULL, NULL);
+               }
        }
 #endif
 }
@@ -2778,7 +2789,7 @@ void putconsxy(int currcons, char *p)
        set_cursor(currcons);
 }
 
-u16 vcs_scr_readw(int currcons, u16 *org)
+u16 vcs_scr_readw(int currcons, const u16 *org)
 {
        if ((unsigned long)org == pos && softcursor_original != -1)
                return softcursor_original;
index 97d13882f7c680223995b86de294bbce98c4662c..4ebbe24755808e3a6cb05419026321be77254d56 100644 (file)
@@ -200,6 +200,16 @@ int rt_getsigstr(struct rt_device *dev)
        return 1;               /* signal present               */
 }
 
+int rt_chkstereo(struct rt_device *dev)
+{
+       outb(0xd8, io);
+       sleep_delay(100000);
+       if (inb(io) & 0x0fd)
+               return VIDEO_SOUND_STEREO;      /* stereo detected */
+       else 
+               return VIDEO_SOUND_MONO;        /* mono */
+}
+
 static int rt_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
 {
        struct rt_device *rt=dev->priv;
@@ -263,6 +273,7 @@ static int rt_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                        memset(&v,0, sizeof(v));
                        v.flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME;
                        v.volume=rt->curvol * 6554;
+                       v.mode=rt_chkstereo(rt);
                        v.step=6554;
                        strcpy(v.name, "Radio");
                        if(copy_to_user(arg,&v, sizeof(v)))
diff --git a/drivers/char/radio-typhoon.c b/drivers/char/radio-typhoon.c
new file mode 100644 (file)
index 0000000..171ae31
--- /dev/null
@@ -0,0 +1,428 @@
+/* Typhoon Radio Card driver for radio support
+ * (c) 1999 Dr. Henrik Seidel <Henrik.Seidel@gmx.de>
+ *
+ * Card manufacturer:
+ * http://194.18.155.92/idc/prod2.idc?nr=50753&lang=e
+ *
+ * Notes on the hardware
+ *
+ * This card has two output sockets, one for speakers and one for line.
+ * The speaker output has volume control, but only in four discrete
+ * steps. The line output has neither volume control nor mute.
+ *
+ * The card has auto-stereo according to its manual, although it all
+ * sounds mono to me (even with the Win/DOS drivers). Maybe it's my
+ * antenna - I really don't know for sure.
+ *
+ * Frequency control is done digitally.
+ *
+ * Volume control is done digitally, but there are only four different
+ * possible values. So you should better always turn the volume up and
+ * use line control. I got the best results by connecting line output
+ * to the sound card microphone input. For such a configuration the
+ * volume control has no effect, since volume control only influences
+ * the speaker output.
+ *
+ * There is no explicit mute/unmute. So I set the radio frequency to a
+ * value where I do expect just noise and turn the speaker volume down.
+ * The frequency change is necessary since the card never seems to be
+ * completely silent.
+ */
+
+#include <linux/module.h>      /* Modules                        */
+#include <linux/init.h>                /* Initdata                       */
+#include <linux/ioport.h>      /* check_region, request_region   */
+#include <linux/proc_fs.h>     /* radio card status report       */
+#include <asm/io.h>            /* outb, outb_p                   */
+#include <asm/uaccess.h>       /* copy to/from user              */
+#include <linux/videodev.h>    /* kernel radio structs           */
+#include <linux/config.h>      /* CONFIG_RADIO_TYPHOON_*         */
+
+#define BANNER "Typhoon Radio Card driver v0.1\n"
+
+#ifndef CONFIG_RADIO_TYPHOON_PORT
+#define CONFIG_RADIO_TYPHOON_PORT -1
+#endif
+
+#ifndef CONFIG_RADIO_TYPHOON_MUTEFREQ
+#define CONFIG_RADIO_TYPHOON_MUTEFREQ 0
+#endif
+
+struct typhoon_device {
+       int users;
+       int iobase;
+       int curvol;
+       int muted;
+       unsigned long curfreq;
+       unsigned long mutefreq;
+};
+
+static void typhoon_setvol_generic(struct typhoon_device *dev, int vol);
+static int typhoon_setfreq_generic(struct typhoon_device *dev,
+                                  unsigned long frequency);
+static int typhoon_setfreq(struct typhoon_device *dev, unsigned long frequency);
+static void typhoon_mute(struct typhoon_device *dev);
+static void typhoon_unmute(struct typhoon_device *dev);
+static int typhoon_setvol(struct typhoon_device *dev, int vol);
+static int typhoon_ioctl(struct video_device *dev, unsigned int cmd, void *arg);
+static int typhoon_open(struct video_device *dev, int flags);
+static void typhoon_close(struct video_device *dev);
+#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
+static int typhoon_read_proc(char *buf, char **start, off_t offset, int len,
+                            int unused);
+#endif
+#ifdef MODULE
+int init_module(void);
+void cleanup_module(void);
+int typhoon_init(struct video_init *v);
+#else
+int typhoon_init(struct video_init *v) __init;
+#endif
+
+static void typhoon_setvol_generic(struct typhoon_device *dev, int vol)
+{
+       vol >>= 14;                             /* Map 16 bit to 2 bit */
+       vol &= 3;
+       outb_p(vol / 2, dev->iobase);           /* Set the volume, high bit. */
+       outb_p(vol % 2, dev->iobase + 2);       /* Set the volume, low bit. */
+}
+
+static int typhoon_setfreq_generic(struct typhoon_device *dev,
+                                  unsigned long frequency)
+{
+       unsigned long outval;
+       unsigned long x;
+
+       /*
+        * The frequency transfer curve is not linear. The best fit I could
+        * get is
+        *
+        * outval = -155 + exp((f + 15.55) * 0.057))
+        *
+        * where frequency f is in MHz. Since we don't have exp in the kernel,
+        * I approximate this function by a third order polynomial.
+        *
+        */
+
+       x = frequency / 160;
+       outval = (x * x + 2500) / 5000;
+       outval = (outval * x + 5000) / 10000;
+       outval -= (10 * x * x + 10433) / 20866;
+       outval += 4 * x - 11505;
+
+       outb_p((outval >> 8) & 0x01, dev->iobase + 4);
+       outb_p(outval >> 9, dev->iobase + 6);
+       outb_p(outval & 0xff, dev->iobase + 8);
+
+       return 0;
+}
+
+static int typhoon_setfreq(struct typhoon_device *dev, unsigned long frequency)
+{
+       typhoon_setfreq_generic(dev, frequency);
+       dev->curfreq = frequency;
+       return 0;
+}
+
+static void typhoon_mute(struct typhoon_device *dev)
+{
+       if (dev->muted == 1)
+               return;
+       typhoon_setvol_generic(dev, 0);
+       typhoon_setfreq_generic(dev, dev->mutefreq);
+       dev->muted = 1;
+}
+
+static void typhoon_unmute(struct typhoon_device *dev)
+{
+       if (dev->muted == 0)
+               return;
+       typhoon_setfreq_generic(dev, dev->curfreq);
+       typhoon_setvol_generic(dev, dev->curvol);
+       dev->muted = 0;
+}
+
+static int typhoon_setvol(struct typhoon_device *dev, int vol)
+{
+       if (dev->muted && vol != 0) {   /* user is unmuting the card */
+               dev->curvol = vol;
+               typhoon_unmute(dev);
+               return 0;
+       }
+       if (vol == dev->curvol)         /* requested volume == current */
+               return 0;
+
+       if (vol == 0) {                 /* volume == 0 means mute the card */
+               typhoon_mute(dev);
+               dev->curvol = vol;
+               return 0;
+       }
+       typhoon_setvol_generic(dev, vol);
+       dev->curvol = vol;
+       return 0;
+}
+
+
+static int typhoon_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
+{
+       struct typhoon_device *typhoon = dev->priv;
+
+       switch (cmd) {
+       case VIDIOCGCAP:
+               {
+                       struct video_capability v;
+                       v.type = VID_TYPE_TUNER;
+                       v.channels = 1;
+                       v.audios = 1;
+                       /* No we don't do pictures */
+                       v.maxwidth = 0;
+                       v.maxheight = 0;
+                       v.minwidth = 0;
+                       v.minheight = 0;
+                       strcpy(v.name, "Typhoon Radio");
+                       if (copy_to_user(arg, &v, sizeof(v)))
+                               return -EFAULT;
+                       return 0;
+               }
+       case VIDIOCGTUNER:
+               {
+                       struct video_tuner v;
+                       if (copy_from_user(&v, arg, sizeof(v)) != 0)
+                               return -EFAULT;
+                       if (v.tuner)    /* Only 1 tuner */
+                               return -EINVAL;
+                       v.rangelow = 875 * 1600;
+                       v.rangehigh = 1080 * 1600;
+                       v.flags = VIDEO_TUNER_LOW;
+                       v.mode = VIDEO_MODE_AUTO;
+                       v.signal = 0;   /* We can't get the signal strength */
+                       if (copy_to_user(arg, &v, sizeof(v)))
+                               return -EFAULT;
+                       return 0;
+               }
+       case VIDIOCSTUNER:
+               {
+                       struct video_tuner v;
+                       if (copy_from_user(&v, arg, sizeof(v)))
+                               return -EFAULT;
+                       if (v.tuner != 0)
+                               return -EINVAL;
+                       /* Only 1 tuner so no setting needed ! */
+                       return 0;
+               }
+       case VIDIOCGFREQ:
+               if (copy_to_user(arg, &typhoon->curfreq,
+                                sizeof(typhoon->curfreq)))
+                       return -EFAULT;
+               return 0;
+       case VIDIOCSFREQ:
+               if (copy_from_user(&typhoon->curfreq, arg,
+                                  sizeof(typhoon->curfreq)))
+                       return -EFAULT;
+               typhoon_setfreq(typhoon, typhoon->curfreq);
+               return 0;
+       case VIDIOCGAUDIO:
+               {
+                       struct video_audio v;
+                       memset(&v, 0, sizeof(v));
+                       v.flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME;
+                       v.mode |= VIDEO_SOUND_MONO;
+                       v.volume = typhoon->curvol;
+                       v.step = 1 << 14;
+                       strcpy(v.name, "Typhoon Radio");
+                       if (copy_to_user(arg, &v, sizeof(v)))
+                               return -EFAULT;
+                       return 0;
+               }
+       case VIDIOCSAUDIO:
+               {
+                       struct video_audio v;
+                       if (copy_from_user(&v, arg, sizeof(v)))
+                               return -EFAULT;
+                       if (v.audio)
+                               return -EINVAL;
+
+                       if (v.flags & VIDEO_AUDIO_MUTE)
+                               typhoon_mute(typhoon);
+                       else
+                               typhoon_unmute(typhoon);
+
+                       if (v.flags & VIDEO_AUDIO_VOLUME)
+                               typhoon_setvol(typhoon, v.volume);
+
+                       return 0;
+               }
+       default:
+               return -ENOIOCTLCMD;
+       }
+}
+
+static int typhoon_open(struct video_device *dev, int flags)
+{
+       struct typhoon_device *typhoon = dev->priv;
+       if (typhoon->users)
+               return -EBUSY;
+       typhoon->users++;
+       MOD_INC_USE_COUNT;
+       return 0;
+}
+
+static void typhoon_close(struct video_device *dev)
+{
+       struct typhoon_device *typhoon = dev->priv;
+       typhoon->users--;
+       MOD_DEC_USE_COUNT;
+}
+
+static struct typhoon_device typhoon_unit =
+{
+       0,                              /* users */
+       CONFIG_RADIO_TYPHOON_PORT,      /* iobase */
+       0,                              /* curvol */
+       0,                              /* muted */
+       CONFIG_RADIO_TYPHOON_MUTEFREQ,  /* curfreq */
+       CONFIG_RADIO_TYPHOON_MUTEFREQ   /* mutefreq */
+};
+
+static struct video_device typhoon_radio =
+{
+       "Typhoon Radio",
+       VID_TYPE_TUNER,
+       VID_HARDWARE_TYPHOON,
+       typhoon_open,
+       typhoon_close,
+       NULL,                   /* Can't read  (no capture ability) */
+       NULL,                   /* Can't write */
+       NULL,                   /* Can't poll */
+       typhoon_ioctl,
+       NULL,
+       NULL
+};
+
+#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
+
+static int typhoon_read_proc(char *buf, char **start, off_t offset, int len,
+                     int unused)
+{
+       #ifdef MODULE
+           #define MODULEPROCSTRING "Driver loaded as a module"
+       #else
+           #define MODULEPROCSTRING "Driver compiled into kernel"
+       #endif
+
+        #define LIMIT (PAGE_SIZE - 80)
+
+       len = 0;
+       len += sprintf(buf + len, BANNER);
+       if (len > LIMIT) return len;
+       len += sprintf(buf + len, "Load type: " MODULEPROCSTRING "\n\n");
+       if (len > LIMIT) return len;
+       len += sprintf(buf + len, "frequency = %lu kHz\n",
+               typhoon_unit.curfreq >> 4);
+       if (len > LIMIT) return len;
+       len += sprintf(buf + len, "volume = %d\n", typhoon_unit.curvol);
+       if (len > LIMIT) return len;
+       len += sprintf(buf + len, "mute = %s\n", typhoon_unit.muted ?
+               "on" : "off");
+       if (len > LIMIT) return len;
+       len += sprintf(buf + len, "iobase = 0x%x\n", typhoon_unit.iobase);
+       if (len > LIMIT) return len;
+       len += sprintf(buf + len, "mute frequency = %lu kHz\n",
+               typhoon_unit.mutefreq >> 4);
+       return len;
+}
+
+static struct proc_dir_entry typhoon_proc_entry = {
+       0,                      /* low_ino: inode is dynamic */
+       13, "radio-typhoon",    /* length of name and name */
+       S_IFREG | S_IRUGO,      /* mode */
+       1, 0, 0,                /* nlinks, owner, group */
+       0,                      /* size -- not used */
+       NULL,                   /* operations -- use default */
+       &typhoon_read_proc,     /* function used to read data */
+       /* nothing more */
+};
+
+#endif /* CONFIG_RADIO_TYPHOON_PROC_FS */
+
+int typhoon_init(struct video_init *v)
+{
+       printk(KERN_INFO BANNER);
+       if (check_region(typhoon_unit.iobase, 8)) {
+               printk(KERN_ERR "radio-typhoon: port 0x%x already in use\n",
+                      typhoon_unit.iobase);
+               return -EBUSY;
+       }
+
+       typhoon_radio.priv = &typhoon_unit;
+       if (video_register_device(&typhoon_radio, VFL_TYPE_RADIO) == -1)
+               return -EINVAL;
+
+       request_region(typhoon_unit.iobase, 8, "typhoon");
+       printk(KERN_INFO "radio-typhoon: port 0x%x.\n", typhoon_unit.iobase);
+       printk(KERN_INFO "radio-typhoon: mute frequency is %lu kHz.\n",
+              typhoon_unit.mutefreq);
+       typhoon_unit.mutefreq <<= 4;
+
+       /* mute card - prevents noisy bootups */
+       typhoon_mute(&typhoon_unit);
+
+#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
+       
+       if (proc_register(&proc_root, &typhoon_proc_entry))
+               printk(KERN_ERR "radio-typhoon: registering /proc/radio-typhoon failed\n");
+
+#endif
+
+       return 0;
+}
+
+#ifdef MODULE
+
+MODULE_AUTHOR("Dr. Henrik Seidel");
+MODULE_DESCRIPTION("A driver for the Typhoon radio card (a.k.a. EcoRadio).");
+MODULE_PARM(io, "i");
+MODULE_PARM_DESC(io, "I/O address of the Typhoon card (0x316 or 0x336)");
+MODULE_PARM(mutefreq, "i");
+MODULE_PARM_DESC(mutefreq, "Frequency used when muting the card (in kHz)");
+
+EXPORT_NO_SYMBOLS;
+
+static int io = -1;
+static unsigned long mutefreq = 0;
+
+int init_module(void)
+{
+       if (io == -1) {
+               printk(KERN_ERR "radio-typhoon: You must set an I/O address with io=0x316 or io=0x336\n");
+               return -EINVAL;
+       }
+       typhoon_unit.iobase = io;
+
+       if (mutefreq < 87000 || mutefreq > 108500) {
+               printk(KERN_ERR "radio-typhoon: You must set a frequency (in kHz) used when muting the card,\n");
+               printk(KERN_ERR "radio-typhoon: e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n");
+               return -EINVAL;
+       }
+       typhoon_unit.mutefreq = mutefreq;
+
+       return typhoon_init(NULL);
+}
+
+void cleanup_module(void)
+{
+
+#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
+
+       if (proc_unregister(&proc_root, typhoon_proc_entry.low_ino))
+               printk(KERN_ERR "radio-typhoon: unregistering /proc/radio-typhoon failed\n");
+
+#endif
+
+       video_unregister_device(&typhoon_radio);
+       release_region(io, 8);
+}
+
+#endif
+
+
index 80a72d4b4c4d403661c9b21949e375db294e29ad..d01e016aac0dc1222a2549d6904198976ff4ff31 100644 (file)
@@ -11,7 +11,8 @@
  *  at a low frequency, and it is not possible (at least I have not found)
  *  to get fine volume control over the low volume range.
  *
- *  Some code derived from code by Frans Brinkman
+ *  Some code derived from code by Romolo Manfredini
+ *                                romolo@bicnet.it
  *
  * 1999-01-05 - (C. van Schaik)
  *           - Changed tuning to 1/160Mhz accuracy
@@ -285,10 +286,10 @@ static int zol_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                        if (v.flags & VIDEO_AUDIO_MUTE)
                                zol_mute(zol);
                        else
+                       {
                                zol_unmute(zol);
-
-                       if (v.flags & VIDEO_AUDIO_VOLUME)
                                zol_setvol(zol, v.volume / 4096);
+                       }
 
                        if (v.mode & VIDEO_SOUND_STEREO)
                        {
index bbdf7e4d5fcc833a9f80927a6bf7db21265fae41..4db4e6efb0f4dfddfb2fbc7e4584790fb33b90f2 100644 (file)
@@ -89,6 +89,7 @@ vcs_read(struct file *file, char *buf, size_t count, loff_t *ppos)
        long p = *ppos;
        long viewed, attr, size, read;
        char *buf0;
+       int col, maxcol;
        unsigned short *org = NULL;
 
        attr = (currcons & 128);
@@ -111,10 +112,19 @@ vcs_read(struct file *file, char *buf, size_t count, loff_t *ppos)
                count = size - p;
 
        buf0 = buf;
+       maxcol = video_num_columns;
        if (!attr) {
                org = screen_pos(currcons, p, viewed);
-               while (count-- > 0)
+               col = p % maxcol;
+               p += maxcol - col;
+               while (count-- > 0) {
                        put_user(vcs_scr_readw(currcons, org++) & 0xff, buf++);
+                       if (++col == maxcol) {
+                               org = screen_pos(currcons, p, viewed);
+                               col = 0;
+                               p += maxcol;
+                       }
+               }
        } else {
                if (p < HEADER_SIZE) {
                        char header[HEADER_SIZE];
@@ -124,20 +134,35 @@ vcs_read(struct file *file, char *buf, size_t count, loff_t *ppos)
                        while (p < HEADER_SIZE && count > 0)
                            { count--; put_user(header[p++], buf++); }
                }
+               p -= HEADER_SIZE;
+               col = (p/2) % maxcol;
                if (count > 0) {
-                   p -= HEADER_SIZE;
-                   org = screen_pos(currcons, p/2, viewed);
-                   if ((p & 1) && count > 0)
+                       org = screen_pos(currcons, p/2, viewed);
+                       if ((p & 1) && count > 0) {
+                               count--;   
 #ifdef __BIG_ENDIAN
-                           { count--; put_user(vcs_scr_readw(currcons, org++) & 0xff, buf++); }
+                               put_user(vcs_scr_readw(currcons, org++) & 0xff, buf++);
 #else
-                           { count--; put_user(vcs_scr_readw(currcons, org++) >> 8, buf++); }
+                               put_user(vcs_scr_readw(currcons, org++) >> 8, buf++);
 #endif
+                               p++;
+                               if (++col == maxcol) {
+                                       org = screen_pos(currcons, p/2, viewed);
+                                       col = 0;
+                               }
+                       }
+                       p /= 2;
+                       p += maxcol - col;
                }
                while (count > 1) {
                        put_user(vcs_scr_readw(currcons, org++), (unsigned short *) buf);
                        buf += 2;
                        count -= 2;
+                       if (++col == maxcol) {
+                               org = screen_pos(currcons, p, viewed);
+                               col = 0;
+                               p += maxcol;
+                       }
                }
                if (count > 0)
 #ifdef __BIG_ENDIAN
@@ -159,6 +184,7 @@ vcs_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
        long p = *ppos;
        long viewed, attr, size, written;
        const char *buf0;
+       int col, maxcol;
        u16 *org0 = NULL, *org = NULL;
 
        attr = (currcons & 128);
@@ -181,14 +207,22 @@ vcs_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
                count = size - p;
 
        buf0 = buf;
+       maxcol = video_num_columns;
        if (!attr) {
                org0 = org = screen_pos(currcons, p, viewed);
+               col = p % maxcol;
+               p += maxcol - col;
                while (count > 0) {
                        unsigned char c;
                        count--;
                        get_user(c, (const unsigned char*)buf++);
                        vcs_scr_writew(currcons, (vcs_scr_readw(currcons, org) & 0xff00) | c, org);
                        org++;
+                       if (++col == maxcol) {
+                               org = screen_pos(currcons, p, viewed);
+                               col = 0;
+                               p += maxcol;
+                       }
                }
        } else {
                if (p < HEADER_SIZE) {
@@ -199,8 +233,9 @@ vcs_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
                        if (!viewed)
                                putconsxy(currcons, header+2);
                }
+               p -= HEADER_SIZE;
+               col = (p/2) % maxcol;
                if (count > 0) {
-                       p -= HEADER_SIZE;
                        org0 = org = screen_pos(currcons, p/2, viewed);
                        if ((p & 1) && count > 0) {
                            char c;
@@ -214,7 +249,14 @@ vcs_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
                                     (vcs_scr_readw(currcons, org) & 0xff), org);
 #endif
                                org++;
+                               p++;
+                               if (++col == maxcol) {
+                                       org = screen_pos(currcons, p/2, viewed);
+                                       col = 0;
+                               }
                        }
+                       p /= 2;
+                       p += maxcol - col;
                }
                while (count > 1) {
                        unsigned short w;
@@ -222,6 +264,11 @@ vcs_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
                        vcs_scr_writew(currcons, w, org++);
                        buf += 2;
                        count -= 2;
+                       if (++col == maxcol) {
+                               org = screen_pos(currcons, p, viewed);
+                               col = 0;
+                               p += maxcol;
+                       }
                }
                if (count > 0) {
                        unsigned char c;
index dd9364ecf6ef45426d6a9f6b68721cf159df85d4..187d0715df8a64e0ea9c6411e105b344dfe6084a 100644 (file)
@@ -72,6 +72,9 @@ extern int pcm20_init(struct video_init *);
 #ifdef CONFIG_RADIO_GEMTEK
 extern int gemtek_init(struct video_init *);
 #endif
+#ifdef CONFIG_RADIO_TYPHOON
+extern int typhoon_init(struct video_init *);
+#endif
 #ifdef CONFIG_VIDEO_PMS
 extern int init_pms_cards(struct video_init *);
 #endif
@@ -101,7 +104,7 @@ static struct video_init video_init_list[]={
 #endif 
 #ifdef CONFIG_RADIO_RTRACK
        {"RTrack", rtrack_init}, 
-#endif 
+#endif 
 #ifdef CONFIG_RADIO_SF16FMI
        {"SF16FMI", fmi_init}, 
 #endif 
@@ -110,6 +113,9 @@ static struct video_init video_init_list[]={
 #endif
 #ifdef CONFIG_RADIO_GEMTEK
        {"GemTek", gemtek_init},
+#endif
+#ifdef CONFIG_RADIO_TYPHOON
+       {"radio-typhoon", typhoon_init},
 #endif
        {"end", NULL}
 };
index 064edb07f598694597ff598fa2ff62112321cb37..89262608af70226af0c699f6d77758b6c937007c 100644 (file)
@@ -165,8 +165,10 @@ int ei_open(struct device *dev)
       
        spin_lock_irqsave(&ei_local->page_lock, flags);
        NS8390_init(dev, 1);
-       spin_unlock_irqrestore(&ei_local->page_lock, flags);
+       /* Set the flag before we drop the lock, That way the IRQ arrives
+          after its set and we get no silly warnings */
        dev->start = 1;
+       spin_unlock_irqrestore(&ei_local->page_lock, flags);
        ei_local->irqlock = 0;
        return 0;
 }
index 898369fb37c550b9c97e20ce6bed9ec536e83cbf..41d257991b6ae7e68bdb89b4e8a23cd9d80bdf8e 100644 (file)
@@ -767,6 +767,8 @@ __initfunc(int a2065_probe(struct device *dev))
                        dev->priv = kmalloc(sizeof(struct
                                                   lance_private),
                                            GFP_KERNEL);
+                       if (dev->priv == NULL)  
+                               return -ENOMEM;
                        priv = (struct lance_private *)dev->priv;
                        memset(priv, 0, sizeof(struct lance_private));
 
index baaa5969298dce9b21fb961a481af65fed085a13..8a1cd4e9db2e788fe52f592842452620e44ab393 100644 (file)
@@ -171,6 +171,8 @@ __initfunc(int ariadne_probe(struct device *dev))
            init_etherdev(dev, 0);
 
            dev->priv = kmalloc(sizeof(struct ariadne_private), GFP_KERNEL);
+           if (dev->priv == NULL)
+               return -ENOMEM;
            priv = (struct ariadne_private *)dev->priv;
            memset(priv, 0, sizeof(struct ariadne_private));
 
index ab82b9d2bf4bd58f9db2af5469ab8654ee90dbce..23de70138f54dd339a247e57b8a329791e2a552d 100644 (file)
  *             This will be fixed in BETA4
  */
  
+/*
+ * bh_atomic() SMP races fixes and rewritten the locking code to be SMP safe
+ * and irq-mask friendly. NOTE: we can't use start_bh_atomic() in kick_shaper()
+ * because it's going to be recalled from an irq handler, and synchronize_bh()
+ * is a nono if called from irq context.
+ *                                             1999  Andrea Arcangeli
+ */
  
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -83,21 +90,17 @@ int sh_debug;               /* Debug flag */
  
 static int shaper_lock(struct shaper *sh)
 {
-       unsigned long flags;
-       save_flags(flags);
-       cli();
        /*
-        *      Lock in an interrupt may fail
+        *      Lock in an interrupt must fail
         */
-       if(sh->locked && in_interrupt())
+       while (test_and_set_bit(0, &sh->locked))
        {
-               restore_flags(flags);
-               return 0;
+               if (!in_interrupt())
+                       sleep_on(&sh->wait_queue);
+               else
+                       return 0;
+                       
        }
-       while(sh->locked)
-               sleep_on(&sh->wait_queue);
-       sh->locked=1;
-       restore_flags(flags);
        return 1;
 }
 
@@ -105,7 +108,7 @@ static void shaper_kick(struct shaper *sh);
 
 static void shaper_unlock(struct shaper *sh)
 {
-       sh->locked=0;
+       clear_bit(0, &sh->locked);
        wake_up(&sh->wait_queue);
        shaper_kick(sh);
 }
@@ -240,7 +243,6 @@ static int shaper_qframe(struct shaper *shaper, struct sk_buff *skb)
                dev_kfree_skb(ptr);
        }
        shaper_unlock(shaper);
-       shaper_kick(shaper);
        return 0;
 }
 
@@ -285,24 +287,16 @@ static void shaper_timer(unsigned long data)
 static void shaper_kick(struct shaper *shaper)
 {
        struct sk_buff *skb;
-       unsigned long flags;
        
-       save_flags(flags);
-       cli();
-
-       del_timer(&shaper->timer);
-
        /*
         *      Shaper unlock will kick
         */
         
-       if(shaper->locked)
-       {       
+       if (test_and_set_bit(0, &shaper->locked))
+       {
                if(sh_debug)
                        printk("Shaper locked.\n");
-               shaper->timer.expires=jiffies+1;
-               add_timer(&shaper->timer);
-               restore_flags(flags);
+               mod_timer(&shaper->timer, jiffies);
                return;
        }
 
@@ -320,7 +314,7 @@ static void shaper_kick(struct shaper *shaper)
                 
                if(sh_debug)
                        printk("Clock = %d, jiffies = %ld\n", skb->shapeclock, jiffies);
-               if(skb->shapeclock - jiffies <= SHAPER_BURST)
+               if(time_before_eq(skb->shapeclock - jiffies, SHAPER_BURST))
                {
                        /*
                         *      Pull the frame and get interrupts back on.
@@ -329,8 +323,6 @@ static void shaper_kick(struct shaper *shaper)
                        skb_unlink(skb);
                        if (shaper->recovery < skb->shapeclock + skb->shapelen)
                                shaper->recovery = skb->shapeclock + skb->shapelen;
-                       restore_flags(flags);
-
                        /*
                         *      Pass on to the physical target device via
                         *      our low level packet thrower.
@@ -338,7 +330,6 @@ static void shaper_kick(struct shaper *shaper)
                        
                        skb->shapepend=0;
                        shaper_queue_xmit(shaper, skb); /* Fire */
-                       cli();
                }
                else
                        break;
@@ -349,17 +340,9 @@ static void shaper_kick(struct shaper *shaper)
         */
         
        if(skb!=NULL)
-       {
-               del_timer(&shaper->timer);
-               shaper->timer.expires=skb->shapeclock;
-               add_timer(&shaper->timer);
-       }
-               
-       /*
-        *      Interrupts on, mission complete
-        */
-               
-       restore_flags(flags);
+               mod_timer(&shaper->timer, skb->shapeclock);
+
+       clear_bit(0, &shaper->locked);
 }
 
 
@@ -370,8 +353,14 @@ static void shaper_kick(struct shaper *shaper)
 static void shaper_flush(struct shaper *shaper)
 {
        struct sk_buff *skb;
+       if(!shaper_lock(shaper))
+       {
+               printk(KERN_ERR "shaper: shaper_flush() called by an irq!\n");
+               return;
+       }
        while((skb=skb_dequeue(&shaper->sendq))!=NULL)
                dev_kfree_skb(skb);
+       shaper_unlock(shaper);
 }
 
 /*
@@ -405,7 +394,9 @@ static int shaper_close(struct device *dev)
 {
        struct shaper *shaper=dev->priv;
        shaper_flush(shaper);
+       start_bh_atomic();
        del_timer(&shaper->timer);
+       end_bh_atomic();
        MOD_DEC_USE_COUNT;
        return 0;
 }
index 75c0f35019c21376f0d6b5ceff4d3b13a28d1461..560af8eee800d66bd9a2377800e2def5ec08637e 100644 (file)
@@ -2,7 +2,7 @@
 /*
        This is a driver for the SMC Ultra and SMC EtherEZ ISA ethercards.
 
-       Written 1993-1996 by Donald Becker.
+       Written 1993-1998 by Donald Becker.
 
        Copyright 1993 United States Government as represented by the
        Director, National Security Agency.
@@ -14,7 +14,7 @@
        Center of Excellence in Space Data and Information Sciences
                Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
 
-       This driver uses the cards in the 8390-compatible, shared memory mode.
+       This driver uses the cards in the 8390-compatible mode.
        Most of the run-time complexity is handled by the generic code in
        8390.c.  The code in this file is responsible for
 
@@ -27,6 +27,8 @@
 
                ultra_block_input()             Routines for reading and writing blocks of
                ultra_block_output()    packet buffer memory.
+               ultra_pio_input()
+               ultra_pio_output()
 
        This driver enables the shared memory only when doing the actual data
        transfers to avoid a bug in early version of the card that corrupted
@@ -34,7 +36,7 @@
 
        This driver now supports the programmed-I/O (PIO) data transfer mode of
        the EtherEZ. It does not use the non-8390-compatible "Altego" mode.
-       That support (if available) is smc-ez.c.
+       That support (if available) is in smc-ez.c.
 
        Changelog:
 
@@ -44,8 +46,7 @@
 */
 
 static const char *version =
-       "smc-ultra.c:v2.00 6/6/96 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
+       "smc-ultra.c:v2.02 2/3/98 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
 
 #include <linux/module.h>
 
@@ -75,13 +76,13 @@ static void ultra_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
 static void ultra_block_input(struct device *dev, int count,
                                                  struct sk_buff *skb, int ring_offset);
 static void ultra_block_output(struct device *dev, int count,
-                                                       const unsigned char *buf, int start_page);
+                                                       const unsigned char *buf, const int start_page);
 static void ultra_pio_get_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
                                                int ring_page);
 static void ultra_pio_input(struct device *dev, int count,
                                                  struct sk_buff *skb, int ring_offset);
 static void ultra_pio_output(struct device *dev, int count,
-                                                       const unsigned char *buf, int start_page);
+                                                        const unsigned char *buf, const int start_page);
 static int ultra_close_card(struct device *dev);
 
 \f
@@ -155,11 +156,8 @@ __initfunc(int ultra_probe1(struct device *dev, int ioaddr))
        if (load_8390_module("smc-ultra.c"))
                return -ENOSYS;
 
-       /* We should have a "dev" from Space.c or the static module table. */
-       if (dev == NULL) {
-               printk("smc-ultra.c: Passed a NULL device.\n");
+       if (dev == NULL)
                dev = init_etherdev(0, 0);
-       }
 
        if (ei_debug  &&  version_printed++ == 0)
                printk(version);
@@ -255,12 +253,19 @@ static int
 ultra_open(struct device *dev)
 {
        int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
+       unsigned char irq2reg[] = {0, 0, 0x04, 0x08, 0, 0x0C, 0, 0x40,
+                                                          0, 0x04, 0x44, 0x48, 0, 0, 0, 0x4C, };
 
        if (request_irq(dev->irq, ei_interrupt, 0, ei_status.name, dev))
                return -EAGAIN;
 
        outb(0x00, ioaddr);     /* Disable shared memory for safety. */
        outb(0x80, ioaddr + 5);
+       /* Set the IRQ line. */
+       outb(inb(ioaddr + 4) | 0x80, ioaddr + 4);
+       outb((inb(ioaddr + 13) & ~0x4C) | irq2reg[dev->irq], ioaddr + 13);
+       outb(inb(ioaddr + 4) & 0x7f, ioaddr + 4);
+
        if (ei_status.block_input == &ultra_pio_input) {
                outb(0x11, ioaddr + 6);         /* Enable interrupts and PIO. */
                outb(0x01, ioaddr + 0x19);      /* Enable ring read auto-wrap. */
@@ -358,7 +363,7 @@ ultra_block_output(struct device *dev, int count, const unsigned char *buf,
    byte-sequentially to IOPA, with no intervening I/O operations, and the
    data is read or written to the IOPD data port.
    The only potential complication is that the address register is shared
-   must be always be rewritten between each read/write direction change.
+   and must be always be rewritten between each read/write direction change.
    This is no problem for us, as the 8390 code ensures that we are single
    threaded. */
 static void ultra_pio_get_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
@@ -379,20 +384,17 @@ static void ultra_pio_input(struct device *dev, int count,
        /* For now set the address again, although it should already be correct. */
        outb(ring_offset, ioaddr + IOPA);       /* Set the address, LSB first. */
        outb(ring_offset >> 8, ioaddr + IOPA);
+       /* We know skbuffs are padded to at least word alignment. */
        insw(ioaddr + IOPD, buf, (count+1)>>1);
-#ifdef notdef
-       /* We don't need this -- skbuffs are padded to at least word alignment. */
-       if (count & 0x01) {
-               buf[count-1] = inb(ioaddr + IOPD);
-#endif
 }
 
 static void ultra_pio_output(struct device *dev, int count,
-                                                       const unsigned char *buf, int start_page)
+                                                       const unsigned char *buf, const int start_page)
 {
        int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
        outb(0x00, ioaddr + IOPA);      /* Set the address, LSB first. */
        outb(start_page, ioaddr + IOPA);
+       /* An extra odd byte is OK here as well. */
        outsw(ioaddr + IOPD, buf, (count+1)>>1);
 }
 
@@ -461,15 +463,12 @@ init_module(void)
                }
                if (register_netdev(dev) != 0) {
                        printk(KERN_WARNING "smc-ultra.c: No SMC Ultra card found (i/o = 0x%x).\n", io[this_dev]);
-                       if (found != 0) {       /* Got at least one. */
-                               lock_8390_module();
-                               return 0;
-                       }
+                       if (found != 0) return 0;       /* Got at least one. */
                        return -ENXIO;
                }
                found++;
        }
-       lock_8390_module();
+
        return 0;
 }
 
@@ -481,15 +480,14 @@ cleanup_module(void)
        for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) {
                struct device *dev = &dev_ultra[this_dev];
                if (dev->priv != NULL) {
+                       /* NB: ultra_close_card() does free_irq + irq2dev */
                        int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET;
-                       void *priv = dev->priv;
-                       /* NB: ultra_close_card() does free_irq */
+                       kfree(dev->priv);
+                       dev->priv = NULL;
                        release_region(ioaddr, ULTRA_IO_EXTENT);
                        unregister_netdev(dev);
-                       kfree(priv);
                }
        }
-       unlock_8390_module();
 }
 #endif /* MODULE */
 \f
@@ -500,6 +498,7 @@ cleanup_module(void)
  *  version-control: t
  *  kept-new-versions: 5
  *  c-indent-level: 4
+ *  c-basic-offset: 4
  *  tab-width: 4
  * End:
  */
index 686df3085af24e495ff9d4241a52336c41b47334..cd21d1cda4e24fa00d98c3cc0a200725f72dfd9a 100644 (file)
@@ -66,6 +66,7 @@ if [ "$CONFIG_SCSI_GENERIC_NCR5380" != "n" ]; then
 fi
 if [ "$CONFIG_PCI" = "y" ]; then
   dep_tristate 'Initio 9100U(W) support' CONFIG_SCSI_INITIO $CONFIG_SCSI
+  dep_tristate 'Initio INI-A100U2W support' CONFIG_SCSI_INIA100 $CONFIG_SCSI
 fi
 if [ "$CONFIG_PARPORT" != "n" ]; then
   dep_tristate 'IOMEGA parallel port (ppa - older drives)' CONFIG_SCSI_PPA $CONFIG_SCSI $CONFIG_PARPORT
@@ -76,6 +77,7 @@ if [ "$CONFIG_PARPORT" != "n" ]; then
   fi
 fi
 dep_tristate 'NCR53c406a SCSI support' CONFIG_SCSI_NCR53C406A $CONFIG_SCSI
+dep_tristate 'symbios 53c416 SCSI support' CONFIG_SCSI_SYM53C416 $CONFIG_SCSI
 if [ "$CONFIG_PCI" = "y" ]; then
   dep_tristate 'NCR53c7,8xx SCSI support'  CONFIG_SCSI_NCR53C7xx $CONFIG_SCSI
   if [ "$CONFIG_SCSI_NCR53C7xx" != "n" ]; then
@@ -117,7 +119,7 @@ dep_tristate 'PSI240i support' CONFIG_SCSI_PSI240I $CONFIG_SCSI
 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 ISP FC SCSI support' CONFIG_SCSI_QLOGIC_FC $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
 if [ "$CONFIG_PCI" = "y" ]; then
index cbffa8aa107dd50c8ad1e381fb33965a59d4bed4..6f34bed50136fb53b322c8a9a24c098744891a93 100644 (file)
@@ -298,6 +298,14 @@ else
   endif
 endif
 
+ifeq ($(CONFIG_SCSI_INIA100),y)
+L_OBJS += a100u2w.o
+else
+  ifeq ($(CONFIG_SCSI_INIA100),m)
+  M_OBJS += a100u2w.o
+  endif
+endif
+
 ifeq ($(CONFIG_SCSI_QLOGIC_FC),y)
 L_OBJS += qlogicfc.o 
 else
@@ -576,6 +584,14 @@ else
   endif
 endif
 
+ifeq ($(CONFIG_SCSI_SYM53C416),y)
+L_OBJS += sym53c416.o
+else
+  ifeq ($(CONFIG_SCSI_SYM53C416),m)
+  M_OBJS += sym53c416.o
+  endif
+endif
+
 ifeq ($(CONFIG_BLK_DEV_IDESCSI),y)
 L_OBJS += ide-scsi.o
 else
@@ -617,6 +633,9 @@ initio.o: ini9100u.c i91uscsi.c
        $(LD) -r -o initio.o ini9100u.o i91uscsi.o
        rm -f ini9100u.o i91uscsi.o
 
+a100u2w.o: inia100.o i60uscsi.o
+       $(LD) -r -o a100u2w.o inia100.o i60uscsi.o
+
 megaraid.o: megaraid.c
        $(CC) $(CFLAGS) -c megaraid.c
 
index 1d253608bad7e06bea595054b86a04cbfbb23915..ada7235b88db9dbd4367c3b3c1db369cbb084eff 100644 (file)
@@ -1684,7 +1684,7 @@ int atp870u_detect(Scsi_Host_Template * tpnt)
     struct Scsi_Host * shpnt = NULL;
     int count = 0;
     static unsigned short devid[7]={0x8002,0x8010,0x8020,0x8030,0x8040,0x8050,0};
-       static struct pci_dev *pdev = NULL;
+    static struct pci_dev *pdev = NULL, *acard_pdev[3];
 
     printk("aec671x_detect: \n");
     if (!pci_present())
@@ -1729,6 +1729,7 @@ int atp870u_detect(Scsi_Host_Template * tpnt)
        chip_ver[2]=0;
           
        /* To avoid messing with the things below...  */
+       acard_pdev[2] = pdev;
        pci_device_fn[2] =  pdev->devfn;
        pci_bus[2] = pdev->bus->number;
 
@@ -1746,15 +1747,18 @@ int atp870u_detect(Scsi_Host_Template * tpnt)
        }
        if ( pci_device_fn[2] < pci_device_fn[0] )
        {
+         acard_pdev[1]=acard_pdev[0];
          pci_bus[1]=pci_bus[0];
          pci_device_fn[1]=pci_device_fn[0];
          chip_ver[1]=chip_ver[0];
+         acard_pdev[0]=acard_pdev[2];
          pci_bus[0]=pci_bus[2];
          pci_device_fn[0]=pci_device_fn[2];
          chip_ver[0]=chip_ver[2];
        }
        else if ( pci_device_fn[2] < pci_device_fn[1] )
        {
+         acard_pdev[1]=acard_pdev[2];
          pci_bus[1]=pci_bus[2];
          pci_device_fn[1]=pci_device_fn[2];
          chip_ver[1]=chip_ver[2];
@@ -1774,6 +1778,7 @@ nxt_devfn:
        return count;
     }
 
+    pdev = acard_pdev[h];
     pdev->devfn = pci_device_fn[h];
     pdev->bus->number = pci_bus[h];
 
index a5ff11ab1f60ea4158d4c9872edc85e28bc1d872..17dbce09e7121ec4bb51fb58c13de7981d4cfcc0 100644 (file)
 #include "NCR53c406a.h"
 #endif
 
+#ifdef CONFIG_SCSI_SYM53C416 
+#include "sym53c416.h" 
+#endif
+
 #ifdef CONFIG_SCSI_DC390T
 #include "dc390.h"
 #endif
 #include "ini9100u.h"
 #endif
 
+#ifdef CONFIG_SCSI_INIA100
+#include "inia100.h"
+#endif
+
 #ifdef CONFIG_SCSI_DEBUG
 #include "scsi_debug.h"
 #endif
@@ -452,7 +460,7 @@ static Scsi_Host_Template builtin_scsi_hosts[] =
 #ifdef CONFIG_SCSI_AIC7XXX
     AIC7XXX,
 #endif
-#ifdef CONFIG_FD_MCS
+#ifdef CONFIG_SCSI_FD_MCS
    FD_MCS,
 #endif
 #ifdef CONFIG_SCSI_FUTURE_DOMAIN
@@ -467,6 +475,9 @@ static Scsi_Host_Template builtin_scsi_hosts[] =
 #ifdef CONFIG_SCSI_NCR53C406A  /* 53C406A should come before QLOGIC */
     NCR53c406a,
 #endif
+#ifdef CONFIG_SCSI_SYM53C416 
+    SYM53C416, 
+#endif
 #ifdef CONFIG_SCSI_QLOGIC_FAS
     QLOGICFAS,
 #endif
@@ -533,6 +544,9 @@ static Scsi_Host_Template builtin_scsi_hosts[] =
 #ifdef CONFIG_SCSI_INITIO
     INI9100U,
 #endif
+#ifdef CONFIG_SCSI_INIA100
+    INIA100,
+#endif
 #ifdef CONFIG_SCSI_QLOGICPTI
     QLOGICPTI,
 #endif
diff --git a/drivers/scsi/i60uscsi.c b/drivers/scsi/i60uscsi.c
new file mode 100644 (file)
index 0000000..6e8e650
--- /dev/null
@@ -0,0 +1,956 @@
+/**************************************************************************
+ * Initio A100 device driver for Linux.
+ *
+ * Copyright (c) 1994-1998 Initio Corporation
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *************************************************************************
+ *
+ * module: i60uscsi.c 
+ * DESCRIPTION:
+ *     This is the Linux low-level SCSI driver for Initio INIA100 SCSI host
+ * adapters
+ *
+ * 07/02/98 hl - v.91n Initial drivers.
+ * 09/14/98 hl - v1.01 Support new Kernel.
+ * 09/22/98 hl - v1.01a Support reset.
+ * 09/24/98 hl - v1.01b Fixed reset.
+ * 10/05/98 hl - v1.02 split the source code and release.
+ * 12/19/98 bv - v1.02a Use spinlocks for 2.1.95 and up
+ **************************************************************************/
+
+#ifndef CVT_LINUX_VERSION
+#define CVT_LINUX_VERSION(V,P,S)        (V * 65536 + P * 256 + S)
+#endif
+
+#include <linux/sched.h>
+#include <asm/io.h>
+#include "i60uscsi.h"
+
+
+/* ---- INTERNAL FUNCTIONS ---- */
+static UCHAR waitChipReady(ORC_HCS * hcsp);
+static UCHAR waitFWReady(ORC_HCS * hcsp);
+static UCHAR waitFWReady(ORC_HCS * hcsp);
+static UCHAR waitSCSIRSTdone(ORC_HCS * hcsp);
+static UCHAR waitHDOoff(ORC_HCS * hcsp);
+static UCHAR waitHDIset(ORC_HCS * hcsp, UCHAR * pData);
+static unsigned short get_FW_version(ORC_HCS * hcsp);
+static UCHAR set_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char value);
+static UCHAR get_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char *pDataIn);
+static int se2_rd_all(ORC_HCS * hcsp);
+static void se2_update_all(ORC_HCS * hcsp);    /* setup default pattern        */
+static void read_eeprom(ORC_HCS * hcsp);
+static UCHAR load_FW(ORC_HCS * hcsp);
+static void setup_SCBs(ORC_HCS * hcsp);
+static void initAFlag(ORC_HCS * hcsp);
+ORC_SCB *orc_alloc_scb(ORC_HCS * hcsp);
+
+/* ---- EXTERNAL FUNCTIONS ---- */
+extern void inia100SCBPost(BYTE * pHcb, BYTE * pScb);
+
+/* ---- INTERNAL VARIABLES ---- */
+ORC_HCS orc_hcs[MAX_SUPPORTED_ADAPTERS];
+static INIA100_ADPT_STRUCT inia100_adpt[MAX_SUPPORTED_ADAPTERS];
+/* set by inia100_setup according to the command line */
+int orc_num_scb;
+
+NVRAM nvram, *nvramp = &nvram;
+static UCHAR dftNvRam[64] =
+{
+/*----------header -------------*/
+       0x01,                   /* 0x00: Sub System Vendor ID 0 */
+       0x11,                   /* 0x01: Sub System Vendor ID 1 */
+       0x60,                   /* 0x02: Sub System ID 0        */
+       0x10,                   /* 0x03: Sub System ID 1        */
+       0x00,                   /* 0x04: SubClass               */
+       0x01,                   /* 0x05: Vendor ID 0            */
+       0x11,                   /* 0x06: Vendor ID 1            */
+       0x60,                   /* 0x07: Device ID 0            */
+       0x10,                   /* 0x08: Device ID 1            */
+       0x00,                   /* 0x09: Reserved               */
+       0x00,                   /* 0x0A: Reserved               */
+       0x01,                   /* 0x0B: Revision of Data Structure     */
+                               /* -- Host Adapter Structure --- */
+       0x01,                   /* 0x0C: Number Of SCSI Channel */
+       0x01,                   /* 0x0D: BIOS Configuration 1   */
+       0x00,                   /* 0x0E: BIOS Configuration 2   */
+       0x00,                   /* 0x0F: BIOS Configuration 3   */
+                               /* --- SCSI Channel 0 Configuration --- */
+       0x07,                   /* 0x10: H/A ID                 */
+       0x83,                   /* 0x11: Channel Configuration  */
+       0x20,                   /* 0x12: MAX TAG per target     */
+       0x0A,                   /* 0x13: SCSI Reset Recovering time     */
+       0x00,                   /* 0x14: Channel Configuration4 */
+       0x00,                   /* 0x15: Channel Configuration5 */
+                               /* SCSI Channel 0 Target Configuration  */
+                               /* 0x16-0x25                    */
+       0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8,
+       0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8,
+                               /* --- SCSI Channel 1 Configuration --- */
+       0x07,                   /* 0x26: H/A ID                 */
+       0x83,                   /* 0x27: Channel Configuration  */
+       0x20,                   /* 0x28: MAX TAG per target     */
+       0x0A,                   /* 0x29: SCSI Reset Recovering time     */
+       0x00,                   /* 0x2A: Channel Configuration4 */
+       0x00,                   /* 0x2B: Channel Configuration5 */
+                               /* SCSI Channel 1 Target Configuration  */
+                               /* 0x2C-0x3B                    */
+       0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8,
+       0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8,
+       0x00,                   /* 0x3C: Reserved               */
+       0x00,                   /* 0x3D: Reserved               */
+       0x00,                   /* 0x3E: Reserved               */
+       0x00                    /* 0x3F: Checksum               */
+};
+
+
+/***************************************************************************/
+static void waitForPause(unsigned amount)
+{
+       ULONG the_time = jiffies + amount;      /* 0.01 seconds per jiffy */
+
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95)
+       while (time_before_eq(jiffies, the_time));
+#else
+       while (jiffies < the_time);
+#endif
+}
+
+/***************************************************************************/
+UCHAR waitChipReady(ORC_HCS * hcsp)
+{
+       int i;
+
+       for (i = 0; i < 2000; i++) {    /* Wait 1 second for report timeout     */
+               if (ORC_RD(hcsp->HCS_Base, ORC_HCTRL) & HOSTSTOP)       /* Wait HOSTSTOP set */
+                       return (TRUE);
+               waitForPause(5);        /* wait 500ms before try again  */
+       }
+       return (FALSE);
+}
+
+/***************************************************************************/
+UCHAR waitFWReady(ORC_HCS * hcsp)
+{
+       int i;
+
+       for (i = 0; i < 2000; i++) {    /* Wait 1 second for report timeout     */
+               if (ORC_RD(hcsp->HCS_Base, ORC_HSTUS) & RREADY)         /* Wait READY set */
+                       return (TRUE);
+               waitForPause(5);        /* wait 500ms before try again  */
+       }
+       return (FALSE);
+}
+
+/***************************************************************************/
+UCHAR waitSCSIRSTdone(ORC_HCS * hcsp)
+{
+       int i;
+
+       for (i = 0; i < 2000; i++) {    /* Wait 1 second for report timeout     */
+               if (!(ORC_RD(hcsp->HCS_Base, ORC_HCTRL) & SCSIRST))     /* Wait SCSIRST done */
+                       return (TRUE);
+               waitForPause(5);        /* wait 500ms before try again  */
+       }
+       return (FALSE);
+}
+
+/***************************************************************************/
+UCHAR waitHDOoff(ORC_HCS * hcsp)
+{
+       int i;
+
+       for (i = 0; i < 2000; i++) {    /* Wait 1 second for report timeout     */
+               if (!(ORC_RD(hcsp->HCS_Base, ORC_HCTRL) & HDO))         /* Wait HDO off */
+                       return (TRUE);
+               waitForPause(5);        /* wait 500ms before try again  */
+       }
+       return (FALSE);
+}
+
+/***************************************************************************/
+UCHAR waitHDIset(ORC_HCS * hcsp, UCHAR * pData)
+{
+       int i;
+
+       for (i = 0; i < 2000; i++) {    /* Wait 1 second for report timeout     */
+               if ((*pData = ORC_RD(hcsp->HCS_Base, ORC_HSTUS)) & HDI)
+                       return (TRUE);  /* Wait HDI set */
+               waitForPause(5);        /* wait 500ms before try again  */
+       }
+       return (FALSE);
+}
+
+/***************************************************************************/
+unsigned short get_FW_version(ORC_HCS * hcsp)
+{
+       UCHAR bData;
+       union {
+               unsigned short sVersion;
+               unsigned char cVersion[2];
+       } Version;
+
+       ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_VERSION);
+       ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);
+       if (waitHDOoff(hcsp) == FALSE)  /* Wait HDO off   */
+               return (FALSE);
+
+       if (waitHDIset(hcsp, &bData) == FALSE)  /* Wait HDI set   */
+               return (FALSE);
+       Version.cVersion[0] = ORC_RD(hcsp->HCS_Base, ORC_HDATA);
+       ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData);      /* Clear HDI            */
+
+       if (waitHDIset(hcsp, &bData) == FALSE)  /* Wait HDI set   */
+               return (FALSE);
+       Version.cVersion[1] = ORC_RD(hcsp->HCS_Base, ORC_HDATA);
+       ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData);      /* Clear HDI            */
+
+       return (Version.sVersion);
+}
+
+/***************************************************************************/
+UCHAR set_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char value)
+{
+       ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_SET_NVM);    /* Write command */
+       ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);
+       if (waitHDOoff(hcsp) == FALSE)  /* Wait HDO off   */
+               return (FALSE);
+
+       ORC_WR(hcsp->HCS_Base + ORC_HDATA, address);    /* Write address */
+       ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);
+       if (waitHDOoff(hcsp) == FALSE)  /* Wait HDO off   */
+               return (FALSE);
+
+       ORC_WR(hcsp->HCS_Base + ORC_HDATA, value);      /* Write value  */
+       ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);
+       if (waitHDOoff(hcsp) == FALSE)  /* Wait HDO off   */
+               return (FALSE);
+
+       return (TRUE);
+}
+
+/***************************************************************************/
+UCHAR get_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char *pDataIn)
+{
+       unsigned char bData;
+
+       ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_GET_NVM);    /* Write command */
+       ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);
+       if (waitHDOoff(hcsp) == FALSE)  /* Wait HDO off   */
+               return (FALSE);
+
+       ORC_WR(hcsp->HCS_Base + ORC_HDATA, address);    /* Write address */
+       ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);
+       if (waitHDOoff(hcsp) == FALSE)  /* Wait HDO off   */
+               return (FALSE);
+
+       if (waitHDIset(hcsp, &bData) == FALSE)  /* Wait HDI set   */
+               return (FALSE);
+       *pDataIn = ORC_RD(hcsp->HCS_Base, ORC_HDATA);
+       ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData);      /* Clear HDI    */
+
+       return (TRUE);
+}
+
+/***************************************************************************/
+void orc_exec_scb(ORC_HCS * hcsp, ORC_SCB * scbp)
+{
+       scbp->SCB_Status = SCB_POST;
+       ORC_WR(hcsp->HCS_Base + ORC_PQUEUE, scbp->SCB_ScbIdx);
+       return;
+}
+
+
+/***********************************************************************
+ Read SCSI H/A configuration parameters from serial EEPROM
+************************************************************************/
+int se2_rd_all(ORC_HCS * hcsp)
+{
+       int i;
+       UCHAR *np, chksum = 0;
+
+       np = (UCHAR *) nvramp;
+       for (i = 0; i < 64; i++, np++) {        /* <01> */
+               if (get_NVRAM(hcsp, (unsigned char) i, np) == FALSE)
+                       return -1;
+//      *np++ = get_NVRAM(hcsp, (unsigned char ) i);
+       }
+
+/*------ Is ckecksum ok ? ------*/
+       np = (UCHAR *) nvramp;
+       for (i = 0; i < 63; i++)
+               chksum += *np++;
+
+       if (nvramp->CheckSum != (UCHAR) chksum)
+               return -1;
+       return 1;
+}
+
+/************************************************************************
+ Update SCSI H/A configuration parameters from serial EEPROM
+*************************************************************************/
+void se2_update_all(ORC_HCS * hcsp)
+{                              /* setup default pattern  */
+       int i;
+       UCHAR *np, *np1, chksum = 0;
+
+       /* Calculate checksum first   */
+       np = (UCHAR *) dftNvRam;
+       for (i = 0; i < 63; i++)
+               chksum += *np++;
+       *np = chksum;
+
+       np = (UCHAR *) dftNvRam;
+       np1 = (UCHAR *) nvramp;
+       for (i = 0; i < 64; i++, np++, np1++) {
+               if (*np != *np1) {
+                       set_NVRAM(hcsp, (unsigned char) i, *np);
+               }
+       }
+       return;
+}
+
+/*************************************************************************
+ Function name  : read_eeprom
+**************************************************************************/
+void read_eeprom(ORC_HCS * hcsp)
+{
+       if (se2_rd_all(hcsp) != 1) {
+               se2_update_all(hcsp);   /* setup default pattern        */
+               se2_rd_all(hcsp);       /* load again                   */
+       }
+}
+
+
+/***************************************************************************/
+UCHAR load_FW(ORC_HCS * hcsp)
+{
+       U32 dData;
+       USHORT wBIOSAddress;
+       USHORT i;
+       UCHAR *pData, bData;
+
+
+       bData = ORC_RD(hcsp->HCS_Base, ORC_GCFG);
+       ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData | EEPRG);       /* Enable EEPROM programming */
+       ORC_WR(hcsp->HCS_Base + ORC_EBIOSADR2, 0x00);
+       ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x00);
+       if (ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA) != 0x55) {
+               ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData);       /* Disable EEPROM programming */
+               return (FALSE);
+       }
+       ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x01);
+       if (ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA) != 0xAA) {
+               ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData);       /* Disable EEPROM programming */
+               return (FALSE);
+       }
+       ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST | DOWNLOAD);       /* Enable SRAM programming */
+       pData = (UCHAR *) & dData;
+       dData = 0;              /* Initial FW address to 0 */
+       ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x10);
+       *pData = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA);         /* Read from BIOS */
+       ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x11);
+       *(pData + 1) = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA);   /* Read from BIOS */
+       ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x12);
+       *(pData + 2) = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA);   /* Read from BIOS */
+       ORC_WR(hcsp->HCS_Base + ORC_EBIOSADR2, *(pData + 2));
+       ORC_WRLONG(hcsp->HCS_Base + ORC_FWBASEADR, dData);      /* Write FW address */
+
+       wBIOSAddress = (USHORT) dData;  /* FW code locate at BIOS address + ? */
+       for (i = 0, pData = (UCHAR *) & dData;  /* Download the code    */
+            i < 0x1000;        /* Firmware code size = 4K      */
+            i++, wBIOSAddress++) {
+               ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, wBIOSAddress);
+               *pData++ = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA);       /* Read from BIOS */
+               if ((i % 4) == 3) {
+                       ORC_WRLONG(hcsp->HCS_Base + ORC_RISCRAM, dData);        /* Write every 4 bytes */
+                       pData = (UCHAR *) & dData;
+               }
+       }
+
+       ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST | DOWNLOAD);       /* Reset program count 0 */
+       wBIOSAddress -= 0x1000; /* Reset the BIOS adddress      */
+       for (i = 0, pData = (UCHAR *) & dData;  /* Check the code       */
+            i < 0x1000;        /* Firmware code size = 4K      */
+            i++, wBIOSAddress++) {
+               ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, wBIOSAddress);
+               *pData++ = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA);       /* Read from BIOS */
+               if ((i % 4) == 3) {
+                       if (ORC_RDLONG(hcsp->HCS_Base, ORC_RISCRAM) != dData) {
+                               ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST);  /* Reset program to 0 */
+                               ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData);       /*Disable EEPROM programming */
+                               return (FALSE);
+                       }
+                       pData = (UCHAR *) & dData;
+               }
+       }
+       ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST);  /* Reset program to 0   */
+       ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData);       /* Disable EEPROM programming */
+       return (TRUE);
+}
+
+/***************************************************************************/
+void setup_SCBs(ORC_HCS * hcsp)
+{
+       ORC_SCB *pVirScb;
+       int i;
+       UCHAR j;
+       ESCB *pVirEscb;
+       PVOID pPhysEscb;
+       PVOID tPhysEscb;
+
+       j = 0;
+       pVirScb = NULL;
+       tPhysEscb = (PVOID) NULL;
+       pPhysEscb = (PVOID) NULL;
+       /* Setup SCB HCS_Base and SCB Size registers */
+       ORC_WR(hcsp->HCS_Base + ORC_SCBSIZE, orc_num_scb);      /* Total number of SCBs */
+       /* SCB HCS_Base address 0      */
+       ORC_WRLONG(hcsp->HCS_Base + ORC_SCBBASE0, hcsp->HCS_physScbArray);
+       /* SCB HCS_Base address 1      */
+       ORC_WRLONG(hcsp->HCS_Base + ORC_SCBBASE1, hcsp->HCS_physScbArray);
+
+       /* setup scatter list address with one buffer */
+       pVirScb = (ORC_SCB *) hcsp->HCS_virScbArray;
+       pVirEscb = (ESCB *) hcsp->HCS_virEscbArray;
+
+       for (i = 0; i < orc_num_scb; i++) {
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0)
+               pPhysEscb = (PVOID) ((ULONG) hcsp->HCS_virEscbArray + (sizeof(ESCB) * i));
+               pVirScb->SCB_SGPAddr = (U32) VIRT_TO_BUS(pPhysEscb);
+               pVirScb->SCB_SensePAddr = (U32) VIRT_TO_BUS(pPhysEscb);
+#else
+               pPhysEscb = (PVOID) (hcsp->HCS_physEscbArray + (sizeof(ESCB) * i));
+               pVirScb->SCB_SGPAddr = (U32) pPhysEscb;
+               pVirScb->SCB_SensePAddr = (U32) pPhysEscb;
+#endif
+               pVirScb->SCB_EScb = pVirEscb;
+               pVirScb->SCB_ScbIdx = i;
+               pVirScb++;
+               pVirEscb++;
+       }
+
+       return;
+}
+
+/***************************************************************************/
+static void initAFlag(ORC_HCS * hcsp)
+{
+       UCHAR i, j;
+
+       for (i = 0; i < MAX_CHANNELS; i++) {
+               for (j = 0; j < 8; j++) {
+                       hcsp->BitAllocFlag[i][j] = 0xffffffff;
+               }
+       }
+}
+
+/***************************************************************************/
+int init_orchid(ORC_HCS * hcsp)
+{
+       UBYTE *readBytep;
+       USHORT revision;
+       UCHAR i;
+
+       initAFlag(hcsp);
+       ORC_WR(hcsp->HCS_Base + ORC_GIMSK, 0xFF);       /* Disable all interrupt        */
+       if (ORC_RD(hcsp->HCS_Base, ORC_HSTUS) & RREADY) {       /* Orchid is ready              */
+               revision = get_FW_version(hcsp);
+               if (revision == 0xFFFF) {
+                       ORC_WR(hcsp->HCS_Base + ORC_HCTRL, DEVRST);     /* Reset Host Adapter   */
+                       if (waitChipReady(hcsp) == FALSE)
+                               return (-1);
+                       load_FW(hcsp);  /* Download FW                  */
+                       setup_SCBs(hcsp);       /* Setup SCB HCS_Base and SCB Size registers */
+                       ORC_WR(hcsp->HCS_Base + ORC_HCTRL, 0);  /* clear HOSTSTOP       */
+                       if (waitFWReady(hcsp) == FALSE)
+                               return (-1);
+                       /* Wait for firmware ready     */
+               } else {
+                       setup_SCBs(hcsp);       /* Setup SCB HCS_Base and SCB Size registers */
+               }
+       } else {                /* Orchid is not Ready          */
+               ORC_WR(hcsp->HCS_Base + ORC_HCTRL, DEVRST);     /* Reset Host Adapter   */
+               if (waitChipReady(hcsp) == FALSE)
+                       return (-1);
+               load_FW(hcsp);  /* Download FW                  */
+               setup_SCBs(hcsp);       /* Setup SCB HCS_Base and SCB Size registers */
+               ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);        /* Do Hardware Reset &  */
+
+               /*     clear HOSTSTOP  */
+               if (waitFWReady(hcsp) == FALSE)         /* Wait for firmware ready      */
+                       return (-1);
+       }
+
+/*------------- get serial EEProm settting -------*/
+
+       read_eeprom(hcsp);
+
+       if (nvramp->Revision != 1)
+               return (-1);
+
+       hcsp->HCS_SCSI_ID = nvramp->SCSI0Id;
+       hcsp->HCS_BIOS = nvramp->BIOSConfig1;
+       hcsp->HCS_MaxTar = MAX_TARGETS;
+       readBytep = (UCHAR *) & (nvramp->Target00Config);
+       for (i = 0; i < 16; readBytep++, i++) {
+               hcsp->TargetFlag[i] = *readBytep;
+               hcsp->MaximumTags[i] = orc_num_scb;
+       }                       /* for                          */
+
+       if (nvramp->SCSI0Config & NCC_BUSRESET) {       /* Reset SCSI bus               */
+               hcsp->HCS_Flags |= HCF_SCSI_RESET;
+       }
+       ORC_WR(hcsp->HCS_Base + ORC_GIMSK, 0xFB);       /* enable RP FIFO interrupt     */
+       return (0);
+}
+
+/*****************************************************************************
+ Function name  : orc_reset_scsi_bus
+ Description    : Reset registers, reset a hanging bus and
+                  kill active and disconnected commands for target w/o soft reset
+ Input          : pHCB  -       Pointer to host adapter structure
+ Output         : None.
+ Return         : pSRB  -       Pointer to SCSI request block.
+*****************************************************************************/
+int orc_reset_scsi_bus(ORC_HCS * pHCB)
+{                              /* I need Host Control Block Information */
+       ULONG flags;
+
+#if 0
+       printk("inia100: enter inia100_reset\n");
+#endif
+
+#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95)
+       save_flags(flags);
+       cli();
+#else
+       spin_lock_irqsave(&(pHCB->BitAllocFlagLock), flags);
+#endif
+
+       initAFlag(pHCB);
+       /* reset scsi bus */
+       ORC_WR(pHCB->HCS_Base + ORC_HCTRL, SCSIRST);
+       if (waitSCSIRSTdone(pHCB) == FALSE) {
+#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95)
+               restore_flags(flags);
+#else
+               spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);
+#endif
+               return (SCSI_RESET_ERROR);
+       } else {
+#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95)
+               restore_flags(flags);
+#else
+               spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);
+#endif
+               return (SCSI_RESET_SUCCESS);
+       }
+}
+
+/*****************************************************************************
+ Function name  : orc_device_reset
+ Description    : Reset registers, reset a hanging bus and
+                  kill active and disconnected commands for target w/o soft reset
+ Input          : pHCB  -       Pointer to host adapter structure
+ Output         : None.
+ Return         : pSRB  -       Pointer to SCSI request block.
+*****************************************************************************/
+int orc_device_reset(ORC_HCS * pHCB, ULONG SCpnt, unsigned int target, unsigned int ResetFlags)
+{                              /* I need Host Control Block Information */
+       ORC_SCB *pScb;
+       ESCB *pVirEscb;
+       ORC_SCB *pVirScb;
+       UCHAR i;
+       ULONG flags;
+
+#if 0
+       printk("inia100: enter inia100_reset\n");
+#endif
+
+#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95)
+       save_flags(flags);
+       cli();
+#else
+       spin_lock_irqsave(&(pHCB->BitAllocFlagLock), flags);
+#endif
+       pScb = (ORC_SCB *) NULL;
+       pVirEscb = (ESCB *) NULL;
+
+       /* setup scatter list address with one buffer */
+       pVirScb = (ORC_SCB *) pHCB->HCS_virScbArray;
+
+       initAFlag(pHCB);
+       /* device reset */
+       for (i = 0; i < orc_num_scb; i++) {
+               pVirEscb = pVirScb->SCB_EScb;
+               if ((pVirScb->SCB_Status) && (pVirEscb->SCB_Srb == (unsigned char *) SCpnt))
+                       break;
+               pVirScb++;
+       }
+
+       if (i == orc_num_scb) {
+               printk("Unable to Reset - No SCB Found\n");
+#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95)
+               restore_flags(flags);
+#else
+               spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);
+#endif
+               return (SCSI_RESET_NOT_RUNNING);
+       }
+       if ((pScb = orc_alloc_scb(pHCB)) == NULL) {
+#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95)
+               restore_flags(flags);
+#else
+               spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);
+#endif
+               return (SCSI_RESET_NOT_RUNNING);
+       }
+       pScb->SCB_Opcode = ORC_BUSDEVRST;
+       pScb->SCB_Target = target;
+       pScb->SCB_HaStat = 0;
+       pScb->SCB_TaStat = 0;
+       pScb->SCB_Status = 0x0;
+       pScb->SCB_Link = 0xFF;
+       pScb->SCB_Reserved0 = 0;
+       pScb->SCB_Reserved1 = 0;
+       pScb->SCB_XferLen = 0;
+       pScb->SCB_SGLen = 0;
+
+       pVirEscb->SCB_Srb = 0;
+       if (ResetFlags & SCSI_RESET_SYNCHRONOUS) {
+               pVirEscb->SCB_Srb = (unsigned char *) SCpnt;
+       }
+       orc_exec_scb(pHCB, pScb);       /* Start execute SCB            */
+#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95)
+       restore_flags(flags);
+#else
+       spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);
+#endif
+       return SCSI_RESET_PENDING;
+}
+
+
+/***************************************************************************/
+ORC_SCB *orc_alloc_scb(ORC_HCS * hcsp)
+{
+       ORC_SCB *pTmpScb;
+       UCHAR Ch;
+       ULONG idx;
+       UCHAR index;
+       UCHAR i;
+       ULONG flags;
+
+#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95)
+       save_flags(flags);
+       cli();
+#else
+       spin_lock_irqsave(&(hcsp->BitAllocFlagLock), flags);
+#endif
+       Ch = hcsp->HCS_Index;
+       for (i = 0; i < 8; i++) {
+               for (index = 0; index < 32; index++) {
+                       if ((hcsp->BitAllocFlag[Ch][i] >> index) & 0x01) {
+                               hcsp->BitAllocFlag[Ch][i] &= ~(1 << index);
+                               break;
+                       }
+               }
+               idx = index + 32 * i;
+               pTmpScb = (PVOID) ((ULONG) hcsp->HCS_virScbArray + (idx * sizeof(ORC_SCB)));
+#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95)
+               restore_flags(flags);
+#else
+               spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);
+#endif
+               return (pTmpScb);
+       }
+#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95)
+       restore_flags(flags);
+#else
+       spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);
+#endif
+       return (NULL);
+}
+
+
+/***************************************************************************/
+void orc_release_scb(ORC_HCS * hcsp, ORC_SCB * scbp)
+{
+       ULONG flags;
+       UCHAR Index;
+       UCHAR i;
+       UCHAR Ch;
+
+#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95)
+       save_flags(flags);
+       cli();
+#else
+       spin_lock_irqsave(&(hcsp->BitAllocFlagLock), flags);
+#endif
+       Ch = hcsp->HCS_Index;
+       Index = scbp->SCB_ScbIdx;
+       i = Index / 32;
+       Index %= 32;
+       hcsp->BitAllocFlag[Ch][i] |= (1 << Index);
+#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95)
+       restore_flags(flags);
+#else
+       spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);
+#endif
+}
+
+
+/*****************************************************************************
+ Function name : Addinia100_into_Adapter_table
+ Description   : This function will scan PCI bus to get all Orchid card
+ Input         : None.
+ Output                : None.
+ Return                : SUCCESSFUL    - Successful scan
+ ohterwise     - No drives founded
+*****************************************************************************/
+int Addinia100_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt,
+                                 BYTE bBus, BYTE bDevice)
+{
+       unsigned int i, j;
+
+       for (i = 0; i < MAX_SUPPORTED_ADAPTERS; i++) {
+               if (inia100_adpt[i].ADPT_BIOS < wBIOS)
+                       continue;
+               if (inia100_adpt[i].ADPT_BIOS == wBIOS) {
+                       if (inia100_adpt[i].ADPT_BASE == wBASE)
+                               if (inia100_adpt[i].ADPT_Bus != 0xFF)
+                                       return (FAILURE);
+                               else if (inia100_adpt[i].ADPT_BASE < wBASE)
+                                       continue;
+               }
+               for (j = MAX_SUPPORTED_ADAPTERS - 1; j > i; j--) {
+                       inia100_adpt[j].ADPT_BASE = inia100_adpt[j - 1].ADPT_BASE;
+                       inia100_adpt[j].ADPT_INTR = inia100_adpt[j - 1].ADPT_INTR;
+                       inia100_adpt[j].ADPT_BIOS = inia100_adpt[j - 1].ADPT_BIOS;
+                       inia100_adpt[j].ADPT_Bus = inia100_adpt[j - 1].ADPT_Bus;
+                       inia100_adpt[j].ADPT_Device = inia100_adpt[j - 1].ADPT_Device;
+               }
+               inia100_adpt[i].ADPT_BASE = wBASE;
+               inia100_adpt[i].ADPT_INTR = bInterrupt;
+               inia100_adpt[i].ADPT_BIOS = wBIOS;
+               inia100_adpt[i].ADPT_Bus = bBus;
+               inia100_adpt[i].ADPT_Device = bDevice;
+               return (SUCCESSFUL);
+       }
+       return (FAILURE);
+}
+
+
+/*****************************************************************************
+ Function name : init_inia100Adapter_table
+ Description   : This function will scan PCI bus to get all Orchid card
+ Input         : None.
+ Output                : None.
+ Return                : SUCCESSFUL    - Successful scan
+ ohterwise     - No drives founded
+*****************************************************************************/
+void init_inia100Adapter_table(void)
+{
+       int i;
+
+       for (i = 0; i < MAX_SUPPORTED_ADAPTERS; i++) {  /* Initialize adapter structure */
+               inia100_adpt[i].ADPT_BIOS = 0xffff;
+               inia100_adpt[i].ADPT_BASE = 0xffff;
+               inia100_adpt[i].ADPT_INTR = 0xff;
+               inia100_adpt[i].ADPT_Bus = 0xff;
+               inia100_adpt[i].ADPT_Device = 0xff;
+       }
+}
+
+/*****************************************************************************
+ Function name  : get_orcPCIConfig
+ Description    : 
+ Input          : pHCB  -       Pointer to host adapter structure
+ Output         : None.
+ Return         : pSRB  -       Pointer to SCSI request block.
+*****************************************************************************/
+void get_orcPCIConfig(ORC_HCS * pCurHcb, int ch_idx)
+{
+       pCurHcb->HCS_Base = inia100_adpt[ch_idx].ADPT_BASE;     /* Supply base address  */
+       pCurHcb->HCS_BIOS = inia100_adpt[ch_idx].ADPT_BIOS;     /* Supply BIOS address  */
+       pCurHcb->HCS_Intr = inia100_adpt[ch_idx].ADPT_INTR;     /* Supply interrupt line */
+       return;
+}
+
+
+/*****************************************************************************
+ Function name  : abort_SCB
+ Description    : Abort a queued command.
+                        (commands that are on the bus can't be aborted easily)
+ Input          : pHCB  -       Pointer to host adapter structure
+ Output         : None.
+ Return         : pSRB  -       Pointer to SCSI request block.
+*****************************************************************************/
+int abort_SCB(ORC_HCS * hcsp, ORC_SCB * pScb)
+{
+       unsigned char bData, bStatus;
+
+       ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_ABORT_SCB);  /* Write command */
+       ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);
+       if (waitHDOoff(hcsp) == FALSE)  /* Wait HDO off   */
+               return (FALSE);
+
+       ORC_WR(hcsp->HCS_Base + ORC_HDATA, pScb->SCB_ScbIdx);   /* Write address */
+       ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);
+       if (waitHDOoff(hcsp) == FALSE)  /* Wait HDO off   */
+               return (FALSE);
+
+       if (waitHDIset(hcsp, &bData) == FALSE)  /* Wait HDI set   */
+               return (FALSE);
+       bStatus = ORC_RD(hcsp->HCS_Base, ORC_HDATA);
+       ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData);      /* Clear HDI    */
+
+       if (bStatus == 1)       /* 0 - Successfully               */
+               return (FALSE); /* 1 - Fail                     */
+       return (TRUE);
+}
+
+/*****************************************************************************
+ Function name  : inia100_abort
+ Description    : Abort a queued command.
+                        (commands that are on the bus can't be aborted easily)
+ Input          : pHCB  -       Pointer to host adapter structure
+ Output         : None.
+ Return         : pSRB  -       Pointer to SCSI request block.
+*****************************************************************************/
+int orc_abort_srb(ORC_HCS * hcsp, ULONG SCpnt)
+{
+       ESCB *pVirEscb;
+       ORC_SCB *pVirScb;
+       UCHAR i;
+       ULONG flags;
+
+#if 0
+       printk("inia100: abort SRB \n");
+#endif
+#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95)
+       save_flags(flags);
+       cli();
+#else
+       spin_lock_irqsave(&(hcsp->BitAllocFlagLock), flags);
+#endif
+
+       pVirScb = (ORC_SCB *) hcsp->HCS_virScbArray;
+
+       for (i = 0; i < orc_num_scb; i++, pVirScb++) {
+               pVirEscb = pVirScb->SCB_EScb;
+               if ((pVirScb->SCB_Status) && (pVirEscb->SCB_Srb == (unsigned char *) SCpnt)) {
+                       if (pVirScb->SCB_TagMsg == 0) {
+#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95)
+                               restore_flags(flags);
+#else
+                               spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);
+#endif
+                               return (SCSI_ABORT_BUSY);
+                       } else {
+                               if (abort_SCB(hcsp, pVirScb)) {
+                                       pVirEscb->SCB_Srb = NULL;
+#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95)
+                                       restore_flags(flags);
+#else
+                                       spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);
+#endif
+                                       return (SCSI_ABORT_SUCCESS);
+                               } else {
+#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95)
+                                       restore_flags(flags);
+#else
+                                       spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);
+#endif
+                                       return (SCSI_ABORT_NOT_RUNNING);
+                               }
+                       }
+               }
+       }
+#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95)
+       restore_flags(flags);
+#else
+       spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);
+#endif
+       return (SCSI_ABORT_NOT_RUNNING);
+}
+
+/***********************************************************************
+ Routine Description:
+         This is the interrupt service routine for the Orchid SCSI adapter.
+         It reads the interrupt register to determine if the adapter is indeed
+         the source of the interrupt and clears the interrupt at the device.
+ Arguments:
+         HwDeviceExtension - HBA miniport driver's adapter data storage
+ Return Value:
+***********************************************************************/
+void orc_interrupt(
+                         ORC_HCS * hcsp
+)
+{
+       BYTE bScbIdx;
+       ORC_SCB *pScb;
+
+       if (ORC_RD(hcsp->HCS_Base, ORC_RQUEUECNT) == 0) {
+               return;         // (FALSE);
+
+       }
+       do {
+               bScbIdx = ORC_RD(hcsp->HCS_Base, ORC_RQUEUE);
+
+               pScb = (ORC_SCB *) ((ULONG) hcsp->HCS_virScbArray + (ULONG) (sizeof(ORC_SCB) * bScbIdx));
+               pScb->SCB_Status = 0x0;
+
+               inia100SCBPost((BYTE *) hcsp, (BYTE *) pScb);
+       } while (ORC_RD(hcsp->HCS_Base, ORC_RQUEUECNT));
+       return;                 //(TRUE);
+
+}                              /* End of I1060Interrupt() */
diff --git a/drivers/scsi/i60uscsi.h b/drivers/scsi/i60uscsi.h
new file mode 100644 (file)
index 0000000..6fff823
--- /dev/null
@@ -0,0 +1,574 @@
+/**************************************************************************
+ * Initio A100 device driver for Linux.
+ *
+ * Copyright (c) 1994-1998 Initio Corporation
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ **************************************************************************
+ *
+ * Module: inia100.h
+ * Description: INI-A100U2W LINUX device driver header
+ * Revision History:
+ *     06/18/98 HL, Initial Version 1.02
+ *     12/19/98 bv, v1.02a Use spinlocks for 2.1.95 and up.
+ **************************************************************************/
+
+#include <linux/config.h>
+
+#define ULONG   unsigned long
+#define PVOID   void *
+#define USHORT  unsigned short
+#define UCHAR   unsigned char
+#define BYTE    unsigned char
+#define WORD    unsigned short
+#define DWORD   unsigned long
+#define UBYTE   unsigned char
+#define UWORD   unsigned short
+#define UDWORD  unsigned long
+#ifdef ALPHA
+#define U32     unsigned int
+#else
+#define U32     unsigned long
+#endif
+
+#ifndef NULL
+#define NULL     0             /* zero          */
+#endif
+#ifndef TRUE
+#define TRUE     (1)           /* boolean true  */
+#endif
+#ifndef FALSE
+#define FALSE    (0)           /* boolean false */
+#endif
+#ifndef FAILURE
+#define FAILURE  (-1)
+#endif
+#if 1
+#define ORC_MAXQUEUE           245
+#else
+#define ORC_MAXQUEUE           25
+#endif
+
+#define TOTAL_SG_ENTRY         32
+#define MAX_TARGETS            16
+#define IMAX_CDB                       15
+#define SENSE_SIZE             14
+#define MAX_SUPPORTED_ADAPTERS  4
+#define SUCCESSFUL              0x00
+
+#define I920_DEVICE_ID 0x0002  /* Initio's inic-950 product ID   */
+
+/************************************************************************/
+/*              Scatter-Gather Element Structure                        */
+/************************************************************************/
+typedef struct ORC_SG_Struc {
+       U32 SG_Ptr;             /* Data Pointer */
+       U32 SG_Len;             /* Data Length */
+} ORC_SG;
+
+typedef struct inia100_Adpt_Struc {
+       UWORD ADPT_BIOS;        /* 0 */
+       UWORD ADPT_BASE;        /* 1 */
+       UBYTE ADPT_Bus;         /* 2 */
+       UBYTE ADPT_Device;      /* 3 */
+       UBYTE ADPT_INTR;        /* 4 */
+} INIA100_ADPT_STRUCT;
+
+
+/* SCSI related definition                                              */
+#define DISC_NOT_ALLOW          0x80   /* Disconnect is not allowed    */
+#define DISC_ALLOW              0xC0   /* Disconnect is allowed        */
+
+
+#define ORC_OFFSET_SCB                 16
+#define ORC_MAX_SCBS               250
+#define MAX_CHANNELS       2
+#define MAX_ESCB_ELE                           64
+#define TCF_DRV_255_63     0x0400
+
+/********************************************************/
+/*      Orchid Configuration Register Set               */
+/********************************************************/
+#define ORC_PVID       0x00    /* Vendor ID                      */
+#define ORC_VENDOR_ID  0x1101  /* Orchid vendor ID               */
+#define ORC_PDID        0x02   /* Device ID                    */
+#define ORC_DEVICE_ID  0x1060  /* Orchid device ID               */
+#define ORC_COMMAND    0x04    /* Command                        */
+#define BUSMS          0x04    /* BUS MASTER Enable              */
+#define IOSPA          0x01    /* IO Space Enable                */
+#define ORC_STATUS     0x06    /* Status register                */
+#define ORC_REVISION   0x08    /* Revision number                */
+#define ORC_BASE       0x10    /* Base address                   */
+#define ORC_BIOS       0x50    /* Expansion ROM base address     */
+#define ORC_INT_NUM    0x3C    /* Interrupt line         */
+#define ORC_INT_PIN    0x3D    /* Interrupt pin          */
+
+
+/********************************************************/
+/*      Orchid Host Command Set                         */
+/********************************************************/
+#define ORC_CMD_NOP            0x00    /* Host command - NOP             */
+#define ORC_CMD_VERSION                0x01    /* Host command - Get F/W version */
+#define ORC_CMD_ECHO           0x02    /* Host command - ECHO            */
+#define ORC_CMD_SET_NVM                0x03    /* Host command - Set NVRAM       */
+#define ORC_CMD_GET_NVM                0x04    /* Host command - Get NVRAM       */
+#define ORC_CMD_GET_BUS_STATUS 0x05    /* Host command - Get SCSI bus status */
+#define ORC_CMD_ABORT_SCB      0x06    /* Host command - Abort SCB       */
+#define ORC_CMD_ISSUE_SCB      0x07    /* Host command - Issue SCB       */
+
+/********************************************************/
+/*              Orchid Register Set                     */
+/********************************************************/
+#define ORC_GINTS      0xA0    /* Global Interrupt Status        */
+#define QINT           0x04    /* Reply Queue Interrupt  */
+#define ORC_GIMSK      0xA1    /* Global Interrupt MASK  */
+#define MQINT          0x04    /* Mask Reply Queue Interrupt     */
+#define        ORC_GCFG        0xA2    /* Global Configure               */
+#define EEPRG          0x01    /* Enable EEPROM programming */
+#define        ORC_GSTAT       0xA3    /* Global status          */
+#define WIDEBUS                0x10    /* Wide SCSI Devices connected    */
+#define ORC_HDATA      0xA4    /* Host Data                      */
+#define ORC_HCTRL      0xA5    /* Host Control                   */
+#define SCSIRST                0x80    /* SCSI bus reset         */
+#define HDO                    0x40    /* Host data out          */
+#define HOSTSTOP               0x02    /* Host stop RISC engine  */
+#define DEVRST         0x01    /* Device reset                   */
+#define ORC_HSTUS      0xA6    /* Host Status                    */
+#define HDI                    0x02    /* Host data in                   */
+#define RREADY         0x01    /* RISC engine is ready to receive */
+#define        ORC_NVRAM       0xA7    /* Nvram port address             */
+#define SE2CS          0x008
+#define SE2CLK         0x004
+#define SE2DO          0x002
+#define SE2DI          0x001
+#define ORC_PQUEUE     0xA8    /* Posting queue FIFO             */
+#define ORC_PQCNT      0xA9    /* Posting queue FIFO Cnt */
+#define ORC_RQUEUE     0xAA    /* Reply queue FIFO               */
+#define ORC_RQUEUECNT  0xAB    /* Reply queue FIFO Cnt           */
+#define        ORC_FWBASEADR   0xAC    /* Firmware base address  */
+
+#define        ORC_EBIOSADR0 0xB0      /* External Bios address */
+#define        ORC_EBIOSADR1 0xB1      /* External Bios address */
+#define        ORC_EBIOSADR2 0xB2      /* External Bios address */
+#define        ORC_EBIOSDATA 0xB3      /* External Bios address */
+
+#define        ORC_SCBSIZE     0xB7    /* SCB size register              */
+#define        ORC_SCBBASE0    0xB8    /* SCB base address 0             */
+#define        ORC_SCBBASE1    0xBC    /* SCB base address 1             */
+
+#define        ORC_RISCCTL     0xE0    /* RISC Control                   */
+#define PRGMRST                0x002
+#define DOWNLOAD               0x001
+#define        ORC_PRGMCTR0    0xE2    /* RISC program counter           */
+#define        ORC_PRGMCTR1    0xE3    /* RISC program counter           */
+#define        ORC_RISCRAM     0xEC    /* RISC RAM data port 4 bytes     */
+
+typedef struct orc_extended_scb {      /* Extended SCB                 */
+       ORC_SG ESCB_SGList[TOTAL_SG_ENTRY];     /*0 Start of SG list              */
+       unsigned char *SCB_Srb; /*50 SRB Pointer */
+//         Scsi_Cmnd    *SCB_Srb;       /*50 SRB Pointer */
+} ESCB;
+
+/***********************************************************************
+               SCSI Control Block
+************************************************************************/
+typedef struct orc_scb {       /* Scsi_Ctrl_Blk                */
+       UBYTE SCB_Opcode;       /*00 SCB command code&residual  */
+       UBYTE SCB_Flags;        /*01 SCB Flags                  */
+       UBYTE SCB_Target;       /*02 Target Id                  */
+       UBYTE SCB_Lun;          /*03 Lun                        */
+       U32 SCB_Reserved0;      /*04 Reserved for ORCHID must 0 */
+       U32 SCB_XferLen;        /*08 Data Transfer Length       */
+       U32 SCB_Reserved1;      /*0C Reserved for ORCHID must 0 */
+       U32 SCB_SGLen;          /*10 SG list # * 8              */
+       U32 SCB_SGPAddr;        /*14 SG List Buf physical Addr  */
+       U32 SCB_SGPAddrHigh;    /*18 SG Buffer high physical Addr */
+       UBYTE SCB_HaStat;       /*1C Host Status                */
+       UBYTE SCB_TaStat;       /*1D Target Status              */
+       UBYTE SCB_Status;       /*1E SCB status                 */
+       UBYTE SCB_Link;         /*1F Link pointer, default 0xFF */
+       UBYTE SCB_SenseLen;     /*20 Sense Allocation Length    */
+       UBYTE SCB_CDBLen;       /*21 CDB Length                 */
+       UBYTE SCB_Ident;        /*22 Identify                   */
+       UBYTE SCB_TagMsg;       /*23 Tag Message                */
+       UBYTE SCB_CDB[IMAX_CDB];        /*24 SCSI CDBs                  */
+       UBYTE SCB_ScbIdx;       /*3C Index for this ORCSCB      */
+       U32 SCB_SensePAddr;     /*34 Sense Buffer physical Addr */
+
+       ESCB *SCB_EScb;         /*38 Extended SCB Pointer       */
+#ifndef ALPHA
+       UBYTE SCB_Reserved2[4]; /*3E Reserved for Driver use    */
+#endif
+} ORC_SCB;
+
+/* Opcodes of ORCSCB_Opcode */
+#define ORC_EXECSCSI   0x00    /* SCSI initiator command with residual */
+#define ORC_BUSDEVRST  0x01    /* SCSI Bus Device Reset  */
+
+/* Status of ORCSCB_Status */
+#define SCB_COMPLETE   0x00    /* SCB request completed  */
+#define SCB_POST       0x01    /* SCB is posted by the HOST      */
+
+/* Bit Definition for ORCSCB_Flags */
+#define SCF_DISINT     0x01    /* Disable HOST interrupt */
+#define SCF_DIR                0x18    /* Direction bits         */
+#define SCF_NO_DCHK    0x00    /* Direction determined by SCSI   */
+#define SCF_DIN                0x08    /* From Target to Initiator       */
+#define SCF_DOUT       0x10    /* From Initiator to Target       */
+#define SCF_NO_XF      0x18    /* No data transfer               */
+#define SCF_POLL   0x40
+
+/* Error Codes for ORCSCB_HaStat */
+#define HOST_SEL_TOUT  0x11
+#define HOST_DO_DU     0x12
+#define HOST_BUS_FREE  0x13
+#define HOST_BAD_PHAS  0x14
+#define HOST_INV_CMD   0x16
+#define HOST_SCSI_RST  0x1B
+#define HOST_DEV_RST   0x1C
+
+
+/* Error Codes for ORCSCB_TaStat */
+#define TARGET_CHK_COND        0x02
+#define TARGET_BUSY    0x08
+#define TARGET_TAG_FULL        0x28
+
+
+/* Queue tag msg: Simple_quque_tag, Head_of_queue_tag, Ordered_queue_tag */
+#define MSG_STAG       0x20
+#define MSG_HTAG       0x21
+#define MSG_OTAG       0x22
+
+#define MSG_IGNOREWIDE 0x23
+
+#define MSG_IDENT      0x80
+#define MSG_DISC       0x40    /* Disconnect allowed             */
+
+
+/* SCSI MESSAGE */
+#define        MSG_EXTEND      0x01
+#define        MSG_SDP         0x02
+#define        MSG_ABORT       0x06
+#define        MSG_REJ         0x07
+#define        MSG_NOP         0x08
+#define        MSG_PARITY      0x09
+#define        MSG_DEVRST      0x0C
+#define        MSG_STAG        0x20
+
+/***********************************************************************
+               Target Device Control Structure
+**********************************************************************/
+
+typedef struct ORC_Tar_Ctrl_Struc {
+       UBYTE TCS_DrvDASD;      /* 6 */
+       UBYTE TCS_DrvSCSI;      /* 7 */
+       UBYTE TCS_DrvHead;      /* 8 */
+       UWORD TCS_DrvFlags;     /* 4 */
+       UBYTE TCS_DrvSector;    /* 7 */
+} ORC_TCS, *PORC_TCS;
+
+/* Bit Definition for TCF_DrvFlags */
+#define        TCS_DF_NODASD_SUPT      0x20    /* Suppress OS/2 DASD Mgr support */
+#define        TCS_DF_NOSCSI_SUPT      0x40    /* Suppress OS/2 SCSI Mgr support */
+
+
+/***********************************************************************
+              Host Adapter Control Structure
+************************************************************************/
+typedef struct ORC_Ha_Ctrl_Struc {
+       USHORT HCS_Base;        /* 00 */
+       UBYTE HCS_Index;        /* 02 */
+       UBYTE HCS_Intr;         /* 04 */
+       UBYTE HCS_SCSI_ID;      /* 06    H/A SCSI ID */
+       UBYTE HCS_BIOS;         /* 07    BIOS configuration */
+
+       UBYTE HCS_Flags;        /* 0B */
+       UBYTE HCS_HAConfig1;    /* 1B    SCSI0MAXTags */
+       UBYTE HCS_MaxTar;       /* 1B    SCSI0MAXTags */
+
+       USHORT HCS_Units;       /* Number of units this adapter  */
+       USHORT HCS_AFlags;      /* Adapter info. defined flags   */
+       ULONG HCS_Timeout;      /* Adapter timeout value   */
+       PVOID HCS_virScbArray;  /* 28 Virtual Pointer to SCB array     */
+       U32 HCS_physScbArray;   /* Scb Physical address */
+       PVOID HCS_virEscbArray; /* Virtual pointer to ESCB Scatter list */
+       U32 HCS_physEscbArray;  /* scatter list Physical address */
+       UBYTE TargetFlag[16];   /* 30  target configuration, TCF_EN_TAG */
+       UBYTE MaximumTags[16];  /* 40  ORC_MAX_SCBS */
+       UBYTE ActiveTags[16][16];       /* 50 */
+       ORC_TCS HCS_Tcs[16];    /* 28 */
+       U32 BitAllocFlag[MAX_CHANNELS][8];      /* Max STB is 256, So 256/32 */
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95)
+       spinlock_t BitAllocFlagLock;
+#endif
+       ULONG pSRB_head;
+       ULONG pSRB_tail;
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95)
+       spinlock_t pSRB_lock;
+#endif
+} ORC_HCS;
+
+/* Bit Definition for HCS_Flags */
+
+#define HCF_SCSI_RESET 0x01    /* SCSI BUS RESET         */
+#define HCF_PARITY     0x02    /* parity card                    */
+#define HCF_LVDS       0x10    /* parity card                    */
+
+/* Bit Definition for TargetFlag */
+
+#define TCF_EN_255         0x08
+#define TCF_EN_TAG         0x10
+#define TCF_BUSY             0x20
+#define TCF_DISCONNECT 0x40
+#define TCF_SPIN_UP      0x80
+
+/* Bit Definition for HCS_AFlags */
+#define        HCS_AF_IGNORE           0x01    /* Adapter ignore         */
+#define        HCS_AF_DISABLE_RESET    0x10    /* Adapter disable reset  */
+#define        HCS_AF_DISABLE_ADPT     0x80    /* Adapter disable                */
+
+
+/*---------------------------------------*/
+/* TimeOut for RESET to complete (30s)   */
+/*                                       */
+/* After a RESET the drive is checked    */
+/* every 200ms.                          */
+/*---------------------------------------*/
+#define DELAYED_RESET_MAX       (30*1000L)
+#define DELAYED_RESET_INTERVAL  200L
+
+/*----------------------------------------------*/
+/* TimeOut for IRQ from last interrupt (5s)     */
+/*----------------------------------------------*/
+#define IRQ_TIMEOUT_INTERVAL    (5*1000L)
+
+/*----------------------------------------------*/
+/* Retry Delay interval (200ms)                 */
+/*----------------------------------------------*/
+#define DELAYED_RETRY_INTERVAL  200L
+
+#define        INQUIRY_SIZE            36
+#define        CAPACITY_SIZE           8
+#define        DEFAULT_SENSE_LEN       14
+
+#define        DEVICE_NOT_FOUND        0x86
+
+/*----------------------------------------------*/
+/* Definition for PCI device                    */
+/*----------------------------------------------*/
+#define        MAX_PCI_DEVICES 21
+#define        MAX_PCI_BUSES   8
+
+typedef struct Adpt_Struc {
+       USHORT ADPT_BIOS;       /* 0 */
+       UBYTE ADPT_BASE;        /* 1 */
+       UBYTE ADPT_Bus;         /* 2 */
+       UBYTE ADPT_Device;      /* 3 */
+       UBYTE ADPT_Reserved[3];
+} JACS, *PJACS;
+
+typedef struct _NVRAM {
+/*----------header ---------------*/
+       UCHAR SubVendorID0;     /* 00 - Sub Vendor ID           */
+       UCHAR SubVendorID1;     /* 00 - Sub Vendor ID           */
+       UCHAR SubSysID0;        /* 02 - Sub System ID           */
+       UCHAR SubSysID1;        /* 02 - Sub System ID           */
+       UCHAR SubClass;         /* 04 - Sub Class               */
+       UCHAR VendorID0;        /* 05 - Vendor ID               */
+       UCHAR VendorID1;        /* 05 - Vendor ID               */
+       UCHAR DeviceID0;        /* 07 - Device ID               */
+       UCHAR DeviceID1;        /* 07 - Device ID               */
+       UCHAR Reserved0[2];     /* 09 - Reserved                */
+       UCHAR Revision;         /* 0B - Revision of data structure */
+       /* ----Host Adapter Structure ---- */
+       UCHAR NumOfCh;          /* 0C - Number of SCSI channel  */
+       UCHAR BIOSConfig1;      /* 0D - BIOS configuration 1    */
+       UCHAR BIOSConfig2;      /* 0E - BIOS boot channel&target ID */
+       UCHAR BIOSConfig3;      /* 0F - BIOS configuration 3    */
+       /* ----SCSI channel Structure ---- */
+       /* from "CTRL-I SCSI Host Adapter SetUp menu "  */
+       UCHAR SCSI0Id;          /* 10 - Channel 0 SCSI ID       */
+       UCHAR SCSI0Config;      /* 11 - Channel 0 SCSI configuration */
+       UCHAR SCSI0MaxTags;     /* 12 - Channel 0 Maximum tags  */
+       UCHAR SCSI0ResetTime;   /* 13 - Channel 0 Reset recovering time */
+       UCHAR ReservedforChannel0[2];   /* 14 - Reserved                */
+
+       /* ----SCSI target Structure ----  */
+       /* from "CTRL-I SCSI device SetUp menu "                        */
+       UCHAR Target00Config;   /* 16 - Channel 0 Target 0 config */
+       UCHAR Target01Config;   /* 17 - Channel 0 Target 1 config */
+       UCHAR Target02Config;   /* 18 - Channel 0 Target 2 config */
+       UCHAR Target03Config;   /* 19 - Channel 0 Target 3 config */
+       UCHAR Target04Config;   /* 1A - Channel 0 Target 4 config */
+       UCHAR Target05Config;   /* 1B - Channel 0 Target 5 config */
+       UCHAR Target06Config;   /* 1C - Channel 0 Target 6 config */
+       UCHAR Target07Config;   /* 1D - Channel 0 Target 7 config */
+       UCHAR Target08Config;   /* 1E - Channel 0 Target 8 config */
+       UCHAR Target09Config;   /* 1F - Channel 0 Target 9 config */
+       UCHAR Target0AConfig;   /* 20 - Channel 0 Target A config */
+       UCHAR Target0BConfig;   /* 21 - Channel 0 Target B config */
+       UCHAR Target0CConfig;   /* 22 - Channel 0 Target C config */
+       UCHAR Target0DConfig;   /* 23 - Channel 0 Target D config */
+       UCHAR Target0EConfig;   /* 24 - Channel 0 Target E config */
+       UCHAR Target0FConfig;   /* 25 - Channel 0 Target F config */
+
+       UCHAR SCSI1Id;          /* 26 - Channel 1 SCSI ID       */
+       UCHAR SCSI1Config;      /* 27 - Channel 1 SCSI configuration */
+       UCHAR SCSI1MaxTags;     /* 28 - Channel 1 Maximum tags  */
+       UCHAR SCSI1ResetTime;   /* 29 - Channel 1 Reset recovering time */
+       UCHAR ReservedforChannel1[2];   /* 2A - Reserved                */
+
+       /* ----SCSI target Structure ----  */
+       /* from "CTRL-I SCSI device SetUp menu "                                          */
+       UCHAR Target10Config;   /* 2C - Channel 1 Target 0 config */
+       UCHAR Target11Config;   /* 2D - Channel 1 Target 1 config */
+       UCHAR Target12Config;   /* 2E - Channel 1 Target 2 config */
+       UCHAR Target13Config;   /* 2F - Channel 1 Target 3 config */
+       UCHAR Target14Config;   /* 30 - Channel 1 Target 4 config */
+       UCHAR Target15Config;   /* 31 - Channel 1 Target 5 config */
+       UCHAR Target16Config;   /* 32 - Channel 1 Target 6 config */
+       UCHAR Target17Config;   /* 33 - Channel 1 Target 7 config */
+       UCHAR Target18Config;   /* 34 - Channel 1 Target 8 config */
+       UCHAR Target19Config;   /* 35 - Channel 1 Target 9 config */
+       UCHAR Target1AConfig;   /* 36 - Channel 1 Target A config */
+       UCHAR Target1BConfig;   /* 37 - Channel 1 Target B config */
+       UCHAR Target1CConfig;   /* 38 - Channel 1 Target C config */
+       UCHAR Target1DConfig;   /* 39 - Channel 1 Target D config */
+       UCHAR Target1EConfig;   /* 3A - Channel 1 Target E config */
+       UCHAR Target1FConfig;   /* 3B - Channel 1 Target F config */
+       UCHAR reserved[3];      /* 3C - Reserved                */
+       /* ---------- CheckSum ----------       */
+       UCHAR CheckSum;         /* 3F - Checksum of NVRam       */
+} NVRAM, *PNVRAM;
+
+/* Bios Configuration for nvram->BIOSConfig1                            */
+#define NBC_BIOSENABLE 0x01    /* BIOS enable                    */
+#define NBC_CDROM      0x02    /* Support bootable CDROM */
+#define NBC_REMOVABLE  0x04    /* Support removable drive        */
+
+/* Bios Configuration for nvram->BIOSConfig2                            */
+#define        NBB_TARGET_MASK 0x0F    /* Boot SCSI target ID number     */
+#define        NBB_CHANL_MASK  0xF0    /* Boot SCSI channel number       */
+
+/* Bit definition for nvram->SCSIConfig                                 */
+#define NCC_BUSRESET   0x01    /* Reset SCSI bus at power up     */
+#define NCC_PARITYCHK  0x02    /* SCSI parity enable             */
+#define NCC_LVDS       0x10    /* Enable LVDS                    */
+#define NCC_ACTTERM1   0x20    /* Enable active terminator 1     */
+#define NCC_ACTTERM2   0x40    /* Enable active terminator 2     */
+#define NCC_AUTOTERM   0x80    /* Enable auto termination        */
+
+/* Bit definition for nvram->TargetxConfig                              */
+#define        NTC_PERIOD      0x07    /* Maximum Sync. Speed            */
+#define NTC_1GIGA      0x08    /* 255 head / 63 sectors (64/32) */
+#define NTC_NO_SYNC    0x10    /* NO SYNC. NEGO          */
+#define NTC_NO_WIDESYNC        0x20    /* NO WIDE SYNC. NEGO             */
+#define        NTC_DISC_ENABLE 0x40    /* Enable SCSI disconnect */
+#define NTC_SPINUP     0x80    /* Start disk drive               */
+
+/* Default NVRam values                                                 */
+#define NBC_DEFAULT    (NBC_ENABLE)
+#define NCC_DEFAULT    (NCC_BUSRESET | NCC_AUTOTERM | NCC_PARITYCHK)
+#define NCC_MAX_TAGS   0x20    /* Maximum tags per target        */
+#define        NCC_RESET_TIME  0x0A    /* SCSI RESET recovering time     */
+#define NTC_DEFAULT    (NTC_1GIGA | NTC_NO_WIDESYNC | NTC_DISC_ENABLE)
+
+typedef union {                        /* Union define for mechanism 1   */
+       struct {
+               unsigned char RegNum;
+               unsigned char FcnNum:3;
+               unsigned char DeviceNum:5;
+               unsigned char BusNum;
+               unsigned char Reserved:7;
+               unsigned char Enable:1;
+       } sConfigAdr;
+       unsigned long lConfigAdr;
+} CONFIG_ADR;
+
+typedef union {                        /* Union define for mechanism 2   */
+       struct {
+               unsigned char RegNum;
+               unsigned char DeviceNum;
+               unsigned short Reserved;
+       } sHostAdr;
+       unsigned long lHostAdr;
+} HOST_ADR;
+
+#define ORC_RD(x,y)             (UCHAR)(inb(  (int)((ULONG)((ULONG)x+(UCHAR)y)) ))
+#define ORC_RDLONG(x,y)         (long)(inl((int)((ULONG)((ULONG)x+(UCHAR)y)) ))
+
+#define ORC_WR(     adr,data)   outb( (UCHAR)(data), (int)(adr))
+#define ORC_WRSHORT(adr,data)   outw( (UWORD)(data), (int)(adr))
+#define ORC_WRLONG( adr,data)   outl( (ULONG)(data), (int)(adr))
+
+
+#define SCSI_ABORT_SNOOZE 0
+#define SCSI_ABORT_SUCCESS 1
+#define SCSI_ABORT_PENDING 2
+#define SCSI_ABORT_BUSY 3
+#define SCSI_ABORT_NOT_RUNNING 4
+#define SCSI_ABORT_ERROR 5
+
+#define SCSI_RESET_SNOOZE 0
+#define SCSI_RESET_PUNT 1
+#define SCSI_RESET_SUCCESS 2
+#define SCSI_RESET_PENDING 3
+#define SCSI_RESET_WAKEUP 4
+#define SCSI_RESET_NOT_RUNNING 5
+#define SCSI_RESET_ERROR 6
+
+#define SCSI_RESET_SYNCHRONOUS         0x01
+#define SCSI_RESET_ASYNCHRONOUS                0x02
+#define SCSI_RESET_SUGGEST_BUS_RESET   0x04
+#define SCSI_RESET_SUGGEST_HOST_RESET  0x08
+
+#define SCSI_RESET_BUS_RESET 0x100
+#define SCSI_RESET_HOST_RESET 0x200
+#define SCSI_RESET_ACTION   0xff
diff --git a/drivers/scsi/inia100.c b/drivers/scsi/inia100.c
new file mode 100644 (file)
index 0000000..b6f4eb3
--- /dev/null
@@ -0,0 +1,952 @@
+/**************************************************************************
+ * Initio A100 device driver for Linux.
+ *
+ * Copyright (c) 1994-1998 Initio Corporation
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ **************************************************************************
+ * 
+ * module: inia100.c
+ * DESCRIPTION:
+ *     This is the Linux low-level SCSI driver for Initio INIA100 SCSI host
+ *     adapters
+ * 09/24/98 hl - v1.02 initial production release.
+ * 12/19/98 bv - v1.02a Use spinlocks for 2.1.95 and up.
+ **************************************************************************/
+
+#define CVT_LINUX_VERSION(V,P,S)        (V * 65536 + P * 256 + S)
+
+#ifndef LINUX_VERSION_CODE
+#include <linux/version.h>
+#endif
+
+#ifdef MODULE
+#include <linux/module.h>
+#endif
+
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0)
+#include <stdarg.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#if LINUX_VERSION_CODE <= CVT_LINUX_VERSION(2,1,92)
+#include <linux/bios32.h>
+#endif
+#include <linux/pci.h>
+#include <linux/proc_fs.h>
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,23)
+#include <linux/init.h>
+#endif
+#include <linux/blk.h>
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95)
+#include <asm/spinlock.h>
+#endif
+#include "sd.h"
+#include "scsi.h"
+#include "hosts.h"
+#include "inia100.h"
+#include <linux/stat.h>
+#include <linux/malloc.h>
+
+
+#else
+
+#include <linux/kernel.h>
+#include <linux/head.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include "../block/blk.h"
+#include "scsi.h"
+#include "sd.h"
+#include "hosts.h"
+#include <linux/malloc.h>
+#include "inia100.h"
+#endif
+
+#ifdef MODULE
+Scsi_Host_Template driver_template = INIA100;
+#include "scsi_module.c"
+#endif
+
+#define ORC_RDWORD(x,y)         (short)(inl((int)((ULONG)((ULONG)x+(UCHAR)y)) ))
+
+char *inia100_Copyright = "Copyright (C) 1998-99";
+char *inia100_InitioName = "by Initio Corporation";
+char *inia100_ProductName = "INI-A100U2W";
+char *inia100_Version = "v1.02a";
+
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0)
+struct proc_dir_entry proc_scsi_inia100 =
+{
+       PROC_SCSI_INIA100, 7, "INIA100",
+       S_IFDIR | S_IRUGO | S_IXUGO, 2,
+       0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+#endif
+
+/* set by inia100_setup according to the command line */
+static int setup_called = 0;
+static int orc_num_ch = MAX_SUPPORTED_ADAPTERS;                /* Maximum 4 adapters           */
+
+/* ---- INTERNAL VARIABLES ---- */
+#define NUMBER(arr)     (sizeof(arr) / sizeof(arr[0]))
+static char *setup_str = (char *) NULL;
+
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0)
+static void inia100_intr0(int irq, void *dev_id, struct pt_regs *);
+static void inia100_intr1(int irq, void *dev_id, struct pt_regs *);
+static void inia100_intr2(int irq, void *dev_id, struct pt_regs *);
+static void inia100_intr3(int irq, void *dev_id, struct pt_regs *);
+static void inia100_intr4(int irq, void *dev_id, struct pt_regs *);
+static void inia100_intr5(int irq, void *dev_id, struct pt_regs *);
+static void inia100_intr6(int irq, void *dev_id, struct pt_regs *);
+static void inia100_intr7(int irq, void *dev_id, struct pt_regs *);
+#else
+static void inia100_intr0(int irq, struct pt_regs *);
+static void inia100_intr1(int irq, struct pt_regs *);
+static void inia100_intr2(int irq, struct pt_regs *);
+static void inia100_intr3(int irq, struct pt_regs *);
+static void inia100_intr4(int irq, struct pt_regs *);
+static void inia100_intr5(int irq, struct pt_regs *);
+static void inia100_intr6(int irq, struct pt_regs *);
+static void inia100_intr7(int irq, struct pt_regs *);
+#endif
+
+static void inia100_panic(char *msg);
+void inia100SCBPost(BYTE * pHcb, BYTE * pScb);
+
+/* ---- EXTERNAL VARIABLES ---- */
+extern int Addinia100_into_Adapter_table(WORD, WORD, BYTE, BYTE, BYTE);
+extern void init_inia100Adapter_table(void);
+extern ORC_SCB *orc_alloc_scb(ORC_HCS * hcsp);
+extern void orc_exec_scb(ORC_HCS * hcsp, ORC_SCB * scbp);
+extern void orc_release_scb(ORC_HCS * hcsp, ORC_SCB * scbp);
+extern void orc_interrupt(ORC_HCS * hcsp);
+extern int orc_device_reset(ORC_HCS * pHCB, ULONG SCpnt, unsigned int target, unsigned int ResetFlags);
+extern int orc_reset_scsi_bus(ORC_HCS * pHCB);
+extern int abort_SCB(ORC_HCS * hcsp, ORC_SCB * pScb);
+extern int orc_abort_srb(ORC_HCS * hcsp, ULONG SCpnt);
+extern void get_orcPCIConfig(ORC_HCS * pCurHcb, int ch_idx);
+extern int init_orchid(ORC_HCS * hcsp);
+
+extern int orc_num_scb;
+extern ORC_HCS orc_hcs[];
+
+/*****************************************************************************
+ Function name  : inia100AppendSRBToQueue
+ Description    : This function will push current request into save list
+ Input          : pSRB  -       Pointer to SCSI request block.
+                 pHCB  -       Pointer to host adapter structure
+ Output         : None.
+ Return         : None.
+*****************************************************************************/
+static void inia100AppendSRBToQueue(ORC_HCS * pHCB, Scsi_Cmnd * pSRB)
+{
+       ULONG flags;
+
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95)
+       spin_lock_irqsave(&(pHCB->pSRB_lock), flags);
+#else
+       save_flags(flags);
+       cli();
+#endif
+
+       pSRB->next = NULL;      /* Pointer to next */
+       if (pHCB->pSRB_head == NULL)
+               pHCB->pSRB_head = pSRB;
+       else
+               pHCB->pSRB_tail->next = pSRB;   /* Pointer to next */
+       pHCB->pSRB_tail = pSRB;
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95)
+       spin_unlock_irqrestore(&(pHCB->pSRB_lock), flags);
+#else
+       restore_flags(flags);
+#endif
+       return;
+}
+
+/*****************************************************************************
+ Function name  : inia100PopSRBFromQueue
+ Description    : This function will pop current request from save list
+ Input          : pHCB  -       Pointer to host adapter structure
+ Output         : None.
+ Return         : pSRB  -       Pointer to SCSI request block.
+*****************************************************************************/
+static Scsi_Cmnd *inia100PopSRBFromQueue(ORC_HCS * pHCB)
+{
+       Scsi_Cmnd *pSRB;
+       ULONG flags;
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95)
+       spin_lock_irqsave(&(pHCB->pSRB_lock), flags);
+#else
+       save_flags(flags);
+       cli();
+#endif
+
+       if ((pSRB = (Scsi_Cmnd *) pHCB->pSRB_head) != NULL) {
+               pHCB->pSRB_head = pHCB->pSRB_head->next;
+               pSRB->next = NULL;
+       }
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95)
+       spin_unlock_irqrestore(&(pHCB->pSRB_lock), flags);
+#else
+       restore_flags(flags);
+#endif
+       return (pSRB);
+}
+
+/*****************************************************************************
+ Function name  : inia100_setup
+ Description    : 
+ Input          : pHCB  -       Pointer to host adapter structure
+ Output         : None.
+ Return         : pSRB  -       Pointer to SCSI request block.
+*****************************************************************************/
+void inia100_setup(char *str, int *ints)
+{
+       if (setup_called)
+               inia100_panic("inia100: inia100_setup called twice.\n");
+
+       setup_called = ints[0];
+       setup_str = str;
+}
+
+/*****************************************************************************
+ Function name : orc_ReturnNumberOfAdapters
+ Description   : This function will scan PCI bus to get all Orchid card
+ Input         : None.
+ Output                : None.
+ Return                : SUCCESSFUL    - Successful scan
+                 ohterwise     - No drives founded
+*****************************************************************************/
+int orc_ReturnNumberOfAdapters(void)
+{
+       unsigned int i, iAdapters;
+
+       iAdapters = 0;
+       /*
+        * PCI-bus probe.
+        */
+       if (pcibios_present()) {
+               struct {
+                       unsigned short vendor_id;
+                       unsigned short device_id;
+               } const inia100_pci_devices[] =
+               {
+                       {ORC_VENDOR_ID, I920_DEVICE_ID},
+                       {ORC_VENDOR_ID, ORC_DEVICE_ID}
+               };
+
+               unsigned int dRegValue;
+               unsigned short command;
+               WORD wBIOS, wBASE;
+               BYTE bPCIBusNum, bInterrupt, bPCIDeviceNum;
+
+#ifdef MMAPIO
+               unsigned long page_offset, base;
+#endif
+
+#if LINUX_VERSION_CODE > CVT_LINUX_VERSION(2,1,92)
+               struct pci_dev *pdev = NULL;
+#else
+               int index;
+               unsigned char pci_bus, pci_devfn;
+#endif
+
+               bPCIBusNum = 0;
+               bPCIDeviceNum = 0;
+               init_inia100Adapter_table();
+               for (i = 0; i < NUMBER(inia100_pci_devices); i++) {
+#if LINUX_VERSION_CODE > CVT_LINUX_VERSION(2,1,92)
+                       pdev = NULL;
+                       while ((pdev = pci_find_device(inia100_pci_devices[i].vendor_id,
+                                       inia100_pci_devices[i].device_id,
+                                                      pdev)))
+#else
+                       index = 0;
+                       while (!(pcibios_find_device(inia100_pci_devices[i].vendor_id,
+                                       inia100_pci_devices[i].device_id,
+                                        index++, &pci_bus, &pci_devfn)))
+#endif
+                       {
+                               if (iAdapters >= MAX_SUPPORTED_ADAPTERS)
+                                       break;  /* Never greater than maximum   */
+
+                               if (i == 0) {
+                                       /*
+                                          printk("inia100: The RAID controller is not supported by\n");
+                                          printk("inia100:         this driver, we are ignoring it.\n");
+                                        */
+                               } else {
+                                       /*
+                                        * Read sundry information from PCI BIOS.
+                                        */
+#if LINUX_VERSION_CODE > CVT_LINUX_VERSION(2,1,92)
+                                       bPCIBusNum = pdev->bus->number;
+                                       bPCIDeviceNum = pdev->devfn;
+                                       dRegValue = pdev->base_address[0];
+                                       if (dRegValue == -1) {  /* Check return code            */
+                                               printk("\n\rinia100: orchid read configuration error.\n");
+                                               return (0);     /* Read configuration space error  */
+                                       }
+                                       /* <02> read from base address + 0x50 offset to get the wBIOS balue. */
+                                       wBASE = (WORD) dRegValue;
+
+                                       /* Now read the interrupt line  */
+                                       dRegValue = pdev->irq;
+                                       bInterrupt = dRegValue & 0xFF;  /* Assign interrupt line      */
+                                       pci_read_config_word(pdev, PCI_COMMAND, &command);
+                                       pci_write_config_word(pdev, PCI_COMMAND,
+                                                             command | PCI_COMMAND_MASTER | PCI_COMMAND_IO);
+
+#else
+                                       bPCIBusNum = pci_bus;
+                                       bPCIDeviceNum = pci_devfn;
+                                       pcibios_read_config_dword(pci_bus, pci_devfn, PCI_BASE_ADDRESS_0,
+                                                            &dRegValue);
+                                       if (dRegValue == -1) {  /* Check return code            */
+                                               printk("\n\rinia100: Orchid read configuration error.\n");
+                                               return (0);     /* Read configuration space error  */
+                                       }
+                                       /* <02> read from base address + 0x50 offset to get the wBIOS balue. */
+                                       wBASE = (WORD) dRegValue;
+
+                                       /* Now read the interrupt line  */
+                                       pcibios_read_config_dword(pci_bus, pci_devfn, PCI_INTERRUPT_LINE,
+                                                            &dRegValue);
+                                       bInterrupt = dRegValue & 0xFF;  /* Assign interrupt line      */
+                                       pcibios_read_config_word(pci_bus, pci_devfn, PCI_COMMAND, &command);
+                                       pcibios_write_config_word(pci_bus, pci_devfn, PCI_COMMAND,
+                                                                 command | PCI_COMMAND_MASTER | PCI_COMMAND_IO);
+#endif
+                                       wBASE &= PCI_BASE_ADDRESS_IO_MASK;
+                                       wBIOS = ORC_RDWORD(wBASE, 0x50);
+
+#ifdef MMAPIO
+                                       base = wBASE & PAGE_MASK;
+                                       page_offset = wBASE - base;
+
+                                       /*
+                                        * replace the next line with this one if you are using 2.1.x:
+                                        * temp_p->maddr = ioremap(base, page_offset + 256);
+                                        */
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,0)
+                                       wBASE = ioremap(base, page_offset + 256);
+#else
+                                       wBASE = (WORD) vremap(base, page_offset + 256);
+#endif
+                                       if (wBASE) {
+                                               wBASE += page_offset;
+                                       }
+#endif
+
+                                       if (Addinia100_into_Adapter_table(wBIOS, wBASE, bInterrupt, bPCIBusNum,
+                                           bPCIDeviceNum) == SUCCESSFUL)
+                                               iAdapters++;
+                               }
+                       }       /* while(pdev=....) */
+               }               /* for PCI_DEVICES */
+       }                       /* PCI BIOS present */
+       return (iAdapters);
+}
+
+/*****************************************************************************
+ Function name  : inia100_detect
+ Description    : 
+ Input          : pHCB  -       Pointer to host adapter structure
+ Output         : None.
+ Return         : pSRB  -       Pointer to SCSI request block.
+*****************************************************************************/
+int inia100_detect(Scsi_Host_Template * tpnt)
+{
+       ORC_HCS *pHCB;
+       struct Scsi_Host *hreg;
+       U32 sz;
+       U32 i;                  /* 01/14/98                     */
+       int ok = 0, iAdapters;
+       ULONG dBiosAdr;
+       BYTE *pbBiosAdr;
+
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0)
+       tpnt->proc_dir = &proc_scsi_inia100;
+#endif
+       if (setup_called) {
+               /* Setup by inia100_setup          */
+               printk("inia100: processing commandline: ");
+       }
+       /* Get total number of adapters in the motherboard */
+       iAdapters = orc_ReturnNumberOfAdapters();
+
+       /* printk("inia100: Total Initio Adapters = %d\n", iAdapters); */
+       if (iAdapters == 0)     /* If no orc founded, return */
+               return (0);
+
+       orc_num_ch = (iAdapters > orc_num_ch) ? orc_num_ch : iAdapters;
+       orc_num_scb = ORC_MAXQUEUE;
+
+       /* clear the memory needed for HCS */
+       i = orc_num_ch * sizeof(ORC_HCS);
+       memset((unsigned char *) &orc_hcs[0], 0, i);    /* Initialize orc_hcs 0   */
+
+#if 0
+       printk("orc_num_scb= %x orc_num_ch= %x hcsize= %x scbsize= %x escbsize= %x\n",
+              orc_num_scb, orc_num_ch, sizeof(ORC_HCS), sizeof(ORC_SCB), sizeof(ESCB));
+#endif
+
+       for (i = 0, pHCB = &orc_hcs[0];         /* Get pointer for control block */
+            i < orc_num_ch;
+            i++, pHCB++) {
+
+               pHCB->pSRB_head = NULL;         /* Initial SRB save queue       */
+               pHCB->pSRB_tail = NULL;         /* Initial SRB save queue       */
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95)
+               pHCB->pSRB_lock = SPIN_LOCK_UNLOCKED; /* SRB save queue lock */
+#endif
+               /* Get total memory needed for SCB */
+               sz = orc_num_scb * sizeof(ORC_SCB);
+               if ((pHCB->HCS_virScbArray = (PVOID) kmalloc(sz, GFP_ATOMIC | GFP_DMA)) == NULL) {
+                       printk("inia100: SCB memory allocation error\n");
+                       return (0);
+               }
+               memset((unsigned char *) pHCB->HCS_virScbArray, 0, sz);
+               pHCB->HCS_physScbArray = (U32) VIRT_TO_BUS(pHCB->HCS_virScbArray);
+
+               /* Get total memory needed for ESCB */
+               sz = orc_num_scb * sizeof(ESCB);
+               if ((pHCB->HCS_virEscbArray = (PVOID) kmalloc(sz, GFP_ATOMIC | GFP_DMA)) == NULL) {
+                       printk("inia100: ESCB memory allocation error\n");
+                       return (0);
+               }
+               memset((unsigned char *) pHCB->HCS_virEscbArray, 0, sz);
+               pHCB->HCS_physEscbArray = (U32) VIRT_TO_BUS(pHCB->HCS_virEscbArray);
+
+               request_region(pHCB->HCS_Base, 0x100, "inia100");       /* Register */
+               get_orcPCIConfig(pHCB, i);
+
+               dBiosAdr = pHCB->HCS_BIOS;
+               dBiosAdr = (dBiosAdr << 4);
+
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0)
+               pbBiosAdr = phys_to_virt(dBiosAdr);
+#endif
+
+               if (init_orchid(pHCB)) {        /* Initial orchid chip    */
+                       printk("inia100: initial orchid fail!!\n");
+                       return (0);
+               }
+               hreg = scsi_register(tpnt, sizeof(ORC_HCS));
+               if (hreg == NULL) {
+                       printk("Invalid scsi_register pointer.\n");
+               }
+               hreg->io_port = pHCB->HCS_Base;
+               hreg->n_io_port = 0xff;
+               hreg->can_queue = orc_num_scb;  /* 03/05/98                   */
+
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0)
+               hreg->unique_id = pHCB->HCS_Base;
+               hreg->max_id = pHCB->HCS_MaxTar;
+#endif
+
+               hreg->max_lun = 32;     /* 10/21/97                     */
+/*
+   hreg->max_lun = 8;
+   hreg->max_channel = 1;
+ */
+               hreg->irq = pHCB->HCS_Intr;
+               hreg->this_id = pHCB->HCS_SCSI_ID;      /* Assign HCS index           */
+               hreg->base = (UCHAR *) pHCB;
+
+#if 1
+               hreg->sg_tablesize = TOTAL_SG_ENTRY;    /* Maximun support is 32 */
+#else
+               hreg->sg_tablesize = SG_NONE;   /* No SG                        */
+#endif
+
+               /* Initial orc chip           */
+               switch (i) {
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0)
+               case 0:
+                       ok = request_irq(pHCB->HCS_Intr, inia100_intr0, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL);
+                       break;
+               case 1:
+                       ok = request_irq(pHCB->HCS_Intr, inia100_intr1, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL);
+                       break;
+               case 2:
+                       ok = request_irq(pHCB->HCS_Intr, inia100_intr2, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL);
+                       break;
+               case 3:
+                       ok = request_irq(pHCB->HCS_Intr, inia100_intr3, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL);
+                       break;
+               case 4:
+                       ok = request_irq(pHCB->HCS_Intr, inia100_intr4, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL);
+                       break;
+               case 5:
+                       ok = request_irq(pHCB->HCS_Intr, inia100_intr5, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL);
+                       break;
+               case 6:
+                       ok = request_irq(pHCB->HCS_Intr, inia100_intr6, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL);
+                       break;
+               case 7:
+                       ok = request_irq(pHCB->HCS_Intr, inia100_intr7, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL);
+                       break;
+               default:
+                       inia100_panic("inia100: Too many host adapters\n");
+                       break;
+               }
+
+               if (ok < 0) {
+                       if (ok == -EINVAL) {
+                               printk("inia100: bad IRQ %d.\n", pHCB->HCS_Intr);
+                               printk("         Contact author.\n");
+                       } else {
+                               if (ok == -EBUSY)
+                                       printk("inia100: IRQ %d already in use. Configure another.\n", pHCB->HCS_Intr);
+                               else {
+                                       printk("\ninia100: Unexpected error code on requesting IRQ %d.\n",
+                                              pHCB->HCS_Intr);
+                                       printk("         Contact author.\n");
+                               }
+                       }
+                       inia100_panic("inia100: driver needs an IRQ.\n");
+               }
+#endif
+       }
+
+       tpnt->this_id = -1;
+       tpnt->can_queue = 1;
+       return 1;
+}
+
+/*****************************************************************************
+ Function name  : inia100BuildSCB
+ Description    : 
+ Input          : pHCB  -       Pointer to host adapter structure
+ Output         : None.
+ Return         : pSRB  -       Pointer to SCSI request block.
+*****************************************************************************/
+static void inia100BuildSCB(ORC_HCS * pHCB, ORC_SCB * pSCB, Scsi_Cmnd * SCpnt)
+{                              /* Create corresponding SCB     */
+       struct scatterlist *pSrbSG;
+       ORC_SG *pSG;            /* Pointer to SG list           */
+       int i;
+       U32 TotalLen;
+       ESCB *pEScb;
+
+       pEScb = pSCB->SCB_EScb;
+       pEScb->SCB_Srb = SCpnt;
+       pSG = NULL;
+
+       pSCB->SCB_Opcode = ORC_EXECSCSI;
+       pSCB->SCB_Flags = SCF_NO_DCHK;  /* Clear done bit               */
+       pSCB->SCB_Target = SCpnt->target;
+       pSCB->SCB_Lun = SCpnt->lun;
+       pSCB->SCB_Reserved0 = 0;
+       pSCB->SCB_Reserved1 = 0;
+       pSCB->SCB_SGLen = 0;
+
+       if ((pSCB->SCB_XferLen = (U32) SCpnt->request_bufflen)) {
+               pSG = (ORC_SG *) & pEScb->ESCB_SGList[0];
+               if (SCpnt->use_sg) {
+                       TotalLen = 0;
+                       pSCB->SCB_SGLen = (U32) (SCpnt->use_sg * 8);
+                       pSrbSG = (struct scatterlist *) SCpnt->request_buffer;
+                       for (i = 0; i < SCpnt->use_sg; i++, pSG++, pSrbSG++) {
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0)
+                               pSG->SG_Ptr = (U32) (VIRT_TO_BUS(pSrbSG->address));
+#else
+                               pSG->SG_Ptr = (U32) pSrbSG->address;
+#endif
+                               pSG->SG_Len = (U32) pSrbSG->length;
+                               TotalLen += (U32) pSrbSG->length;
+                       }
+               } else {        /* Non SG                       */
+                       pSCB->SCB_SGLen = 0x8;
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0)
+                       pSG->SG_Ptr = (U32) (VIRT_TO_BUS(SCpnt->request_buffer));
+#else
+                       pSG->SG_PTR = (U32) SCpnt->request_buffer;
+#endif
+                       pSG->SG_Len = (U32) SCpnt->request_bufflen;
+               }
+       }
+       pSCB->SCB_SGPAddr = (U32) pSCB->SCB_SensePAddr;
+       pSCB->SCB_HaStat = 0;
+       pSCB->SCB_TaStat = 0;
+       pSCB->SCB_Link = 0xFF;
+       pSCB->SCB_SenseLen = SENSE_SIZE;
+       pSCB->SCB_CDBLen = SCpnt->cmd_len;
+       if (pSCB->SCB_CDBLen >= IMAX_CDB) {
+               printk("max cdb length= %x\b", SCpnt->cmd_len);
+               pSCB->SCB_CDBLen = IMAX_CDB;
+       }
+       pSCB->SCB_Ident = SCpnt->lun | DISC_ALLOW;
+       if (SCpnt->device->tagged_supported) {  /* Tag Support                  */
+               pSCB->SCB_TagMsg = SIMPLE_QUEUE_TAG;    /* Do simple tag only   */
+       } else {
+               pSCB->SCB_TagMsg = 0;   /* No tag support               */
+       }
+       memcpy(&pSCB->SCB_CDB[0], &SCpnt->cmnd, pSCB->SCB_CDBLen);
+       return;
+}
+
+/*****************************************************************************
+ Function name  : inia100_queue
+ Description    : Queue a command and setup interrupts for a free bus.
+ Input          : pHCB  -       Pointer to host adapter structure
+ Output         : None.
+ Return         : pSRB  -       Pointer to SCSI request block.
+*****************************************************************************/
+int inia100_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
+{
+       register ORC_SCB *pSCB;
+       ORC_HCS *pHCB;          /* Point to Host adapter control block */
+
+       if (SCpnt->lun > 16) {
+               SCpnt->result = (DID_TIME_OUT << 16);
+               done(SCpnt);    /* Notify system DONE           */
+               return (0);
+       }
+       pHCB = (ORC_HCS *) SCpnt->host->base;
+       SCpnt->scsi_done = done;
+       /* Get free SCSI control block  */
+       if ((pSCB = orc_alloc_scb(pHCB)) == NULL) {
+               inia100AppendSRBToQueue(pHCB, SCpnt);   /* Buffer this request  */
+               /* printk("inia100_entry: can't allocate SCB\n"); */
+               return (0);
+       }
+       inia100BuildSCB(pHCB, pSCB, SCpnt);
+       orc_exec_scb(pHCB, pSCB);       /* Start execute SCB            */
+
+       return (0);
+}
+
+/*****************************************************************************
+ Function name  : inia100_command
+ Description    : We only support command in interrupt-driven fashion
+ Input          : pHCB  -       Pointer to host adapter structure
+ Output         : None.
+ Return         : pSRB  -       Pointer to SCSI request block.
+*****************************************************************************/
+int inia100_command(Scsi_Cmnd * SCpnt)
+{
+       printk("inia100: interrupt driven driver; use inia100_queue()\n");
+       return -1;
+}
+
+/*****************************************************************************
+ Function name  : inia100_abort
+ Description    : Abort a queued command.
+                        (commands that are on the bus can't be aborted easily)
+ Input          : pHCB  -       Pointer to host adapter structure
+ Output         : None.
+ Return         : pSRB  -       Pointer to SCSI request block.
+*****************************************************************************/
+int inia100_abort(Scsi_Cmnd * SCpnt)
+{
+       ORC_HCS *hcsp;
+
+       hcsp = (ORC_HCS *) SCpnt->host->base;
+       return orc_abort_srb(hcsp, (ULONG) SCpnt);
+}
+
+/*****************************************************************************
+ Function name  : inia100_reset
+ Description    : Reset registers, reset a hanging bus and
+                  kill active and disconnected commands for target w/o soft reset
+ Input          : pHCB  -       Pointer to host adapter structure
+ Output         : None.
+ Return         : pSRB  -       Pointer to SCSI request block.
+*****************************************************************************/
+int inia100_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
+{                              /* I need Host Control Block Information */
+       ORC_HCS *pHCB;
+       pHCB = (ORC_HCS *) SCpnt->host->base;
+
+       if (reset_flags & (SCSI_RESET_SUGGEST_BUS_RESET | SCSI_RESET_SUGGEST_HOST_RESET))
+               return orc_reset_scsi_bus(pHCB);
+       else
+               return orc_device_reset(pHCB, (ULONG) SCpnt, SCpnt->target, reset_flags);
+
+}
+
+/*****************************************************************************
+ Function name  : inia100SCBPost
+ Description    : This is callback routine be called when orc finish one
+                       SCSI command.
+ Input          : pHCB  -       Pointer to host adapter control block.
+                 pSCB  -       Pointer to SCSI control block.
+ Output         : None.
+ Return         : None.
+*****************************************************************************/
+void inia100SCBPost(BYTE * pHcb, BYTE * pScb)
+{
+       Scsi_Cmnd *pSRB;        /* Pointer to SCSI request block */
+       ORC_HCS *pHCB;
+       ORC_SCB *pSCB;
+       ESCB *pEScb;
+
+       pHCB = (ORC_HCS *) pHcb;
+       pSCB = (ORC_SCB *) pScb;
+       pEScb = pSCB->SCB_EScb;
+       if ((pSRB = (Scsi_Cmnd *) pEScb->SCB_Srb) == 0) {
+               printk("inia100SCBPost: SRB pointer is empty\n");
+               orc_release_scb(pHCB, pSCB);    /* Release SCB for current channel */
+               return;
+       }
+       pEScb->SCB_Srb = NULL;
+
+       switch (pSCB->SCB_HaStat) {
+       case 0x0:
+       case 0xa:               /* Linked command complete without error and linked normally */
+       case 0xb:               /* Linked command complete without error interrupt generated */
+               pSCB->SCB_HaStat = 0;
+               break;
+
+       case 0x11:              /* Selection time out-The initiator selection or target
+                                  reselection was not complete within the SCSI Time out period */
+               pSCB->SCB_HaStat = DID_TIME_OUT;
+               break;
+
+       case 0x14:              /* Target bus phase sequence failure-An invalid bus phase or bus
+                                  phase sequence was requested by the target. The host adapter
+                                  will generate a SCSI Reset Condition, notifying the host with
+                                  a SCRD interrupt */
+               pSCB->SCB_HaStat = DID_RESET;
+               break;
+
+       case 0x1a:              /* SCB Aborted. 07/21/98 */
+               pSCB->SCB_HaStat = DID_ABORT;
+               break;
+
+       case 0x12:              /* Data overrun/underrun-The target attempted to transfer more data
+                                  than was allocated by the Data Length field or the sum of the
+                                  Scatter / Gather Data Length fields. */
+       case 0x13:              /* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */
+       case 0x16:              /* Invalid CCB Operation Code-The first byte of the CCB was invalid. */
+
+       default:
+               printk("inia100: %x %x\n", pSCB->SCB_HaStat, pSCB->SCB_TaStat);
+               pSCB->SCB_HaStat = DID_ERROR;   /* Couldn't find any better */
+               break;
+       }
+
+       if (pSCB->SCB_TaStat == 2) {    /* Check condition              */
+               memcpy((unsigned char *) &pSRB->sense_buffer[0],
+                  (unsigned char *) &pEScb->ESCB_SGList[0], SENSE_SIZE);
+       }
+       pSRB->result = pSCB->SCB_TaStat | (pSCB->SCB_HaStat << 16);
+       pSRB->scsi_done(pSRB);  /* Notify system DONE           */
+
+       /* Find the next pending SRB    */
+       if ((pSRB = inia100PopSRBFromQueue(pHCB)) != NULL) {    /* Assume resend will success   */
+               /* Reuse old SCB                */
+               inia100BuildSCB(pHCB, pSCB, pSRB);      /* Create corresponding SCB     */
+               orc_exec_scb(pHCB, pSCB);       /* Start execute SCB            */
+       } else {                /* No Pending SRB               */
+               orc_release_scb(pHCB, pSCB);    /* Release SCB for current channel */
+       }
+       return;
+}
+
+/*****************************************************************************
+ Function name  : inia100_biosparam
+ Description    : Return the "logical geometry"
+ Input          : pHCB  -       Pointer to host adapter structure
+ Output         : None.
+ Return         : pSRB  -       Pointer to SCSI request block.
+*****************************************************************************/
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0)
+int inia100_biosparam(Scsi_Disk * disk, kdev_t dev, int *info_array)
+#else
+int inia100_biosparam(Scsi_Disk * disk, int dev, int *info_array)
+#endif
+{
+       ORC_HCS *pHcb;          /* Point to Host adapter control block */
+       ORC_TCS *pTcb;
+
+       pHcb = (ORC_HCS *) disk->device->host->base;
+       pTcb = &pHcb->HCS_Tcs[disk->device->id];
+
+       if (pTcb->TCS_DrvHead) {
+               info_array[0] = pTcb->TCS_DrvHead;
+               info_array[1] = pTcb->TCS_DrvSector;
+               info_array[2] = disk->capacity / pTcb->TCS_DrvHead / pTcb->TCS_DrvSector;
+       } else {
+               if (pTcb->TCS_DrvFlags & TCF_DRV_255_63) {
+                       info_array[0] = 255;
+                       info_array[1] = 63;
+                       info_array[2] = disk->capacity / 255 / 63;
+               } else {
+                       info_array[0] = 64;
+                       info_array[1] = 32;
+                       info_array[2] = disk->capacity >> 11;
+               }
+       }
+       return 0;
+}
+
+
+static void subIntr(ORC_HCS * pHCB, int irqno)
+{
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95)
+       unsigned long flags;
+
+       spin_lock_irqsave(&io_request_lock, flags);
+#endif
+
+       if (pHCB->HCS_Intr != irqno) {
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95)
+               spin_unlock_irqrestore(&io_request_lock, flags);
+#endif
+               return;
+       }
+       orc_interrupt(pHCB);
+
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95)
+       spin_unlock_irqrestore(&io_request_lock, flags);
+#endif
+}
+
+/*
+ * Interrupts handler (main routine of the driver)
+ */
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0)
+static void inia100_intr0(int irqno, void *dev_id, struct pt_regs *regs)
+#else
+static void inia100_intr0(int irqno, struct pt_regs *regs)
+#endif
+{
+       subIntr(&orc_hcs[0], irqno);
+}
+
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0)
+static void inia100_intr1(int irqno, void *dev_id, struct pt_regs *regs)
+#else
+static void inia100_intr1(int irqno, struct pt_regs *regs)
+#endif
+{
+       subIntr(&orc_hcs[1], irqno);
+}
+
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0)
+static void inia100_intr2(int irqno, void *dev_id, struct pt_regs *regs)
+#else
+static void inia100_intr2(int irqno, struct pt_regs *regs)
+#endif
+{
+       subIntr(&orc_hcs[2], irqno);
+}
+
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0)
+static void inia100_intr3(int irqno, void *dev_id, struct pt_regs *regs)
+#else
+static void inia100_intr3(int irqno, struct pt_regs *regs)
+#endif
+{
+       subIntr(&orc_hcs[3], irqno);
+}
+
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0)
+static void inia100_intr4(int irqno, void *dev_id, struct pt_regs *regs)
+#else
+static void inia100_intr4(int irqno, struct pt_regs *regs)
+#endif
+{
+       subIntr(&orc_hcs[4], irqno);
+}
+
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0)
+static void inia100_intr5(int irqno, void *dev_id, struct pt_regs *regs)
+#else
+static void inia100_intr5(int irqno, struct pt_regs *regs)
+#endif
+{
+       subIntr(&orc_hcs[5], irqno);
+}
+
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0)
+static void inia100_intr6(int irqno, void *dev_id, struct pt_regs *regs)
+#else
+static void inia100_intr6(int irqno, struct pt_regs *regs)
+#endif
+{
+       subIntr(&orc_hcs[6], irqno);
+}
+
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0)
+static void inia100_intr7(int irqno, void *dev_id, struct pt_regs *regs)
+#else
+static void inia100_intr7(int irqno, struct pt_regs *regs)
+#endif
+{
+       subIntr(&orc_hcs[7], irqno);
+}
+
+/* 
+ * Dump the current driver status and panic...
+ */
+static void inia100_panic(char *msg)
+{
+       printk("\ninia100_panic: %s\n", msg);
+       panic("inia100 panic");
+}
+
+/*#include "inia100scsi.c" */
diff --git a/drivers/scsi/inia100.h b/drivers/scsi/inia100.h
new file mode 100644 (file)
index 0000000..e269ea7
--- /dev/null
@@ -0,0 +1,503 @@
+/**************************************************************************
+ * Initio A100 device driver for Linux.
+ *
+ * Copyright (c) 1994-1998 Initio Corporation
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ **************************************************************************
+ *
+ * Module: inia100.h
+ * Description: INI-A100U2W LINUX device driver header
+ * Revision History:
+ *     06/18/98 HL, Initial production Version 1.02
+ *     12/19/98 bv, Use spinlocks for 2.1.95 and up
+ ****************************************************************************/
+
+#ifndef        CVT_LINUX_VERSION
+#define        CVT_LINUX_VERSION(V,P,S)        (((V) * 65536) + ((P) * 256) + (S))
+#endif
+
+#ifndef        LINUX_VERSION_CODE
+#include <linux/version.h>
+#endif
+
+#include "sd.h"
+
+extern int inia100_detect(Scsi_Host_Template *);
+extern int inia100_command(Scsi_Cmnd *);
+extern int inia100_queue(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
+extern int inia100_abort(Scsi_Cmnd *);
+extern int inia100_reset(Scsi_Cmnd *, unsigned int);
+
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1, 3, 0)
+extern int inia100_biosparam(Scsi_Disk *, kdev_t, int *);      /*for linux v2.0 */
+extern struct proc_dir_entry proc_scsi_inia100;
+#else
+extern int inia100_biosparam(Disk *, int, int *);      /*for linux v1.13 */
+#endif
+
+#define inia100_REVID "Initio INI-A100U2W SCSI device driver; Revision: 1.02a"
+
+#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(1, 3, 0)
+#define INIA100        { \
+               NULL, \
+               NULL, \
+               inia100_REVID, \
+               inia100_detect, \
+               NULL, \
+               NULL, \
+               inia100_command, \
+               inia100_queue, \
+               inia100_abort, \
+               inia100_reset, \
+               NULL, \
+               inia100_biosparam, \
+               1, \
+7, \
+SG_ALL, \
+1, \
+0, \
+0, \
+ENABLE_CLUSTERING \
+}
+
+#else
+
+#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2, 1, 75)
+#define INIA100        { \
+               NULL, \
+               NULL, \
+               &proc_scsi_inia100, \
+               NULL, \
+               inia100_REVID, \
+               inia100_detect, \
+               NULL, \
+               NULL, \
+               inia100_command, \
+               inia100_queue, \
+               inia100_abort, \
+               inia100_reset, \
+               NULL, \
+               inia100_biosparam, \
+               1, \
+               7, \
+               0, \
+               1, \
+               0, \
+               0, \
+               ENABLE_CLUSTERING \
+}
+#else                          /* Version >= 2.1.75 */
+#define INIA100        { \
+       next:           NULL,                                           \
+       module:         NULL,                                           \
+       proc_dir:       &proc_scsi_inia100, \
+       proc_info:      NULL,                           \
+       name:           inia100_REVID, \
+       detect:         inia100_detect, \
+       release:        NULL, \
+       info:           NULL,                                   \
+       command:        inia100_command, \
+       queuecommand:   inia100_queue, \
+       eh_strategy_handler: NULL, \
+       eh_abort_handler: NULL, \
+       eh_device_reset_handler: NULL, \
+       eh_bus_reset_handler: NULL, \
+       eh_host_reset_handler: NULL, \
+       abort:          inia100_abort, \
+       reset:          inia100_reset, \
+       slave_attach:   NULL, \
+       bios_param:     inia100_biosparam, \
+       can_queue:      1, \
+       this_id:        1, \
+       sg_tablesize:   SG_ALL, \
+       cmd_per_lun:    1, \
+       present:        0, \
+       unchecked_isa_dma: 0, \
+       use_clustering: ENABLE_CLUSTERING, \
+ use_new_eh_code: 0 \
+}
+#endif
+#endif
+
+#define VIRT_TO_BUS(i)  (unsigned int) virt_to_bus((void *)(i))
+#define ULONG   unsigned long
+#define PVOID   void *
+#define USHORT  unsigned short
+#define UCHAR   unsigned char
+#define BYTE    unsigned char
+#define WORD    unsigned short
+#define DWORD   unsigned long
+#define UBYTE   unsigned char
+#define UWORD   unsigned short
+#define UDWORD  unsigned long
+#ifdef ALPHA
+#define U32     unsigned int
+#else
+#define U32     unsigned long
+#endif
+
+#ifndef NULL
+#define NULL     0             /* zero          */
+#endif
+#ifndef TRUE
+#define TRUE     (1)           /* boolean true  */
+#endif
+#ifndef FALSE
+#define FALSE    (0)           /* boolean false */
+#endif
+#ifndef FAILURE
+#define FAILURE  (-1)
+#endif
+#if 1
+#define ORC_MAXQUEUE           245
+#else
+#define ORC_MAXQUEUE           25
+#endif
+
+#define TOTAL_SG_ENTRY         32
+#define MAX_TARGETS            16
+#define IMAX_CDB                       15
+#define SENSE_SIZE             14
+#define MAX_SUPPORTED_ADAPTERS  4
+#define SUCCESSFUL              0x00
+
+#define I920_DEVICE_ID 0x0002  /* Initio's inic-950 product ID   */
+
+/************************************************************************/
+/*              Scatter-Gather Element Structure                        */
+/************************************************************************/
+typedef struct ORC_SG_Struc {
+       U32 SG_Ptr;             /* Data Pointer */
+       U32 SG_Len;             /* Data Length */
+} ORC_SG;
+
+
+/* SCSI related definition                                              */
+#define DISC_NOT_ALLOW          0x80   /* Disconnect is not allowed    */
+#define DISC_ALLOW              0xC0   /* Disconnect is allowed        */
+
+
+#define ORC_OFFSET_SCB                 16
+#define ORC_MAX_SCBS               250
+#define MAX_CHANNELS       2
+#define MAX_ESCB_ELE                           64
+#define TCF_DRV_255_63     0x0400
+
+/********************************************************/
+/*      Orchid Configuration Register Set               */
+/********************************************************/
+#define ORC_PVID       0x00    /* Vendor ID                      */
+#define ORC_VENDOR_ID  0x1101  /* Orchid vendor ID               */
+#define ORC_PDID        0x02   /* Device ID                    */
+#define ORC_DEVICE_ID  0x1060  /* Orchid device ID               */
+#define ORC_COMMAND    0x04    /* Command                        */
+#define BUSMS          0x04    /* BUS MASTER Enable              */
+#define IOSPA          0x01    /* IO Space Enable                */
+#define ORC_STATUS     0x06    /* Status register                */
+#define ORC_REVISION   0x08    /* Revision number                */
+#define ORC_BASE       0x10    /* Base address                   */
+#define ORC_BIOS       0x50    /* Expansion ROM base address     */
+#define ORC_INT_NUM    0x3C    /* Interrupt line         */
+#define ORC_INT_PIN    0x3D    /* Interrupt pin          */
+
+/********************************************************/
+/*      Orchid Host Command Set                         */
+/********************************************************/
+#define ORC_CMD_NOP            0x00    /* Host command - NOP             */
+#define ORC_CMD_VERSION                0x01    /* Host command - Get F/W version */
+#define ORC_CMD_ECHO           0x02    /* Host command - ECHO            */
+#define ORC_CMD_SET_NVM                0x03    /* Host command - Set NVRAM       */
+#define ORC_CMD_GET_NVM                0x04    /* Host command - Get NVRAM       */
+#define ORC_CMD_GET_BUS_STATUS 0x05    /* Host command - Get SCSI bus status */
+#define ORC_CMD_ABORT_SCB      0x06    /* Host command - Abort SCB       */
+#define ORC_CMD_ISSUE_SCB      0x07    /* Host command - Issue SCB       */
+
+/********************************************************/
+/*              Orchid Register Set                     */
+/********************************************************/
+#define ORC_GINTS      0xA0    /* Global Interrupt Status        */
+#define QINT           0x04    /* Reply Queue Interrupt  */
+#define ORC_GIMSK      0xA1    /* Global Interrupt MASK  */
+#define MQINT          0x04    /* Mask Reply Queue Interrupt     */
+#define        ORC_GCFG        0xA2    /* Global Configure               */
+#define EEPRG          0x01    /* Enable EEPROM programming */
+#define        ORC_GSTAT       0xA3    /* Global status          */
+#define WIDEBUS                0x10    /* Wide SCSI Devices connected    */
+#define ORC_HDATA      0xA4    /* Host Data                      */
+#define ORC_HCTRL      0xA5    /* Host Control                   */
+#define SCSIRST                0x80    /* SCSI bus reset         */
+#define HDO                    0x40    /* Host data out          */
+#define HOSTSTOP               0x02    /* Host stop RISC engine  */
+#define DEVRST         0x01    /* Device reset                   */
+#define ORC_HSTUS      0xA6    /* Host Status                    */
+#define HDI                    0x02    /* Host data in                   */
+#define RREADY         0x01    /* RISC engine is ready to receive */
+#define        ORC_NVRAM       0xA7    /* Nvram port address             */
+#define SE2CS          0x008
+#define SE2CLK         0x004
+#define SE2DO          0x002
+#define SE2DI          0x001
+#define ORC_PQUEUE     0xA8    /* Posting queue FIFO             */
+#define ORC_PQCNT      0xA9    /* Posting queue FIFO Cnt */
+#define ORC_RQUEUE     0xAA    /* Reply queue FIFO               */
+#define ORC_RQUEUECNT  0xAB    /* Reply queue FIFO Cnt           */
+#define        ORC_FWBASEADR   0xAC    /* Firmware base address  */
+
+#define        ORC_EBIOSADR0 0xB0      /* External Bios address */
+#define        ORC_EBIOSADR1 0xB1      /* External Bios address */
+#define        ORC_EBIOSADR2 0xB2      /* External Bios address */
+#define        ORC_EBIOSDATA 0xB3      /* External Bios address */
+
+#define        ORC_SCBSIZE     0xB7    /* SCB size register              */
+#define        ORC_SCBBASE0    0xB8    /* SCB base address 0             */
+#define        ORC_SCBBASE1    0xBC    /* SCB base address 1             */
+
+#define        ORC_RISCCTL     0xE0    /* RISC Control                   */
+#define PRGMRST                0x002
+#define DOWNLOAD               0x001
+#define        ORC_PRGMCTR0    0xE2    /* RISC program counter           */
+#define        ORC_PRGMCTR1    0xE3    /* RISC program counter           */
+#define        ORC_RISCRAM     0xEC    /* RISC RAM data port 4 bytes     */
+
+typedef struct orc_extended_scb {      /* Extended SCB                 */
+       ORC_SG ESCB_SGList[TOTAL_SG_ENTRY];     /*0 Start of SG list              */
+       Scsi_Cmnd *SCB_Srb;     /*50 SRB Pointer */
+} ESCB;
+
+/***********************************************************************
+               SCSI Control Block
+************************************************************************/
+typedef struct orc_scb {       /* Scsi_Ctrl_Blk                */
+       UBYTE SCB_Opcode;       /*00 SCB command code&residual  */
+       UBYTE SCB_Flags;        /*01 SCB Flags                  */
+       UBYTE SCB_Target;       /*02 Target Id                  */
+       UBYTE SCB_Lun;          /*03 Lun                        */
+       U32 SCB_Reserved0;      /*04 Reserved for ORCHID must 0 */
+       U32 SCB_XferLen;        /*08 Data Transfer Length       */
+       U32 SCB_Reserved1;      /*0C Reserved for ORCHID must 0 */
+       U32 SCB_SGLen;          /*10 SG list # * 8              */
+       U32 SCB_SGPAddr;        /*14 SG List Buf physical Addr  */
+       U32 SCB_SGPAddrHigh;    /*18 SG Buffer high physical Addr */
+       UBYTE SCB_HaStat;       /*1C Host Status                */
+       UBYTE SCB_TaStat;       /*1D Target Status              */
+       UBYTE SCB_Status;       /*1E SCB status                 */
+       UBYTE SCB_Link;         /*1F Link pointer, default 0xFF */
+       UBYTE SCB_SenseLen;     /*20 Sense Allocation Length    */
+       UBYTE SCB_CDBLen;       /*21 CDB Length                 */
+       UBYTE SCB_Ident;        /*22 Identify                   */
+       UBYTE SCB_TagMsg;       /*23 Tag Message                */
+       UBYTE SCB_CDB[IMAX_CDB];        /*24 SCSI CDBs                  */
+       UBYTE SCB_ScbIdx;       /*3C Index for this ORCSCB      */
+       U32 SCB_SensePAddr;     /*34 Sense Buffer physical Addr */
+
+       ESCB *SCB_EScb;         /*38 Extended SCB Pointer       */
+#ifndef ALPHA
+       UBYTE SCB_Reserved2[4]; /*3E Reserved for Driver use    */
+#endif
+} ORC_SCB;
+
+/* Opcodes of ORCSCB_Opcode */
+#define ORC_EXECSCSI   0x00    /* SCSI initiator command with residual */
+#define ORC_BUSDEVRST  0x01    /* SCSI Bus Device Reset  */
+
+/* Status of ORCSCB_Status */
+#define SCB_COMPLETE   0x00    /* SCB request completed  */
+#define SCB_POST       0x01    /* SCB is posted by the HOST      */
+
+/* Bit Definition for ORCSCB_Flags */
+#define SCF_DISINT     0x01    /* Disable HOST interrupt */
+#define SCF_DIR                0x18    /* Direction bits         */
+#define SCF_NO_DCHK    0x00    /* Direction determined by SCSI   */
+#define SCF_DIN                0x08    /* From Target to Initiator       */
+#define SCF_DOUT       0x10    /* From Initiator to Target       */
+#define SCF_NO_XF      0x18    /* No data transfer               */
+#define SCF_POLL   0x40
+
+/* Error Codes for ORCSCB_HaStat */
+#define HOST_SEL_TOUT  0x11
+#define HOST_DO_DU     0x12
+#define HOST_BUS_FREE  0x13
+#define HOST_BAD_PHAS  0x14
+#define HOST_INV_CMD   0x16
+#define HOST_SCSI_RST  0x1B
+#define HOST_DEV_RST   0x1C
+
+
+/* Error Codes for ORCSCB_TaStat */
+#define TARGET_CHK_COND        0x02
+#define TARGET_BUSY    0x08
+#define TARGET_TAG_FULL        0x28
+
+
+/* Queue tag msg: Simple_quque_tag, Head_of_queue_tag, Ordered_queue_tag */
+#define MSG_STAG       0x20
+#define MSG_HTAG       0x21
+#define MSG_OTAG       0x22
+
+#define MSG_IGNOREWIDE 0x23
+
+#define MSG_IDENT      0x80
+#define MSG_DISC       0x40    /* Disconnect allowed             */
+
+
+/* SCSI MESSAGE */
+#define        MSG_EXTEND      0x01
+#define        MSG_SDP         0x02
+#define        MSG_ABORT       0x06
+#define        MSG_REJ         0x07
+#define        MSG_NOP         0x08
+#define        MSG_PARITY      0x09
+#define        MSG_DEVRST      0x0C
+#define        MSG_STAG        0x20
+
+/***********************************************************************
+               Target Device Control Structure
+**********************************************************************/
+
+typedef struct ORC_Tar_Ctrl_Struc {
+       UBYTE TCS_DrvDASD;      /* 6 */
+       UBYTE TCS_DrvSCSI;      /* 7 */
+       UBYTE TCS_DrvHead;      /* 8 */
+       UWORD TCS_DrvFlags;     /* 4 */
+       UBYTE TCS_DrvSector;    /* 7 */
+} ORC_TCS, *PORC_TCS;
+
+/* Bit Definition for TCF_DrvFlags */
+#define        TCS_DF_NODASD_SUPT      0x20    /* Suppress OS/2 DASD Mgr support */
+#define        TCS_DF_NOSCSI_SUPT      0x40    /* Suppress OS/2 SCSI Mgr support */
+
+
+/***********************************************************************
+              Host Adapter Control Structure
+************************************************************************/
+typedef struct ORC_Ha_Ctrl_Struc {
+       USHORT HCS_Base;        /* 00 */
+       UBYTE HCS_Index;        /* 02 */
+       UBYTE HCS_Intr;         /* 04 */
+       UBYTE HCS_SCSI_ID;      /* 06    H/A SCSI ID */
+       UBYTE HCS_BIOS;         /* 07    BIOS configuration */
+
+       UBYTE HCS_Flags;        /* 0B */
+       UBYTE HCS_HAConfig1;    /* 1B    SCSI0MAXTags */
+       UBYTE HCS_MaxTar;       /* 1B    SCSI0MAXTags */
+
+       USHORT HCS_Units;       /* Number of units this adapter  */
+       USHORT HCS_AFlags;      /* Adapter info. defined flags   */
+       ULONG HCS_Timeout;      /* Adapter timeout value   */
+       PVOID HCS_virScbArray;  /* 28 Virtual Pointer to SCB array     */
+       U32 HCS_physScbArray;   /* Scb Physical address */
+       PVOID HCS_virEscbArray; /* Virtual pointer to ESCB Scatter list */
+       U32 HCS_physEscbArray;  /* scatter list Physical address */
+       UBYTE TargetFlag[16];   /* 30  target configuration, TCF_EN_TAG */
+       UBYTE MaximumTags[16];  /* 40  ORC_MAX_SCBS */
+       UBYTE ActiveTags[16][16];       /* 50 */
+       ORC_TCS HCS_Tcs[16];    /* 28 */
+       U32 BitAllocFlag[MAX_CHANNELS][8];      /* Max STB is 256, So 256/32 */
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95)
+       spinlock_t BitAllocFlagLock;
+#endif
+       Scsi_Cmnd *pSRB_head;
+       Scsi_Cmnd *pSRB_tail;
+#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95)
+       spinlock_t pSRB_lock;
+#endif
+} ORC_HCS;
+
+/* Bit Definition for HCS_Flags */
+
+#define HCF_SCSI_RESET 0x01    /* SCSI BUS RESET         */
+#define HCF_PARITY     0x02    /* parity card                    */
+#define HCF_LVDS       0x10    /* parity card                    */
+
+/* Bit Definition for TargetFlag */
+
+#define TCF_EN_255         0x08
+#define TCF_EN_TAG         0x10
+#define TCF_BUSY             0x20
+#define TCF_DISCONNECT 0x40
+#define TCF_SPIN_UP      0x80
+
+/* Bit Definition for HCS_AFlags */
+#define        HCS_AF_IGNORE           0x01    /* Adapter ignore         */
+#define        HCS_AF_DISABLE_RESET    0x10    /* Adapter disable reset  */
+#define        HCS_AF_DISABLE_ADPT     0x80    /* Adapter disable                */
+
+
+/*---------------------------------------*/
+/* TimeOut for RESET to complete (30s)   */
+/*                                       */
+/* After a RESET the drive is checked    */
+/* every 200ms.                          */
+/*---------------------------------------*/
+#define DELAYED_RESET_MAX       (30*1000L)
+#define DELAYED_RESET_INTERVAL  200L
+
+/*----------------------------------------------*/
+/* TimeOut for IRQ from last interrupt (5s)     */
+/*----------------------------------------------*/
+#define IRQ_TIMEOUT_INTERVAL    (5*1000L)
+
+/*----------------------------------------------*/
+/* Retry Delay interval (200ms)                 */
+/*----------------------------------------------*/
+#define DELAYED_RETRY_INTERVAL  200L
+
+#define        INQUIRY_SIZE            36
+#define        CAPACITY_SIZE           8
+#define        DEFAULT_SENSE_LEN       14
+
+#define        DEVICE_NOT_FOUND        0x86
+
+/*----------------------------------------------*/
+/* Definition for PCI device                    */
+/*----------------------------------------------*/
+#define        MAX_PCI_DEVICES 21
+#define        MAX_PCI_BUSES   8
index 13882a253af7d68248c45ccce2ecc8282075d3c1..c6d9a4f0e0d3a8eb1b8fb27f1624005e87c4df84 100644 (file)
@@ -1,24 +1,27 @@
 /*===================================================================
  *
  *                    Linux MegaRAID device driver
- * 
+ *
  * Copyright 1998 American Megatrends Inc.
  *
- *             This program is free software; you can redistribute it and/or
- *             modify it under the terms of the GNU General Public License
- *             as published by the Free Software Foundation; either version
- *             2 of the License, or (at your option) any later version.
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
  *
- * Version : 0.92
+ * Version : 0.96
  * 
  * Description: Linux device driver for AMI MegaRAID controller
  *
+ * Supported controllers: MegaRAID 418, 428, 438, 466, 762
+ * 
+ * Maintainer: Jeff L Jones <jeffreyj@ami.com>
+ *
  * History:
  *
  * Version 0.90:
- *     Works and has been tested with the MegaRAID 428 controller, and
- *     the MegaRAID 438 controller.  Probably works with the 466 also,
- *     but not tested.
+ *     Original source contributed by Dell; integrated it into the kernel and
+ *     cleaned up some things.  Added support for 438/466 controllers.
  *
  * Version 0.91:
  *     Aligned mailbox area on 16-byte boundry.
  *     Removed setting of SA_INTERRUPT flag when requesting Irq.
  *
  * Version 0.92ac:
- *     Small changes to the comments/formatting. Plus a couple of
- *     added notes. Returned to the authors. No actual code changes
- *     save printk levels.
- *     8 Oct 98        Alan Cox <alan.cox@linux.org>
+ *      Small changes to the comments/formatting. Plus a couple of
+ *      added notes. Returned to the authors. No actual code changes
+ *      save printk levels.
+ *      8 Oct 98        Alan Cox <alan.cox@linux.org>
  *
  *     Merged with 2.1.131 source tree.
- *     12 Dec 98       K. Baranowski <kgb@knm.org.pl>
+ *     12 Dec 98       K. Baranowski <kgb@knm.org.pl>                          
+ *
+ * Version 0.93:
+ *     Added support for vendor specific ioctl commands (0x80+xxh)
+ *     Changed some fields in MEGARAID struct to better values.
+ *     Added signature check for Rp controllers under 2.0 kernels
+ *     Changed busy-wait loop to be time-based
+ *     Fixed SMP race condition in isr
+ *     Added kfree (sgList) on release
+ *     Added #include linux/version.h to megaraid.h for hosts.h
+ *     Changed max_id to represent max logical drives instead of targets.
+ *
+ * Version 0.94:
+ *     Got rid of some excess locking/unlocking
+ *     Fixed slight memory corruption problem while memcpy'ing into mailbox
+ *     Changed logical drives to be reported as luns rather than targets
+ *     Changed max_id to 16 since it is now max targets/chan again.
+ *     Improved ioctl interface for upcoming megamgr
+ *
+ * Version 0.95:
+ *     Fixed problem of queueing multiple commands to adapter;
+ *       still has some strange problems on some setups, so still
+ *       defaults to single.  To enable parallel commands change
+ *       #define MULTI_IO in megaraid.h
+ *     Changed kmalloc allocation to be done in beginning.
+ *     Got rid of C++ style comments
+ *
+ * Version 0.96:
+ *     762 fully supported.
  *
  * BUGS:
- *     Tested with 2.1.90, but unfortunately there is a bug in pci.c which
- *     fails to detect our controller.  Does work with 2.1.118--don't know
- *     which kernel in between it was fixed in.
- *     With SMP enabled under 2.1.118 with more than one processor, gets an
- *     error message "scsi_end_request: buffer-list destroyed" under heavy
- *     IO, but doesn't seem to affect operation, or data integrity.  The
- *     message doesn't occur without SMP enabled, or with one proccessor with
- *     SMP enabled, or under any combination under 2.0 kernels.
+ *     Some older 2.1 kernels (eg. 2.1.90) have a bug in pci.c that
+ *     fails to detect the controller as a pci device on the system.
  *
  *===================================================================*/
-#define QISR 1
 
 #define CRLFSTR "\n"
 
-#define MULTIQ 1
-
+#include <linux/config.h>
 #include <linux/version.h>
 
 #ifdef MODULE
 #if LINUX_VERSION_CODE >= 0x20100
 char kernel_version[] = UTS_RELEASE;
 
-/* originally ported by Dell Corporation; updated, released, and maintained by
-   American Megatrends */
-MODULE_AUTHOR("American Megatrends Inc."); 
-MODULE_DESCRIPTION("AMI MegaRAID driver");    
+MODULE_AUTHOR ("American Megatrends Inc.");
+MODULE_DESCRIPTION ("AMI MegaRAID driver");
 #endif
 #endif
 
@@ -93,6 +114,7 @@ MODULE_DESCRIPTION("AMI MegaRAID driver");
 #include <linux/sched.h>
 #include <linux/stat.h>
 #include <linux/malloc.h>      /* for kmalloc() */
+#include <linux/config.h>      /* for CONFIG_PCI */
 #if LINUX_VERSION_CODE < 0x20100
 #include <linux/bios32.h>
 #else
@@ -112,14 +134,18 @@ MODULE_DESCRIPTION("AMI MegaRAID driver");
  *
  *                          #Defines
  *
- *================================================================*/
+ *================================================================
+ */
 
 #if LINUX_VERSION_CODE < 0x020100
 #define ioremap vremap
 #define iounmap vfree
 
 /* simulate spin locks */
-typedef struct {volatile char lock;} spinlock_t;
+typedef struct {
+  volatile char lock;
+} spinlock_t;
+
 #define spin_lock_init(x) { (x)->lock = 0;}
 #define spin_lock_irqsave(x,flags) { while ((x)->lock) barrier();\
                                         (x)->lock=1; save_flags(flags);\
@@ -143,7 +169,15 @@ typedef struct {volatile char lock;} spinlock_t;
   (*node) = obj; \
   (*node)->##next = NULL; \
   spin_unlock_irqrestore(&mega_lock,cpuflag);\
-};
+}
+
+/* a non-locking version (if we already have the lock) */
+#define ENQUEUE_NL(obj,type,list,next) \
+{ type **node; \
+  for(node=&(list); *node; node=(type **)&(*node)->##next); \
+  (*node) = obj; \
+  (*node)->##next = NULL; \
+}
 
 #define DEQUEUE(obj,type,list,next) \
 { long cpuflag; \
@@ -154,125 +188,124 @@ typedef struct {volatile char lock;} spinlock_t;
   spin_unlock_irqrestore(&mega_lock,cpuflag);\
 };
 
-u_long RDINDOOR(mega_host_config *megaCfg)
+u_long RDINDOOR (mega_host_config * megaCfg)
 {
-  return readl(megaCfg->base + 0x20);
+  return readl (megaCfg->base + 0x20);
 }
 
-void WRINDOOR(mega_host_config *megaCfg, u_long value)
+void WRINDOOR (mega_host_config * megaCfg, u_long value)
 {
-  writel(value,megaCfg->base+0x20);
+  writel (value, megaCfg->base + 0x20);
 }
 
-u_long RDOUTDOOR(mega_host_config *megaCfg)
+u_long RDOUTDOOR (mega_host_config * megaCfg)
 {
-  return readl(megaCfg->base+0x2C);
+  return readl (megaCfg->base + 0x2C);
 }
 
-void WROUTDOOR(mega_host_config *megaCfg, u_long value)
+void WROUTDOOR (mega_host_config * megaCfg, u_long value)
 {
-  writel(value,megaCfg->base+0x2C);
+  writel (value, megaCfg->base + 0x2C);
 }
 
 /*================================================================
  *
  *                    Function prototypes
  *
- *================================================================*/
-static int  MegaIssueCmd(mega_host_config *megaCfg,
-                        u_char *mboxData,
-                        mega_scb *scb,
+ *================================================================
+ */
+static int MegaIssueCmd (mega_host_config * megaCfg,
+                        u_char * mboxData,
+                        mega_scb * scb,
                         int intr);
-static int  build_sglist(mega_host_config *megaCfg, mega_scb *scb, 
-                        u_long *buffer, u_long *length);
+static int build_sglist (mega_host_config * megaCfg, mega_scb * scb,
+                        u_long * buffer, u_long * length);
 
-static void mega_runque(void *);
-static void mega_rundoneq(void);
-static void mega_cmd_done(mega_host_config *,mega_scb *, int);
+static void mega_runque (void *);
+static void mega_rundoneq (void);
+static void mega_cmd_done (mega_host_config *, mega_scb *, int);
+static mega_scb *mega_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt);
+static inline void freeSgList(mega_host_config *megaCfg);
 
 /* set SERDEBUG to 1 to enable serial debugging */
 #define SERDEBUG 0
 #if SERDEBUG
-static void ser_init(void);
-static void ser_puts(char *str);
-static void ser_putc(char c);
-static int  ser_printk(const char *fmt, ...);
+static void ser_init (void);
+static void ser_puts (char *str);
+static void ser_putc (char c);
+static int ser_printk (const char *fmt,...);
 #endif
 
 /*================================================================
  *
  *                    Global variables
  *
- *================================================================*/
-static int               numCtlrs = 0;
-static mega_host_config *megaCtlrs[4] = { 0 };
-
-/* Change this to 0 if you want to see the raw drives */
-static int use_raid   = 1;
+ *================================================================
+ */
+static int numCtlrs = 0;
+static mega_host_config *megaCtlrs[12] = {0};
 
 /* Queue of pending/completed SCBs */
-static mega_scb  *qPending   = NULL;
+static mega_scb *qPending = NULL;
 static Scsi_Cmnd *qCompleted = NULL;
 
 volatile static spinlock_t mega_lock;
-static struct tq_struct runq = {0,0,mega_runque,NULL};
+static struct tq_struct runq = {0, 0, mega_runque, NULL};
 
-struct proc_dir_entry proc_scsi_megaraid = {
+struct proc_dir_entry proc_scsi_megaraid =
+{
   PROC_SCSI_MEGARAID, 8, "megaraid",
   S_IFDIR | S_IRUGO | S_IXUGO, 2
 };
 
 #if SERDEBUG
-static char strbuf[MAX_SERBUF+1];
+static char strbuf[MAX_SERBUF + 1];
 
-static void ser_init()
+static void ser_init ()
 {
-    unsigned port=COM_BASE;
-
-    outb(0x80,port+3);
-    outb(0,port+1);
-    /* 9600 Baud, if 19200: outb(6,port) */
-    outb(12, port);
-    outb(3,port+3);
-    outb(0,port+1);
+  unsigned port = COM_BASE;
+
+  outb (0x80, port + 3);
+  outb (0, port + 1);
+  /* 9600 Baud, if 19200: outb(6,port) */
+  outb (12, port);
+  outb (3, port + 3);
+  outb (0, port + 1);
 }
 
-static void ser_puts(char *str)
+static void ser_puts (char *str)
 {
-    char *ptr;
+  char *ptr;
 
-    ser_init();
-    for (ptr=str;*ptr;++ptr)
-        ser_putc(*ptr);
+  ser_init ();
+  for (ptr = str; *ptr; ++ptr)
+    ser_putc (*ptr);
 }
 
-static void ser_putc(char c)
+static void ser_putc (char c)
 {
-    unsigned port=COM_BASE;
-
-    while ((inb(port+5) & 0x20)==0);
-    outb(c,port);
-    if (c==0x0a)
-    {
-        while ((inb(port+5) & 0x20)==0);
-        outb(0x0d,port);
-    }
+  unsigned port = COM_BASE;
+
+  while ((inb (port + 5) & 0x20) == 0);
+  outb (c, port);
+  if (c == 0x0a) {
+    while ((inb (port + 5) & 0x20) == 0);
+    outb (0x0d, port);
+  }
 }
 
-static int ser_printk(const char *fmt, ...)
+static int ser_printk (const char *fmt,...)
 {
-    va_list args;
-    int i;
-    long flags;
-
-    spin_lock_irqsave(mega_lock,flags);
-    va_start(args,fmt);
-    i = vsprintf(strbuf,fmt,args);
-    ser_puts(strbuf);
-    va_end(args);
-    spin_unlock_irqrestore(&mega_lock,flags);
+  va_list args;
+  int i;
+  long flags;
+
+  va_start (args, fmt);
+  i = vsprintf (strbuf, fmt, args);
+  ser_puts (strbuf);
+  va_end (args);
 
-    return i;
+  return i;
 }
 
 #define TRACE(a)    { ser_printk a;}
@@ -281,14 +314,14 @@ static int ser_printk(const char *fmt, ...)
 #define TRACE(A)
 #endif
 
-void callDone(Scsi_Cmnd *SCpnt)
+void callDone (Scsi_Cmnd * SCpnt)
 {
   if (SCpnt->result) {
-    TRACE(("*** %.08lx %.02x <%d.%d.%d> = %x\n", SCpnt->serial_number, 
-          SCpnt->cmnd[0], SCpnt->channel, SCpnt->target, SCpnt->lun, 
-          SCpnt->result));
+    TRACE (("*** %.08lx %.02x <%d.%d.%d> = %x\n", SCpnt->serial_number,
+           SCpnt->cmnd[0], SCpnt->channel, SCpnt->target, SCpnt->lun,
+           SCpnt->result));
   }
-  SCpnt->scsi_done(SCpnt);
+  SCpnt->scsi_done (SCpnt);
 }
 
 /*-------------------------------------------------------------------------
@@ -299,96 +332,95 @@ void callDone(Scsi_Cmnd *SCpnt)
 
 /*================================================
  * Initialize SCB structures
- *================================================*/
-static void initSCB(mega_host_config *megaCfg)
+ *================================================
+ */
+static int initSCB (mega_host_config * megaCfg)
 {
   int idx;
 
-  for(idx=0; idx<megaCfg->max_cmds; idx++) {
-    megaCfg->scbList[idx].idx    = -1;
-    megaCfg->scbList[idx].flag   = 0;
-    megaCfg->scbList[idx].sgList = NULL;
-    megaCfg->scbList[idx].SCpnt  = NULL;
+  for (idx = 0; idx < megaCfg->max_cmds; idx++) {
+    megaCfg->scbList[idx].idx = -1;
+    megaCfg->scbList[idx].flag = 0;
+    megaCfg->scbList[idx].sgList = kmalloc(sizeof(mega_sglist) * MAX_SGLIST,
+                               GFP_ATOMIC | GFP_DMA);
+    if (megaCfg->scbList[idx].sgList == NULL) {
+        printk(KERN_WARNING "Can't allocate sglist for id %d\n",idx);
+        freeSgList(megaCfg);
+        return -1;
+    }
+    megaCfg->scbList[idx].SCpnt = NULL;
   }
+  return 0;
 }
 
 /*===========================
  * Allocate a SCB structure
- *===========================*/
-static mega_scb *allocateSCB(mega_host_config *megaCfg,Scsi_Cmnd *SCpnt)
+ *===========================
+ */
+static mega_scb * allocateSCB (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
 {
-  int        idx;
-  long       flags;
+  int idx;
+  long flags;
 
-  spin_lock_irqsave(&mega_lock,flags);
-  for(idx=0; idx<megaCfg->max_cmds; idx++) {
+  spin_lock_irqsave (&mega_lock, flags);
+  for (idx = 0; idx < megaCfg->max_cmds; idx++) {
     if (megaCfg->scbList[idx].idx < 0) {
 
-      /* Set Index and SCB pointer */ 
-      megaCfg->scbList[idx].flag  = 0;
-      megaCfg->scbList[idx].idx   = idx;
+      /* Set Index and SCB pointer */
+      megaCfg->scbList[idx].idx = idx;
+      spin_unlock_irqrestore (&mega_lock, flags);
+      megaCfg->scbList[idx].flag = 0;
       megaCfg->scbList[idx].SCpnt = SCpnt;
-      megaCfg->scbList[idx].next  = NULL;
-      spin_unlock_irqrestore(&mega_lock,flags);
-
-      if (megaCfg->scbList[idx].sgList == NULL) {
-       megaCfg->scbList[idx].sgList =
-                  kmalloc(sizeof(mega_sglist)*MAX_SGLIST,GFP_ATOMIC|GFP_DMA);
-      }
+      megaCfg->scbList[idx].next = NULL;
 
       return &megaCfg->scbList[idx];
     }
   }
-  spin_unlock_irqrestore(&mega_lock,flags);
+  spin_unlock_irqrestore (&mega_lock, flags);
+
+  printk (KERN_WARNING "Megaraid: Could not allocate free SCB!!!\n");
 
-  printk(KERN_WARNING "Megaraid: Could not allocate free SCB!!!\n");
-  
   return NULL;
 }
 
 /*=======================
  * Free a SCB structure
- *=======================*/
-static void freeSCB(mega_scb *scb)
+ *=======================
+ */
+static void freeSCB (mega_scb * scb)
 {
-  long flags;
-
-  spin_lock_irqsave(&mega_lock,flags);
-  scb->flag  = 0;
-  scb->idx   = -1;
-  scb->next  = NULL;
+  scb->flag = 0;
+  scb->next = NULL;
   scb->SCpnt = NULL;
-  spin_unlock_irqrestore(&mega_lock,flags);
+    scb->idx = -1;
 }
 
 /* Run through the list of completed requests */
-static void mega_rundoneq()
+static void mega_rundoneq ()
 {
   mega_host_config *megaCfg;
-  Scsi_Cmnd        *SCpnt;
-  long              islogical;
+  Scsi_Cmnd *SCpnt;
+  char islogical;
 
-  while(1) {
-    DEQUEUE(SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
-    if (SCpnt == NULL) return;
+  while (1) {
+    DEQUEUE (SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
+    if (SCpnt == NULL)
+      return;
 
-    megaCfg = (mega_host_config *)SCpnt->host->hostdata;
+    megaCfg = (mega_host_config *) SCpnt->host->hostdata;
 
-    /* Check if we're allowing access to RAID drives or physical
-     *  if use_raid == 1 and this wasn't a disk on the max channel or
-     *  if use_raid == 0 and this was a disk on the max channel
-     *  then fail.
-     */
-    islogical = (SCpnt->channel == megaCfg->host->max_channel) ? 1 : 0;
+    islogical = (SCpnt->channel == megaCfg->host->max_channel &&
+                 SCpnt->target == 0);
     if (SCpnt->cmnd[0] == INQUIRY &&
-       ((((u_char*)SCpnt->request_buffer)[0] & 0x1F) == TYPE_DISK) &&
-       (islogical != use_raid)) {
-       SCpnt->result = 0xF0;
+       ((((u_char *) SCpnt->request_buffer)[0] & 0x1F) == TYPE_DISK) &&
+       !islogical) {
+      SCpnt->result = 0xF0;
     }
 
     /* Convert result to error */
-    switch(SCpnt->result) {
-    case 0x00: case 0x02:
+    switch (SCpnt->result) {
+    case 0x00:
+    case 0x02:
       SCpnt->result |= (DID_OK << 16);
       break;
     case 0x8:
@@ -400,16 +432,16 @@ static void mega_rundoneq()
     }
 
     /* Callback */
-    callDone(SCpnt);
+    callDone (SCpnt);
   }
 }
 
 /* Add command to the list of completed requests */
-static void mega_cmd_done(mega_host_config *megaCfg,mega_scb *pScb, int status)
+static void mega_cmd_done (mega_host_config * megaCfg, mega_scb * pScb, int status)
 {
   pScb->SCpnt->result = status;
-  ENQUEUE(pScb->SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
-  freeSCB(pScb);
+  ENQUEUE (pScb->SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
+  freeSCB (pScb);
 }
 
 /*----------------------------------------------------
@@ -417,42 +449,45 @@ static void mega_cmd_done(mega_host_config *megaCfg,mega_scb *pScb, int status)
  *
  * Run as a scheduled task 
  *----------------------------------------------------*/
-static void mega_runque(void *dummy)
+static void mega_runque (void *dummy)
 {
   mega_host_config *megaCfg;
-  mega_scb         *pScb;
-  long              flags;
+  mega_scb *pScb;
+  long flags;
 
   /* Take care of any completed requests */
-  mega_rundoneq();
+  mega_rundoneq ();
 
-  DEQUEUE(pScb,mega_scb,qPending,next);
+  DEQUEUE (pScb, mega_scb, qPending, next);
 
   if (pScb) {
-    megaCfg = (mega_host_config *)pScb->SCpnt->host->hostdata;
-
-    if (megaCfg->mbox->busy || megaCfg->flag & (IN_ISR|PENDING)) {
-      TRACE(("%.08lx %.02x <%d.%d.%d> intr%d busy%d isr%d pending%d\n",
-            pScb->SCpnt->serial_number,
-            pScb->SCpnt->cmnd[0],
-            pScb->SCpnt->channel,
-            pScb->SCpnt->target,
-            pScb->SCpnt->lun,
-            intr_count,
-            megaCfg->mbox->busy,
-            (megaCfg->flag & IN_ISR)  ? 1 : 0,
-            (megaCfg->flag & PENDING) ? 1 : 0));
+    if (pScb->SCpnt) {
+        TRACE(("NULL SCpnt for idx %d!\n",pScb->idx));
+    }
+    megaCfg = (mega_host_config *) pScb->SCpnt->host->hostdata;
+
+    if (megaCfg->mbox->busy || megaCfg->flag & (IN_ISR | PENDING)) {
+      TRACE (("%.08lx %.02x <%d.%d.%d> busy%d isr%d pending%d\n",
+             pScb->SCpnt->serial_number,
+             pScb->SCpnt->cmnd[0],
+             pScb->SCpnt->channel,
+             pScb->SCpnt->target,
+             pScb->SCpnt->lun,
+             megaCfg->mbox->busy,
+             (megaCfg->flag & IN_ISR) ? 1 : 0,
+             (megaCfg->flag & PENDING) ? 1 : 0));
     }
 
-    if (MegaIssueCmd(megaCfg, pScb->mboxData, pScb, 1)) {
+    if (MegaIssueCmd (megaCfg, pScb->mboxData, pScb, 1)) {
       /* We're BUSY... come back later */
-      spin_lock_irqsave(&mega_lock,flags);
+      spin_lock_irqsave (&mega_lock, flags);
       pScb->next = qPending;
-      qPending   = pScb;
-      spin_unlock_irqrestore(&mega_lock,flags);
+      qPending = pScb;
+      spin_unlock_irqrestore (&mega_lock, flags);
 
-      if (!(megaCfg->flag & PENDING)) { /* If PENDING, irq will schedule task */
-          queue_task(&runq, &tq_scheduler);
+      if (!(megaCfg->flag & PENDING)) {
+       /* If PENDING, irq will schedule task */
+       queue_task (&runq, &tq_scheduler);
       }
     }
   }
@@ -466,17 +501,22 @@ static void mega_runque(void *dummy)
  * If NULL is returned, the scsi_done function MUST have been called
  *
  *-------------------------------------------------------------------*/
-static mega_scb *mega_build_cmd(mega_host_config *megaCfg, Scsi_Cmnd *SCpnt)
+static mega_scb * mega_build_cmd (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
 {
-  mega_scb      *pScb;
-  mega_mailbox  *mbox;
+  mega_scb *pScb;
+  mega_mailbox *mbox;
   mega_passthru *pthru;
-  long           seg;
+  long seg;
+  char islogical;
+
+  if (SCpnt->cmnd[0] & 0x80)   /* ioctl from megamgr */
+    return mega_ioctl (megaCfg, SCpnt);
 
-  /* We don't support multi-luns */
-  if (SCpnt->lun != 0) {
+  islogical = (SCpnt->channel == megaCfg->host->max_channel && SCpnt->target == 0);
+
+  if (!islogical && SCpnt->lun != 0) {
     SCpnt->result = (DID_BAD_TARGET << 16);
-    callDone(SCpnt);
+    callDone (SCpnt);
     return NULL;
   }
 
@@ -485,45 +525,46 @@ static mega_scb *mega_build_cmd(mega_host_config *megaCfg, Scsi_Cmnd *SCpnt)
    *               Logical drive commands
    *
    *-----------------------------------------------------*/
-  if (SCpnt->channel == megaCfg->host->max_channel) {
-    switch(SCpnt->cmnd[0]) {
+  if (islogical) {
+    switch (SCpnt->cmnd[0]) {
     case TEST_UNIT_READY:
-      memset(SCpnt->request_buffer, 0, SCpnt->request_bufflen);
+      memset (SCpnt->request_buffer, 0, SCpnt->request_bufflen);
       SCpnt->result = (DID_OK << 16);
-      callDone(SCpnt);
+      callDone (SCpnt);
       return NULL;
 
     case MODE_SENSE:
-      memset(SCpnt->request_buffer, 0, SCpnt->cmnd[4]);
+      memset (SCpnt->request_buffer, 0, SCpnt->cmnd[4]);
       SCpnt->result = (DID_OK << 16);
-      callDone(SCpnt);
+      callDone (SCpnt);
       return NULL;
 
     case READ_CAPACITY:
     case INQUIRY:
       /* Allocate a SCB and initialize passthru */
-      if ((pScb = allocateSCB(megaCfg,SCpnt)) == NULL) {
+      if ((pScb = allocateSCB (megaCfg, SCpnt)) == NULL) {
        SCpnt->result = (DID_ERROR << 16);
-       callDone(SCpnt);
+       callDone (SCpnt);
        return NULL;
       }
       pthru = &pScb->pthru;
-      mbox  = (mega_mailbox *)&pScb->mboxData;
-
-      memset(mbox,  0, sizeof(pScb->mboxData));
-      memset(pthru, 0, sizeof(mega_passthru));
-      pthru->timeout      = 0;
-      pthru->ars          = 0;
-      pthru->islogical    = 1;
-      pthru->logdrv       = SCpnt->target;
-      pthru->cdblen       = SCpnt->cmd_len;
-      pthru->dataxferaddr = virt_to_bus(SCpnt->request_buffer);
-      pthru->dataxferlen  = SCpnt->request_bufflen;
-      memcpy(pthru->cdb, SCpnt->cmnd, SCpnt->cmd_len);
+      mbox = (mega_mailbox *) & pScb->mboxData;
+
+      memset (mbox, 0, sizeof (pScb->mboxData));
+      memset (pthru, 0, sizeof (mega_passthru));
+      pthru->timeout = 0;
+      pthru->ars = 1;
+      pthru->reqsenselen = 14;
+      pthru->islogical = 1;
+      pthru->logdrv = SCpnt->lun;
+      pthru->cdblen = SCpnt->cmd_len;
+      pthru->dataxferaddr = virt_to_bus (SCpnt->request_buffer);
+      pthru->dataxferlen = SCpnt->request_bufflen;
+      memcpy (pthru->cdb, SCpnt->cmnd, SCpnt->cmd_len);
 
       /* Initialize mailbox area */
-      mbox->cmd      = MEGA_MBOXCMD_PASSTHRU;
-      mbox->xferaddr = virt_to_bus(pthru);
+      mbox->cmd = MEGA_MBOXCMD_PASSTHRU;
+      mbox->xferaddr = virt_to_bus (pthru);
 
       return pScb;
 
@@ -532,51 +573,51 @@ static mega_scb *mega_build_cmd(mega_host_config *megaCfg, Scsi_Cmnd *SCpnt)
     case READ_10:
     case WRITE_10:
       /* Allocate a SCB and initialize mailbox */
-      if ((pScb = allocateSCB(megaCfg,SCpnt)) == NULL) {
+      if ((pScb = allocateSCB (megaCfg, SCpnt)) == NULL) {
        SCpnt->result = (DID_ERROR << 16);
-       callDone(SCpnt);
+       callDone (SCpnt);
        return NULL;
       }
-      mbox = (mega_mailbox *)&pScb->mboxData;
+      mbox = (mega_mailbox *) & pScb->mboxData;
 
-      memset(mbox, 0, sizeof(pScb->mboxData));
-      mbox->logdrv = SCpnt->target;
-      mbox->cmd    = (*SCpnt->cmnd == READ_6 || *SCpnt->cmnd == READ_10) ?
+      memset (mbox, 0, sizeof (pScb->mboxData));
+      mbox->logdrv = SCpnt->lun;
+      mbox->cmd = (*SCpnt->cmnd == READ_6 || *SCpnt->cmnd == READ_10) ?
        MEGA_MBOXCMD_LREAD : MEGA_MBOXCMD_LWRITE;
-      
+
       /* 6-byte */
       if (*SCpnt->cmnd == READ_6 || *SCpnt->cmnd == WRITE_6) {
-       mbox->numsectors = 
-         (u_long)SCpnt->cmnd[4];
-       mbox->lba = 
-         ((u_long)SCpnt->cmnd[1] << 16) |
-         ((u_long)SCpnt->cmnd[2] << 8) |
-         (u_long)SCpnt->cmnd[3];
+       mbox->numsectors =
+         (u_long) SCpnt->cmnd[4];
+       mbox->lba =
+         ((u_long) SCpnt->cmnd[1] << 16) |
+         ((u_long) SCpnt->cmnd[2] << 8) |
+         (u_long) SCpnt->cmnd[3];
        mbox->lba &= 0x1FFFFF;
       }
-      
+
       /* 10-byte */
       if (*SCpnt->cmnd == READ_10 || *SCpnt->cmnd == WRITE_10) {
-       mbox->numsectors = 
-         (u_long)SCpnt->cmnd[8] |
-         ((u_long)SCpnt->cmnd[7] << 8);
+       mbox->numsectors =
+         (u_long) SCpnt->cmnd[8] |
+         ((u_long) SCpnt->cmnd[7] << 8);
        mbox->lba =
-         ((u_long)SCpnt->cmnd[2] << 24) |
-         ((u_long)SCpnt->cmnd[3] << 16) |
-         ((u_long)SCpnt->cmnd[4] << 8) |
-         (u_long)SCpnt->cmnd[5];
+         ((u_long) SCpnt->cmnd[2] << 24) |
+         ((u_long) SCpnt->cmnd[3] << 16) |
+         ((u_long) SCpnt->cmnd[4] << 8) |
+         (u_long) SCpnt->cmnd[5];
       }
-      
+
       /* Calculate Scatter-Gather info */
-      mbox->numsgelements = build_sglist(megaCfg, pScb, 
-                                        (u_long*)&mbox->xferaddr,
-                                        (u_long*)&seg);
+      mbox->numsgelements = build_sglist (megaCfg, pScb,
+                                         (u_long *) & mbox->xferaddr,
+                                         (u_long *) & seg);
 
       return pScb;
-      
+
     default:
       SCpnt->result = (DID_BAD_TARGET << 16);
-      callDone(SCpnt);
+      callDone (SCpnt);
       return NULL;
     }
   }
@@ -587,120 +628,216 @@ static mega_scb *mega_build_cmd(mega_host_config *megaCfg, Scsi_Cmnd *SCpnt)
    *-----------------------------------------------------*/
   else {
     /* Allocate a SCB and initialize passthru */
-    if ((pScb = allocateSCB(megaCfg,SCpnt)) == NULL) {
+    if ((pScb = allocateSCB (megaCfg, SCpnt)) == NULL) {
       SCpnt->result = (DID_ERROR << 16);
-      callDone(SCpnt);
+      callDone (SCpnt);
       return NULL;
     }
     pthru = &pScb->pthru;
-    mbox  = (mega_mailbox *)pScb->mboxData;
-    
-    memset(mbox,  0, sizeof(pScb->mboxData));
-    memset(pthru, 0, sizeof(mega_passthru));
-    pthru->timeout   = 0;
-    pthru->ars       = 0;
+    mbox = (mega_mailbox *) pScb->mboxData;
+
+    memset (mbox, 0, sizeof (pScb->mboxData));
+    memset (pthru, 0, sizeof (mega_passthru));
+    pthru->timeout = 0;
+    pthru->ars = 1;
+    pthru->reqsenselen = 14;
     pthru->islogical = 0;
-    pthru->channel   = SCpnt->channel;
-    pthru->target    = SCpnt->target;
-    pthru->cdblen    = SCpnt->cmd_len;
-    memcpy(pthru->cdb, SCpnt->cmnd, SCpnt->cmd_len);
-   
-    pthru->numsgelements = build_sglist(megaCfg, pScb,
-                                       (u_long *)&pthru->dataxferaddr,
-                                       (u_long *)&pthru->dataxferlen);
-    
+    pthru->channel = SCpnt->channel;
+    pthru->target = SCpnt->target;
+    pthru->cdblen = SCpnt->cmd_len;
+    memcpy (pthru->cdb, SCpnt->cmnd, SCpnt->cmd_len);
+
+    pthru->numsgelements = build_sglist (megaCfg, pScb,
+                                        (u_long *) & pthru->dataxferaddr,
+                                        (u_long *) & pthru->dataxferlen);
+
     /* Initialize mailbox */
-    mbox->cmd      = MEGA_MBOXCMD_PASSTHRU;
-    mbox->xferaddr = virt_to_bus(pthru);
+    mbox->cmd = MEGA_MBOXCMD_PASSTHRU;
+    mbox->xferaddr = virt_to_bus (pthru);
 
     return pScb;
   }
   return NULL;
 }
 
+/*--------------------------------------------------------------------
+ * build RAID commands for controller, passed down through ioctl()
+ *--------------------------------------------------------------------*/
+static mega_scb * mega_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
+{
+  mega_scb *pScb;
+  mega_ioctl_mbox *mbox;
+  mega_mailbox *mailbox;
+  mega_passthru *pthru;
+  long seg;
+  unsigned char *data = (unsigned char *)SCpnt->request_buffer;
+  int i;
+
+  if ((pScb = allocateSCB (megaCfg, SCpnt)) == NULL) {
+    SCpnt->result = (DID_ERROR << 16);
+    callDone (SCpnt);
+    return NULL;
+  }
+
+#if 0
+  printk("\nBUF: ");
+  for (i=0;i<18;i++) {
+     printk(" %x",data[i]);
+  }
+  printk("......\n");
+#endif
+
+  mbox = (mega_ioctl_mbox *) & pScb->mboxData;
+  mailbox = (mega_mailbox *) & pScb->mboxData;
+  memset (mailbox, 0, sizeof (pScb->mboxData));
+
+  if (data[0] == 0x03) {       /* passthrough command */
+    unsigned char cdblen = data[2];
+
+    pthru = &pScb->pthru;
+    memset (pthru, 0, sizeof (mega_passthru));
+    pthru->islogical = (data[cdblen+3] & 0x80) ? 1:0;
+    pthru->timeout = data[cdblen+3] & 0x07;
+    pthru->reqsenselen = 14;
+    pthru->ars = (data[cdblen+3] & 0x08) ? 1:0;
+    pthru->logdrv = data[cdblen+4];
+    pthru->channel = data[cdblen+5];
+    pthru->target = data[cdblen+6];
+    pthru->cdblen = cdblen;
+    memcpy (pthru->cdb, &data[3], cdblen);
+
+    mailbox->cmd = MEGA_MBOXCMD_PASSTHRU;
+    mailbox->xferaddr = virt_to_bus (pthru);
+
+
+    pthru->numsgelements = build_sglist (megaCfg, pScb,
+                                        (u_long *) & pthru->dataxferaddr,
+                                        (u_long *) & pthru->dataxferlen);
+
+    for (i=0;i<(SCpnt->request_bufflen-cdblen-7);i++) {
+       data[i] = data[i+cdblen+7];
+    }
+
+    return pScb;
+  }
+  /* else normal (nonpassthru) command */
+
+  mbox->cmd = data[0];
+  mbox->channel = data[1];
+  mbox->param = data[2];
+  mbox->pad[0] = data[3];
+  mbox->logdrv = data[4];
+
+  mbox->numsgelements = build_sglist (megaCfg, pScb,
+                                     (u_long *) & mbox->xferaddr,
+                                     (u_long *) & seg);
+
+  for (i=0;i<(SCpnt->request_bufflen-6);i++) {
+     data[i] = data[i+6];
+  }
+
+  return (pScb);
+}
+
+
 /*--------------------------------------------------------------------
  * Interrupt service routine
  *--------------------------------------------------------------------*/
-static void megaraid_isr(int irq, void *devp, struct pt_regs *regs)
+static void megaraid_isr (int irq, void *devp, struct pt_regs *regs)
 {
-  mega_host_config *megaCfg;
-  u_char            byte, idx, sIdx;
-  u_long            dword;
-  mega_mailbox     *mbox;
-  mega_scb         *pScb;
-  long              flags;
-  int               qCnt, qStatus;
+  mega_host_config    *megaCfg;
+  u_char byte, idx, sIdx;
+  u_long dword;
+  mega_mailbox *mbox;
+  mega_scb *pScb;
+  long flags;
+  int qCnt, qStatus;
 
-  megaCfg = (mega_host_config *)devp;
-  mbox    = (mega_mailbox *)megaCfg->mbox;
+  megaCfg = (mega_host_config *) devp;
+  mbox = (mega_mailbox *) megaCfg->mbox;
 
   if (megaCfg->host->irq == irq) {
-    spin_lock_irqsave(&mega_lock,flags);
+
+#if LINUX_VERSION_CODE >= 0x20100
+    spin_lock_irqsave (&io_request_lock, flags);
+#endif
+
+    spin_lock_irqsave (&mega_lock, flags);
 
     if (megaCfg->flag & IN_ISR) {
-      TRACE(("ISR called reentrantly!!\n"));
+      TRACE (("ISR called reentrantly!!\n"));
     }
 
     megaCfg->flag |= IN_ISR;
 
     /* Check if a valid interrupt is pending */
     if (megaCfg->flag & BOARD_QUARTZ) {
-        dword = RDOUTDOOR(megaCfg);
-        if (dword != 0x10001234) {
-            /* Spurious interrupt */
-            megaCfg->flag &= ~IN_ISR;
-            spin_unlock_irqrestore(&mega_lock,flags);
-            return;
-        }
-        WROUTDOOR(megaCfg,dword);
-    } else {
-        byte = READ_PORT(megaCfg->host->io_port, INTR_PORT);
-        if ((byte & VALID_INTR_BYTE) == 0) {
-          /* Spurious interrupt */
-          megaCfg->flag &= ~IN_ISR;
-          spin_unlock_irqrestore(&mega_lock,flags);
-          return;
-        }
-        WRITE_PORT(megaCfg->host->io_port, INTR_PORT, byte);
+      dword = RDOUTDOOR (megaCfg);
+      if (dword != 0x10001234) {
+       /* Spurious interrupt */
+       megaCfg->flag &= ~IN_ISR;
+       spin_unlock_irqrestore (&mega_lock, flags);
+#if LINUX_VERSION_CODE >= 0x20100
+        spin_unlock_irqrestore (&io_request_lock, flags);
+#endif
+       return;
+      }
+      WROUTDOOR (megaCfg, dword);
+    }
+    else {
+      byte = READ_PORT (megaCfg->host->io_port, INTR_PORT);
+      if ((byte & VALID_INTR_BYTE) == 0) {
+       /* Spurious interrupt */
+       megaCfg->flag &= ~IN_ISR;
+       spin_unlock_irqrestore (&mega_lock, flags);
+#if LINUX_VERSION_CODE >= 0x20100
+        spin_unlock_irqrestore (&io_request_lock, flags);
+#endif
+       return;
+      }
+      WRITE_PORT (megaCfg->host->io_port, INTR_PORT, byte);
     }
-    
-    qCnt    = mbox->numstatus;
+
+    qCnt = mbox->numstatus;
     qStatus = mbox->status;
 
-    if (qCnt > 1) {TRACE(("ISR: Received %d status\n", qCnt))
-        printk(KERN_DEBUG "Got numstatus = %d\n",qCnt);
+    if (qCnt > 1) {
+      TRACE (("ISR: Received %d status\n", qCnt))
+       printk (KERN_DEBUG "Got numstatus = %d\n", qCnt);
     }
-    
-    for(idx=0; idx<qCnt; idx++) {
+
+    for (idx = 0; idx < qCnt; idx++) {
       sIdx = mbox->completed[idx];
       if (sIdx > 0) {
-       pScb = &megaCfg->scbList[sIdx-1];
-        spin_unlock_irqrestore(&mega_lock,flags); /* locks within cmd_done */
-       mega_cmd_done(megaCfg,&megaCfg->scbList[sIdx-1], qStatus);
-        spin_lock_irqsave(&mega_lock,flags);
+       pScb = &megaCfg->scbList[sIdx - 1];
+        /* FVF: let's try to avoid un/locking for no good reason */
+        pScb->SCpnt->result = qStatus;
+        ENQUEUE_NL (pScb->SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
+        freeSCB (pScb);
       }
     }
     if (megaCfg->flag & BOARD_QUARTZ) {
-        WRINDOOR(megaCfg,virt_to_bus(megaCfg->mbox)|0x2);
-        while (RDINDOOR(megaCfg) & 0x02);
-    } else {
-        CLEAR_INTR(megaCfg->host->io_port);
+      WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x2);
+      while (RDINDOOR (megaCfg) & 0x02);
+    }
+    else {
+      CLEAR_INTR (megaCfg->host->io_port);
     }
 
     megaCfg->flag &= ~IN_ISR;
     megaCfg->flag &= ~PENDING;
 
-    spin_unlock_irqrestore(&mega_lock,flags);
+    spin_unlock_irqrestore (&mega_lock, flags);
+    mega_runque (NULL);
 
-    spin_lock_irqsave(&io_request_lock, flags);
-    mega_runque(NULL);
-    spin_unlock_irqrestore(&io_request_lock,flags);              
+#if LINUX_VERSION_CODE >= 0x20100
+    spin_unlock_irqrestore (&io_request_lock, flags);
+#endif
 
 #if 0
     /* Queue as a delayed ISR routine */
-    queue_task_irq_off(&runq, &tq_immediate);
-    mark_bh(IMMEDIATE_BH);
-    spin_unlock_irqrestore(&mega_lock,flags);
+    queue_task_irq_off (&runq, &tq_immediate);
+    mark_bh (IMMEDIATE_BH);
 #endif
 
   }
@@ -709,15 +846,17 @@ static void megaraid_isr(int irq, void *devp, struct pt_regs *regs)
 /*==================================================*/
 /* Wait until the controller's mailbox is available */
 /*==================================================*/
-static int busyWaitMbox(mega_host_config *megaCfg)
+static int busyWaitMbox (mega_host_config * megaCfg)
 {
-  mega_mailbox *mbox = (mega_mailbox *)megaCfg->mbox;
-  long          counter;
+  mega_mailbox *mbox = (mega_mailbox *) megaCfg->mbox;
+  long counter;
 
-  for(counter=0; counter<0xFFFFFF; counter++) {
-    if (!mbox->busy) return 0;
+  for (counter = 0; counter < 10000; counter++) {
+    udelay (100);
+    if (!mbox->busy)
+      return 0;
   }
-  return -1;
+  return -1;                   /* give up after 1 second */
 }
 
 /*=====================================================
@@ -728,92 +867,105 @@ static int busyWaitMbox(mega_host_config *megaCfg)
  *   u_char *mboxData - Mailbox area, 16 bytes
  *   mega_scb *pScb   - SCB posting (or NULL if N/A)
  *   int intr         - if 1, interrupt, 0 is blocking
- *=====================================================*/
-static int MegaIssueCmd(mega_host_config *megaCfg,
-                       u_char *mboxData,
-                       mega_scb *pScb,
-                       int intr)
+ *=====================================================
+ */
+static int MegaIssueCmd (mega_host_config * megaCfg,
+             u_char * mboxData,
+             mega_scb * pScb,
+             int intr)
 {
-  mega_mailbox *mbox = (mega_mailbox *)megaCfg->mbox;
-  long          flags;
-  u_char        byte;
-  u_long        cmdDone;
+  mega_mailbox *mbox = (mega_mailbox *) megaCfg->mbox;
+  long flags;
+  u_char byte;
+  u_long cmdDone;
 
-  mboxData[0x1] = (pScb ? pScb->idx+1 : 0x00);  /* Set cmdid */
-  mboxData[0xF] = 1;                            /* Set busy */
+  mboxData[0x1] = (pScb ? pScb->idx + 1 : 0x00);       /* Set cmdid */
+  mboxData[0xF] = 1;           /* Set busy */
 
-  /* one bad report of problem when issuing a command while pending.
-   * Wasn't able to duplicate, but it doesn't really affect performance
-   * anyway, so don't allow command while PENDING
-   */
+  spin_lock_irqsave(&mega_lock,flags);
+
+#if !MULTI_IO
   if (megaCfg->flag & PENDING) {
-    return -1;
+     spin_unlock_irqrestore(&mega_lock,flags);
+     return -1;
   }
+#endif
 
   /* Wait until mailbox is free */
-  if (busyWaitMbox(megaCfg)) {
+  if (busyWaitMbox (megaCfg)) {
     if (pScb) {
-      TRACE(("Mailbox busy %.08lx <%d.%d.%d>\n", pScb->SCpnt->serial_number,
-            pScb->SCpnt->channel, pScb->SCpnt->target, pScb->SCpnt->lun));
+      TRACE (("Mailbox busy %.08lx <%d.%d.%d>\n", pScb->SCpnt->serial_number,
+             pScb->SCpnt->channel, pScb->SCpnt->target, pScb->SCpnt->lun));
+    } else {
+       TRACE(("pScb NULL in MegaIssueCmd!\n"));
     }
+    spin_unlock_irqrestore(&mega_lock,flags);
     return -1;
   }
 
   /* Copy mailbox data into host structure */
-  spin_lock_irqsave(&mega_lock,flags);
-  memset(mbox, 0, sizeof(mega_mailbox));
-  memcpy(mbox, mboxData, 16);
-  spin_unlock_irqrestore(&mega_lock,flags);
+  memset (mbox, 0, 16);
+  memcpy (mbox, mboxData, 16);
 
   /* Kick IO */
   megaCfg->flag |= PENDING;
   if (intr) {
     /* Issue interrupt (non-blocking) command */
     if (megaCfg->flag & BOARD_QUARTZ) {
-        mbox->mraid_poll = 0; 
-        mbox->mraid_ack = 0; 
-        WRINDOOR(megaCfg, virt_to_bus(megaCfg->mbox) | 0x1);
-    } else {
-        ENABLE_INTR(megaCfg->host->io_port);
-        ISSUE_COMMAND(megaCfg->host->io_port);
+      mbox->mraid_poll = 0;
+      mbox->mraid_ack = 0;
+      WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x1);
     }
+    else {
+      ENABLE_INTR (megaCfg->host->io_port);
+      ISSUE_COMMAND (megaCfg->host->io_port);
+    }
+    spin_unlock_irqrestore(&mega_lock,flags);
   }
-  else {      /* Issue non-ISR (blocking) command */
+  else {                       /* Issue non-ISR (blocking) command */
 
     if (megaCfg->flag & BOARD_QUARTZ) {
 
-      mbox->mraid_poll = 0; 
-      mbox->mraid_ack = 0; 
-      WRINDOOR(megaCfg, virt_to_bus(megaCfg->mbox) | 0x1);
+      mbox->mraid_poll = 0;
+      mbox->mraid_ack = 0;
+      WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x1);
 
-      while((cmdDone=RDOUTDOOR(megaCfg)) != 0x10001234);
-      WROUTDOOR(megaCfg, cmdDone);
+      while ((cmdDone = RDOUTDOOR (megaCfg)) != 0x10001234);
+      WROUTDOOR (megaCfg, cmdDone);
 
+      spin_unlock_irqrestore(&mega_lock,flags);
       if (pScb) {
-       mega_cmd_done(megaCfg,pScb, mbox->status);
-       mega_rundoneq();
+       mega_cmd_done (megaCfg, pScb, mbox->status);
+       mega_rundoneq ();
       }
 
-      WRINDOOR(megaCfg,virt_to_bus(megaCfg->mbox) | 0x2);
-      while(RDINDOOR(megaCfg) & 0x2);
+      WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x2);
+      while (RDINDOOR (megaCfg) & 0x2);
 
       megaCfg->flag &= ~PENDING;
+
     }
     else {
-      DISABLE_INTR(megaCfg->host->io_port);
-      ISSUE_COMMAND(megaCfg->host->io_port);
-      
-      while(!((byte=READ_PORT(megaCfg->host->io_port,INTR_PORT))&INTR_VALID));
-      WRITE_PORT(megaCfg->host->io_port, INTR_PORT, byte);
-      
-      ENABLE_INTR(megaCfg->host->io_port);
-      CLEAR_INTR(megaCfg->host->io_port);
-      
+      DISABLE_INTR (megaCfg->host->io_port);
+      ISSUE_COMMAND (megaCfg->host->io_port);
+
+      while (!((byte = READ_PORT (megaCfg->host->io_port, INTR_PORT)) & INTR_VALID));
+      WRITE_PORT (megaCfg->host->io_port, INTR_PORT, byte);
+
+
+      ENABLE_INTR (megaCfg->host->io_port);
+      CLEAR_INTR (megaCfg->host->io_port);
+      megaCfg->flag &= ~PENDING;
+      spin_unlock_irqrestore(&mega_lock,flags);
+
       if (pScb) {
-       mega_cmd_done(megaCfg,pScb, mbox->status);
-       mega_rundoneq();
+       mega_cmd_done (megaCfg, pScb, mbox->status);
+       mega_rundoneq ();
       }
-      megaCfg->flag &= ~PENDING;
+      else {
+       TRACE (("Error: NULL pScb!\n"));
+      }
+
     }
   }
 
@@ -823,42 +975,42 @@ static int MegaIssueCmd(mega_host_config *megaCfg,
 /*-------------------------------------------------------------------
  * Copies data to SGLIST
  *-------------------------------------------------------------------*/
-static int build_sglist(mega_host_config *megaCfg, mega_scb *scb, 
-                       u_long *buffer, u_long *length)
+static int build_sglist (mega_host_config * megaCfg, mega_scb * scb,
+             u_long * buffer, u_long * length)
 {
   struct scatterlist *sgList;
   int idx;
 
   /* Scatter-gather not used */
   if (scb->SCpnt->use_sg == 0) {
-    *buffer = virt_to_bus(scb->SCpnt->request_buffer);
-    *length = (u_long)scb->SCpnt->request_bufflen;
+    *buffer = virt_to_bus (scb->SCpnt->request_buffer);
+    *length = (u_long) scb->SCpnt->request_bufflen;
     return 0;
   }
 
-  sgList = (struct scatterlist *)scb->SCpnt->buffer;
+  sgList = (struct scatterlist *) scb->SCpnt->request_buffer;
   if (scb->SCpnt->use_sg == 1) {
-    *buffer = virt_to_bus(sgList[0].address);
-    *length = (u_long)sgList[0].length;
+    *buffer = virt_to_bus (sgList[0].address);
+    *length = (u_long) sgList[0].length;
     return 0;
   }
 
   /* Copy Scatter-Gather list info into controller structure */
-  for(idx=0; idx<scb->SCpnt->use_sg; idx++) {
-    scb->sgList[idx].address = virt_to_bus(sgList[idx].address);
-    scb->sgList[idx].length  = (u_long)sgList[idx].length;
+  for (idx = 0; idx < scb->SCpnt->use_sg; idx++) {
+    scb->sgList[idx].address = virt_to_bus (sgList[idx].address);
+    scb->sgList[idx].length = (u_long) sgList[idx].length;
   }
-  
+
   /* Reset pointer and length fields */
-  *buffer = virt_to_bus(scb->sgList);
+  *buffer = virt_to_bus (scb->sgList);
   *length = 0;
 
   /* Return count of SG requests */
   return scb->SCpnt->use_sg;
 }
-    
+
 /*--------------------------------------------------------------------
- * Initializes the address of the controller's mailbox register
+ * Initializes the adress of the controller's mailbox register
  *  The mailbox register is used to issue commands to the card.
  *  Format of the mailbox area:
  *   00 01 command
@@ -873,25 +1025,25 @@ static int build_sglist(mega_host_config *megaCfg, mega_scb *scb,
  *   10 01 numstatus byte
  *   11 01 status byte
  *--------------------------------------------------------------------*/
-static int mega_register_mailbox(mega_host_config *megaCfg, u_long paddr)
+static int mega_register_mailbox (mega_host_config * megaCfg, u_long paddr)
 {
   /* align on 16-byte boundry */
   megaCfg->mbox = &megaCfg->mailbox;
-  megaCfg->mbox = (mega_mailbox *) ((((ulong)megaCfg->mbox) + 16)&0xfffffff0);
-  paddr = (paddr+16)&0xfffffff0;
+  megaCfg->mbox = (mega_mailbox *) ((((ulong) megaCfg->mbox) + 16) & 0xfffffff0);
+  paddr = (paddr + 16) & 0xfffffff0;
 
   /* Register mailbox area with the firmware */
   if (megaCfg->flag & BOARD_QUARTZ) {
   }
   else {
-    WRITE_PORT(megaCfg->host->io_port, MBOX_PORT0, paddr         & 0xFF);
-    WRITE_PORT(megaCfg->host->io_port, MBOX_PORT1, (paddr >>  8) & 0xFF);
-    WRITE_PORT(megaCfg->host->io_port, MBOX_PORT2, (paddr >> 16) & 0xFF);
-    WRITE_PORT(megaCfg->host->io_port, MBOX_PORT3, (paddr >> 24) & 0xFF);
-    WRITE_PORT(megaCfg->host->io_port, ENABLE_MBOX_REGION, ENABLE_MBOX_BYTE);
-    
-    CLEAR_INTR(megaCfg->host->io_port);
-    ENABLE_INTR(megaCfg->host->io_port);
+    WRITE_PORT (megaCfg->host->io_port, MBOX_PORT0, paddr & 0xFF);
+    WRITE_PORT (megaCfg->host->io_port, MBOX_PORT1, (paddr >> 8) & 0xFF);
+    WRITE_PORT (megaCfg->host->io_port, MBOX_PORT2, (paddr >> 16) & 0xFF);
+    WRITE_PORT (megaCfg->host->io_port, MBOX_PORT3, (paddr >> 24) & 0xFF);
+    WRITE_PORT (megaCfg->host->io_port, ENABLE_MBOX_REGION, ENABLE_MBOX_BYTE);
+
+    CLEAR_INTR (megaCfg->host->io_port);
+    ENABLE_INTR (megaCfg->host->io_port);
   }
   return 0;
 }
@@ -899,77 +1051,79 @@ static int mega_register_mailbox(mega_host_config *megaCfg, u_long paddr)
 /*-------------------------------------------------------------------
  * Issue an adapter info query to the controller
  *-------------------------------------------------------------------*/
-static int mega_i_query_adapter(mega_host_config *megaCfg)
+static int mega_i_query_adapter (mega_host_config * megaCfg)
 {
   mega_RAIDINQ *adapterInfo;
   mega_mailbox *mbox;
-  u_char        mboxData[16];
-  u_long        paddr;
+  u_char mboxData[16];
+  u_long paddr;
 
-  spin_lock_init(&mega_lock);
+  spin_lock_init (&mega_lock);
   /* Initialize adapter inquiry */
-  paddr = virt_to_bus(megaCfg->mega_buffer);
-  mbox  = (mega_mailbox *)mboxData;
+  paddr = virt_to_bus (megaCfg->mega_buffer);
+  mbox = (mega_mailbox *) mboxData;
 
-  memset((void *)megaCfg->mega_buffer, 0, sizeof(megaCfg->mega_buffer));
-  memset(mbox, 0, 16);
+  memset ((void *) megaCfg->mega_buffer, 0, sizeof (megaCfg->mega_buffer));
+  memset (mbox, 0, 16);
 
   /* Initialize mailbox registers */
-  mbox->cmd      = MEGA_MBOXCMD_ADAPTERINQ;
+  mbox->cmd = MEGA_MBOXCMD_ADAPTERINQ;
   mbox->xferaddr = paddr;
 
   /* Issue a blocking command to the card */
-  MegaIssueCmd(megaCfg, mboxData, NULL, 0);
-  
+  MegaIssueCmd (megaCfg, mboxData, NULL, 0);
+
   /* Initialize host/local structures with Adapter info */
-  adapterInfo = (mega_RAIDINQ *)megaCfg->mega_buffer;
+  adapterInfo = (mega_RAIDINQ *) megaCfg->mega_buffer;
   megaCfg->host->max_channel = adapterInfo->AdpInfo.ChanPresent;
-  megaCfg->host->max_id      = adapterInfo->AdpInfo.MaxTargPerChan;
-  megaCfg->numldrv           = adapterInfo->LogdrvInfo.NumLDrv;
+/*  megaCfg->host->max_id = adapterInfo->AdpInfo.MaxTargPerChan; */
+  megaCfg->host->max_id = 16; /* max targets/chan */
+  megaCfg->numldrv = adapterInfo->LogdrvInfo.NumLDrv;
 
 #if 0
-  printk(KERN_DEBUG "---- Logical drive info ----\n");
-  for(i=0; i<megaCfg->numldrv; i++) {
-    printk(KERN_DEBUG "%d: size: %ld prop: %x state: %x\n",i,
-          adapterInfo->LogdrvInfo.LDrvSize[i],
-          adapterInfo->LogdrvInfo.LDrvProp[i],
-          adapterInfo->LogdrvInfo.LDrvState[i]);
+  printk ("KERN_DEBUG ---- Logical drive info ----\n");
+  for (i = 0; i < megaCfg->numldrv; i++) {
+    printk ("%d: size: %ld prop: %x state: %x\n", i,
+           adapterInfo->LogdrvInfo.LDrvSize[i],
+           adapterInfo->LogdrvInfo.LDrvProp[i],
+           adapterInfo->LogdrvInfo.LDrvState[i]);
   }
-  printk(KERN_DEBUG "---- Physical drive info ----\n");
-  for(i=0; i<MAX_PHYSICAL_DRIVES; i++) {
-    if (i && !(i % 8)) printk("\n");
-    printk("%d: %x   ", i, adapterInfo->PhysdrvInfo.PDrvState[i]);
+  printk (KERN_DEBUG "---- Physical drive info ----\n");
+  for (i = 0; i < MAX_PHYSICAL_DRIVES; i++) {
+    if (i && !(i % 8))
+      printk ("\n");
+    printk ("%d: %x   ", i, adapterInfo->PhysdrvInfo.PDrvState[i]);
   }
-  printk("\n");
+  printk ("\n");
 #endif
 
   megaCfg->max_cmds = adapterInfo->AdpInfo.MaxConcCmds;
 
-#ifdef HP            /* use HP firmware and bios version encoding */
-      sprintf(megaCfg->fwVer,"%c%d%d.%d%d",
-          adapterInfo->AdpInfo.FwVer[2],
-          adapterInfo->AdpInfo.FwVer[1] >> 8,
-          adapterInfo->AdpInfo.FwVer[1] & 0x0f,
-          adapterInfo->AdpInfo.FwVer[2] >> 8,
-          adapterInfo->AdpInfo.FwVer[2] & 0x0f);
-      sprintf(megaCfg->biosVer,"%c%d%d.%d%d",
-          adapterInfo->AdpInfo.BiosVer[2],
-          adapterInfo->AdpInfo.BiosVer[1] >> 8,
-          adapterInfo->AdpInfo.BiosVer[1] & 0x0f,
-          adapterInfo->AdpInfo.BiosVer[2] >> 8,
-          adapterInfo->AdpInfo.BiosVer[2] & 0x0f);
+#ifdef HP                      /* use HP firmware and bios version encoding */
+  sprintf (megaCfg->fwVer, "%c%d%d.%d%d",
+          adapterInfo->AdpInfo.FwVer[2],
+          adapterInfo->AdpInfo.FwVer[1] >> 8,
+          adapterInfo->AdpInfo.FwVer[1] & 0x0f,
+          adapterInfo->AdpInfo.FwVer[2] >> 8,
+          adapterInfo->AdpInfo.FwVer[2] & 0x0f);
+  sprintf (megaCfg->biosVer, "%c%d%d.%d%d",
+          adapterInfo->AdpInfo.BiosVer[2],
+          adapterInfo->AdpInfo.BiosVer[1] >> 8,
+          adapterInfo->AdpInfo.BiosVer[1] & 0x0f,
+          adapterInfo->AdpInfo.BiosVer[2] >> 8,
+          adapterInfo->AdpInfo.BiosVer[2] & 0x0f);
 #else
-      memcpy(megaCfg->fwVer, adapterInfo->AdpInfo.FwVer, 4);
-      megaCfg->fwVer[4] = 0;
+  memcpy (megaCfg->fwVer, adapterInfo->AdpInfo.FwVer, 4);
+  megaCfg->fwVer[4] = 0;
 
-      memcpy(megaCfg->biosVer, adapterInfo->AdpInfo.BiosVer, 4);
-      megaCfg->biosVer[4] = 0;
+  memcpy (megaCfg->biosVer, adapterInfo->AdpInfo.BiosVer, 4);
+  megaCfg->biosVer[4] = 0;
 #endif
 
-  printk(KERN_INFO "megaraid: [%s:%s] detected %d logical drives" CRLFSTR,
-        megaCfg->fwVer,
-        megaCfg->biosVer,
-        megaCfg->numldrv);
+  printk (KERN_INFO "megaraid: [%s:%s] detected %d logical drives" CRLFSTR,
+         megaCfg->fwVer,
+         megaCfg->biosVer,
+         megaCfg->numldrv);
   return 0;
 }
 
@@ -982,47 +1136,65 @@ static int mega_i_query_adapter(mega_host_config *megaCfg)
 /*----------------------------------------------------------
  * Returns data to be displayed in /proc/scsi/megaraid/X
  *----------------------------------------------------------*/
-int megaraid_proc_info(char *buffer, char **start, off_t offset,
-                      int length, int inode, int inout)
+int megaraid_proc_info (char *buffer, char **start, off_t offset,
+                   int length, int inode, int inout)
 {
   *start = buffer;
   return 0;
 }
 
-int findCard(Scsi_Host_Template *pHostTmpl, 
-            u_short pciVendor, u_short pciDev,
-            long flag)
+int findCard (Scsi_Host_Template * pHostTmpl,
+         u_short pciVendor, u_short pciDev,
+         long flag)
 {
   mega_host_config *megaCfg;
   struct Scsi_Host *host;
-  u_char            pciBus, pciDevFun, megaIrq;
-  u_long            megaBase;
-  u_short           pciIdx = 0;
+  u_char pciBus, pciDevFun, megaIrq;
+  u_long megaBase;
+  u_short pciIdx = 0;
+  u_short numFound = 0;
 
 #if LINUX_VERSION_CODE < 0x20100
-  while(!pcibios_find_device(pciVendor, pciDev, pciIdx,&pciBus,&pciDevFun)) {
+  while (!pcibios_find_device (pciVendor, pciDev, pciIdx, &pciBus, &pciDevFun)) {
+#if 0
+    if (flag & BOARD_QUARTZ) {
+      u_int magic;
+      pcibios_read_config_dword (pciBus, pciDevFun,
+                                PCI_CONF_AMISIG,
+                                &magic);
+      if (magic != AMI_SIGNATURE) {
+        pciIdx++;
+       continue;               /* not an AMI board */
+      }
+    }
+#endif
+
+#if 0
+    } /* keep auto-indenters happy */
+#endif
+
 #else
-  struct pci_dev   *pdev=pci_devices;
+  struct pci_dev *pdev = pci_devices;
 
-  while((pdev = pci_find_device(pciVendor, pciDev, pdev))) {
+  while ((pdev = pci_find_device (pciVendor, pciDev, pdev))) {
     pciBus = pdev->bus->number;
     pciDevFun = pdev->devfn;
 #endif
-    printk(KERN_INFO "megaraid: found 0x%4.04x:0x%4.04x:idx %d:bus %d:slot %d:fun %d\n",
-          pciVendor, 
-          pciDev, 
-          pciIdx, pciBus, 
-          PCI_SLOT(pciDevFun), 
-          PCI_FUNC(pciDevFun));
-    
+    printk (KERN_INFO "megaraid: found 0x%4.04x:0x%4.04x:idx %d:bus %d:slot %d:fun %d\n",
+           pciVendor,
+           pciDev,
+           pciIdx, pciBus,
+           PCI_SLOT (pciDevFun),
+           PCI_FUNC (pciDevFun));
+
     /* Read the base port and IRQ from PCI */
 #if LINUX_VERSION_CODE < 0x20100
-    pcibios_read_config_dword(pciBus, pciDevFun,
-                            PCI_BASE_ADDRESS_0,
-                            (u_int *)&megaBase);
-    pcibios_read_config_byte(pciBus, pciDevFun,                               
-                            PCI_INTERRUPT_LINE,
-                            &megaIrq);
+    pcibios_read_config_dword (pciBus, pciDevFun,
+                              PCI_BASE_ADDRESS_0,
+                              (u_int *) & megaBase);
+    pcibios_read_config_byte (pciBus, pciDevFun,
+                             PCI_INTERRUPT_LINE,
+                             &megaIrq);
 #else
     megaBase = pdev->base_address[0];
     megaIrq = pdev->irq;
@@ -1031,7 +1203,7 @@ int findCard(Scsi_Host_Template *pHostTmpl,
 
     if (flag & BOARD_QUARTZ) {
       megaBase &= PCI_BASE_ADDRESS_MEM_MASK;
-      megaBase = (long) ioremap(megaBase,128);
+      megaBase = (long) ioremap (megaBase, 128);
     }
     else {
       megaBase &= PCI_BASE_ADDRESS_IO_MASK;
@@ -1039,72 +1211,75 @@ int findCard(Scsi_Host_Template *pHostTmpl,
     }
 
     /* Initialize SCSI Host structure */
-    host    = scsi_register(pHostTmpl, sizeof(mega_host_config));
-    megaCfg = (mega_host_config *)host->hostdata;
-    memset(megaCfg, 0, sizeof(mega_host_config));
+    host = scsi_register (pHostTmpl, sizeof (mega_host_config));
+    megaCfg = (mega_host_config *) host->hostdata;
+    memset (megaCfg, 0, sizeof (mega_host_config));
+
+    printk (KERN_INFO " scsi%d: Found a MegaRAID controller at 0x%x, IRQ: %d" CRLFSTR,
+           host->host_no, (u_int) megaBase, megaIrq);
 
-    printk(KERN_INFO " scsi%d: Found a MegaRAID controller at 0x%x, IRQ: %d" CRLFSTR, 
-          host->host_no, (u_int)megaBase, megaIrq);
-    
     /* Copy resource info into structure */
-    megaCfg->flag            = flag;
-    megaCfg->host            = host;
-    megaCfg->base            = megaBase;
-    megaCfg->host->irq       = megaIrq;
-    megaCfg->host->io_port   = megaBase;
+    megaCfg->flag = flag;
+    megaCfg->host = host;
+    megaCfg->base = megaBase;
+    megaCfg->host->irq = megaIrq;
+    megaCfg->host->io_port = megaBase;
     megaCfg->host->n_io_port = 16;
     megaCfg->host->unique_id = (pciBus << 8) | pciDevFun;
-    megaCtlrs[numCtlrs++]    = megaCfg;
+    megaCtlrs[numCtlrs++] = megaCfg;
 
     if (flag != BOARD_QUARTZ) {
       /* Request our IO Range */
-      if (check_region(megaBase, 16)) {
-       printk(KERN_WARNING "megaraid: Couldn't register I/O range!" CRLFSTR);
-       scsi_unregister(host);
+      if (check_region (megaBase, 16)) {
+       printk (KERN_WARNING "megaraid: Couldn't register I/O range!" CRLFSTR);
+       scsi_unregister (host);
        continue;
       }
-      request_region(megaBase, 16, "megaraid");
+      request_region (megaBase, 16, "megaraid");
     }
 
     /* Request our IRQ */
-    if (request_irq(megaIrq, megaraid_isr, SA_SHIRQ, 
-                   "megaraid", megaCfg)) {
-      printk(KERN_WARNING "megaraid: Couldn't register IRQ %d!" CRLFSTR,
-            megaIrq);
-      scsi_unregister(host);
+    if (request_irq (megaIrq, megaraid_isr, SA_SHIRQ,
+                    "megaraid", megaCfg)) {
+      printk (KERN_WARNING "megaraid: Couldn't register IRQ %d!" CRLFSTR,
+             megaIrq);
+      scsi_unregister (host);
       continue;
     }
 
-    mega_register_mailbox(megaCfg, virt_to_bus((void*)&megaCfg->mailbox));
-    mega_i_query_adapter(megaCfg);
+    mega_register_mailbox (megaCfg, virt_to_bus ((void *) &megaCfg->mailbox));
+    mega_i_query_adapter (megaCfg);
 
     /* Initialize SCBs */
-    initSCB(megaCfg);
+    if (initSCB (megaCfg)) {
+       scsi_unregister (host);
+       continue;
+    }
 
+    numFound++;
   }
-  return pciIdx;
+  return numFound;
 }
 
 /*---------------------------------------------------------
  * Detects if a megaraid controller exists in this system
  *---------------------------------------------------------*/
-int megaraid_detect(Scsi_Host_Template *pHostTmpl)
+int megaraid_detect (Scsi_Host_Template * pHostTmpl)
 {
   int count = 0;
 
   pHostTmpl->proc_dir = &proc_scsi_megaraid;
 
 #if LINUX_VERSION_CODE < 0x20100
-  if (!pcibios_present()) 
-    {
-      printk(KERN_WARNING "megaraid: PCI bios not present." CRLFSTR);
-      return 0;
-    }
+  if (!pcibios_present ()) {
+    printk (KERN_WARNING "megaraid: PCI bios not present." CRLFSTR);
+    return 0;
+  }
 #endif
 
-  count += findCard(pHostTmpl, 0x101E, 0x9010, 0);
-  count += findCard(pHostTmpl, 0x101E, 0x9060, 0);
-  count += findCard(pHostTmpl, 0x8086, 0x1960, BOARD_QUARTZ);
+  count += findCard (pHostTmpl, 0x101E, 0x9010, 0);
+  count += findCard (pHostTmpl, 0x101E, 0x9060, 0);
+  count += findCard (pHostTmpl, 0x8086, 0x1960, BOARD_QUARTZ);
 
   return count;
 }
@@ -1112,54 +1287,67 @@ int megaraid_detect(Scsi_Host_Template *pHostTmpl)
 /*---------------------------------------------------------------------
  * Release the controller's resources
  *---------------------------------------------------------------------*/
-int megaraid_release(struct Scsi_Host *pSHost)
+int megaraid_release (struct Scsi_Host *pSHost)
 {
   mega_host_config *megaCfg;
-  mega_mailbox         *mbox;
-  u_char                mboxData[16];
+  mega_mailbox *mbox;
+  u_char mboxData[16];
 
-  megaCfg = (mega_host_config*)pSHost->hostdata;
-  mbox    = (mega_mailbox *)mboxData;
+  megaCfg = (mega_host_config *) pSHost->hostdata;
+  mbox = (mega_mailbox *) mboxData;
 
   /* Flush cache to disk */
-  memset(mbox, 0, 16);
+  memset (mbox, 0, 16);
   mboxData[0] = 0xA;
 
   /* Issue a blocking (interrupts disabled) command to the card */
-  MegaIssueCmd(megaCfg, mboxData, NULL, 0);
+  MegaIssueCmd (megaCfg, mboxData, NULL, 0);
 
-  schedule();
+  schedule ();
 
   /* Free our resources */
   if (megaCfg->flag & BOARD_QUARTZ) {
-      iounmap((void *)megaCfg->base);
-  } else {
-      release_region(megaCfg->host->io_port, 16);
+    iounmap ((void *) megaCfg->base);
   }
-  free_irq(megaCfg->host->irq, megaCfg); /* Must be freed first, otherwise
-                                            extra interrupt is generated */
-  scsi_unregister(pSHost);
+  else {
+    release_region (megaCfg->host->io_port, 16);
+  }
+  free_irq (megaCfg->host->irq, megaCfg);      /* Must be freed first, otherwise
+
+                                                  extra interrupt is generated */
+  freeSgList(megaCfg);
+  scsi_unregister (pSHost);
 
   return 0;
 }
 
+static inline void freeSgList(mega_host_config *megaCfg)
+{
+  int i;
+
+  for (i = 0; i < megaCfg->max_cmds; i++) {
+    if (megaCfg->scbList[i].sgList)
+      kfree (megaCfg->scbList[i].sgList);      /* free sgList */
+  }
+}
+
 /*----------------------------------------------
  * Get information about the card/driver 
  *----------------------------------------------*/
-const char *megaraid_info(struct Scsi_Host *pSHost)
+const char * megaraid_info (struct Scsi_Host *pSHost)
 {
-  static char           buffer[512];
-  mega_host_config  *megaCfg;
-  mega_RAIDINQ          *adapterInfo;
+  static char buffer[512];
+  mega_host_config *megaCfg;
+  mega_RAIDINQ *adapterInfo;
 
-  megaCfg     = (mega_host_config *)pSHost->hostdata;
-  adapterInfo = (mega_RAIDINQ *)megaCfg->mega_buffer;
+  megaCfg = (mega_host_config *) pSHost->hostdata;
+  adapterInfo = (mega_RAIDINQ *) megaCfg->mega_buffer;
 
-  sprintf(buffer, "AMI MegaRAID %s %d commands %d targs %d chans",
-         megaCfg->fwVer,
-         adapterInfo->AdpInfo.MaxConcCmds,
-         megaCfg->host->max_id,
-         megaCfg->host->max_channel);
+  sprintf (buffer, "AMI MegaRAID %s %d commands %d targs %d chans",
+          megaCfg->fwVer,
+          adapterInfo->AdpInfo.MaxConcCmds,
+          megaCfg->host->max_id,
+          megaCfg->host->max_channel);
   return buffer;
 }
 
@@ -1178,29 +1366,29 @@ const char *megaraid_info(struct Scsi_Host *pSHost)
  *   10 01 numstatus byte
  *   11 01 status byte 
  *-----------------------------------------------------------------*/
-int megaraid_queue(Scsi_Cmnd *SCpnt, void (*pktComp)(Scsi_Cmnd *))
+int megaraid_queue (Scsi_Cmnd * SCpnt, void (*pktComp) (Scsi_Cmnd *))
 {
   mega_host_config *megaCfg;
-  mega_scb         *pScb;
+  mega_scb *pScb;
 
-  megaCfg = (mega_host_config *)SCpnt->host->hostdata;
+  megaCfg = (mega_host_config *) SCpnt->host->hostdata;
 
   if (!(megaCfg->flag & (1L << SCpnt->channel))) {
-    printk(KERN_INFO "scsi%d: scanning channel %c for devices.\n",
-          megaCfg->host->host_no,
-          SCpnt->channel + 'A');
+    printk (KERN_INFO "scsi%d: scanning channel %c for devices.\n",
+           megaCfg->host->host_no,
+           SCpnt->channel + 'A');
     megaCfg->flag |= (1L << SCpnt->channel);
   }
 
   SCpnt->scsi_done = pktComp;
 
   /* Allocate and build a SCB request */
-  if ((pScb = mega_build_cmd(megaCfg, SCpnt)) != NULL) {
+  if ((pScb = mega_build_cmd (megaCfg, SCpnt)) != NULL) {
     /* Add SCB to the head of the pending queue */
-    ENQUEUE(pScb, mega_scb, qPending, next);
+    ENQUEUE (pScb, mega_scb, qPending, next);
 
     /* Issue the command to the card */
-      mega_runque(NULL);
+    mega_runque (NULL);
   }
 
   return 0;
@@ -1208,37 +1396,44 @@ int megaraid_queue(Scsi_Cmnd *SCpnt, void (*pktComp)(Scsi_Cmnd *))
 
 /*----------------------------------------------------------------------
  * Issue a blocking command to the controller
- *
- * Note - this isnt 2.0.x SMP safe
  *----------------------------------------------------------------------*/
-volatile static int internal_done_flag    = 0;
+volatile static int internal_done_flag = 0;
 volatile static int internal_done_errcode = 0;
 
-static void internal_done(Scsi_Cmnd *SCpnt)
+static void internal_done (Scsi_Cmnd * SCpnt)
 {
   internal_done_errcode = SCpnt->result;
   internal_done_flag++;
 }
 
 /*
- *     This seems dangerous in an SMP environment because 
- *     while spinning on internal_done_flag in 2.0.x SMP
- *     no IRQ's will be taken, including those that might
- *     be needed to clear this.
+ *      This seems dangerous in an SMP environment because
+ *      while spinning on internal_done_flag in 2.0.x SMP
+ *      no IRQ's will be taken, including those that might
+ *      be needed to clear this.
  *
- *     I think this should be using a wait queue ?
- *                             -- AC
+ *      I think this should be using a wait queue ?
+ *                              -- AC
+ */      
+
+/*
+ *      I'll probably fix this in the next version, but
+ *      megaraid_command() will never get called since can_queue is set,
+ *      except maybe in a *really* old kernel in which case it's very
+ *      unlikely they'd be using SMP anyway.  Really this function is
+ *      just here for completeness.
+ *                              - JLJ
  */
-int megaraid_command(Scsi_Cmnd *SCpnt)
+
+int megaraid_command (Scsi_Cmnd * SCpnt)
 {
   internal_done_flag = 0;
 
   /* Queue command, and wait until it has completed */
-  megaraid_queue(SCpnt, internal_done);
+  megaraid_queue (SCpnt, internal_done);
 
-  while(!internal_done_flag)
-    barrier();
+  while (!internal_done_flag)
+    barrier ();
 
   return internal_done_errcode;
 }
@@ -1246,67 +1441,67 @@ int megaraid_command(Scsi_Cmnd *SCpnt)
 /*---------------------------------------------------------------------
  * Abort a previous SCSI request
  *---------------------------------------------------------------------*/
-int megaraid_abort(Scsi_Cmnd *SCpnt)
+int megaraid_abort (Scsi_Cmnd * SCpnt)
 {
   mega_host_config *megaCfg;
-  int       idx;
-  long      flags;
+  int idx;
+  long flags;
 
-  spin_lock_irqsave(&mega_lock,flags);
+  spin_lock_irqsave (&mega_lock, flags);
 
-  megaCfg = (mega_host_config *)SCpnt->host->hostdata;
+  megaCfg = (mega_host_config *) SCpnt->host->hostdata;
 
-  TRACE(("ABORT!!! %.08lx %.02x <%d.%d.%d>\n",
-        SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel, SCpnt->target, 
-        SCpnt->lun));
+  TRACE (("ABORT!!! %.08lx %.02x <%d.%d.%d>\n",
+       SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel, SCpnt->target,
+         SCpnt->lun));
   /*
    * Walk list of SCBs for any that are still outstanding
    */
-  for(idx=0; idx<megaCfg->max_cmds; idx++) {
+  for (idx = 0; idx < megaCfg->max_cmds; idx++) {
     if (megaCfg->scbList[idx].idx >= 0) {
       if (megaCfg->scbList[idx].SCpnt == SCpnt) {
-       freeSCB(&megaCfg->scbList[idx]);
+       freeSCB (&megaCfg->scbList[idx]);
 
-       SCpnt->result = (DID_RESET << 16) | (SUGGEST_RETRY<<24);
-       callDone(SCpnt);
+       SCpnt->result = (DID_RESET << 16) | (SUGGEST_RETRY << 24);
+       callDone (SCpnt);
       }
     }
   }
-  spin_unlock_irqrestore(&mega_lock,flags);
+  spin_unlock_irqrestore (&mega_lock, flags);
   return SCSI_ABORT_SNOOZE;
 }
 
 /*---------------------------------------------------------------------
  * Reset a previous SCSI request
  *---------------------------------------------------------------------*/
-int megaraid_reset(Scsi_Cmnd *SCpnt, unsigned int rstflags)
+int megaraid_reset (Scsi_Cmnd * SCpnt, unsigned int rstflags)
 {
   mega_host_config *megaCfg;
-  int       idx;
-  long      flags;
+  int idx;
+  long flags;
 
-  spin_lock_irqsave(&mega_lock,flags);
+  spin_lock_irqsave (&mega_lock, flags);
 
-  megaCfg = (mega_host_config *)SCpnt->host->hostdata;
+  megaCfg = (mega_host_config *) SCpnt->host->hostdata;
 
-  TRACE(("RESET: %.08lx %.02x <%d.%d.%d>\n",
-        SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel, SCpnt->target, 
-        SCpnt->lun));
+  TRACE (("RESET: %.08lx %.02x <%d.%d.%d>\n",
+       SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel, SCpnt->target,
+         SCpnt->lun));
 
   /*
    * Walk list of SCBs for any that are still outstanding
    */
-  for(idx=0; idx<megaCfg->max_cmds; idx++) {
+  for (idx = 0; idx < megaCfg->max_cmds; idx++) {
     if (megaCfg->scbList[idx].idx >= 0) {
       SCpnt = megaCfg->scbList[idx].SCpnt;
-      freeSCB(&megaCfg->scbList[idx]);
-      SCpnt->result = (DID_RESET << 16) | (SUGGEST_RETRY<<24);
-      callDone(SCpnt);
+      freeSCB (&megaCfg->scbList[idx]);
+      SCpnt->result = (DID_RESET << 16) | (SUGGEST_RETRY << 24);
+      callDone (SCpnt);
     }
   }
-  spin_unlock_irqrestore(&mega_lock,flags);
+  spin_unlock_irqrestore (&mega_lock, flags);
   return SCSI_RESET_PUNT;
-} 
+}
 
 /*-------------------------------------------------------------
  * Return the disk geometry for a particular disk
@@ -1318,23 +1513,23 @@ int megaraid_reset(Scsi_Cmnd *SCpnt, unsigned int rstflags)
  *     geom[1] = sectors
  *     geom[2] = cylinders
  *-------------------------------------------------------------*/
-int megaraid_biosparam(Disk *disk, kdev_t dev, int *geom)
+int megaraid_biosparam (Disk * disk, kdev_t dev, int *geom)
 {
-  int                   heads, sectors, cylinders;
+  int heads, sectors, cylinders;
   mega_host_config *megaCfg;
 
   /* Get pointer to host config structure */
-  megaCfg = (mega_host_config *)disk->device->host->hostdata;
+  megaCfg = (mega_host_config *) disk->device->host->hostdata;
 
   /* Default heads (64) & sectors (32) */
-  heads     = 64;
-  sectors   = 32;
+  heads = 64;
+  sectors = 32;
   cylinders = disk->capacity / (heads * sectors);
 
   /* Handle extended translation size for logical drives > 1Gb */
   if (disk->capacity >= 0x200000) {
-    heads     = 255;
-    sectors   = 63;
+    heads = 255;
+    sectors = 63;
     cylinders = disk->capacity / (heads * sectors);
   }
 
index b020d1b7896e2e751ea45b0818ca81f3536ce396..dc10a47e22df7270f91cc0066dc9d510889f9d28 100644 (file)
@@ -1,7 +1,12 @@
 #ifndef __MEGARAID_H__
 #define __MEGARAID_H__
 
+#ifndef LINUX_VERSION_CODE
 #include <linux/version.h>
+#endif
+
+#define MULTI_IO 0    /* change to 1 for fully parallel I/O to adapter */
+                      /* works on some systems, not on others yet */
 
 #define IN_ISR                  0x80000000L
 #define NO_INTR                 0x40000000L
@@ -20,7 +25,7 @@
 
 #define MEGA_CMD_TIMEOUT        10
 
-#define MAX_SGLIST              20
+#define MAX_SGLIST              17
 #define MAX_COMMANDS            254
 
 #define MAX_LOGICAL_DRIVES      8
@@ -56,7 +61,7 @@
 #define I_TOGGLE_PORT      0x01
 #define INTR_PORT          0x0a
 
-#define MAILBOX_SIZE       70
+#define MAILBOX_SIZE       (sizeof(mega_mailbox)-16)
 #define MBOX_BUSY_PORT     0x00
 #define MBOX_PORT0         0x04
 #define MBOX_PORT1         0x05
 
 #define PCI_CONF_BASE_ADDR_OFFSET  0x10
 #define PCI_CONF_IRQ_OFFSET        0x3c
+#define PCI_CONF_AMISIG            0xa0
+#define AMI_SIGNATURE              0x11223344
 
 #if LINUX_VERSION_CODE < 0x20100
 #define MEGARAID \
     megaraid_reset,                     /* Reset Command Function    */\
     NULL,                               /* Slave Attach Function     */\
     megaraid_biosparam,                 /* Disk BIOS Parameters      */\
-    1,                                  /* # of cmds that can be\
+    254,                                /* # of cmds that can be\
                                            outstanding at any time */\
     7,                                  /* HBA Target ID             */\
     MAX_SGLIST,                         /* Scatter/Gather Table Size */\
-    1,                                  /* SCSI Commands per LUN     */\
+    64,                                 /* SCSI Commands per LUN     */\
     0,                                  /* Present                   */\
     0,                                  /* Default Unchecked ISA DMA */\
-    ENABLE_CLUSTERING }                 /* Enable Clustering         */
+    ENABLE_CLUSTERING }                /* Enable Clustering         */
 #else
 #define MEGARAID \
   {\
     abort:            megaraid_abort,          /* Abort Command Function    */\
     reset:            megaraid_reset,          /* Reset Command Function    */\
     bios_param:       megaraid_biosparam,      /* Disk BIOS Parameters      */\
-    can_queue:        255,                     /* Can Queue                 */\
+    can_queue:        1 /* MAX_COMMANDS */,            /* Can Queue                 */\
     this_id:          7,                       /* HBA Target ID             */\
     sg_tablesize:     MAX_SGLIST,              /* Scatter/Gather Table Size */\
-    cmd_per_lun:      1,                       /* SCSI Commands per LUN     */\
+    cmd_per_lun:      64,                      /* SCSI Commands per LUN     */\
     present:          0,                       /* Present                   */\
     unchecked_isa_dma:0,                       /* Default Unchecked ISA DMA */\
     use_clustering:   ENABLE_CLUSTERING       /* Enable Clustering         */\
 #endif
 
 /* Structures */
-typedef struct _mega_ADP_INFO
-{
-  u_char    MaxConcCmds;
-  u_char    RbldRate;
-  u_char    MaxTargPerChan;
-  u_char    ChanPresent;
-  u_char    FwVer[4];
-  u_short   AgeOfFlash;
-  u_char    ChipSet;
-  u_char    DRAMSize;
-  u_char    CacheFlushInterval;
-  u_char    BiosVer[4];
-  u_char    resvd[7];
+typedef struct _mega_ADP_INFO {
+    u_char MaxConcCmds;
+    u_char RbldRate;
+    u_char MaxTargPerChan;
+    u_char ChanPresent;
+    u_char FwVer[4];
+    u_short AgeOfFlash;
+    u_char ChipSet;
+    u_char DRAMSize;
+    u_char CacheFlushInterval;
+    u_char BiosVer[4];
+    u_char resvd[7];
 } mega_ADP_INFO;
 
-typedef struct _mega_LDRV_INFO
-{
-  u_char   NumLDrv;
-  u_char   resvd[3];
-  u_long   LDrvSize[MAX_LOGICAL_DRIVES];
-  u_char   LDrvProp[MAX_LOGICAL_DRIVES];
-  u_char   LDrvState[MAX_LOGICAL_DRIVES];
+typedef struct _mega_LDRV_INFO {
+    u_char NumLDrv;
+    u_char resvd[3];
+    u_long LDrvSize[MAX_LOGICAL_DRIVES];
+    u_char LDrvProp[MAX_LOGICAL_DRIVES];
+    u_char LDrvState[MAX_LOGICAL_DRIVES];
 } mega_LDRV_INFO;
 
-typedef struct _mega_PDRV_INFO
-{
-  u_char   PDrvState[MAX_PHYSICAL_DRIVES];
-  u_char   resvd;
+typedef struct _mega_PDRV_INFO {
+    u_char PDrvState[MAX_PHYSICAL_DRIVES];
+    u_char resvd;
 } mega_PDRV_INFO;
 
 // RAID inquiry: Mailbox command 0x5
-typedef struct _mega_RAIDINQ
-{
-  mega_ADP_INFO    AdpInfo;
-  mega_LDRV_INFO   LogdrvInfo;
-  mega_PDRV_INFO   PhysdrvInfo;
+typedef struct _mega_RAIDINQ {
+    mega_ADP_INFO AdpInfo;
+    mega_LDRV_INFO LogdrvInfo;
+    mega_PDRV_INFO PhysdrvInfo;
 } mega_RAIDINQ;
 
 // Passthrough command: Mailbox command 0x3
-typedef struct mega_passthru
-{
-  u_char            timeout:3;              /* 0=6sec/1=60sec/2=10min/3=3hrs */
-  u_char            ars:1;
-  u_char            reserved:3;
-  u_char            islogical:1;
-  u_char            logdrv;                 /* if islogical == 1 */
-  u_char            channel;                /* if islogical == 0 */
-  u_char            target;                 /* if islogical == 0 */
-  u_char            queuetag;               /* unused */
-  u_char            queueaction;            /* unused */
-  u_char            cdb[MAX_CDB_LEN];
-  u_char            cdblen;
-  u_char            reqsenselen;
-  u_char            reqsensearea[MAX_REQ_SENSE_LEN];
-  u_char            numsgelements;
-  u_char            scsistatus;
-  u_long            dataxferaddr;
-  u_long            dataxferlen;
+typedef struct mega_passthru {
+    u_char timeout:3;          /* 0=6sec/1=60sec/2=10min/3=3hrs */
+    u_char ars:1;
+    u_char reserved:3;
+    u_char islogical:1;
+    u_char logdrv;             /* if islogical == 1 */
+    u_char channel;            /* if islogical == 0 */
+    u_char target;             /* if islogical == 0 */
+    u_char queuetag;           /* unused */
+    u_char queueaction;                /* unused */
+    u_char cdb[MAX_CDB_LEN];
+    u_char cdblen;
+    u_char reqsenselen;
+    u_char reqsensearea[MAX_REQ_SENSE_LEN];
+    u_char numsgelements;
+    u_char scsistatus;
+    u_long dataxferaddr;
+    u_long dataxferlen;
 } mega_passthru;
 
-typedef struct _mega_mailbox
-{
-  /* 0x0 */ u_char    cmd;
-  /* 0x1 */ u_char    cmdid;
-  /* 0x2 */ u_short   numsectors;
-  /* 0x4 */ u_long    lba;
-  /* 0x8 */ u_long    xferaddr;
-  /* 0xC */ u_char    logdrv;
-  /* 0xD */ u_char    numsgelements;
-  /* 0xE */ u_char    resvd;
-  /* 0xF */ u_char    busy;
-  /* 0x10*/ u_char    numstatus;
-  /* 0x11*/ u_char    status;
-  /* 0x12*/ u_char    completed[46];
-            u_char    mraid_poll;
-            u_char    mraid_ack;
-            u_char    pad[16];
+typedef struct _mega_mailbox {
+    /* 0x0 */ u_char cmd;
+    /* 0x1 */ u_char cmdid;
+    /* 0x2 */ u_short numsectors;
+    /* 0x4 */ u_long lba;
+    /* 0x8 */ u_long xferaddr;
+    /* 0xC */ u_char logdrv;
+    /* 0xD */ u_char numsgelements;
+    /* 0xE */ u_char resvd;
+    /* 0xF */ u_char busy;
+    /* 0x10 */ u_char numstatus;
+    /* 0x11 */ u_char status;
+    /* 0x12 */ u_char completed[46];
+    u_char mraid_poll;
+    u_char mraid_ack;
+    u_char pad[16];
 } mega_mailbox;
 
-typedef struct _mega_sglist
-{
-  u_long     address;
-  u_long     length;
+typedef struct _mega_ioctl_mbox {
+    /* 0x0 */ u_char cmd;
+    /* 0x1 */ u_char cmdid;
+    /* 0x2 */ u_char channel;
+    /* 0x3 */ u_char param;
+    /* 0x4 */ u_char pad[4];
+    /* 0x8 */ u_long xferaddr;
+    /* 0xC */ u_char logdrv;
+    /* 0xD */ u_char numsgelements;
+    /* 0xE */ u_char resvd;
+    /* 0xF */ u_char busy;
+    /* 0x10 */ u_char numstatus;
+    /* 0x11 */ u_char status;
+    /* 0x12 */ u_char completed[46];
+    u_char mraid_poll;
+    u_char mraid_ack;
+    u_char malign[16];
+} mega_ioctl_mbox;
+
+typedef struct _mega_sglist {
+    u_long address;
+    u_long length;
 } mega_sglist;
 
 /* Queued command data */
 typedef struct _mega_scb mega_scb;
 
-struct _mega_scb
-{
-  int             idx;
-  u_long          flag;
-  Scsi_Cmnd      *SCpnt;
-  u_char          mboxData[16];
-  mega_passthru   pthru;
-  mega_sglist    *sgList;
-  mega_scb       *next;
+struct _mega_scb {
+    int idx;
+    u_long flag;
+    Scsi_Cmnd *SCpnt;
+    u_char mboxData[16];
+    mega_passthru pthru;
+    mega_sglist *sgList;
+    mega_scb *next;
 };
 
 /* Per-controller data */
-typedef struct _mega_host_config
-{
-  u_char               numldrv;
-  u_long               flag;
-  u_long               base;
+typedef struct _mega_host_config {
+    u_char numldrv;
+    u_long flag;
+    u_long base;
 
-  struct tq_struct     megaTq;
+    struct tq_struct megaTq;
 
-  /* Host adapter parameters */
-  u_char               fwVer[7];
-  u_char               biosVer[7];
+    /* Host adapter parameters */
+    u_char fwVer[7];
+    u_char biosVer[7];
 
-  struct Scsi_Host     *host;
+    struct Scsi_Host *host;
 
-  /* The following must be DMA-able!! */
-  volatile mega_mailbox *mbox;
-  volatile mega_mailbox mailbox;
-  volatile u_char       mega_buffer[2*1024L];
+    /* The following must be DMA-able!! */
+    volatile mega_mailbox *mbox;
+    volatile mega_mailbox mailbox;
+    volatile u_char mega_buffer[2 * 1024L];
 
-  u_char                max_cmds;
-  mega_scb              scbList[MAX_COMMANDS];
+    u_char max_cmds;
+    mega_scb scbList[MAX_COMMANDS];
 } mega_host_config;
 
 extern struct proc_dir_entry proc_scsi_megaraid;
 
-const char *megaraid_info( struct Scsi_Host * );
-int        megaraid_detect( Scsi_Host_Template * );
-int        megaraid_release(struct Scsi_Host *);
-int        megaraid_command( Scsi_Cmnd * );
-int        megaraid_abort( Scsi_Cmnd * );
-int        megaraid_reset( Scsi_Cmnd *, unsigned int); 
-int        megaraid_queue( Scsi_Cmnd *, void (*done)(Scsi_Cmnd *) );
-int        megaraid_biosparam( Disk *, kdev_t, int * );
-int        megaraid_proc_info( char *buffer, char **start, off_t offset,
-                              int length, int hostno, int inout );
+const char *megaraid_info(struct Scsi_Host *);
+int megaraid_detect(Scsi_Host_Template *);
+int megaraid_release(struct Scsi_Host *);
+int megaraid_command(Scsi_Cmnd *);
+int megaraid_abort(Scsi_Cmnd *);
+int megaraid_reset(Scsi_Cmnd *, unsigned int);
+int megaraid_queue(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
+int megaraid_biosparam(Disk *, kdev_t, int *);
+int megaraid_proc_info(char *buffer, char **start, off_t offset,
+                      int length, int hostno, int inout);
 
 #endif
diff --git a/drivers/scsi/qlogicfc.c b/drivers/scsi/qlogicfc.c
new file mode 100644 (file)
index 0000000..d112096
--- /dev/null
@@ -0,0 +1,1937 @@
+/*
+ * QLogic ISP2100 SCSI-FCP
+ * Written by Erik H. Moe, ehm@cris.com
+ * Copyright 1995, Erik H. Moe
+ *
+ * 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.
+ */
+
+/* Renamed and updated to 1.3.x by Michael Griffith <grif@cs.ucr.edu> */
+
+/* This is a version of the isp1020 driver which was modified by
+ * Chris Loveland <cwl@iol.unh.edu> to support the isp2100
+ */
+
+/*
+ * $Date: 1995/09/22 02:23:15 $
+ * $Revision: 0.5 $
+ *
+ * $Log: isp1020.c,v $
+ * Revision 0.5  1995/09/22  02:23:15  root
+ * do auto request sense
+ *
+ * Revision 0.4  1995/08/07  04:44:33  root
+ * supply firmware with driver.
+ * numerous bug fixes/general cleanup of code.
+ *
+ * Revision 0.3  1995/07/16  16:15:39  root
+ * added reset/abort code.
+ *
+ * Revision 0.2  1995/06/29  03:14:19  root
+ * fixed biosparam.
+ * added queue protocol.
+ *
+ * Revision 0.1  1995/06/25  01:55:45  root
+ * Initial release.
+ *
+ */
+
+#include <linux/blk.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/unistd.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/spinlock.h>
+
+#include "sd.h"
+#include "hosts.h"
+#include "qlogicfc.h"
+
+/* Configuration section **************************************************** */
+
+/* Set the following macro to 1 to reload the ISP2100's firmware.  This is
+   version 1.13 of the firmware. */
+
+#define RELOAD_FIRMWARE                1
+
+#define USE_NVRAM_DEFAULTS      1
+
+
+/* Set the following to 1 to include fabric support, fabric support is 
+ * currently not as well tested as the other aspects of the driver */
+
+#define ISP2100_FABRIC          0
+
+/*  Macros used for debugging */
+/*
+#define DEBUG_ISP2100          1
+#define DEBUG_ISP2100_INT      1
+#define DEBUG_ISP2100_INTR     1
+#define DEBUG_ISP2100_SETUP    1
+
+#define DEBUG_ISP2100_FABRIC    1
+*/
+/* #define TRACE_ISP             1 */
+
+
+#define DEFAULT_LOOP_COUNT     10000000
+
+/* End Configuration section ************************************************ */
+
+#include <linux/module.h>
+
+#if TRACE_ISP
+
+#define TRACE_BUF_LEN  (32*1024)
+
+struct {
+       u_long next;
+       struct {
+               u_long time;
+               u_int index;
+               u_int addr;
+               u_char *name;
+       } buf[TRACE_BUF_LEN];
+} trace;
+
+#define TRACE(w, i, a)                                         \
+{                                                              \
+       unsigned long flags;                                    \
+                                                               \
+       save_flags(flags);                                      \
+       cli();                                                  \
+       trace.buf[trace.next].name  = (w);                      \
+       trace.buf[trace.next].time  = jiffies;                  \
+       trace.buf[trace.next].index = (i);                      \
+       trace.buf[trace.next].addr  = (long) (a);               \
+       trace.next = (trace.next + 1) & (TRACE_BUF_LEN - 1);    \
+       restore_flags(flags);                                   \
+}
+
+#else
+#define TRACE(w, i, a)
+#endif
+
+#if DEBUG_ISP2100_FABRIC
+#define DEBUG_FABRIC(x)        x
+#else
+#define DEBUG_FABRIC(x)
+#endif                         /* DEBUG_ISP2100_FABRIC */
+
+
+#if DEBUG_ISP2100
+#define ENTER(x)       printk("isp2100 : entering %s()\n", x);
+#define LEAVE(x)       printk("isp2100 : leaving %s()\n", x);
+#define DEBUG(x)       x
+#else
+#define ENTER(x)
+#define LEAVE(x)
+#define DEBUG(x)
+#endif                         /* DEBUG_ISP2100 */
+
+#if DEBUG_ISP2100_INTR
+#define ENTER_INTR(x)  printk("isp2100 : entering %s()\n", x);
+#define LEAVE_INTR(x)  printk("isp2100 : leaving %s()\n", x);
+#define DEBUG_INTR(x)  x
+#else
+#define ENTER_INTR(x)
+#define LEAVE_INTR(x)
+#define DEBUG_INTR(x)
+#endif                         /* DEBUG ISP2100_INTR */
+
+
+#if defined(__i386__)
+#define virt_to_bus_low32(x)   virt_to_bus(x)
+#define virt_to_bus_high32(x)  0x0
+#define bus_to_virt_low32(x)   bus_to_virt(x)
+#define bus_to_virt_high32(x)  0x0
+#elif defined(__alpha__)
+#define virt_to_bus_low32(x)   ((u32) (0xffffffff & virt_to_bus(x)))
+#define virt_to_bus_high32(x)  ((u32) (0xffffffff & (virt_to_bus(x)>>32)))
+#define bus_to_virt_low32(x)   ((u32) (0xffffffff & bus_to_virt(x)))
+#define bus_to_virt_high32(x)  ((u32) (0xffffffff & (bus_to_virt(x)>>32)))
+#endif
+
+#define ISP2100_REV_ID 1
+#define ISP2100_REV_ID3        3
+
+#define MAX_TARGETS    16
+#define MAX_LUNS       8
+
+/* host configuration and control registers */
+#define HOST_HCCR      0xc0    /* host command and control */
+
+/* pci bus interface registers */
+#define FLASH_BIOS_ADDR        0x00
+#define FLASH_BIOS_DATA        0x02
+#define ISP_CTRL_STATUS        0x06    /* configuration register #1 */
+#define PCI_INTER_CTL  0x08    /* pci interupt control */
+#define PCI_INTER_STS  0x0a    /* pci interupt status */
+#define PCI_SEMAPHORE  0x0c    /* pci semaphore */
+#define PCI_NVRAM      0x0e    /* pci nvram interface */
+
+/* mailbox registers */
+#define MBOX0          0x10    /* mailbox 0 */
+#define MBOX1          0x12    /* mailbox 1 */
+#define MBOX2          0x14    /* mailbox 2 */
+#define MBOX3          0x16    /* mailbox 3 */
+#define MBOX4          0x18    /* mailbox 4 */
+#define MBOX5          0x1a    /* mailbox 5 */
+#define MBOX6          0x1c    /* mailbox 6 */
+#define MBOX7          0x1e    /* mailbox 7 */
+
+/* mailbox command complete status codes */
+#define MBOX_COMMAND_COMPLETE          0x4000
+#define INVALID_COMMAND                        0x4001
+#define HOST_INTERFACE_ERROR           0x4002
+#define TEST_FAILED                    0x4003
+#define COMMAND_ERROR                  0x4005
+#define COMMAND_PARAM_ERROR            0x4006
+#define PORT_ID_USED                    0x4007
+#define LOOP_ID_USED                    0x4008
+#define ALL_IDS_USED                    0x4009
+
+/* async event status codes */
+#define RESET_DETECTED                 0x8001
+#define SYSTEM_ERROR                   0x8002
+#define REQUEST_TRANSFER_ERROR         0x8003
+#define RESPONSE_TRANSFER_ERROR                0x8004
+#define REQUEST_QUEUE_WAKEUP           0x8005
+#define LIP_OCCURED                     0x8010
+#define LOOP_UP                         0x8011
+#define LOOP_DOWN                       0x8012
+#define LIP_RECEIVED                    0x8013
+#define PORT_DB_CHANGED                 0x8014
+#define CHANGE_NOTIFICATION             0x8015
+#define SCSI_COMMAND_COMPLETE           0x8020
+
+struct Entry_header {
+       u_char entry_type;
+       u_char entry_cnt;
+       u_char sys_def_1;
+       u_char flags;
+};
+
+/* entry header type commands */
+#define ENTRY_COMMAND          0x19
+#define ENTRY_CONTINUATION     0x0a
+#define ENTRY_STATUS           0x03
+#define ENTRY_MARKER           0x04
+
+/* entry header flag definitions */
+#define EFLAG_BUSY             2
+#define EFLAG_BAD_HEADER       4
+#define EFLAG_BAD_PAYLOAD      8
+
+struct dataseg {
+       u_int d_base_lo;
+       u_int d_base_high;
+       u_int d_count;
+};
+
+struct Command_Entry {
+       struct Entry_header hdr;
+       u_int handle;
+       u_char target_lun;
+       u_char target_id;
+       u_short rsvd1;
+       u_short control_flags;
+       u_short rsvd2;
+       u_short time_out;
+       u_short segment_cnt;
+       u_char cdb[16];
+       u_int total_byte_cnt;
+       struct dataseg dataseg[2];
+};
+
+/* command entry control flag definitions */
+#define CFLAG_NODISC           0x01
+#define CFLAG_HEAD_TAG         0x02
+#define CFLAG_ORDERED_TAG      0x04
+#define CFLAG_SIMPLE_TAG       0x08
+#define CFLAG_TAR_RTN          0x10
+#define CFLAG_READ             0x20
+#define CFLAG_WRITE            0x40
+
+struct Ext_Command_Entry {
+       struct Entry_header hdr;
+       u_int handle;
+       u_char target_lun;
+       u_char target_id;
+       u_short cdb_length;
+       u_short control_flags;
+       u_short rsvd;
+       u_short time_out;
+       u_short segment_cnt;
+       u_char cdb[44];
+};
+
+struct Continuation_Entry {
+       struct Entry_header hdr;
+       struct dataseg dataseg[5];
+};
+
+struct Marker_Entry {
+       struct Entry_header hdr;
+       u_int reserved;
+       u_char target_lun;
+       u_char target_id;
+       u_char modifier;
+       u_char rsvd;
+       u_char rsvds[52];
+};
+
+/* marker entry modifier definitions */
+#define SYNC_DEVICE    0
+#define SYNC_TARGET    1
+#define SYNC_ALL       2
+
+struct Status_Entry {
+       struct Entry_header hdr;
+       u_int handle;
+       u_short scsi_status;
+       u_short completion_status;
+       u_short state_flags;
+       u_short status_flags;
+       u_short res_info_len;
+       u_short req_sense_len;
+       u_int residual;
+       u_char res_info[8];
+       u_char req_sense_data[32];
+};
+
+/* status entry completion status definitions */
+#define CS_COMPLETE                    0x0000
+#define CS_INCOMPLETE                  0x0001
+#define CS_DMA_ERROR                   0x0002
+#define CS_TRANSPORT_ERROR             0x0003
+#define CS_RESET_OCCURRED              0x0004
+#define CS_ABORTED                     0x0005
+#define CS_TIMEOUT                     0x0006
+#define CS_DATA_OVERRUN                        0x0007
+#define CS_ABORT_MSG_FAILED            0x000e
+#define CS_REJECT_MSG_FAILED           0x000f
+#define CS_DATA_UNDERRUN               0x0015
+#define CS_PORT_UNAVAILABLE             0x0028
+#define CS_PORT_LOGGED_OUT              0x0029
+#define CS_PORT_CONFIG_CHANGED         0x002a
+
+/* status entry state flag definitions */
+#define SF_SENT_CDB                    0x0400
+#define SF_TRANSFERRED_DATA            0x0800
+#define SF_GOT_STATUS                  0x1000
+
+/* status entry status flag definitions */
+#define STF_BUS_RESET                  0x0008
+#define STF_DEVICE_RESET               0x0010
+#define STF_ABORTED                    0x0020
+#define STF_TIMEOUT                    0x0040
+
+/* interupt control commands */
+#define ISP_EN_INT                     0x8000
+#define ISP_EN_RISC                    0x0008
+
+/* host control commands */
+#define HCCR_NOP                       0x0000
+#define HCCR_RESET                     0x1000
+#define HCCR_PAUSE                     0x2000
+#define HCCR_RELEASE                   0x3000
+#define HCCR_SINGLE_STEP               0x4000
+#define HCCR_SET_HOST_INTR             0x5000
+#define HCCR_CLEAR_HOST_INTR           0x6000
+#define HCCR_CLEAR_RISC_INTR           0x7000
+#define HCCR_BP_ENABLE                 0x8000
+#define HCCR_BIOS_DISABLE              0x9000
+#define HCCR_TEST_MODE                 0xf000
+
+#define RISC_BUSY                      0x0004
+
+/* mailbox commands */
+#define MBOX_NO_OP                     0x0000
+#define MBOX_LOAD_RAM                  0x0001
+#define MBOX_EXEC_FIRMWARE             0x0002
+#define MBOX_DUMP_RAM                  0x0003
+#define MBOX_WRITE_RAM_WORD            0x0004
+#define MBOX_READ_RAM_WORD             0x0005
+#define MBOX_MAILBOX_REG_TEST          0x0006
+#define MBOX_VERIFY_CHECKSUM           0x0007
+#define MBOX_ABOUT_FIRMWARE            0x0008
+#define MBOX_LOAD_RISC_RAM              0x0009
+#define MBOX_DUMP_RISC_RAM              0x000a
+#define MBOX_CHECK_FIRMWARE            0x000e
+#define MBOX_INIT_REQ_QUEUE            0x0010
+#define MBOX_INIT_RES_QUEUE            0x0011
+#define MBOX_EXECUTE_IOCB              0x0012
+#define MBOX_WAKE_UP                   0x0013
+#define MBOX_STOP_FIRMWARE             0x0014
+#define MBOX_ABORT_IOCB                        0x0015
+#define MBOX_ABORT_DEVICE              0x0016
+#define MBOX_ABORT_TARGET              0x0017
+#define MBOX_BUS_RESET                 0x0018
+#define MBOX_STOP_QUEUE                        0x0019
+#define MBOX_START_QUEUE               0x001a
+#define MBOX_SINGLE_STEP_QUEUE         0x001b
+#define MBOX_ABORT_QUEUE               0x001c
+#define MBOX_GET_DEV_QUEUE_STATUS      0x001d
+#define MBOX_GET_FIRMWARE_STATUS       0x001f
+#define MBOX_GET_INIT_SCSI_ID          0x0020
+#define MBOX_GET_RETRY_COUNT           0x0022
+#define MBOX_GET_TARGET_PARAMS         0x0028
+#define MBOX_GET_DEV_QUEUE_PARAMS      0x0029
+#define MBOX_SET_RETRY_COUNT           0x0032
+#define MBOX_SET_TARGET_PARAMS         0x0038
+#define MBOX_SET_DEV_QUEUE_PARAMS      0x0039
+#define MBOX_EXECUTE_IOCB64             0x0054
+#define MBOX_INIT_FIRMWARE              0x0060
+#define MBOX_GET_INIT_CB                0x0061
+#define MBOX_INIT_LIP                  0x0062
+#define MBOX_GET_POS_MAP                0x0063
+#define MBOX_GET_PORT_DB                0x0064
+#define MBOX_CLEAR_ACA                  0x0065
+#define MBOX_TARGET_RESET               0x0066
+#define MBOX_CLEAR_TASK_SET             0x0067
+#define MBOX_ABORT_TASK_SET             0x0068
+#define MBOX_GET_FIRMWARE_STATE         0x0069
+#define MBOX_GET_PORT_NAME              0x006a
+#define MBOX_SEND_SNS                   0x006e
+#define MBOX_PORT_LOGIN                 0x006f
+#define MBOX_SEND_CHANGE_REQUEST        0x0070
+#define MBOX_PORT_LOGOUT                0x0071
+
+#include "qlogicfc_asm.c"
+
+/* Each element in mbox_param is an 8 bit bitmap where each bit indicates
+   if that mbox should be copied as input.  For example 0x2 would mean
+   only copy mbox1. */
+
+const u_char mbox_param[] =
+{
+       0x01,                   /* MBOX_NO_OP */
+       0x1f,                   /* MBOX_LOAD_RAM */
+       0x03,                   /* MBOX_EXEC_FIRMWARE */
+       0x1f,                   /* MBOX_DUMP_RAM */
+       0x07,                   /* MBOX_WRITE_RAM_WORD */
+       0x03,                   /* MBOX_READ_RAM_WORD */
+       0xff,                   /* MBOX_MAILBOX_REG_TEST */
+       0x03,                   /* MBOX_VERIFY_CHECKSUM */
+       0x01,                   /* MBOX_ABOUT_FIRMWARE */
+       0xff,                   /* MBOX_LOAD_RISC_RAM */
+       0xff,                   /* MBOX_DUMP_RISC_RAM */
+       0x00,                   /* 0x000b */
+       0x00,                   /* 0x000c */
+       0x00,                   /* 0x000d */
+       0x01,                   /* MBOX_CHECK_FIRMWARE */
+       0x00,                   /* 0x000f */
+       0x1f,                   /* MBOX_INIT_REQ_QUEUE */
+       0x2f,                   /* MBOX_INIT_RES_QUEUE */
+       0x0f,                   /* MBOX_EXECUTE_IOCB */
+       0x03,                   /* MBOX_WAKE_UP */
+       0x01,                   /* MBOX_STOP_FIRMWARE */
+       0x0f,                   /* MBOX_ABORT_IOCB */
+       0x03,                   /* MBOX_ABORT_DEVICE */
+       0x07,                   /* MBOX_ABORT_TARGET */
+       0x03,                   /* MBOX_BUS_RESET */
+       0x03,                   /* MBOX_STOP_QUEUE */
+       0x03,                   /* MBOX_START_QUEUE */
+       0x03,                   /* MBOX_SINGLE_STEP_QUEUE */
+       0x03,                   /* MBOX_ABORT_QUEUE */
+       0x03,                   /* MBOX_GET_DEV_QUEUE_STATUS */
+       0x00,                   /* 0x001e */
+       0x01,                   /* MBOX_GET_FIRMWARE_STATUS */
+       0x01,                   /* MBOX_GET_INIT_SCSI_ID */
+       0x00,                   /* 0x0021 */
+       0x01,                   /* MBOX_GET_RETRY_COUNT */
+       0x00,                   /* 0x0023 */
+       0x00,                   /* 0x0024 */
+       0x00,                   /* 0x0025 */
+       0x00,                   /* 0x0026 */
+       0x00,                   /* 0x0027 */
+       0x03,                   /* MBOX_GET_TARGET_PARAMS */
+       0x03,                   /* MBOX_GET_DEV_QUEUE_PARAMS */
+       0x00,                   /* 0x002a */
+       0x00,                   /* 0x002b */
+       0x00,                   /* 0x002c */
+       0x00,                   /* 0x002d */
+       0x00,                   /* 0x002e */
+       0x00,                   /* 0x002f */
+       0x00,                   /* 0x0030 */
+       0x00,                   /* 0x0031 */
+       0x07,                   /* MBOX_SET_RETRY_COUNT */
+       0x00,                   /* 0x0033 */
+       0x00,                   /* 0x0034 */
+       0x00,                   /* 0x0035 */
+       0x00,                   /* 0x0036 */
+       0x00,                   /* 0x0037 */
+       0x0f,                   /* MBOX_SET_TARGET_PARAMS */
+       0x0f,                   /* MBOX_SET_DEV_QUEUE_PARAMS */
+       0x00,                   /* 0x003a */
+       0x00,                   /* 0x003b */
+       0x00,                   /* 0x003c */
+       0x00,                   /* 0x003d */
+       0x00,                   /* 0x003e */
+       0x00,                   /* 0x003f */
+       0x00,                   /* 0x0040 */
+       0x00,                   /* 0x0041 */
+       0x00,                   /* 0x0042 */
+       0x00,                   /* 0x0043 */
+       0x00,                   /* 0x0044 */
+       0x00,                   /* 0x0045 */
+       0x00,                   /* 0x0046 */
+       0x00,                   /* 0x0047 */
+       0x00,                   /* 0x0048 */
+       0x00,                   /* 0x0049 */
+       0x00,                   /* 0x004a */
+       0x00,                   /* 0x004b */
+       0x00,                   /* 0x004c */
+       0x00,                   /* 0x004d */
+       0x00,                   /* 0x004e */
+       0x00,                   /* 0x004f */
+       0x00,                   /* 0x0050 */
+       0x00,                   /* 0x0051 */
+       0x00,                   /* 0x0052 */
+       0x00,                   /* 0x0053 */
+       0xcf,                   /* MBOX_EXECUTE_IOCB64 */
+       0x00,                   /* 0x0055 */
+       0x00,                   /* 0x0056 */
+       0x00,                   /* 0x0057 */
+       0x00,                   /* 0x0058 */
+       0x00,                   /* 0x0059 */
+       0x00,                   /* 0x005a */
+       0x00,                   /* 0x005b */
+       0x00,                   /* 0x005c */
+       0x00,                   /* 0x005d */
+       0x00,                   /* 0x005e */
+       0x00,                   /* 0x005f */
+       0xff,                   /* MBOX_INIT_FIRMWARE */
+       0xcd,                   /* MBOX_GET_INIT_CB */
+       0x01,                   /* MBOX_INIT_LIP */
+       0xcd,                   /* MBOX_GET_POS_MAP */
+       0xcf,                   /* MBOX_GET_PORT_DB */
+       0x03,                   /* MBOX_CLEAR_ACA */
+       0x03,                   /* MBOX_TARGET_RESET */
+       0x03,                   /* MBOX_CLEAR_TASK_SET */
+       0x03,                   /* MBOX_ABORT_TASK_SET */
+       0x01,                   /* MBOX_GET_FIRMWARE_STATE */
+       0x03,                   /* MBOX_GET_PORT_NAME */
+       0x00,                   /* 0x006b */
+       0x00,                   /* 0x006c */
+       0x00,                   /* 0x006d */
+       0xcf,                   /* MBOX_SEND_SNS */
+       0x0f,                   /* MBOX_PORT_LOGIN */
+       0x03,                   /* MBOX_SEND_CHANGE_REQUEST */
+       0x03,                   /* MBOX_PORT_LOGOUT */
+};
+
+#define MAX_MBOX_COMMAND       (sizeof(mbox_param)/sizeof(u_short))
+
+
+struct id_name_map {
+       u64 wwn;
+       u_char loop_id;
+};
+
+struct sns_cb {
+       u_short len;
+       u_short res1;
+       u_int response_low;
+       u_int response_high;
+       u_short sub_len;
+       u_short res2;
+       u_short data[22];
+};
+
+/* address of instance of this struct is passed to adapter to initialize things
+ */
+struct init_cb {
+       u_char version;
+       u_char reseverd1[1];
+       u_short firm_opts;
+       u_short max_frame_len;
+       u_short max_iocb;
+       u_short exec_throttle;
+       u_char retry_cnt;
+       u_char retry_delay;
+       u_short node_name[4];
+       u_short hard_addr;
+       u_char reserved2[10];
+       u_short req_queue_out;
+       u_short res_queue_in;
+       u_short req_queue_len;
+       u_short res_queue_len;
+       u_int req_queue_addr_lo;
+       u_int req_queue_addr_high;
+       u_int res_queue_addr_lo;
+       u_int res_queue_addr_high;
+};
+
+/*
+ * The result queue can be quite a bit smaller since continuation entries
+ * do not show up there:
+ */
+#define RES_QUEUE_LEN          ((QLOGICFC_REQ_QUEUE_LEN + 1) / 8 - 1)
+#define QUEUE_ENTRY_LEN                64
+
+#if ISP2100_FABRIC
+#define QLOGICFC_MAX_ID    0xff
+#else
+#define QLOGICFC_MAX_ID    0x80
+#endif
+
+struct isp2100_hostdata {
+       u_char revision;
+       struct pci_dev *pci_dev;
+       /* result and request queues (shared with isp2100): */
+       u_int req_in_ptr;       /* index of next request slot */
+       u_int res_out_ptr;      /* index of next result slot */
+
+       /* this is here so the queues are nicely aligned */
+       long send_marker;       /* do we need to send a marker? */
+
+       char res[RES_QUEUE_LEN + 1][QUEUE_ENTRY_LEN];
+       char req[QLOGICFC_REQ_QUEUE_LEN + 1][QUEUE_ENTRY_LEN];
+       struct init_cb control_block;
+       int loop_up;
+       unsigned long int tag_ages[126];
+       Scsi_Cmnd *handle_ptrs[QLOGICFC_REQ_QUEUE_LEN + 1];
+       unsigned long handle_serials[QLOGICFC_REQ_QUEUE_LEN + 1];
+       struct id_name_map port_db[QLOGICFC_MAX_ID + 1];
+       u_char mbox_done;
+       u64 wwn;
+       u_int port_id;
+       u_char queued;
+};
+
+
+/* queue length's _must_ be power of two: */
+#define QUEUE_DEPTH(in, out, ql)       ((in - out) & (ql))
+#define REQ_QUEUE_DEPTH(in, out)       QUEUE_DEPTH(in, out,                 \
+                                                   QLOGICFC_REQ_QUEUE_LEN)
+#define RES_QUEUE_DEPTH(in, out)       QUEUE_DEPTH(in, out, RES_QUEUE_LEN)
+
+static void isp2100_enable_irqs(struct Scsi_Host *);
+static void isp2100_disable_irqs(struct Scsi_Host *);
+static int isp2100_init(struct Scsi_Host *);
+static int isp2100_reset_hardware(struct Scsi_Host *);
+static int isp2100_mbox_command(struct Scsi_Host *, u_short[]);
+static int isp2100_return_status(struct Status_Entry *);
+static void isp2100_intr_handler(int, void *, struct pt_regs *);
+static void do_isp2100_intr_handler(int, void *, struct pt_regs *);
+static int isp2100_make_portdb(struct Scsi_Host *);
+
+#if ISP2100_FABRIC
+static int isp2100_init_fabric(struct Scsi_Host *, struct id_name_map *, int);
+#endif
+
+#if USE_NVRAM_DEFAULTS
+static int isp2100_get_nvram_defaults(struct Scsi_Host *, struct init_cb *);
+static u_short isp2100_read_nvram_word(struct Scsi_Host *, u_short);
+#endif
+
+#if DEBUG_ISP2100
+static void isp2100_print_scsi_cmd(Scsi_Cmnd *);
+#endif
+
+#if DEBUG_ISP2100_INTR
+static void isp2100_print_status_entry(struct Status_Entry *);
+#endif
+
+static struct proc_dir_entry proc_scsi_isp2100 =
+{
+       PROC_SCSI_QLOGICFC, 7, "isp2100",
+       S_IFDIR | S_IRUGO | S_IXUGO, 2
+};
+
+
+static inline void isp2100_enable_irqs(struct Scsi_Host *host)
+{
+       outw(ISP_EN_INT | ISP_EN_RISC, host->io_port + PCI_INTER_CTL);
+}
+
+
+static inline void isp2100_disable_irqs(struct Scsi_Host *host)
+{
+       outw(0x0, host->io_port + PCI_INTER_CTL);
+}
+
+
+int isp2100_detect(Scsi_Host_Template * tmpt)
+{
+       int hosts = 0;
+       int wait_time;
+       struct Scsi_Host *host = NULL;
+       struct isp2100_hostdata *hostdata;
+       struct pci_dev *pdev = NULL;
+
+       ENTER("isp2100_detect");
+
+       tmpt->proc_dir = &proc_scsi_isp2100;
+
+       if (pci_present() == 0) {
+               printk("qlogicfc : PCI not present\n");
+               return 0;
+       }
+       while ((pdev = pci_find_device(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2100, pdev))) {
+
+               host = scsi_register(tmpt, sizeof(struct isp2100_hostdata));
+               host->max_id = QLOGICFC_MAX_ID + 1;
+               host->hostt->use_new_eh_code = 1;
+               hostdata = (struct isp2100_hostdata *) host->hostdata;
+
+               memset(hostdata, 0, sizeof(struct isp2100_hostdata));
+               hostdata->pci_dev = pdev;
+
+               hostdata->queued = 0;
+               /* set up the control block */
+               hostdata->control_block.version = 0x0f;
+               hostdata->control_block.firm_opts = 0x010c;
+               hostdata->control_block.max_frame_len = 2048;
+               hostdata->control_block.max_iocb = 256;
+               hostdata->control_block.exec_throttle = 8;
+               hostdata->control_block.retry_delay = 5;
+               hostdata->control_block.retry_cnt = 0;
+               hostdata->control_block.node_name[0] = 0x0020;
+               hostdata->control_block.node_name[1] = 0xE000;
+               hostdata->control_block.node_name[2] = 0x008B;
+               hostdata->control_block.node_name[3] = 0x0000;
+               hostdata->control_block.hard_addr = 0x0003;
+               hostdata->control_block.req_queue_len = QLOGICFC_REQ_QUEUE_LEN + 1;
+               hostdata->control_block.res_queue_len = RES_QUEUE_LEN + 1;
+               hostdata->control_block.res_queue_addr_lo = virt_to_bus_low32(&hostdata->res);
+               hostdata->control_block.res_queue_addr_high = virt_to_bus_high32(&hostdata->res);
+               hostdata->control_block.req_queue_addr_lo = virt_to_bus_low32(&hostdata->req);
+               hostdata->control_block.req_queue_addr_high = virt_to_bus_high32(&hostdata->req);
+
+               hostdata->loop_up = 0;
+
+               if (isp2100_init(host) || isp2100_reset_hardware(host)) {
+                       scsi_unregister(host);
+                       continue;
+               }
+               host->this_id = tmpt->this_id;
+
+               if (request_irq(host->irq, do_isp2100_intr_handler, SA_INTERRUPT | SA_SHIRQ, "qlogicfc", host)) {
+                       printk("qlogicfc : interrupt %d already in use\n",
+                              host->irq);
+                       scsi_unregister(host);
+                       continue;
+               }
+               if (check_region(host->io_port, 0xff)) {
+                       printk("qlogicfc : i/o region 0x%lx-0x%lx already "
+                              "in use\n",
+                              host->io_port, host->io_port + 0xff);
+                       free_irq(host->irq, host);
+                       scsi_unregister(host);
+                       continue;
+               }
+               request_region(host->io_port, 0xff, "qlogicfc");
+
+               outw(0x0, host->io_port + PCI_SEMAPHORE);
+               outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR);
+               isp2100_enable_irqs(host);
+               /* wait for the loop to come up */
+               for (wait_time = jiffies + 20 * HZ; wait_time > jiffies && hostdata->loop_up == 0;)
+                       barrier();
+
+               if (hostdata->loop_up == 0) {
+                       printk("qlogicfc: loop is not up\n");
+                       release_region(host->io_port, 0xff);
+                       free_irq(host->irq, host);
+                       scsi_unregister(host);
+                       continue;
+               }
+               hosts++;
+       }
+
+
+       /* this busy loop should not be needed but the isp2100 seems to need 
+          some time before recognizing it is attached to a fabric */
+
+#if ISP2100_FABRIC
+       for (wait_time = jiffies + 5 * HZ; wait_time > jiffies;)
+               barrier();
+#endif
+
+       LEAVE("isp2100_detect");
+
+       return hosts;
+}
+
+
+static int isp2100_make_portdb(struct Scsi_Host *host)
+{
+
+       short param[8];
+       int i, j;
+       struct id_name_map temp[QLOGICFC_MAX_ID + 1];
+       struct isp2100_hostdata *hostdata;
+
+       isp2100_disable_irqs(host);
+
+       memset(temp, 0, sizeof(temp));
+       hostdata = (struct isp2100_hostdata *) host->hostdata;
+
+#if ISP2100_FABRIC
+       for (i = 0x81; i < QLOGICFC_MAX_ID; i++) {
+               param[0] = MBOX_PORT_LOGOUT;
+               param[1] = i << 8;
+               param[2] = 0;
+               param[3] = 0;
+
+               isp2100_mbox_command(host, param);
+
+               if (param[0] != MBOX_COMMAND_COMPLETE) {
+                       printk("logout failed %x  %x\n", i, param[0]);
+               }
+       }
+#endif
+
+
+       param[0] = MBOX_GET_INIT_SCSI_ID;
+
+       isp2100_mbox_command(host, param);
+
+       if (param[0] == MBOX_COMMAND_COMPLETE) {
+               host->this_id = param[1];
+               hostdata->port_id = ((u_int) param[3]) << 16;
+               hostdata->port_id |= param[2];
+       }
+
+       for (i = 0, j = 0; i <= QLOGICFC_MAX_ID; i++) {
+               temp[i].loop_id = host->this_id;
+
+               param[0] = MBOX_GET_PORT_NAME;
+               param[1] = (i << 8) & 0xff00;
+
+               isp2100_mbox_command(host, param);
+
+               if (param[0] == MBOX_COMMAND_COMPLETE) {
+                       temp[j].loop_id = i;
+                       temp[j].wwn = ((u64) (param[2] & 0xff)) << 56;
+                       temp[j].wwn |= ((u64) ((param[2] >> 8) & 0xff)) << 48;
+                       temp[j].wwn |= ((u64) (param[3] & 0xff)) << 40;
+                       temp[j].wwn |= ((u64) ((param[3] >> 8) & 0xff)) << 32;
+                       temp[j].wwn |= ((u64) (param[6] & 0xff)) << 24;
+                       temp[j].wwn |= ((u64) ((param[6] >> 8) & 0xff)) << 16;
+                       temp[j].wwn |= ((u64) (param[7] & 0xff)) << 8;
+                       temp[j].wwn |= ((u64) ((param[7] >> 8) & 0xff));
+
+                       j++;
+
+               }
+       }
+
+
+#if ISP2100_FABRIC
+       isp2100_init_fabric(host, temp, j);
+#endif
+
+       for (i = 0; i <= QLOGICFC_MAX_ID; i++) {
+               if (temp[i].wwn != hostdata->port_db[i].wwn) {
+                       for (j = 0; j <= QLOGICFC_MAX_ID; j++) {
+                               if (temp[j].wwn == hostdata->port_db[i].wwn) {
+                                       hostdata->port_db[i].loop_id = temp[j].loop_id;
+                                       break;
+                               }
+                       }
+                       if (j == QLOGICFC_MAX_ID + 1)
+                               hostdata->port_db[i].loop_id = host->this_id;
+
+                       for (j = 0; j <= QLOGICFC_MAX_ID; j++) {
+                               if (hostdata->port_db[j].wwn == temp[i].wwn || !hostdata->port_db[j].wwn) {
+                                       break;
+                               }
+                       }
+                       if (j == QLOGICFC_MAX_ID + 1)
+                               printk("qlogicfc.c: Too many scsi devices, no more room in port map.\n");
+                       if (!hostdata->port_db[j].wwn) {
+                               hostdata->port_db[j].loop_id = temp[i].loop_id;
+                               hostdata->port_db[j].wwn = temp[i].wwn;
+                       }
+               } else
+                       hostdata->port_db[i].loop_id = temp[i].loop_id;
+
+       }
+
+       isp2100_enable_irqs(host);
+
+       return 0;
+}
+
+
+#if ISP2100_FABRIC
+
+int isp2100_init_fabric(struct Scsi_Host *host, struct id_name_map *port_db, int j)
+{
+
+       u_short param[8];
+       u64 wwn;
+       int done = 0;
+       u_short loop_id = 0x81;
+       u_short scsi_id = j;
+       u_int port_id;
+       struct sns_cb req;
+       u_char sns_response[608];
+       struct isp2100_hostdata *hostdata;
+
+       hostdata = (struct isp2100_hostdata *) host->hostdata;
+
+       DEBUG_FABRIC(printk("qlogicfc.c: Checking for a fabric.\n"));
+       param[0] = MBOX_GET_PORT_NAME;
+       param[1] = 0x7E00;
+
+       isp2100_mbox_command(host, param);
+
+       if (param[0] != MBOX_COMMAND_COMPLETE) {
+               DEBUG_FABRIC(printk("fabric check result %x\n", param[0]));
+               return 0;
+       }
+       printk("qlogicfc.c: Fabric found.\n");
+
+
+       port_id = hostdata->port_id;
+       while (!done) {
+               memset(&req, 0, sizeof(req));
+
+               req.len = 304;
+               req.response_low = virt_to_bus_low32(sns_response);
+               req.response_high = virt_to_bus_high32(sns_response);
+               req.sub_len = 6;
+               req.data[0] = 0x0100;
+               req.data[4] = (u_short) (port_id & 0xffff);
+               req.data[5] = (u_short) (port_id >> 16 & 0xffff);
+
+               param[0] = MBOX_SEND_SNS;
+               param[1] = 14;
+               param[2] = virt_to_bus_low32(&req) >> 16;
+               param[3] = virt_to_bus_low32(&req);
+               param[6] = virt_to_bus_high32(&req) >> 16;
+               param[7] = virt_to_bus_high32(&req);
+
+               isp2100_mbox_command(host, param);
+
+               if (param[0] == MBOX_COMMAND_COMPLETE) {
+                       DEBUG_FABRIC(printk("found node %02x%02x%02x%02x%02x%02x%02x%02x ", sns_response[20], sns_response[21], sns_response[22], sns_response[23], sns_response[24], sns_response[25], sns_response[26], sns_response[27]));
+                       DEBUG_FABRIC(printk("  port id: %02x%02x%02x\n", sns_response[17], sns_response[18], sns_response[19]));
+                       port_id = ((u_int) sns_response[17]) << 16;
+                       port_id |= ((u_int) sns_response[18]) << 8;
+                       port_id |= ((u_int) sns_response[19]);
+                       wwn = ((u64) sns_response[20]) << 56;
+                       wwn |= ((u64) sns_response[21]) << 48;
+                       wwn |= ((u64) sns_response[22]) << 40;
+                       wwn |= ((u64) sns_response[23]) << 32;
+                       wwn |= ((u64) sns_response[24]) << 24;
+                       wwn |= ((u64) sns_response[25]) << 16;
+                       wwn |= ((u64) sns_response[26]) << 8;
+                       wwn |= ((u64) sns_response[27]);
+                       if (hostdata->port_id >> 8 != port_id >> 8) {
+                               DEBUG_FABRIC(printk("adding a fabric port: %x\n", port_id));
+                               param[0] = MBOX_PORT_LOGIN;
+                               param[1] = loop_id << 8;
+                               param[2] = (u_short) (port_id >> 16);
+                               param[3] = (u_short) (port_id);
+
+                               isp2100_mbox_command(host, param);
+
+                               if (param[0] == MBOX_COMMAND_COMPLETE) {
+                                       port_db[scsi_id].wwn = wwn;
+                                       port_db[scsi_id].loop_id = loop_id;
+                                       loop_id++;
+                                       scsi_id++;
+                               } else {
+                                       printk("qlogicfc.c: Error performing port login %x\n", param[0]);
+                                       DEBUG_FABRIC(printk("loop_id: %x\n", loop_id));
+                               }
+
+                       }
+                       if (hostdata->port_id == port_id)
+                               done = 1;
+               } else {
+                       printk("qlogicfc.c: Get All Next failed %x.\n", param[0]);
+                       return 0;
+               }
+       }
+
+       return 1;
+}
+
+#endif                         /* ISP2100_FABRIC */
+
+
+int isp2100_release(struct Scsi_Host *host)
+{
+       struct isp2100_hostdata *hostdata;
+
+       ENTER("isp2100_release");
+
+       hostdata = (struct isp2100_hostdata *) host->hostdata;
+
+       outw(0x0, host->io_port + PCI_INTER_CTL);
+       free_irq(host->irq, host);
+
+       release_region(host->io_port, 0xff);
+
+       LEAVE("isp2100_release");
+
+       return 0;
+}
+
+
+const char *isp2100_info(struct Scsi_Host *host)
+{
+       static char buf[80];
+       struct isp2100_hostdata *hostdata;
+       ENTER("isp2100_info");
+
+       hostdata = (struct isp2100_hostdata *) host->hostdata;
+       sprintf(buf,
+               "QLogic ISP2100 SCSI on PCI bus %02x device %02x irq %d base 0x%lx",
+               hostdata->pci_dev->bus->number, hostdata->pci_dev->devfn, host->irq,
+               host->io_port);
+
+
+       LEAVE("isp2100_info");
+
+       return buf;
+}
+
+
+/*
+ * The middle SCSI layer ensures that queuecommand never gets invoked
+ * concurrently with itself or the interrupt handler (though the
+ * interrupt handler may call this routine as part of
+ * request-completion handling).
+ */
+int isp2100_queuecommand(Scsi_Cmnd * Cmnd, void (*done) (Scsi_Cmnd *))
+{
+       int i, sg_count, n, num_free;
+       u_int in_ptr, out_ptr;
+       struct dataseg *ds;
+       struct scatterlist *sg;
+       struct Command_Entry *cmd;
+       struct Continuation_Entry *cont;
+       struct Scsi_Host *host;
+       struct isp2100_hostdata *hostdata;
+
+       ENTER("isp2100_queuecommand");
+
+       host = Cmnd->host;
+       hostdata = (struct isp2100_hostdata *) host->hostdata;
+       Cmnd->scsi_done = done;
+
+       DEBUG(isp2100_print_scsi_cmd(Cmnd));
+
+       if (hostdata->loop_up == 2) {
+               hostdata->loop_up = 1;
+               isp2100_make_portdb(host);
+               for (i = 0; hostdata->port_db[i].wwn != 0; i++) {
+                       DEBUG(printk("wwn: %08x%08x  scsi_id: %x  loop_id: %x\n", (u_int) (hostdata->port_db[i].wwn >> 32), (u_int) hostdata->port_db[i].wwn, i, hostdata->port_db[i].loop_id));
+               }
+       }
+       if (hostdata->loop_up == -1) {
+               printk("qlogicfc.c: The firmware is dead, just return.\n");
+               host->max_id = 0;
+               return 0;
+       }
+       out_ptr = inw(host->io_port + MBOX4);
+       in_ptr = hostdata->req_in_ptr;
+
+       DEBUG(printk("qlogicfc : request queue depth %d\n",
+                    REQ_QUEUE_DEPTH(in_ptr, out_ptr)));
+
+       cmd = (struct Command_Entry *) &hostdata->req[in_ptr][0];
+       in_ptr = (in_ptr + 1) & QLOGICFC_REQ_QUEUE_LEN;
+       if (in_ptr == out_ptr) {
+               DEBUG(printk("qlogicfc : request queue overflow\n"));
+               return 1;
+       }
+       if (hostdata->send_marker) {
+               struct Marker_Entry *marker;
+
+               TRACE("queue marker", in_ptr, 0);
+
+               DEBUG(printk("qlogicfc : adding marker entry\n"));
+               marker = (struct Marker_Entry *) cmd;
+               memset(marker, 0, sizeof(struct Marker_Entry));
+
+               marker->hdr.entry_type = ENTRY_MARKER;
+               marker->hdr.entry_cnt = 1;
+               marker->modifier = SYNC_ALL;
+
+               hostdata->send_marker = 0;
+
+               if (((in_ptr + 1) & QLOGICFC_REQ_QUEUE_LEN) == out_ptr) {
+                       outw(in_ptr, host->io_port + MBOX4);
+                       hostdata->req_in_ptr = in_ptr;
+                       DEBUG(printk("qlogicfc : request queue overflow\n"));
+                       return 1;
+               }
+               cmd = (struct Command_Entry *) &hostdata->req[in_ptr][0];
+               in_ptr = (in_ptr + 1) & QLOGICFC_REQ_QUEUE_LEN;
+       }
+       TRACE("queue command", in_ptr, Cmnd);
+
+       memset(cmd, 0, sizeof(struct Command_Entry));
+
+       /* find a free handle mapping slot */
+       for (i = in_ptr; i != (in_ptr - 1) && hostdata->handle_ptrs[i]; i = ((i + 1) % (QLOGICFC_REQ_QUEUE_LEN + 1)));
+
+       if (!hostdata->handle_ptrs[i]) {
+               cmd->handle = i;
+               hostdata->handle_ptrs[i] = Cmnd;
+               hostdata->handle_serials[i] = Cmnd->serial_number;
+       } else
+               printk("qlogicfc: no handle slots, this should not happen.\n");
+
+       cmd->hdr.entry_type = ENTRY_COMMAND;
+       cmd->hdr.entry_cnt = 1;
+       cmd->target_lun = Cmnd->lun;
+       cmd->target_id = hostdata->port_db[Cmnd->target].loop_id;
+       cmd->total_byte_cnt = (u_int) Cmnd->request_bufflen;
+       cmd->time_out = SCSI_TIMEOUT / HZ;
+
+       memcpy(cmd->cdb, Cmnd->cmnd, Cmnd->cmd_len);
+
+       if (Cmnd->use_sg) {
+               cmd->segment_cnt = sg_count = Cmnd->use_sg;
+               sg = (struct scatterlist *) Cmnd->request_buffer;
+               ds = cmd->dataseg;
+               /* fill in first two sg entries: */
+               n = sg_count;
+               if (n > 2)
+                       n = 2;
+               for (i = 0; i < n; i++) {
+                       ds[i].d_base_lo = virt_to_bus_low32(sg->address);
+                       ds[i].d_base_high = virt_to_bus_high32(sg->address);
+                       ds[i].d_count = sg->length;
+                       ++sg;
+               }
+               sg_count -= 2;
+
+               while (sg_count > 0) {
+                       ++cmd->hdr.entry_cnt;
+                       cont = (struct Continuation_Entry *)
+                           &hostdata->req[in_ptr][0];
+                       memset(cont, 0, sizeof(struct Continuation_Entry));
+                       in_ptr = (in_ptr + 1) & QLOGICFC_REQ_QUEUE_LEN;
+                       if (in_ptr == out_ptr) {
+                               DEBUG(printk("isp2100: unexpected request queue overflow\n"));
+                               return 1;
+                       }
+                       TRACE("queue continuation", in_ptr, 0);
+                       cont->hdr.entry_type = ENTRY_CONTINUATION;
+                       ds = cont->dataseg;
+                       n = sg_count;
+                       if (n > 5)
+                               n = 5;
+                       for (i = 0; i < n; ++i) {
+                               ds[i].d_base_lo = virt_to_bus_low32(sg->address);
+                               ds[i].d_base_high = virt_to_bus_high32(sg->address);
+                               ds[i].d_count = sg->length;
+                               ++sg;
+                       }
+                       sg_count -= n;
+               }
+       } else {
+               cmd->dataseg[0].d_base_lo = virt_to_bus_low32(Cmnd->request_buffer);
+               cmd->dataseg[0].d_base_high = virt_to_bus_high32(Cmnd->request_buffer);
+               cmd->dataseg[0].d_count =
+                   (u_int) Cmnd->request_bufflen;
+               cmd->segment_cnt = 1;
+       }
+
+       switch (Cmnd->cmnd[0]) {
+       case WRITE_10:
+       case WRITE_6:
+       case WRITE_BUFFER:
+               cmd->control_flags = CFLAG_WRITE;
+               break;
+       case REQUEST_SENSE:
+               /* scsi.c expects sense info in a different buffer */
+               cmd->dataseg[0].d_base_lo = virt_to_bus_low32(Cmnd->sense_buffer);
+               cmd->dataseg[0].d_base_high = virt_to_bus_high32(Cmnd->sense_buffer);
+               cmd->segment_cnt = 1;
+               cmd->control_flags = CFLAG_READ;
+               break;
+       default:
+               cmd->control_flags = CFLAG_READ;
+               break;
+       }
+
+
+       if (Cmnd->device->tagged_supported) {
+               switch (Cmnd->tag) {
+               case SIMPLE_QUEUE_TAG:
+                       cmd->control_flags |= CFLAG_SIMPLE_TAG;
+                       break;
+               case HEAD_OF_QUEUE_TAG:
+                       cmd->control_flags |= CFLAG_HEAD_TAG;
+                       break;
+               case ORDERED_QUEUE_TAG:
+                       cmd->control_flags |= CFLAG_ORDERED_TAG;
+                       break;
+               default:
+                       if ((jiffies - hostdata->tag_ages[Cmnd->target]) > (5 * HZ)) {
+                               cmd->control_flags |= CFLAG_ORDERED_TAG;
+                               hostdata->tag_ages[Cmnd->target] = jiffies;
+                       } else
+                               cmd->control_flags |= CFLAG_SIMPLE_TAG;
+               }
+       }
+       outw(in_ptr, host->io_port + MBOX4);
+       hostdata->req_in_ptr = in_ptr;
+
+       hostdata->queued++;
+
+       num_free = QLOGICFC_REQ_QUEUE_LEN - REQ_QUEUE_DEPTH(in_ptr, out_ptr);
+       num_free = num_free - 2;
+       host->can_queue = hostdata->queued + num_free;
+       if (host->can_queue > QLOGICFC_REQ_QUEUE_LEN)
+               host->can_queue = QLOGICFC_REQ_QUEUE_LEN;
+       host->sg_tablesize = QLOGICFC_MAX_SG(num_free);
+
+       /* this is really gross */
+       if (host->can_queue < host->host_busy){
+               if (host->can_queue+2 < host->host_busy) 
+                 printk("qlogicfc.c crosses its fingers.\n");
+               host->can_queue = host->host_busy;
+       }
+
+       LEAVE("isp2100_queuecommand");
+
+       return 0;
+}
+
+
+#define ASYNC_EVENT_INTERRUPT  0x01
+
+
+void do_isp2100_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&io_request_lock, flags);
+       isp2100_intr_handler(irq, dev_id, regs);
+       spin_unlock_irqrestore(&io_request_lock, flags);
+}
+
+void isp2100_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+       Scsi_Cmnd *Cmnd;
+       struct Status_Entry *sts;
+       struct Scsi_Host *host = dev_id;
+       struct isp2100_hostdata *hostdata;
+       u_int in_ptr, out_ptr, handle, num_free;
+       u_short status;
+
+       ENTER_INTR("isp2100_intr_handler");
+
+       hostdata = (struct isp2100_hostdata *) host->hostdata;
+
+       DEBUG_INTR(printk("qlogicfc : interrupt on line %d\n", irq));
+
+       if (!(inw(host->io_port + PCI_INTER_STS) & 0x08)) {
+               /* spurious interrupts can happen legally */
+               DEBUG_INTR(printk("qlogicfc: got spurious interrupt\n"));
+               return;
+       }
+       in_ptr = inw(host->io_port + MBOX5);
+       out_ptr = hostdata->res_out_ptr;
+
+       if ((inw(host->io_port + PCI_SEMAPHORE) & ASYNC_EVENT_INTERRUPT)) {
+               status = inw(host->io_port + MBOX0);
+
+               DEBUG_INTR(printk("qlogicfc : mbox completion status: %x\n",
+                                 status));
+
+               switch (status) {
+               case LOOP_UP:
+                       hostdata->loop_up = 2;
+                       break;
+               case LOOP_DOWN:
+                       hostdata->loop_up = 0;
+                       break;
+               case LIP_OCCURED:
+               case CHANGE_NOTIFICATION:
+               case PORT_DB_CHANGED:
+               case LIP_RECEIVED:
+                       if (hostdata->loop_up == 1)
+                               hostdata->loop_up = 2;
+                       break;
+               case SYSTEM_ERROR:
+                       printk("The firmware just choked.\n");
+                       hostdata->loop_up = -1;
+                       break;
+               case SCSI_COMMAND_COMPLETE:
+                       handle = inw(host->io_port + MBOX1) | (inw(host->io_port + MBOX2) << 16);
+                       Cmnd = hostdata->handle_ptrs[handle];
+                       hostdata->handle_ptrs[handle] = NULL;
+                       hostdata->handle_serials[handle] = 0;
+                       hostdata->queued--;
+                       if (Cmnd != NULL) {
+                               Cmnd->result = 0x0;
+                               (*Cmnd->scsi_done) (Cmnd);
+                       } else
+                               printk("qlogicfc.c: got a null value out of handle_ptrs, this sucks\n");
+                       break;
+               case MBOX_COMMAND_COMPLETE:
+               case INVALID_COMMAND:
+               case HOST_INTERFACE_ERROR:
+               case TEST_FAILED:
+               case COMMAND_ERROR:
+               case COMMAND_PARAM_ERROR:
+               case PORT_ID_USED:
+               case LOOP_ID_USED:
+               case ALL_IDS_USED:
+                       hostdata->mbox_done = 1;
+                       outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR);
+                       return;
+               default:
+                       printk("qlogicfc: got an unknown status? %x\n", status);
+               }
+               outw(0x0, host->io_port + PCI_SEMAPHORE);
+       } else {
+               DEBUG_INTR(printk("qlogicfc : response queue update\n"));
+               DEBUG_INTR(printk("qlogicfc : response queue depth %d\n", RES_QUEUE_DEPTH(in_ptr, out_ptr)));
+
+               while (out_ptr != in_ptr) {
+                       sts = (struct Status_Entry *) &hostdata->res[out_ptr][0];
+                       out_ptr = (out_ptr + 1) & RES_QUEUE_LEN;
+                       Cmnd = hostdata->handle_ptrs[sts->handle];
+
+                       hostdata->handle_ptrs[sts->handle] = NULL;
+
+                       if (hostdata->handle_serials[sts->handle] != Cmnd->serial_number) {
+                               hostdata->queued--;
+                               hostdata->handle_serials[sts->handle] = 0;
+                               outw(out_ptr, host->io_port + MBOX5);
+                               continue;
+                       }
+                       hostdata->handle_serials[sts->handle] = 0;
+
+                       TRACE("done", out_ptr, Cmnd);
+                       DEBUG_INTR(isp2100_print_status_entry(sts));
+                       if (sts->hdr.entry_type == ENTRY_STATUS) {
+                               Cmnd->result = isp2100_return_status(sts);
+                       } else {
+                               outw(out_ptr, host->io_port + MBOX5);
+                               continue;
+                       }
+
+                       if (sts->completion_status == CS_RESET_OCCURRED
+                           || sts->completion_status == CS_ABORTED
+                           || (sts->status_flags & STF_BUS_RESET))
+                               hostdata->send_marker = 1;
+
+                       if (sts->scsi_status & 0x0200)
+                               memcpy(Cmnd->sense_buffer, sts->req_sense_data,
+                                      sizeof(Cmnd->sense_buffer));
+
+                       outw(out_ptr, host->io_port + MBOX5);
+
+                       hostdata->queued--;
+                       if (Cmnd->scsi_done != NULL) {
+                               (*Cmnd->scsi_done) (Cmnd);
+                       } else
+                               printk("Ouch, scsi done is NULL\n");
+               }
+               hostdata->res_out_ptr = out_ptr;
+       }
+
+
+       out_ptr = inw(host->io_port + MBOX4);
+       in_ptr = hostdata->req_in_ptr;
+
+       num_free = QLOGICFC_REQ_QUEUE_LEN - REQ_QUEUE_DEPTH(in_ptr, out_ptr);
+       num_free = num_free-2;
+       host->can_queue = hostdata->queued + num_free;
+       if (host->can_queue > QLOGICFC_REQ_QUEUE_LEN)
+               host->can_queue = QLOGICFC_REQ_QUEUE_LEN;
+       host->sg_tablesize = QLOGICFC_MAX_SG(num_free);
+
+       if (host->can_queue < host->host_busy){
+               if (host->can_queue+2 < host->host_busy) 
+                       DEBUG(printk("qlogicfc crosses its fingers.\n"));
+               host->can_queue = host->host_busy;
+       }
+
+       outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR);
+       LEAVE_INTR("isp2100_intr_handler");
+}
+
+
+static int isp2100_return_status(struct Status_Entry *sts)
+{
+       int host_status = DID_ERROR;
+#if DEBUG_ISP2100_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_ISP2100_INTR */
+
+       ENTER("isp2100_return_status");
+
+       DEBUG(printk("qlogicfc : completion status = 0x%04x\n",
+                    sts->completion_status));
+
+       switch (sts->completion_status) {
+       case CS_COMPLETE:
+               host_status = DID_OK;
+               break;
+       case CS_INCOMPLETE:
+               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;
+               break;
+       case CS_DMA_ERROR:
+       case CS_TRANSPORT_ERROR:
+               host_status = DID_ERROR;
+               break;
+       case CS_RESET_OCCURRED:
+               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:
+       case CS_ABORT_MSG_FAILED:
+               host_status = DID_ERROR;
+               break;
+       case CS_DATA_UNDERRUN:
+               host_status = DID_OK;
+               break;
+       case CS_PORT_UNAVAILABLE:
+       case CS_PORT_LOGGED_OUT:
+       case CS_PORT_CONFIG_CHANGED:
+               host_status = DID_BAD_TARGET;
+               break;
+       default:
+               printk("qlogicfc : unknown completion status 0x%04x\n",
+                      sts->completion_status);
+               host_status = DID_ERROR;
+               break;
+       }
+
+       DEBUG_INTR(printk("qlogicfc : host status (%s) scsi status %x\n",
+                         reason[host_status], sts->scsi_status));
+
+       LEAVE("isp2100_return_status");
+
+       return (sts->scsi_status & STATUS_MASK) | (host_status << 16);
+}
+
+
+int isp2100_abort(Scsi_Cmnd * Cmnd)
+{
+       u_short param[8];
+       int i;
+       struct Scsi_Host *host;
+       struct isp2100_hostdata *hostdata;
+       int return_status = SCSI_ABORT_SUCCESS;
+
+       ENTER("isp2100_abort");
+
+       host = Cmnd->host;
+       hostdata = (struct isp2100_hostdata *) host->hostdata;
+
+       for (i = 0; i < QLOGICFC_REQ_QUEUE_LEN; i++)
+               if (hostdata->handle_ptrs[i] == Cmnd)
+                       break;
+
+       if (i == QLOGICFC_REQ_QUEUE_LEN)
+               return SCSI_ABORT_ERROR;
+
+       isp2100_disable_irqs(host);
+
+       param[0] = MBOX_ABORT_IOCB;
+       param[1] = (((u_short) Cmnd->target) << 8) | Cmnd->lun;
+       param[2] = i >> 16;
+       param[3] = i & 0xffff;
+
+       isp2100_mbox_command(host, param);
+
+       if (param[0] != MBOX_COMMAND_COMPLETE) {
+               printk("qlogicfc : scsi abort failure: %x\n", param[0]);
+               if (param[0] == 0x4005)
+                       Cmnd->result = DID_ERROR << 16;
+               if (param[0] == 0x4006)
+                       Cmnd->result = DID_BAD_TARGET << 16;
+               (*Cmnd->scsi_done) (Cmnd);
+               return_status = SCSI_ABORT_ERROR;
+       }
+       isp2100_enable_irqs(host);
+
+       LEAVE("isp2100_abort");
+
+       return return_status;
+}
+
+
+int isp2100_reset(Scsi_Cmnd * Cmnd, unsigned int reset_flags)
+{
+       u_short param[8];
+       struct Scsi_Host *host;
+       struct isp2100_hostdata *hostdata;
+       int return_status = SCSI_RESET_SUCCESS;
+
+       ENTER("isp2100_reset");
+
+       host = Cmnd->host;
+       hostdata = (struct isp2100_hostdata *) host->hostdata;
+       param[0] = MBOX_BUS_RESET;
+       param[1] = 3;
+
+       isp2100_disable_irqs(host);
+
+       isp2100_mbox_command(host, param);
+
+       if (param[0] != MBOX_COMMAND_COMPLETE) {
+               printk("qlogicfc : scsi bus reset failure: %x\n", param[0]);
+               return_status = SCSI_RESET_ERROR;
+       }
+       isp2100_enable_irqs(host);
+
+       LEAVE("isp2100_reset");
+
+       return return_status;;
+}
+
+
+int isp2100_biosparam(Disk * disk, kdev_t n, int ip[])
+{
+       int size = disk->capacity;
+
+       ENTER("isp2100_biosparam");
+
+       ip[0] = 64;
+       ip[1] = 32;
+       ip[2] = size >> 11;
+       if (ip[2] > 1024) {
+               ip[0] = 255;
+               ip[1] = 63;
+               ip[2] = size / (ip[0] * ip[1]);
+               if (ip[2] > 1023)
+                       ip[2] = 1023;
+       }
+       LEAVE("isp2100_biosparam");
+
+       return 0;
+}
+
+
+static int isp2100_reset_hardware(struct Scsi_Host *host)
+{
+       u_short param[8];
+       struct isp2100_hostdata *hostdata;
+       int loop_count;
+
+       ENTER("isp2100_reset_hardware");
+
+       outw(0x01, host->io_port + ISP_CTRL_STATUS);
+       outw(HCCR_RESET, host->io_port + HOST_HCCR);
+       outw(HCCR_RELEASE, host->io_port + HOST_HCCR);
+       outw(HCCR_BIOS_DISABLE, host->io_port + HOST_HCCR);
+
+       loop_count = DEFAULT_LOOP_COUNT;
+       while (--loop_count && inw(host->io_port + HOST_HCCR) == RISC_BUSY)
+               barrier();
+       if (!loop_count)
+               printk("qlogicfc: reset_hardware loop timeout\n");
+
+
+
+#if DEBUG_ISP2100
+       printk("qlogicfc : mbox 0 0x%04x \n", inw(host->io_port + MBOX0));
+       printk("qlogicfc : mbox 1 0x%04x \n", inw(host->io_port + MBOX1));
+       printk("qlogicfc : mbox 2 0x%04x \n", inw(host->io_port + MBOX2));
+       printk("qlogicfc : mbox 3 0x%04x \n", inw(host->io_port + MBOX3));
+       printk("qlogicfc : mbox 4 0x%04x \n", inw(host->io_port + MBOX4));
+       printk("qlogicfc : mbox 5 0x%04x \n", inw(host->io_port + MBOX5));
+       printk("qlogicfc : mbox 6 0x%04x \n", inw(host->io_port + MBOX6));
+       printk("qlogicfc : mbox 7 0x%04x \n", inw(host->io_port + MBOX7));
+#endif                         /* DEBUG_ISP2100 */
+
+       DEBUG(printk("qlogicfc : verifying checksum\n"));
+
+#if RELOAD_FIRMWARE
+       {
+               int i;
+               for (i = 0; i < risc_code_length01; i++) {
+                       param[0] = MBOX_WRITE_RAM_WORD;
+                       param[1] = risc_code_addr01 + i;
+                       param[2] = risc_code01[i];
+
+                       isp2100_mbox_command(host, param);
+
+                       if (param[0] != MBOX_COMMAND_COMPLETE) {
+                               printk("qlogicfc : firmware load failure\n");
+                               return 1;
+                       }
+               }
+       }
+#endif                         /* RELOAD_FIRMWARE */
+
+       param[0] = MBOX_VERIFY_CHECKSUM;
+       param[1] = risc_code_addr01;
+
+       isp2100_mbox_command(host, param);
+
+       if (param[0] != MBOX_COMMAND_COMPLETE) {
+               printk("qlogicfc : ram checksum failure\n");
+               return 1;
+       }
+       DEBUG(printk("qlogicfc : executing firmware\n"));
+
+       param[0] = MBOX_EXEC_FIRMWARE;
+       param[1] = risc_code_addr01;
+
+       isp2100_mbox_command(host, param);
+
+       param[0] = MBOX_ABOUT_FIRMWARE;
+
+       isp2100_mbox_command(host, param);
+
+       if (param[0] != MBOX_COMMAND_COMPLETE) {
+               printk("qlogicfc : about firmware failure\n");
+               return 1;
+       }
+       DEBUG(printk("qlogicfc : firmware major revision %d\n", param[1]));
+       DEBUG(printk("qlogicfc : firmware minor revision %d\n", param[2]));
+
+       hostdata = (struct isp2100_hostdata *) host->hostdata;
+
+#ifdef USE_NVRAM_DEFAULTS
+
+       if (isp2100_get_nvram_defaults(host, &hostdata->control_block) != 0) {
+               printk("qlogicfc: Could not read from NVRAM\n");
+       }
+#endif
+
+       hostdata->wwn = (u64) (hostdata->control_block.node_name[0]) << 56;
+       hostdata->wwn |= (u64) (hostdata->control_block.node_name[0] & 0xff00) << 48;
+       hostdata->wwn |= (u64) (hostdata->control_block.node_name[1] & 0xff00) << 24;
+       hostdata->wwn |= (u64) (hostdata->control_block.node_name[1] & 0x00ff) << 48;
+       hostdata->wwn |= (u64) (hostdata->control_block.node_name[2] & 0x00ff) << 24;
+       hostdata->wwn |= (u64) (hostdata->control_block.node_name[2] & 0xff00) << 8;
+       hostdata->wwn |= (u64) (hostdata->control_block.node_name[3] & 0x00ff) << 8;
+       hostdata->wwn |= (u64) (hostdata->control_block.node_name[3] & 0xff00) >> 8;
+
+       param[0] = MBOX_INIT_FIRMWARE;
+       param[2] = (u_short) (virt_to_bus_low32(&hostdata->control_block) >> 16);
+       param[3] = (u_short) (virt_to_bus_low32(&hostdata->control_block) & 0xffff);
+       param[4] = 0;
+       param[5] = 0;
+       param[6] = (u_short) (virt_to_bus_high32(&hostdata->control_block) >> 16);
+       param[7] = (u_short) (virt_to_bus_high32(&hostdata->control_block) & 0xffff);
+       isp2100_mbox_command(host, param);
+       if (param[0] != MBOX_COMMAND_COMPLETE) {
+               printk("qlogicfc.c: Ouch 0x%04x\n", param[0]);
+               return 1;
+       }
+       param[0] = MBOX_GET_FIRMWARE_STATE;
+       isp2100_mbox_command(host, param);
+       if (param[0] != MBOX_COMMAND_COMPLETE) {
+               printk("qlogicfc.c: 0x%04x\n", param[0]);
+               return 1;
+       }
+
+       LEAVE("isp2100_reset_hardware");
+
+       return 0;
+}
+
+#ifdef USE_NVRAM_DEFAULTS
+
+static int isp2100_get_nvram_defaults(struct Scsi_Host *host, struct init_cb *control_block)
+{
+
+       u_short value;
+       if (isp2100_read_nvram_word(host, 0) != 0x5349)
+               return 1;
+
+       control_block->max_frame_len = isp2100_read_nvram_word(host, 5);
+       control_block->max_iocb = isp2100_read_nvram_word(host, 6);
+       control_block->exec_throttle = isp2100_read_nvram_word(host, 7);
+       value = isp2100_read_nvram_word(host, 8);
+       control_block->node_name[0] = isp2100_read_nvram_word(host, 9);
+       control_block->node_name[1] = isp2100_read_nvram_word(host, 10);
+       control_block->node_name[2] = isp2100_read_nvram_word(host, 11);
+       control_block->node_name[3] = isp2100_read_nvram_word(host, 12);
+       control_block->hard_addr = isp2100_read_nvram_word(host, 13);
+
+       return 0;
+
+}
+
+#endif
+
+static int isp2100_init(struct Scsi_Host *sh)
+{
+       u_int io_base;
+       struct isp2100_hostdata *hostdata;
+       u_char revision;
+       u_int irq;
+       u_short command;
+       struct pci_dev *pdev;
+
+
+       ENTER("isp2100_init");
+
+       hostdata = (struct isp2100_hostdata *) sh->hostdata;
+       pdev = hostdata->pci_dev;
+
+       if (pci_read_config_word(pdev, PCI_COMMAND, &command)
+         || pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision)) {
+               printk("qlogicfc : error reading PCI configuration\n");
+               return 1;
+       }
+       io_base = pdev->base_address[0];
+       irq = pdev->irq;
+
+
+
+       if (pdev->vendor != PCI_VENDOR_ID_QLOGIC) {
+               printk("qlogicfc : 0x%04x is not QLogic vendor ID\n",
+                      pdev->vendor);
+               return 1;
+       }
+       if (pdev->device != PCI_DEVICE_ID_QLOGIC_ISP2100) {
+               printk("qlogicfc : 0x%04x does not match ISP2100 device id\n",
+                      pdev->device);
+               return 1;
+       }
+       if (command & PCI_COMMAND_IO && (io_base & 3) == 1)
+               io_base &= PCI_BASE_ADDRESS_IO_MASK;
+       else {
+               printk("qlogicfc : i/o mapping is disabled\n");
+               return 1;
+       }
+
+       if (!(command & PCI_COMMAND_MASTER)) {
+               printk("qlogicfc : bus mastering is disabled\n");
+               return 1;
+       }
+       if (revision != ISP2100_REV_ID && revision != ISP2100_REV_ID3)
+               printk("qlogicfc : new isp2100 revision ID (%d)\n", revision);
+
+
+       hostdata->revision = revision;
+
+       sh->irq = irq;
+       sh->io_port = io_base;
+
+       LEAVE("isp2100_init");
+
+       return 0;
+}
+
+#if USE_NVRAM_DEFAULTS
+
+#define NVRAM_DELAY() udelay(10)       /* 10 microsecond delay */
+
+
+u_short isp2100_read_nvram_word(struct Scsi_Host * host, u_short byte)
+{
+       int i;
+       u_short value, output, input;
+
+       outw(0x2, host->io_port + PCI_NVRAM);
+       NVRAM_DELAY();
+       outw(0x3, host->io_port + PCI_NVRAM);
+       NVRAM_DELAY();
+
+       byte &= 0xff;
+       byte |= 0x0600;
+       for (i = 10; i >= 0; i--) {
+               output = ((byte >> i) & 0x1) ? 0x4 : 0x0;
+               outw(output | 0x2, host->io_port + PCI_NVRAM);
+               NVRAM_DELAY();
+               outw(output | 0x3, host->io_port + PCI_NVRAM);
+               NVRAM_DELAY();
+               outw(output | 0x2, host->io_port + PCI_NVRAM);
+               NVRAM_DELAY();
+       }
+
+       for (i = 0xf, value = 0; i >= 0; i--) {
+               value <<= 1;
+               outw(0x3, host->io_port + PCI_NVRAM);
+               NVRAM_DELAY();
+               input = inw(host->io_port + PCI_NVRAM);
+               NVRAM_DELAY();
+               outw(0x2, host->io_port + PCI_NVRAM);
+               NVRAM_DELAY();
+               if (input & 0x8)
+                       value |= 1;
+       }
+
+       outw(0x0, host->io_port + PCI_NVRAM);
+       NVRAM_DELAY();
+
+       return value;
+}
+
+
+#endif                         /* USE_NVRAM_DEFAULTS */
+
+
+
+/*
+ * currently, this is only called during initialization or abort/reset,
+ * at which times interrupts are disabled, so polling is OK, I guess...
+ */
+static int isp2100_mbox_command(struct Scsi_Host *host, u_short param[])
+{
+       int loop_count;
+       struct isp2100_hostdata *hostdata = (struct isp2100_hostdata *) host->hostdata;
+
+       if (mbox_param[param[0]] == 0)
+               return 1;
+
+       loop_count = DEFAULT_LOOP_COUNT;
+       while (--loop_count && inw(host->io_port + HOST_HCCR) & 0x0080)
+               barrier();
+       if (!loop_count) {
+               printk("qlogicfc: mbox_command loop timeout #1\n");
+               param[0] = 0x4006;
+               return 1;
+       }
+       hostdata->mbox_done = 0;
+
+       if (mbox_param[param[0]] == 0)
+               printk("qlogicfc: invalid mbox command\n");
+
+       if (mbox_param[param[0]] & 0x80)
+               outw(param[7], host->io_port + MBOX7);
+       if (mbox_param[param[0]] & 0x40)
+               outw(param[6], host->io_port + MBOX6);
+       if (mbox_param[param[0]] & 0x20)
+               outw(param[5], host->io_port + MBOX5);
+       if (mbox_param[param[0]] & 0x10)
+               outw(param[4], host->io_port + MBOX4);
+       if (mbox_param[param[0]] & 0x08)
+               outw(param[3], host->io_port + MBOX3);
+       if (mbox_param[param[0]] & 0x04)
+               outw(param[2], host->io_port + MBOX2);
+       if (mbox_param[param[0]] & 0x02)
+               outw(param[1], host->io_port + MBOX1);
+       if (mbox_param[param[0]] & 0x01)
+               outw(param[0], host->io_port + MBOX0);
+
+
+       outw(HCCR_SET_HOST_INTR, host->io_port + HOST_HCCR);
+
+       while (1) {
+               loop_count = DEFAULT_LOOP_COUNT;
+               while (--loop_count && !(inw(host->io_port + PCI_INTER_STS) & 0x08)) {
+                       barrier();
+               }
+
+               if (!loop_count) {
+                       printk("qlogicfc: mbox_command loop timeout #2\n");
+                       break;
+               }
+               isp2100_intr_handler(host->irq, host, NULL);
+
+               if (hostdata->mbox_done == 1)
+                       break;
+
+       }
+
+       loop_count = DEFAULT_LOOP_COUNT;
+       while (--loop_count && inw(host->io_port + MBOX0) == 0x04) {
+               barrier();
+       }
+       if (!loop_count)
+               printk("qlogicfc: mbox_command loop timeout #3\n");
+
+       param[7] = inw(host->io_port + MBOX7);
+       param[6] = inw(host->io_port + MBOX6);
+       param[5] = inw(host->io_port + MBOX5);
+       param[4] = inw(host->io_port + MBOX4);
+       param[3] = inw(host->io_port + MBOX3);
+       param[2] = inw(host->io_port + MBOX2);
+       param[1] = inw(host->io_port + MBOX1);
+       param[0] = inw(host->io_port + MBOX0);
+
+
+       outw(0x0, host->io_port + PCI_SEMAPHORE);
+
+       if (inw(host->io_port + HOST_HCCR) & 0x0080) {
+               printk("mbox op is still pending\n");
+       }
+       return 0;
+}
+
+
+#if DEBUG_ISP2100_INTR
+
+void isp2100_print_status_entry(struct Status_Entry *status)
+{
+       printk("qlogicfc : entry count = 0x%02x, type = 0x%02x, flags = 0x%02x\n",
+       status->hdr.entry_cnt, status->hdr.entry_type, status->hdr.flags);
+       printk("qlogicfc : scsi status = 0x%04x, completion status = 0x%04x\n",
+              status->scsi_status, status->completion_status);
+       printk("qlogicfc : state flags = 0x%04x, status flags = 0x%04x\n",
+              status->state_flags, status->status_flags);
+       printk("qlogicfc : response info length = 0x%04x, request sense length = 0x%04x\n",
+              status->res_info_len, status->req_sense_len);
+       printk("qlogicfc : residual transfer length = 0x%08x, response = 0x%02x\n", status->residual, status->res_info[3]);
+
+}
+
+#endif                         /* DEBUG_ISP2100_INTR */
+
+
+#if DEBUG_ISP2100
+
+void isp2100_print_scsi_cmd(Scsi_Cmnd * cmd)
+{
+       int i;
+
+       printk("qlogicfc : target = 0x%02x, lun = 0x%02x, cmd_len = 0x%02x\n",
+              cmd->target, cmd->lun, cmd->cmd_len);
+       printk("qlogicfc : command = ");
+       for (i = 0; i < cmd->cmd_len; i++)
+               printk("0x%02x ", cmd->cmnd[i]);
+       printk("\n");
+}
+
+#endif                         /* DEBUG_ISP2100 */
+
+
+#ifdef MODULE
+
+Scsi_Host_Template driver_template = QLOGICFC;
+
+#include "scsi_module.c"
+
+#endif
diff --git a/drivers/scsi/qlogicfc.h b/drivers/scsi/qlogicfc.h
new file mode 100644 (file)
index 0000000..ad35329
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * QLogic ISP2100 SCSI-FCP
+ * 
+ * Written by Erik H. Moe, ehm@cris.com
+ * Copyright 1995, Erik H. Moe
+ *
+ * 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.
+ */
+
+/* Renamed and updated to 1.3.x by Michael Griffith <grif@cs.ucr.edu> */
+
+/* This is a version of the isp1020 driver which was modified by
+ * Chris Loveland <cwl@iol.unh.edu> to support the isp2100
+ */
+
+
+/*
+ * $Date: 1995/09/22 02:32:56 $
+ * $Revision: 0.5 $
+ *
+ * $Log: isp1020.h,v $
+ * Revision 0.5  1995/09/22  02:32:56  root
+ * do auto request sense
+ *
+ * Revision 0.4  1995/08/07  04:48:28  root
+ * supply firmware with driver.
+ * numerous bug fixes/general cleanup of code.
+ *
+ * Revision 0.3  1995/07/16  16:17:16  root
+ * added reset/abort code.
+ *
+ * Revision 0.2  1995/06/29  03:19:43  root
+ * fixed biosparam.
+ * added queue protocol.
+ *
+ * Revision 0.1  1995/06/25  01:56:13  root
+ * Initial release.
+ *
+ */
+
+#ifndef _QLOGICFC_H
+#define _QLOGICFC_H
+
+/*
+ * With the qlogic interface, every queue slot can hold a SCSI
+ * command with up to 2 scatter/gather entries.  If we need more
+ * than 2 entries, continuation entries can be used that hold
+ * another 5 entries each.  Unlike for other drivers, this means
+ * that the maximum number of scatter/gather entries we can
+ * support at any given time is a function of the number of queue
+ * slots available.  That is, host->can_queue and host->sg_tablesize
+ * are dynamic and _not_ independent.  This all works fine because
+ * requests are queued serially and the scatter/gather limit is
+ * determined for each queue request anew.
+ */
+#define QLOGICFC_REQ_QUEUE_LEN 63      /* must be power of two - 1 */
+#define QLOGICFC_MAX_SG(ql)    (2 + (((ql) > 0) ? 5*((ql) - 1) : 0))
+#define QLOGICFC_CMD_PER_LUN    8
+
+int isp2100_detect(Scsi_Host_Template *);
+int isp2100_release(struct Scsi_Host *);
+const char * isp2100_info(struct Scsi_Host *);
+int isp2100_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
+int isp2100_abort(Scsi_Cmnd *);
+int isp2100_reset(Scsi_Cmnd *, unsigned int);
+int isp2100_biosparam(Disk *, kdev_t, int[]);
+
+#ifndef NULL
+#define NULL (0)
+#endif
+
+extern struct proc_dir_entry proc_scsi_isp2100;
+
+#define QLOGICFC {                                                        \
+        detect:                 isp2100_detect,                            \
+        release:                isp2100_release,                           \
+        info:                   isp2100_info,                              \
+        queuecommand:           isp2100_queuecommand,                      \
+        abort:                  isp2100_abort,                             \
+        reset:                  isp2100_reset,                             \
+        bios_param:             isp2100_biosparam,                         \
+        can_queue:              QLOGICFC_REQ_QUEUE_LEN,                    \
+        this_id:                -1,                                        \
+        sg_tablesize:           QLOGICFC_MAX_SG(QLOGICFC_REQ_QUEUE_LEN),   \
+        cmd_per_lun:            QLOGICFC_CMD_PER_LUN,                      \
+        present:                0,                                         \
+        unchecked_isa_dma:      0,                                         \
+        use_clustering:         DISABLE_CLUSTERING                         \
+}
+
+#endif /* _QLOGICFC_H */
+
+
+
diff --git a/drivers/scsi/qlogicfc_asm.c b/drivers/scsi/qlogicfc_asm.c
new file mode 100644 (file)
index 0000000..bedeabc
--- /dev/null
@@ -0,0 +1,2985 @@
+/************************************************************************
+ *                                                                     *
+ *      --- ISP2100 Fabric Initiator/Target Firmware ---               *
+ *                                                                     *
+ *                                                                     *
+ *                                                                     *
+ ************************************************************************
+ */
+/*
+ *     Firmware Version 1.13.00 (18:06 May 04, 1998)
+ */
+
+unsigned short risc_code_version = 1*1024+13;
+
+unsigned char firmware_version[] = {1,13,0};
+
+unsigned short risc_code_addr01 = 0x1000 ;
+
+unsigned short risc_code01[] = { 
+       0x0078, 0x1029, 0x0000, 0x5c95, 0x0000, 0x2043, 0x4f50, 0x5952,
+       0x4947, 0x4854, 0x2031, 0x3939, 0x3620, 0x514c, 0x4f47, 0x4943,
+       0x2043, 0x4f52, 0x504f, 0x5241, 0x5449, 0x4f4e, 0x2049, 0x5350,
+       0x3231, 0x3030, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056,
+       0x6572, 0x7369, 0x6f6e, 0x2030, 0x312e, 0x3133, 0x2020, 0x2020,
+       0x2400, 0x20c1, 0x0021, 0x20a1, 0x6c95, 0x2009, 0x0000, 0x20a9,
+       0x076b, 0x41a4, 0x3400, 0x20c9, 0x71ff, 0x2091, 0x2000, 0x2059,
+       0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x1e36, 0x2051, 0x6d00,
+       0x2a70, 0x705b, 0x8c00, 0x705f, 0xffff, 0x7057, 0x8bf9, 0x7063,
+       0x0300, 0x1078, 0x1264, 0x20a1, 0x7400, 0x715c, 0x810d, 0x810d,
+       0x810d, 0x810d, 0xa18c, 0x000f, 0x2001, 0x0007, 0xa112, 0xa00e,
+       0x21a8, 0x41a4, 0x3400, 0x8211, 0x00c0, 0x1058, 0x715c, 0x3400,
+       0xa102, 0x0040, 0x1068, 0x0048, 0x1068, 0x20a8, 0xa00e, 0x41a4,
+       0x1078, 0x122b, 0x1078, 0x134e, 0x1078, 0x14d3, 0x1078, 0x17d7,
+       0x1078, 0x324a, 0x1078, 0x54fc, 0x1078, 0x12d9, 0x1078, 0x2191,
+       0x1078, 0x3875, 0x1078, 0x3655, 0x1078, 0x4064, 0x1078, 0x1c35,
+       0x1078, 0x4213, 0x1078, 0x3d73, 0x1078, 0x1b5d, 0x1078, 0x1c14,
+       0x2091, 0x3009, 0x7823, 0x0000, 0x0090, 0x109d, 0x7820, 0xa086,
+       0x0002, 0x00c0, 0x109d, 0x7823, 0x4000, 0x0068, 0x1095, 0x781b,
+       0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2a70, 0x7003, 0x0000,
+       0x2001, 0x017f, 0x2003, 0x0000, 0x2a70, 0x7000, 0xa08e, 0x0003,
+       0x00c0, 0x10bd, 0x1078, 0x2a96, 0x1078, 0x21b9, 0x1078, 0x38c5,
+       0x1078, 0x373c, 0x2009, 0x0100, 0x2104, 0xa082, 0x0002, 0x0048,
+       0x10c1, 0x1078, 0x4078, 0x0078, 0x10a4, 0x1079, 0x10c5, 0x0078,
+       0x10aa, 0x1078, 0x52d8, 0x0078, 0x10b9, 0x10cf, 0x10d0, 0x1151,
+       0x10cd, 0x11aa, 0x1228, 0x1229, 0x122a, 0x1078, 0x12b7, 0x007c,
+       0x127e, 0x0f7e, 0x2091, 0x8000, 0x1078, 0x2aec, 0x2079, 0x0100,
+       0x7844, 0xa005, 0x00c0, 0x1142, 0x2011, 0x318e, 0x1078, 0x40d1,
+       0x780f, 0x00ff, 0x7840, 0xa084, 0xfffb, 0x7842, 0x2011, 0x8010,
+       0x73b8, 0x1078, 0x2a53, 0x1078, 0x5129, 0x2011, 0x0004, 0x1078,
+       0x6135, 0x1078, 0x35ef, 0x70c7, 0x0000, 0x70bf, 0x0000, 0x70c3,
+       0x0000, 0x1078, 0x1145, 0x2011, 0x0000, 0x2079, 0x6d51, 0x7804,
+       0xd0ac, 0x0040, 0x1104, 0xc295, 0x70a4, 0xa005, 0x0040, 0x1109,
+       0xc29d, 0x72be, 0xa296, 0x0004, 0x0040, 0x112a, 0x2011, 0x0001,
+       0x1078, 0x6135, 0x708b, 0x0000, 0x708f, 0xffff, 0x7003, 0x0002,
+       0x0f7f, 0x1078, 0x1ee6, 0x2011, 0x0005, 0x1078, 0x5232, 0x1078,
+       0x476a, 0x0c7e, 0x2061, 0x0100, 0x60e3, 0x0008, 0x0c7f, 0x127f,
+       0x0078, 0x1144, 0x7003, 0x0003, 0x2001, 0x0000, 0x1078, 0x1dc9,
+       0x2011, 0x0000, 0x1078, 0x5232, 0x2011, 0x0000, 0x1078, 0x523c,
+       0x0c7e, 0x2061, 0x0100, 0x60e3, 0x0008, 0x0c7f, 0x1078, 0x476a,
+       0x1078, 0x4821, 0x0f7f, 0x127f, 0x007c, 0x0c7e, 0x20a9, 0x0082,
+       0x2009, 0x007e, 0x1078, 0x342f, 0x8108, 0x00f0, 0x114a, 0x0c7f,
+       0x007c, 0x127e, 0x2091, 0x8000, 0x708c, 0xa086, 0xffff, 0x0040,
+       0x115f, 0x1078, 0x1ee6, 0x1078, 0x476a, 0x0078, 0x11a8, 0x70bc,
+       0xd09c, 0x0040, 0x1187, 0xd084, 0x0040, 0x1187, 0x0f7e, 0x2079,
+       0x0100, 0x790c, 0xc1b5, 0x790e, 0x0f7f, 0xd08c, 0x0040, 0x1187,
+       0x70c0, 0xa086, 0xffff, 0x0040, 0x1183, 0x1078, 0x1fdb, 0x1078,
+       0x476a, 0x2011, 0x0001, 0x2019, 0x0000, 0x1078, 0x2013, 0x1078,
+       0x476a, 0x0078, 0x11a8, 0x70c4, 0xa005, 0x00c0, 0x11a8, 0x7088,
+       0xa005, 0x00c0, 0x11a8, 0x7003, 0x0003, 0x708f, 0xffff, 0x2001,
+       0x0000, 0x1078, 0x1dc9, 0x1078, 0x2ad1, 0x2001, 0x6f11, 0x2004,
+       0xa086, 0x0005, 0x00c0, 0x11a0, 0x2011, 0x0000, 0x1078, 0x5232,
+       0x2011, 0x0000, 0x1078, 0x523c, 0x1078, 0x476a, 0x1078, 0x4821,
+       0x127f, 0x007c, 0x017e, 0x0f7e, 0x127e, 0x2091, 0x8000, 0x2079,
+       0x0100, 0x7843, 0x0000, 0x7924, 0xd1b4, 0x0040, 0x11b9, 0x7827,
+       0x0040, 0xd19c, 0x0040, 0x11be, 0x7827, 0x0008, 0x007e, 0x037e,
+       0x157e, 0x7900, 0xa18a, 0x0003, 0x0050, 0x11e4, 0x7954, 0xd1ac,
+       0x00c0, 0x11e4, 0x2009, 0x00f8, 0x1078, 0x3233, 0x7843, 0x0090,
+       0x7843, 0x0010, 0x20a9, 0x09c4, 0x7820, 0xd09c, 0x00c0, 0x11dc,
+       0x7824, 0xd0ac, 0x00c0, 0x1218, 0x00f0, 0x11d4, 0x2001, 0x0001,
+       0x1078, 0x1dc9, 0x0078, 0x1221, 0x7853, 0x0000, 0x782f, 0x0020,
+       0x20a9, 0x0008, 0x00e0, 0x11ea, 0x2091, 0x6000, 0x00f0, 0x11ea,
+       0x7853, 0x0400, 0x782f, 0x0000, 0x2009, 0x00f8, 0x1078, 0x3233,
+       0x20a9, 0x000e, 0x0005, 0x00f0, 0x11fa, 0x7853, 0x1400, 0x7843,
+       0x0090, 0x7843, 0x0010, 0x2019, 0x61a8, 0x7854, 0x0005, 0x0005,
+       0xd08c, 0x0040, 0x120f, 0x7824, 0xd0ac, 0x00c0, 0x1218, 0x8319,
+       0x00c0, 0x1205, 0x2001, 0x0001, 0x1078, 0x1dc9, 0x0078, 0x121f,
+       0x7828, 0xc09d, 0x782a, 0x7827, 0x0008, 0x7827, 0x0040, 0x7853,
+       0x0400, 0x157f, 0x037f, 0x007f, 0x127f, 0x0f7f, 0x017f, 0x007c,
+       0x007c, 0x007c, 0x007c, 0x2a70, 0x2009, 0x0100, 0x2104, 0xa082,
+       0x0002, 0x0048, 0x1237, 0x704f, 0xffff, 0x0078, 0x1239, 0x704f,
+       0x0000, 0x7053, 0xffff, 0x7067, 0x0000, 0x706b, 0x0000, 0x2061,
+       0x6f00, 0x6003, 0x0909, 0x6007, 0x0000, 0x600b, 0x8800, 0x600f,
+       0x0200, 0x6013, 0x00ff, 0x6017, 0x0003, 0x601b, 0x0000, 0x601f,
+       0x07d0, 0x2061, 0x6f08, 0x6003, 0x8000, 0x6007, 0x0000, 0x600b,
+       0x0000, 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x0000, 0x601b,
+       0x0001, 0x601f, 0x0000, 0x007c, 0x1078, 0x128a, 0x2011, 0x0000,
+       0x81ff, 0x0040, 0x1289, 0xa186, 0x0001, 0x00c0, 0x1279, 0x705f,
+       0x8fff, 0x7057, 0x7c01, 0x7063, 0x0100, 0x705b, 0x7c00, 0x0078,
+       0x1287, 0xa186, 0x0002, 0x00c0, 0x1281, 0x2011, 0x0000, 0x0078,
+       0x1287, 0xa186, 0x0005, 0x00c0, 0x1287, 0x2011, 0x0001, 0x1078,
+       0x12b1, 0x007c, 0x2009, 0x0000, 0x2011, 0x0000, 0x1078, 0x12b1,
+       0x2019, 0xaaaa, 0x2061, 0xffff, 0x2362, 0x2c24, 0x2061, 0x7fff,
+       0x2c04, 0xa406, 0x0040, 0x129f, 0xc18d, 0x0078, 0x12ac, 0xc185,
+       0x2011, 0x0001, 0x1078, 0x12b1, 0x2061, 0xffff, 0x2362, 0x2c04,
+       0xa306, 0x00c0, 0x12ac, 0xc195, 0x2011, 0x0001, 0x1078, 0x12b1,
+       0x007c, 0x3800, 0xa084, 0xfffc, 0xa205, 0x20c0, 0x007c, 0x2091,
+       0x8000, 0x0068, 0x12b9, 0x007e, 0x017e, 0x2079, 0x0000, 0x7818,
+       0xa084, 0x0000, 0x00c0, 0x12bf, 0x017f, 0x792e, 0x007f, 0x782a,
+       0x007f, 0x7826, 0x7823, 0x8002, 0x781b, 0x0001, 0x2091, 0x5000,
+       0x2091, 0x4080, 0x2079, 0x6d00, 0x7803, 0x0005, 0x0078, 0x12d6,
+       0x007c, 0x2071, 0x6d00, 0x7158, 0x712e, 0x2021, 0x0001, 0xa190,
+       0x002d, 0xa298, 0x002d, 0x0048, 0x12ef, 0x705c, 0xa302, 0x00c8,
+       0x12ef, 0x220a, 0x2208, 0x2310, 0x8420, 0x0078, 0x12e1, 0x200b,
+       0x0000, 0x749e, 0x74a2, 0x007c, 0x0e7e, 0x127e, 0x2091, 0x8000,
+       0x2071, 0x6d00, 0x70a0, 0xa0ea, 0x0010, 0x00c8, 0x1302, 0xa06e,
+       0x0078, 0x130c, 0x8001, 0x70a2, 0x702c, 0x2068, 0x2d04, 0x702e,
+       0x206b, 0x0000, 0x6807, 0x0000, 0x127f, 0x0e7f, 0x007c, 0x0e7e,
+       0x2071, 0x6d00, 0x127e, 0x2091, 0x8000, 0x70a0, 0x8001, 0x00c8,
+       0x131c, 0xa06e, 0x0078, 0x1325, 0x70a2, 0x702c, 0x2068, 0x2d04,
+       0x702e, 0x206b, 0x0000, 0x6807, 0x0000, 0x127f, 0x0e7f, 0x007c,
+       0x0e7e, 0x127e, 0x2091, 0x8000, 0x2071, 0x6d00, 0x702c, 0x206a,
+       0x2d00, 0x702e, 0x70a0, 0x8000, 0x70a2, 0x127f, 0x0e7f, 0x007c,
+       0x8dff, 0x0040, 0x1344, 0x6804, 0x6807, 0x0000, 0x007e, 0x1078,
+       0x1328, 0x0d7f, 0x0078, 0x1338, 0x007c, 0x0e7e, 0x2071, 0x6d00,
+       0x70a0, 0xa08a, 0x0010, 0xa00d, 0x0e7f, 0x007c, 0x0e7e, 0x2071,
+       0x6f31, 0x7007, 0x0000, 0x701b, 0x0000, 0x701f, 0x0000, 0x2071,
+       0x0000, 0x7010, 0xa085, 0x8004, 0x7012, 0x0e7f, 0x007c, 0x0e7e,
+       0x2270, 0x700b, 0x0000, 0x2071, 0x6f31, 0x7018, 0xa088, 0x6f3a,
+       0x220a, 0x8000, 0xa084, 0x0007, 0x701a, 0x7004, 0xa005, 0x00c0,
+       0x1377, 0x0f7e, 0x2079, 0x0010, 0x1078, 0x1388, 0x0f7f, 0x0e7f,
+       0x007c, 0x0e7e, 0x2071, 0x6f31, 0x7004, 0xa005, 0x00c0, 0x1386,
+       0x0f7e, 0x2079, 0x0010, 0x1078, 0x1388, 0x0f7f, 0x0e7f, 0x007c,
+       0x7000, 0x0079, 0x138b, 0x138f, 0x13f9, 0x1416, 0x1416, 0x7018,
+       0x711c, 0xa106, 0x00c0, 0x1397, 0x7007, 0x0000, 0x007c, 0x0d7e,
+       0xa180, 0x6f3a, 0x2004, 0x700a, 0x2068, 0x8108, 0xa18c, 0x0007,
+       0x711e, 0x7803, 0x0026, 0x6824, 0x7832, 0x6828, 0x7836, 0x682c,
+       0x783a, 0x6830, 0x783e, 0x6810, 0x700e, 0x680c, 0x7016, 0x6804,
+       0x0d7f, 0xd084, 0x0040, 0x13b9, 0x7007, 0x0001, 0x1078, 0x13be,
+       0x007c, 0x7007, 0x0002, 0x1078, 0x13d4, 0x007c, 0x017e, 0x027e,
+       0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x00c8, 0x13c9, 0x2110,
+       0xa006, 0x700e, 0x7212, 0x8203, 0x7822, 0x7803, 0x0020, 0x7803,
+       0x0041, 0x027f, 0x017f, 0x007c, 0x017e, 0x027e, 0x137e, 0x147e,
+       0x157e, 0x7014, 0x2098, 0x20a1, 0x0014, 0x7803, 0x0026, 0x710c,
+       0x2011, 0x0040, 0xa182, 0x0040, 0x00c8, 0x13e8, 0x2110, 0xa006,
+       0x700e, 0x22a8, 0x53a6, 0x8203, 0x7822, 0x7803, 0x0020, 0x7803,
+       0x0001, 0x3300, 0x7016, 0x157f, 0x147f, 0x137f, 0x027f, 0x017f,
+       0x007c, 0x137e, 0x147e, 0x157e, 0x2099, 0x6dc5, 0x20a1, 0x0018,
+       0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e, 0x2091, 0x8000,
+       0x7803, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084, 0x7002, 0x700b,
+       0x6dc0, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c, 0x137e, 0x147e,
+       0x157e, 0x2001, 0x6df4, 0x209c, 0x20a1, 0x0014, 0x7803, 0x0026,
+       0x2001, 0x6df5, 0x20ac, 0x53a6, 0x2099, 0x6df6, 0x20a1, 0x0018,
+       0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e, 0x2091, 0x8000,
+       0x7803, 0x0001, 0x7007, 0x0004, 0x7000, 0xc08c, 0x7002, 0x700b,
+       0x6df1, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c, 0x017e, 0x0e7e,
+       0x2071, 0x6f31, 0x0f7e, 0x2079, 0x0010, 0x7904, 0x7803, 0x0002,
+       0xd1fc, 0x0040, 0x1459, 0xa18c, 0x0700, 0x0040, 0x1456, 0x7008,
+       0xa080, 0x0002, 0x2003, 0x0200, 0x0078, 0x1459, 0x7004, 0x1079,
+       0x145d, 0x0f7f, 0x0e7f, 0x017f, 0x007c, 0x1388, 0x1465, 0x1487,
+       0x14a1, 0x14ca, 0x1463, 0x0078, 0x1463, 0x137e, 0x147e, 0x157e,
+       0x7014, 0x20a0, 0x2099, 0x0014, 0x7803, 0x0040, 0x7010, 0x20a8,
+       0x53a5, 0x3400, 0x7016, 0x157f, 0x147f, 0x137f, 0x700c, 0xa005,
+       0x0040, 0x148e, 0x1078, 0x13be, 0x007c, 0x7008, 0xa080, 0x0002,
+       0x2003, 0x0100, 0x7007, 0x0000, 0x1078, 0x1388, 0x007c, 0x700c,
+       0xa005, 0x0040, 0x148e, 0x1078, 0x13d4, 0x007c, 0x0d7e, 0x7008,
+       0x2068, 0x7830, 0x6826, 0x7834, 0x682a, 0x7838, 0x682e, 0x783c,
+       0x6832, 0x680b, 0x0100, 0x0d7f, 0x7007, 0x0000, 0x1078, 0x1388,
+       0x007c, 0x137e, 0x147e, 0x157e, 0x2001, 0x6dc3, 0x2004, 0xa080,
+       0x000d, 0x20a0, 0x2099, 0x0014, 0x7803, 0x0040, 0x20a9, 0x0020,
+       0x53a5, 0x2001, 0x6dc5, 0x2004, 0xd0bc, 0x0040, 0x14c0, 0x2001,
+       0x6dce, 0x2004, 0xa080, 0x000d, 0x20a0, 0x20a9, 0x0020, 0x53a5,
+       0x157f, 0x147f, 0x137f, 0x7007, 0x0000, 0x1078, 0x396e, 0x1078,
+       0x1388, 0x007c, 0x2001, 0x6df3, 0x2003, 0x0100, 0x7007, 0x0000,
+       0x1078, 0x1388, 0x007c, 0x127e, 0x2091, 0x2100, 0x2079, 0x0030,
+       0x2071, 0x6f42, 0x7003, 0x0000, 0x700f, 0x6f48, 0x7013, 0x6f48,
+       0x780f, 0x0070, 0x127f, 0x007c, 0x6934, 0xa184, 0x0007, 0x0079,
+       0x14e9, 0x14f1, 0x151b, 0x14f1, 0x14f1, 0x14f1, 0x1500, 0x14f1,
+       0x14f5, 0xa085, 0x0001, 0x0078, 0x1531, 0x684c, 0xd0bc, 0x0040,
+       0x14f1, 0x6860, 0x682e, 0x685c, 0x682a, 0x6858, 0x0078, 0x1523,
+       0xa18c, 0x00ff, 0xa186, 0x0015, 0x00c0, 0x14f1, 0x684c, 0xd0ac,
+       0x0040, 0x14f1, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084,
+       0x000f, 0xa080, 0x1a82, 0x2004, 0x6832, 0xa006, 0x682e, 0x682a,
+       0x6858, 0x0078, 0x152b, 0x684c, 0xd0ac, 0x0040, 0x14f1, 0xa006,
+       0x682e, 0x682a, 0x6858, 0xa18c, 0x000f, 0xa188, 0x1a82, 0x210c,
+       0x6932, 0x2d08, 0x691a, 0x6826, 0x684c, 0xc0dd, 0x684e, 0xa006,
+       0x680a, 0x007c, 0x82ff, 0x0040, 0x1545, 0xa280, 0x0004, 0x0d7e,
+       0x206c, 0x684c, 0xd0dc, 0x00c0, 0x1541, 0x1078, 0x14e4, 0x10c0,
+       0x12b7, 0x6808, 0x8000, 0x680a, 0x0d7f, 0x127e, 0x047e, 0x037e,
+       0x027e, 0x2091, 0x2100, 0x027f, 0x037f, 0x047f, 0x7000, 0xa005,
+       0x00c0, 0x1559, 0x7206, 0x2001, 0x156d, 0x007e, 0x2260, 0x0078,
+       0x164f, 0x710c, 0x220a, 0x8108, 0x230a, 0x8108, 0x240a, 0x8108,
+       0xa182, 0x6f63, 0x0048, 0x1566, 0x2009, 0x6f48, 0x710e, 0x7000,
+       0xa005, 0x00c0, 0x156d, 0x1078, 0x1638, 0x127f, 0x007c, 0x127e,
+       0x027e, 0x037e, 0x0c7e, 0x007e, 0x2091, 0x2100, 0x007f, 0x047f,
+       0x037f, 0x027f, 0x0c7e, 0x0d7e, 0x2460, 0x6110, 0x2168, 0x6a62,
+       0x6b5e, 0xa005, 0x0040, 0x15bc, 0x6808, 0xa005, 0x0040, 0x15ea,
+       0x7000, 0xa005, 0x00c0, 0x158e, 0x0078, 0x15b4, 0x700c, 0x7110,
+       0xa106, 0x00c0, 0x15ba, 0x7004, 0xa406, 0x00c0, 0x15b4, 0x2001,
+       0x0005, 0x2004, 0xd08c, 0x00c0, 0x15ee, 0x2001, 0x0207, 0x2004,
+       0xd09c, 0x00c0, 0x1597, 0x7804, 0xa084, 0x6000, 0x0040, 0x15ae,
+       0xa086, 0x6000, 0x0040, 0x15ae, 0x0078, 0x1597, 0x7803, 0x0004,
+       0x7003, 0x0000, 0x7004, 0x2060, 0x2009, 0x0048, 0x1078, 0x5591,
+       0x0078, 0x15ee, 0x0078, 0x15ee, 0x6808, 0xa005, 0x0040, 0x15ea,
+       0x7000, 0xa005, 0x00c0, 0x15c6, 0x0078, 0x15ea, 0x700c, 0x7110,
+       0xa106, 0x00c0, 0x15ba, 0x7004, 0xa406, 0x00c0, 0x15ea, 0x2001,
+       0x0005, 0x2004, 0xd08c, 0x00c0, 0x15ee, 0x2001, 0x0207, 0x2004,
+       0xd09c, 0x00c0, 0x15cf, 0x7804, 0xa084, 0x6000, 0x0040, 0x15e6,
+       0xa086, 0x6000, 0x0040, 0x15e6, 0x0078, 0x15cf, 0x7803, 0x0004,
+       0x7003, 0x0000, 0x2009, 0x0048, 0x1078, 0x5591, 0x0d7f, 0x0c7f,
+       0x127f, 0x007c, 0x0f7e, 0x0e7e, 0x2071, 0x6f42, 0x7000, 0xa086,
+       0x0000, 0x0040, 0x1635, 0x7004, 0xac06, 0x00c0, 0x1626, 0x2079,
+       0x0030, 0x7804, 0xd0fc, 0x00c0, 0x1622, 0x2001, 0x0207, 0x2004,
+       0xd09c, 0x00c0, 0x1601, 0x7803, 0x0004, 0x7804, 0xd0ac, 0x00c0,
+       0x160d, 0x7908, 0xd1ec, 0x00c0, 0x1619, 0x2009, 0x0009, 0x0078,
+       0x161b, 0x2009, 0x0019, 0x7803, 0x0002, 0x7902, 0x7003, 0x0003,
+       0x0078, 0x1635, 0x1078, 0x16e5, 0x0078, 0x15f6, 0x157e, 0x20a9,
+       0x0009, 0x2009, 0x6f48, 0x2104, 0xac06, 0x00c0, 0x1630, 0x200a,
+       0xa188, 0x0003, 0x00f0, 0x162b, 0x157f, 0x0e7f, 0x0f7f, 0x007c,
+       0x700c, 0x7110, 0xa106, 0x00c0, 0x1640, 0x7003, 0x0000, 0x007c,
+       0x2104, 0x7006, 0x2060, 0x8108, 0x211c, 0x8108, 0x2124, 0x8108,
+       0xa182, 0x6f63, 0x0048, 0x164e, 0x2009, 0x6f48, 0x7112, 0x8cff,
+       0x00c0, 0x1658, 0x7803, 0x0019, 0x7003, 0x0003, 0x0078, 0x167b,
+       0x6010, 0x2068, 0x2d58, 0x6828, 0xa406, 0x00c0, 0x1663, 0x682c,
+       0xa306, 0x0040, 0x1667, 0x1078, 0x1aa2, 0x00c0, 0x1652, 0x6824,
+       0x2050, 0x6818, 0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc, 0x000f,
+       0x2009, 0x0011, 0x1078, 0x167c, 0x0040, 0x167a, 0x2009, 0x0001,
+       0x1078, 0x167c, 0x2d58, 0x007c, 0x8aff, 0x0040, 0x16e0, 0xa03e,
+       0x2730, 0x6850, 0xd0fc, 0x00c0, 0x169b, 0x0d7e, 0x2804, 0xac68,
+       0x2900, 0x0079, 0x168b, 0x16ca, 0x16ab, 0x16ab, 0x16ca, 0x16ca,
+       0x16c2, 0x16ca, 0x16ab, 0x16ca, 0x16b1, 0x16b1, 0x16ca, 0x16ca,
+       0x16ca, 0x16ca, 0x16b1, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c,
+       0x6c20, 0x0d7e, 0xd99c, 0x0040, 0x16cd, 0x2804, 0xac68, 0x6f08,
+       0x6e0c, 0x0078, 0x16cd, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x0078,
+       0x16cd, 0x7b0c, 0xd3bc, 0x0040, 0x16ba, 0x7b08, 0xa39c, 0x0fff,
+       0x0078, 0x16bb, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c,
+       0x0078, 0x16cd, 0x0d7f, 0x1078, 0x1a3f, 0x00c0, 0x167c, 0xa00e,
+       0x0078, 0x16e0, 0x0d7f, 0x1078, 0x12b7, 0x7b22, 0x7a26, 0x7d32,
+       0x7c36, 0x7f3a, 0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x0d7f,
+       0x6828, 0xa300, 0x682a, 0x682c, 0xa201, 0x682e, 0x1078, 0x1a3f,
+       0x007c, 0x1078, 0x12b7, 0x1078, 0x12b7, 0x127e, 0x2091, 0x2100,
+       0x007e, 0x017e, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002,
+       0xa184, 0x0700, 0x00c0, 0x16e3, 0xa184, 0x0003, 0xa086, 0x0003,
+       0x0040, 0x16e3, 0x7000, 0x0079, 0x16fd, 0x1701, 0x1703, 0x1779,
+       0x17c0, 0x1078, 0x12b7, 0x8001, 0x7002, 0xa184, 0x0880, 0x00c0,
+       0x1718, 0x8aff, 0x0040, 0x175b, 0x2009, 0x0001, 0x1078, 0x167c,
+       0x0040, 0x17d3, 0x2009, 0x0001, 0x1078, 0x167c, 0x0078, 0x17d3,
+       0x7803, 0x0004, 0x7003, 0x0000, 0xd1dc, 0x0040, 0x1751, 0x027e,
+       0x037e, 0x6b28, 0x6a2c, 0x7820, 0x686e, 0xa31a, 0x7824, 0x6872,
+       0xa213, 0x6b2a, 0x6a2e, 0x037f, 0x027f, 0x7830, 0x681e, 0x7834,
+       0x6822, 0x1078, 0x1a58, 0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800,
+       0x6832, 0x7003, 0x0000, 0x6850, 0xc0fd, 0x6852, 0x6808, 0x8001,
+       0x680a, 0x00c0, 0x174d, 0x684c, 0xd0e4, 0x0040, 0x174d, 0x7004,
+       0x2060, 0x2009, 0x0048, 0x1078, 0x5591, 0x1078, 0x1638, 0x0078,
+       0x17d3, 0x057e, 0x7d0c, 0xd5bc, 0x00c0, 0x1758, 0x1078, 0x6c41,
+       0x057f, 0x0078, 0x1773, 0x684c, 0xc0f5, 0x684e, 0x7814, 0xa005,
+       0x00c0, 0x1773, 0x7003, 0x0000, 0x6808, 0x8001, 0x680a, 0x00c0,
+       0x176f, 0x7004, 0x2060, 0x2009, 0x0048, 0x1078, 0x5591, 0x1078,
+       0x1638, 0x0078, 0x17d3, 0x7803, 0x0009, 0x7003, 0x0003, 0x0078,
+       0x17d3, 0x8001, 0x7002, 0xd194, 0x0040, 0x178b, 0x7804, 0xd0fc,
+       0x00c0, 0x16ed, 0x8aff, 0x0040, 0x17d3, 0x2009, 0x0001, 0x1078,
+       0x167c, 0x0078, 0x17d3, 0xa184, 0x0880, 0x00c0, 0x1798, 0x8aff,
+       0x0040, 0x17d3, 0x2009, 0x0001, 0x1078, 0x167c, 0x0078, 0x17d3,
+       0x7803, 0x0004, 0x7003, 0x0000, 0xd1dc, 0x0040, 0x17b9, 0x027e,
+       0x037e, 0x6b28, 0x6a2c, 0x1078, 0x1a58, 0x0d7e, 0x2804, 0xac68,
+       0x6034, 0xd09c, 0x00c0, 0x17b2, 0x6808, 0xa31a, 0x680c, 0xa213,
+       0x0078, 0x17b6, 0x6810, 0xa31a, 0x6814, 0xa213, 0x0d7f, 0x0078,
+       0x1723, 0x057e, 0x7d0c, 0x1078, 0x6c41, 0x057f, 0x0078, 0x1773,
+       0x7003, 0x0000, 0x7004, 0xa00d, 0x0040, 0x17d1, 0x6808, 0x8001,
+       0x680a, 0x00c0, 0x17d1, 0x7004, 0x2060, 0x2009, 0x0048, 0x1078,
+       0x5591, 0x1078, 0x1638, 0x017f, 0x007f, 0x127f, 0x007c, 0x0e7e,
+       0x2071, 0x6f63, 0x7003, 0x0000, 0x0e7f, 0x007c, 0x0d7e, 0xa280,
+       0x0004, 0x206c, 0x694c, 0xd1dc, 0x00c0, 0x1836, 0x6934, 0xa184,
+       0x0007, 0x0079, 0x17eb, 0x17f3, 0x1821, 0x17f3, 0x17f3, 0x17f3,
+       0x1806, 0x17f3, 0x17f5, 0x1078, 0x12b7, 0x684c, 0xd0b4, 0x0040,
+       0x192f, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812, 0x687c,
+       0x680a, 0x6880, 0x680e, 0x6958, 0x0078, 0x1829, 0xa18c, 0x00ff,
+       0xa186, 0x0015, 0x00c0, 0x1836, 0x684c, 0xd0b4, 0x0040, 0x192f,
+       0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080,
+       0x1a82, 0x2004, 0x6832, 0x6958, 0xa006, 0x682e, 0x682a, 0x0078,
+       0x1832, 0x684c, 0xd0b4, 0x0040, 0x16e1, 0x6958, 0xa006, 0x682e,
+       0x682a, 0x2d00, 0x681a, 0x6834, 0xa084, 0x000f, 0xa080, 0x1a82,
+       0x2004, 0x6832, 0x6926, 0x684c, 0xc0dd, 0x684e, 0x0d7f, 0x007c,
+       0x0f7e, 0x2079, 0x0020, 0x7804, 0xd0fc, 0x10c0, 0x1933, 0x0e7e,
+       0x0d7e, 0x2071, 0x6f63, 0x7000, 0xa005, 0x00c0, 0x18b2, 0x0c7e,
+       0x7206, 0xa280, 0x0004, 0x205c, 0x7004, 0x2068, 0x6818, 0x0d7e,
+       0x2068, 0x686c, 0x7812, 0x6890, 0x0f7e, 0x20e1, 0x9040, 0x2079,
+       0x0200, 0x781a, 0x2079, 0x0100, 0x8004, 0x78d6, 0x0f7f, 0x0d7f,
+       0x2b68, 0x6824, 0x2050, 0x6818, 0x2060, 0x6830, 0x2040, 0x6034,
+       0xa0cc, 0x000f, 0x6908, 0xa184, 0x0007, 0x0040, 0x1874, 0x017e,
+       0x2009, 0x0008, 0xa102, 0x017f, 0xa108, 0x791a, 0x7116, 0x701e,
+       0x680c, 0xa081, 0x0000, 0x781e, 0x701a, 0xa006, 0x700e, 0x7012,
+       0x7004, 0x692c, 0x6814, 0xa106, 0x00c0, 0x188b, 0x6928, 0x6810,
+       0xa106, 0x0040, 0x1898, 0x037e, 0x047e, 0x6b14, 0x6c10, 0x1078,
+       0x1aa2, 0x047f, 0x037f, 0x0040, 0x1898, 0x0c7f, 0x0078, 0x18b2,
+       0x8aff, 0x00c0, 0x18a0, 0x0c7f, 0xa085, 0x0001, 0x0078, 0x18b2,
+       0x127e, 0x2091, 0x8000, 0x2079, 0x0020, 0x2009, 0x0001, 0x1078,
+       0x18b6, 0x0040, 0x18af, 0x2009, 0x0001, 0x1078, 0x18b6, 0x127f,
+       0x0c7f, 0xa006, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x077e, 0x067e,
+       0x057e, 0x047e, 0x037e, 0x027e, 0x8aff, 0x0040, 0x1928, 0x700c,
+       0x7214, 0xa202, 0x7010, 0x7218, 0xa203, 0x0048, 0x1927, 0xa03e,
+       0x2730, 0x6850, 0xd0fc, 0x00c0, 0x18e3, 0x0d7e, 0x2804, 0xac68,
+       0x2900, 0x0079, 0x18d3, 0x1909, 0x18f3, 0x18f3, 0x1909, 0x1909,
+       0x1901, 0x1909, 0x18f3, 0x1909, 0x18f9, 0x18f9, 0x1909, 0x1909,
+       0x1909, 0x1909, 0x18f9, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c,
+       0x6c20, 0xd99c, 0x0040, 0x190d, 0x0d7e, 0x2804, 0xac68, 0x6f08,
+       0x6e0c, 0x0078, 0x190c, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x0078,
+       0x190c, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x0078,
+       0x190c, 0x0d7f, 0x1078, 0x1a3f, 0x00c0, 0x18bc, 0xa00e, 0x0078,
+       0x1928, 0x0d7f, 0x1078, 0x12b7, 0x0d7f, 0x7b22, 0x7a26, 0x7d32,
+       0x7c36, 0x7f3a, 0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x6828,
+       0xa300, 0x682a, 0x682c, 0xa201, 0x682e, 0x700c, 0xa300, 0x700e,
+       0x7010, 0xa201, 0x7012, 0x1078, 0x1a3f, 0x0078, 0x1928, 0xa006,
+       0x027f, 0x037f, 0x047f, 0x057f, 0x067f, 0x077f, 0x007c, 0x1078,
+       0x12b7, 0x1078, 0x12b7, 0x127e, 0x2091, 0x2200, 0x007e, 0x017e,
+       0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x2079, 0x0020, 0x2071, 0x6f63,
+       0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700,
+       0x00c0, 0x1931, 0x7000, 0x0079, 0x194d, 0x1a09, 0x1951, 0x19d6,
+       0x1a07, 0x8001, 0x7002, 0xd19c, 0x00c0, 0x1965, 0x8aff, 0x0040,
+       0x199a, 0x2009, 0x0001, 0x1078, 0x18b6, 0x0040, 0x1a09, 0x2009,
+       0x0001, 0x1078, 0x18b6, 0x0078, 0x1a09, 0x7803, 0x0004, 0xd194,
+       0x0040, 0x1975, 0x6850, 0xc0fc, 0x6852, 0x8aff, 0x00c0, 0x1990,
+       0x684c, 0xc0f5, 0x684e, 0x0078, 0x1990, 0x027e, 0x037e, 0x6b28,
+       0x6a2c, 0x701c, 0xa005, 0x10c0, 0x1a11, 0x7820, 0x686e, 0xa31a,
+       0x7824, 0x6872, 0xa213, 0x6b2a, 0x6a2e, 0x037f, 0x027f, 0x7830,
+       0x681e, 0x7834, 0x6822, 0x1078, 0x1a58, 0x6850, 0xc0fd, 0x6852,
+       0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x7003, 0x0000,
+       0x0078, 0x1a09, 0x711c, 0x81ff, 0x0040, 0x19af, 0x7922, 0x7827,
+       0x0000, 0x7803, 0x0001, 0x7000, 0x8000, 0x7002, 0x700c, 0xa100,
+       0x700e, 0x7010, 0xa081, 0x0000, 0x7012, 0x0078, 0x1a09, 0x0f7e,
+       0x027e, 0x781c, 0x007e, 0x7818, 0x007e, 0x2079, 0x0100, 0x7a14,
+       0xa284, 0x0004, 0xa085, 0x0012, 0x7816, 0x7820, 0xd0bc, 0x00c0,
+       0x19bd, 0x79c8, 0x007f, 0xa102, 0x78ca, 0x79c4, 0x007f, 0xa102,
+       0x78c6, 0xa284, 0x0004, 0xa085, 0x0012, 0x7816, 0x027f, 0x0f7f,
+       0x7803, 0x0008, 0x7003, 0x0000, 0x0078, 0x1a09, 0x8001, 0x7002,
+       0xd194, 0x0040, 0x19eb, 0x7804, 0xd0fc, 0x00c0, 0x1943, 0xd19c,
+       0x00c0, 0x1a05, 0x8aff, 0x0040, 0x1a09, 0x2009, 0x0001, 0x1078,
+       0x18b6, 0x0078, 0x1a09, 0x027e, 0x037e, 0x6b28, 0x6a2c, 0x1078,
+       0x1a58, 0x0d7e, 0x2804, 0xac68, 0x6034, 0xd09c, 0x00c0, 0x19fe,
+       0x6808, 0xa31a, 0x680c, 0xa213, 0x0078, 0x1a02, 0x6810, 0xa31a,
+       0x6814, 0xa213, 0x0d7f, 0x0078, 0x1979, 0x0078, 0x1975, 0x1078,
+       0x12b7, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x017f, 0x007f, 0x127f,
+       0x007c, 0x7920, 0xa108, 0x7922, 0x7924, 0xa189, 0x0000, 0x7926,
+       0x7930, 0xa10a, 0x7932, 0x7934, 0xa18b, 0x0000, 0x7936, 0x007c,
+       0x0f7e, 0x0e7e, 0x2071, 0x6f63, 0x7000, 0xa086, 0x0000, 0x0040,
+       0x1a3c, 0x2079, 0x0020, 0x7804, 0xa084, 0x0003, 0x0040, 0x1a36,
+       0x7803, 0x0004, 0x7804, 0xd0ac, 0x00c0, 0x1a32, 0x20e1, 0x9040,
+       0x7803, 0x0002, 0x7003, 0x0000, 0x0e7f, 0x0f7f, 0x007c, 0x8840,
+       0x2804, 0xa005, 0x00c0, 0x1a53, 0x6004, 0xa005, 0x0040, 0x1a55,
+       0x681a, 0x2060, 0x6034, 0xa084, 0x000f, 0xa080, 0x1a82, 0x2044,
+       0x88ff, 0x1040, 0x12b7, 0x8a51, 0x007c, 0x2051, 0x0000, 0x007c,
+       0x8a50, 0x8841, 0x2804, 0xa005, 0x00c0, 0x1a72, 0x2c00, 0xad06,
+       0x0040, 0x1a67, 0x6000, 0xa005, 0x00c0, 0x1a67, 0x2d00, 0x2060,
+       0x681a, 0x6034, 0xa084, 0x000f, 0xa080, 0x1a92, 0x2044, 0x88ff,
+       0x1040, 0x12b7, 0x007c, 0x0000, 0x0011, 0x0015, 0x0019, 0x001d,
+       0x0021, 0x0025, 0x0029, 0x0000, 0x000f, 0x0015, 0x001b, 0x0021,
+       0x0027, 0x0000, 0x0000, 0x1a78, 0x1a74, 0x0000, 0x0000, 0x8000,
+       0x0000, 0x1a78, 0x0000, 0x1a7f, 0x1a7c, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x1a7f, 0x0000, 0x1a7a, 0x1a7a, 0x0000, 0x0000, 0x8000,
+       0x0000, 0x1a7a, 0x0000, 0x1a80, 0x1a80, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x1a80, 0x0a7e, 0x097e, 0x087e, 0x6858, 0xa055, 0x0040,
+       0x1b28, 0x2d60, 0x6034, 0xa0cc, 0x000f, 0xa9c0, 0x1a82, 0xa986,
+       0x0007, 0x0040, 0x1ab7, 0xa986, 0x000f, 0x00c0, 0x1abb, 0x605c,
+       0xa422, 0x6060, 0xa31a, 0x2804, 0xa045, 0x00c0, 0x1ac9, 0x0050,
+       0x1ac3, 0x0078, 0x1b28, 0x6004, 0xa065, 0x0040, 0x1b28, 0x0078,
+       0x1aaa, 0x2804, 0xa005, 0x0040, 0x1ae7, 0xac68, 0xd99c, 0x00c0,
+       0x1ad7, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0078, 0x1adb, 0x6810,
+       0xa422, 0x6814, 0xa31b, 0x0048, 0x1af5, 0x2300, 0xa405, 0x0040,
+       0x1aed, 0x8a51, 0x0040, 0x1b28, 0x8840, 0x0078, 0x1ac9, 0x6004,
+       0xa065, 0x0040, 0x1b28, 0x0078, 0x1aaa, 0x8a51, 0x8840, 0x2b68,
+       0x6850, 0xc0fc, 0x6852, 0x0078, 0x1b22, 0x8422, 0x8420, 0x831a,
+       0xa399, 0x0000, 0x0d7e, 0x2b68, 0x6c6e, 0x6b72, 0x0d7f, 0xd99c,
+       0x00c0, 0x1b10, 0x6908, 0x2400, 0xa122, 0x690c, 0x2300, 0xa11b,
+       0x1048, 0x12b7, 0x6800, 0xa420, 0x6804, 0xa319, 0x0078, 0x1b1c,
+       0x6910, 0x2400, 0xa122, 0x6914, 0x2300, 0xa11b, 0x1048, 0x12b7,
+       0x6800, 0xa420, 0x6804, 0xa319, 0x2b68, 0x6c1e, 0x6b22, 0x6850,
+       0xc0fd, 0x6852, 0x007f, 0x007f, 0x007f, 0xa006, 0x0078, 0x1b2d,
+       0x087f, 0x097f, 0x0a7f, 0xa085, 0x0001, 0x007c, 0x2001, 0x0005,
+       0x2004, 0xa084, 0x0007, 0x0079, 0x1b35, 0x1b3d, 0x1b3e, 0x1b41,
+       0x1b44, 0x1b49, 0x1b4c, 0x1b51, 0x1b56, 0x007c, 0x1078, 0x1933,
+       0x007c, 0x1078, 0x16e5, 0x007c, 0x1078, 0x16e5, 0x1078, 0x1933,
+       0x007c, 0x1078, 0x143e, 0x007c, 0x1078, 0x1933, 0x1078, 0x143e,
+       0x007c, 0x1078, 0x16e5, 0x1078, 0x143e, 0x007c, 0x1078, 0x16e5,
+       0x1078, 0x1933, 0x1078, 0x143e, 0x007c, 0x127e, 0x2091, 0x2300,
+       0x2079, 0x0200, 0x2071, 0x7280, 0x2069, 0x6d00, 0x2009, 0x0004,
+       0x7912, 0x7916, 0x1078, 0x1df6, 0x781b, 0x0002, 0x20e1, 0x8700,
+       0x127f, 0x007c, 0x127e, 0x2091, 0x2300, 0x781c, 0xa084, 0x0007,
+       0x0079, 0x1b7a, 0x1b9e, 0x1b82, 0x1b86, 0x1b8a, 0x1b90, 0x1b94,
+       0x1b98, 0x1b9c, 0x1078, 0x3d7c, 0x0078, 0x1b9e, 0x1078, 0x3db0,
+       0x0078, 0x1b9e, 0x1078, 0x3d7c, 0x1078, 0x3db0, 0x0078, 0x1b9e,
+       0x1078, 0x1ba0, 0x0078, 0x1b9e, 0x1078, 0x1ba0, 0x0078, 0x1b9e,
+       0x1078, 0x1ba0, 0x0078, 0x1b9e, 0x1078, 0x1ba0, 0x127f, 0x007c,
+       0x007e, 0x017e, 0x027e, 0x7930, 0xa184, 0x0003, 0x0040, 0x1baa,
+       0x1078, 0x12b7, 0xa184, 0x0030, 0x0040, 0x1bbb, 0x6a00, 0xa286,
+       0x0003, 0x00c0, 0x1bb5, 0x1078, 0x12b7, 0x1078, 0x31cb, 0x20e1,
+       0x9010, 0x0078, 0x1bc7, 0xa184, 0x00c0, 0x0040, 0x1bc1, 0x1078,
+       0x12b7, 0xa184, 0x0300, 0x0040, 0x1bc7, 0x20e1, 0x9020, 0x7932,
+       0x027f, 0x017f, 0x007f, 0x007c, 0x017e, 0x0e7e, 0x0f7e, 0x2071,
+       0x6d00, 0x7128, 0x2001, 0x6f03, 0x2102, 0x2001, 0x6f0b, 0x2102,
+       0xa182, 0x0211, 0x00c8, 0x1be0, 0x2009, 0x0008, 0x0078, 0x1c0a,
+       0xa182, 0x0259, 0x00c8, 0x1be8, 0x2009, 0x0007, 0x0078, 0x1c0a,
+       0xa182, 0x02c1, 0x00c8, 0x1bf0, 0x2009, 0x0006, 0x0078, 0x1c0a,
+       0xa182, 0x0349, 0x00c8, 0x1bf8, 0x2009, 0x0005, 0x0078, 0x1c0a,
+       0xa182, 0x0421, 0x00c8, 0x1c00, 0x2009, 0x0004, 0x0078, 0x1c0a,
+       0xa182, 0x0581, 0x00c8, 0x1c08, 0x2009, 0x0003, 0x0078, 0x1c0a,
+       0x2009, 0x0002, 0x2079, 0x0200, 0x7912, 0x7916, 0x1078, 0x1df6,
+       0x0f7f, 0x0e7f, 0x017f, 0x007c, 0x127e, 0x2091, 0x2200, 0x2061,
+       0x0100, 0x2071, 0x6d00, 0x6024, 0x6026, 0x6033, 0x00ef, 0x60e7,
+       0x0000, 0x60eb, 0x00ef, 0x60e3, 0x0008, 0x604b, 0xf7f7, 0x6043,
+       0x0000, 0x602f, 0x0080, 0x602f, 0x0000, 0x6007, 0x0caf, 0x600f,
+       0x00ff, 0x602b, 0x002f, 0x127f, 0x007c, 0x2001, 0x6d2d, 0x2003,
+       0x0000, 0x2001, 0x6d2c, 0x2003, 0x0001, 0x007c, 0x127e, 0x2091,
+       0x2200, 0x007e, 0x017e, 0x027e, 0x6124, 0xa184, 0x002c, 0x00c0,
+       0x1c4d, 0xa184, 0x0007, 0x0079, 0x1c53, 0xa195, 0x0004, 0xa284,
+       0x0007, 0x0079, 0x1c53, 0x1c7f, 0x1c5b, 0x1c5f, 0x1c63, 0x1c69,
+       0x1c6d, 0x1c73, 0x1c79, 0x1078, 0x4226, 0x0078, 0x1c7f, 0x1078,
+       0x42e4, 0x0078, 0x1c7f, 0x1078, 0x42e4, 0x1078, 0x4226, 0x0078,
+       0x1c7f, 0x1078, 0x1c84, 0x0078, 0x1c7f, 0x1078, 0x4226, 0x1078,
+       0x1c84, 0x0078, 0x1c7f, 0x1078, 0x42e4, 0x1078, 0x1c84, 0x0078,
+       0x1c7f, 0x1078, 0x42e4, 0x1078, 0x4226, 0x1078, 0x1c84, 0x027f,
+       0x017f, 0x007f, 0x127f, 0x007c, 0xd1ac, 0x0040, 0x1d24, 0x017e,
+       0x047e, 0x0c7e, 0x644c, 0x74ba, 0xa48c, 0xff00, 0xa196, 0xff00,
+       0x0040, 0x1cb3, 0x6030, 0xa084, 0x00ff, 0x810f, 0xa116, 0x0040,
+       0x1cb3, 0x7130, 0xd18c, 0x00c0, 0x1cb3, 0x2011, 0x6d52, 0x2214,
+       0xd2ec, 0x0040, 0x1ca7, 0xc18d, 0x7132, 0x0078, 0x1cb3, 0x6240,
+       0xa294, 0x0010, 0x0040, 0x1cf2, 0x6248, 0xa294, 0xff00, 0xa296,
+       0xff00, 0x00c0, 0x1cf2, 0x2011, 0x8013, 0x1078, 0x2a53, 0x7130,
+       0xc185, 0x7132, 0x2011, 0x6d52, 0x220c, 0xd1a4, 0x0040, 0x1cda,
+       0x017e, 0x2009, 0x0001, 0x2011, 0x0100, 0x1078, 0x41f4, 0x2019,
+       0x000e, 0x1078, 0x6b8f, 0xa484, 0x00ff, 0xa080, 0x2091, 0x200c,
+       0xa18c, 0xff00, 0x810f, 0x8127, 0xa006, 0x2009, 0x000e, 0x1078,
+       0x6bf7, 0x017f, 0xd1ac, 0x00c0, 0x1ce3, 0x2019, 0x0004, 0x1078,
+       0x202f, 0x0078, 0x1cf2, 0x157e, 0x20a9, 0x007f, 0x2009, 0x0000,
+       0x1078, 0x3447, 0x00c0, 0x1cee, 0x1078, 0x3256, 0x8108, 0x00f0,
+       0x1ce8, 0x157f, 0x0c7f, 0x047f, 0x6043, 0x0000, 0x2009, 0x00f7,
+       0x1078, 0x3233, 0x2011, 0x0003, 0x1078, 0x5232, 0x2011, 0x0002,
+       0x1078, 0x523c, 0x1078, 0x5148, 0x1078, 0x414c, 0x037e, 0x2019,
+       0x0000, 0x1078, 0x51da, 0x037f, 0x60e3, 0x0000, 0x017f, 0x2001,
+       0x6d00, 0x2014, 0xa296, 0x0004, 0x00c0, 0x1d1c, 0xd19c, 0x00c0,
+       0x1d1c, 0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0x6d20,
+       0x2003, 0x0000, 0x6027, 0x0020, 0xd194, 0x0040, 0x1d9d, 0x017e,
+       0x6220, 0xd2b4, 0x0040, 0x1d5b, 0x1078, 0x414c, 0x1078, 0x4fe5,
+       0x6027, 0x0004, 0x0d7e, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000,
+       0x0040, 0x1d3e, 0x6803, 0x1000, 0x6803, 0x0000, 0x0d7f, 0x0c7e,
+       0x2061, 0x6f10, 0x6028, 0xa09a, 0x0002, 0x00c8, 0x1d4e, 0x8000,
+       0x602a, 0x0c7f, 0x1078, 0x4fd7, 0x0078, 0x1d9c, 0x2019, 0x6f19,
+       0x2304, 0xa065, 0x0040, 0x1d58, 0x2009, 0x0014, 0x1078, 0x5591,
+       0x0c7f, 0x0078, 0x1d9c, 0xd2bc, 0x0040, 0x1d9c, 0x1078, 0x415a,
+       0x6017, 0x0010, 0x6027, 0x0004, 0x0d7e, 0x2069, 0x0140, 0x6804,
+       0xa084, 0x4000, 0x0040, 0x1d70, 0x6803, 0x1000, 0x6803, 0x0000,
+       0x0d7f, 0x0c7e, 0x2061, 0x6f10, 0x6044, 0xa09a, 0x0002, 0x00c8,
+       0x1d91, 0x8000, 0x6046, 0x603c, 0x0c7f, 0xa005, 0x0040, 0x1d9c,
+       0x1078, 0x4151, 0xa080, 0x0007, 0x2004, 0xa086, 0x0006, 0x00c0,
+       0x1d8d, 0x6017, 0x0012, 0x0078, 0x1d9c, 0x6017, 0x0016, 0x0078,
+       0x1d9c, 0x2019, 0x6f1f, 0x2304, 0xa065, 0x0040, 0x1d9b, 0x2009,
+       0x004a, 0x1078, 0x5591, 0x0c7f, 0x017f, 0xd19c, 0x0040, 0x1dc5,
+       0x017e, 0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x1078, 0x5232,
+       0x2011, 0x0002, 0x1078, 0x523c, 0x1078, 0x5148, 0x1078, 0x414c,
+       0x037e, 0x2019, 0x0000, 0x1078, 0x51da, 0x037f, 0x60e3, 0x0000,
+       0x1078, 0x6c5f, 0x1078, 0x6c7d, 0x2001, 0x6d00, 0x2003, 0x0004,
+       0x6027, 0x0008, 0x1078, 0x11aa, 0x017f, 0xa18c, 0xffd0, 0x6126,
+       0x007c, 0x007e, 0x017e, 0x027e, 0x0e7e, 0x0f7e, 0x127e, 0x2091,
+       0x8000, 0x2071, 0x6d00, 0x71b0, 0x70b2, 0xa116, 0x0040, 0x1def,
+       0x81ff, 0x0040, 0x1de1, 0x2011, 0x8011, 0x1078, 0x2a53, 0x0078,
+       0x1def, 0x2011, 0x8012, 0x1078, 0x2a53, 0x037e, 0x0c7e, 0x2061,
+       0x0100, 0x2019, 0x0028, 0x1078, 0x202f, 0x0c7f, 0x037f, 0x127f,
+       0x0f7f, 0x0e7f, 0x027f, 0x017f, 0x007f, 0x007c, 0x0c7e, 0x0f7e,
+       0x007e, 0x027e, 0x2061, 0x0100, 0xa190, 0x1e09, 0x2204, 0x60f2,
+       0xa190, 0x1e12, 0x2204, 0x60ee, 0x027f, 0x007f, 0x0f7f, 0x0c7f,
+       0x007c, 0x083e, 0x083e, 0x083e, 0x0580, 0x0420, 0x0348, 0x02c0,
+       0x0258, 0x0210, 0x01a8, 0x01a8, 0x01a8, 0x01a8, 0x0140, 0x00f8,
+       0x00d0, 0x00b0, 0x00a0, 0x2028, 0x2130, 0xa094, 0xff00, 0x00c0,
+       0x1e24, 0x81ff, 0x0040, 0x1e28, 0x1078, 0x3f00, 0x0078, 0x1e2f,
+       0xa080, 0x2091, 0x200c, 0xa18c, 0xff00, 0x810f, 0xa006, 0x007c,
+       0xa080, 0x2091, 0x200c, 0xa18c, 0x00ff, 0x007c, 0x1e56, 0x1e5a,
+       0x1e5e, 0x1e64, 0x1e6a, 0x1e70, 0x1e76, 0x1e7e, 0x1e86, 0x1e8c,
+       0x1e92, 0x1e9a, 0x1ea2, 0x1eaa, 0x1eb2, 0x1ebc, 0x1ec6, 0x1ec6,
+       0x1ec6, 0x1ec6, 0x1ec6, 0x1ec6, 0x1ec6, 0x1ec6, 0x1ec6, 0x1ec6,
+       0x1ec6, 0x1ec6, 0x1ec6, 0x1ec6, 0x1ec6, 0x1ec6, 0x107e, 0x007e,
+       0x0078, 0x1edf, 0x107e, 0x007e, 0x0078, 0x1edf, 0x107e, 0x007e,
+       0x1078, 0x1c3e, 0x0078, 0x1edf, 0x107e, 0x007e, 0x1078, 0x1c3e,
+       0x0078, 0x1edf, 0x107e, 0x007e, 0x1078, 0x1b2e, 0x0078, 0x1edf,
+       0x107e, 0x007e, 0x1078, 0x1b2e, 0x0078, 0x1edf, 0x107e, 0x007e,
+       0x1078, 0x1c3e, 0x1078, 0x1b2e, 0x0078, 0x1edf, 0x107e, 0x007e,
+       0x1078, 0x1c3e, 0x1078, 0x1b2e, 0x0078, 0x1edf, 0x107e, 0x007e,
+       0x1078, 0x1b72, 0x0078, 0x1edf, 0x107e, 0x007e, 0x1078, 0x1b72,
+       0x0078, 0x1edf, 0x107e, 0x007e, 0x1078, 0x1c3e, 0x1078, 0x1b72,
+       0x0078, 0x1edf, 0x107e, 0x007e, 0x1078, 0x1c3e, 0x1078, 0x1b72,
+       0x0078, 0x1edf, 0x107e, 0x007e, 0x1078, 0x1b2e, 0x1078, 0x1b72,
+       0x0078, 0x1edf, 0x107e, 0x007e, 0x1078, 0x1b2e, 0x1078, 0x1b72,
+       0x0078, 0x1edf, 0x107e, 0x007e, 0x1078, 0x1c3e, 0x1078, 0x1b2e,
+       0x1078, 0x1b72, 0x0078, 0x1edf, 0x107e, 0x007e, 0x1078, 0x1c3e,
+       0x1078, 0x1b2e, 0x1078, 0x1b72, 0x0078, 0x1edf, 0x0005, 0x0078,
+       0x1ec6, 0xb084, 0x003c, 0x8004, 0x8004, 0x0079, 0x1ecf, 0x1edf,
+       0x1e5c, 0x1e60, 0x1e66, 0x1e6c, 0x1e72, 0x1e78, 0x1e80, 0x1e88,
+       0x1e8e, 0x1e94, 0x1e9c, 0x1ea4, 0x1eac, 0x1eb4, 0x1ebe, 0x0008,
+       0x1ec9, 0x007f, 0x107f, 0x2091, 0x8001, 0x007c, 0x0c7e, 0x027e,
+       0x2041, 0x007e, 0x70bc, 0xd09c, 0x0040, 0x1ef0, 0x2041, 0x007f,
+       0x2001, 0x010c, 0x203c, 0x727c, 0x82ff, 0x0040, 0x1f3b, 0x037e,
+       0x738c, 0xa38e, 0xffff, 0x00c0, 0x1eff, 0x2019, 0x0001, 0x8314,
+       0xa2e0, 0x73c0, 0x2c04, 0xa38c, 0x0001, 0x0040, 0x1f0c, 0xa084,
+       0xff00, 0x8007, 0x0078, 0x1f0e, 0xa084, 0x00ff, 0xa70e, 0x0040,
+       0x1f30, 0xa08e, 0x00ff, 0x0040, 0x1f36, 0x2009, 0x0000, 0x1078,
+       0x1e1b, 0x1078, 0x3410, 0x00c0, 0x1f33, 0x6004, 0xa084, 0x00ff,
+       0xa086, 0x0006, 0x00c0, 0x1f2a, 0x1078, 0x1f8d, 0x0040, 0x1f33,
+       0x0078, 0x1f30, 0x1078, 0x208d, 0x1078, 0x1fb4, 0x0040, 0x1f33,
+       0x8318, 0x0078, 0x1eff, 0x738e, 0x0078, 0x1f38, 0x708f, 0xffff,
+       0x037f, 0x0078, 0x1f8a, 0xa780, 0x2091, 0x203c, 0xa7bc, 0xff00,
+       0x873f, 0x708c, 0xa096, 0xffff, 0x0040, 0x1f4d, 0xa812, 0x00c8,
+       0x1f5d, 0x708f, 0xffff, 0x0078, 0x1f87, 0x2009, 0x0000, 0x70bc,
+       0xd09c, 0x0040, 0x1f58, 0xd094, 0x0040, 0x1f58, 0x2009, 0x007e,
+       0x2100, 0xa802, 0x20a8, 0x0078, 0x1f61, 0x2008, 0x2810, 0xa202,
+       0x20a8, 0x2700, 0x157e, 0x017e, 0xa106, 0x0040, 0x1f7e, 0x1078,
+       0x3410, 0x00c0, 0x1f87, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006,
+       0x00c0, 0x1f78, 0x1078, 0x1f8d, 0x0040, 0x1f87, 0x0078, 0x1f7e,
+       0x1078, 0x208d, 0x1078, 0x1fb4, 0x0040, 0x1f87, 0x017f, 0x8108,
+       0x157f, 0x00f0, 0x1f61, 0x708f, 0xffff, 0x0078, 0x1f8a, 0x017f,
+       0x157f, 0x718e, 0x027f, 0x0c7f, 0x007c, 0x017e, 0x077e, 0x0d7e,
+       0x0c7e, 0x2c68, 0x1078, 0x5504, 0x0040, 0x1faf, 0x2d00, 0x601a,
+       0x601f, 0x0001, 0x2001, 0x0000, 0x1078, 0x33df, 0x2001, 0x0000,
+       0x1078, 0x33f3, 0x127e, 0x2091, 0x8000, 0x7088, 0x8000, 0x708a,
+       0x127f, 0x2009, 0x0004, 0x1078, 0x5591, 0xa085, 0x0001, 0x0c7f,
+       0x0d7f, 0x077f, 0x017f, 0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e,
+       0x2c68, 0x1078, 0x5504, 0x0040, 0x1fd6, 0x2d00, 0x601a, 0x601f,
+       0x0001, 0x2001, 0x0000, 0x1078, 0x33df, 0x2001, 0x0002, 0x1078,
+       0x33f3, 0x127e, 0x2091, 0x8000, 0x7088, 0x8000, 0x708a, 0x127f,
+       0x2009, 0x0002, 0x1078, 0x5591, 0xa085, 0x0001, 0x0c7f, 0x0d7f,
+       0x077f, 0x017f, 0x007c, 0x0c7e, 0x027e, 0x2009, 0x0080, 0x1078,
+       0x3410, 0x00c0, 0x1fe9, 0x1078, 0x1fec, 0x0040, 0x1fe9, 0x70c3,
+       0xffff, 0x027f, 0x0c7f, 0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e,
+       0x2c68, 0x1078, 0x5504, 0x0040, 0x200e, 0x2d00, 0x601a, 0x601f,
+       0x0001, 0x2001, 0x0000, 0x1078, 0x33df, 0x2001, 0x0002, 0x1078,
+       0x33f3, 0x127e, 0x2091, 0x8000, 0x70c4, 0x8000, 0x70c6, 0x127f,
+       0x2009, 0x0002, 0x1078, 0x5591, 0xa085, 0x0001, 0x0c7f, 0x0d7f,
+       0x077f, 0x017f, 0x007c, 0x0c7e, 0x0d7e, 0x2009, 0x007f, 0x1078,
+       0x3410, 0x00c0, 0x202c, 0x2c68, 0x1078, 0x5504, 0x0040, 0x202c,
+       0x2d00, 0x601a, 0x6312, 0x601f, 0x0001, 0x620a, 0x2009, 0x0022,
+       0x1078, 0x5591, 0xa085, 0x0001, 0x0d7f, 0x0c7f, 0x007c, 0x0e7e,
+       0x0c7e, 0x067e, 0x037e, 0x027e, 0x1078, 0x4463, 0x1078, 0x4417,
+       0x1078, 0x59ce, 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078,
+       0x3447, 0x00c0, 0x2047, 0x1078, 0x35cf, 0x1078, 0x3256, 0x017f,
+       0x8108, 0x00f0, 0x203e, 0x027f, 0x037f, 0x067f, 0x0c7f, 0x0e7f,
+       0x007c, 0x0e7e, 0x0c7e, 0x037e, 0x027e, 0x017e, 0x6218, 0x2270,
+       0x72a0, 0x027e, 0x2019, 0x0029, 0x1078, 0x445c, 0x1078, 0x43a9,
+       0x2c08, 0x1078, 0x6a57, 0x017f, 0x2e60, 0x1078, 0x35cf, 0x1078,
+       0x3256, 0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f, 0x007c, 0x0e7e,
+       0x007e, 0x6018, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x00c0, 0x2083,
+       0x2071, 0x6d00, 0x7088, 0xa005, 0x0040, 0x2080, 0x8001, 0x708a,
+       0x007f, 0x0e7f, 0x007c, 0x2071, 0x6d00, 0x70c4, 0xa005, 0x0040,
+       0x2080, 0x8001, 0x70c6, 0x0078, 0x2080, 0x6000, 0xc08c, 0x6002,
+       0x007c, 0x7eef, 0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc,
+       0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1,
+       0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6,
+       0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4,
+       0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa,
+       0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d,
+       0x809b, 0x8098, 0x6797, 0x6690, 0x658f, 0x6488, 0x6384, 0x6282,
+       0x8081, 0x8080, 0x617c, 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074,
+       0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a,
+       0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863, 0x575c, 0x565a, 0x5559,
+       0x8056, 0x8055, 0x5454, 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d,
+       0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043,
+       0x803c, 0x803a, 0x8039, 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932,
+       0x4831, 0x802e, 0x472d, 0x462c, 0x452b, 0x442a, 0x4329, 0x4227,
+       0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18,
+       0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000,
+       0x8000, 0x3800, 0x3700, 0x3600, 0x8000, 0x3500, 0x8000, 0x8000,
+       0x8000, 0x3400, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+       0x3300, 0x3200, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+       0x3100, 0x3000, 0x8000, 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00,
+       0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900,
+       0x2800, 0x8000, 0x2700, 0x2600, 0x2500, 0x2400, 0x2300, 0x2200,
+       0x8000, 0x8000, 0x2100, 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00,
+       0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000,
+       0x8000, 0x8000, 0x8000, 0x8000, 0x1800, 0x8000, 0x1700, 0x1600,
+       0x1500, 0x8000, 0x1400, 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00,
+       0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900,
+       0x8000, 0x8000, 0x0800, 0x0700, 0x8000, 0x0600, 0x8000, 0x8000,
+       0x8000, 0x0500, 0x0400, 0x0300, 0x8000, 0x0200, 0x8000, 0x8000,
+       0x8000, 0x0100, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+       0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+       0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+       0x8000, 0x2071, 0x6d6d, 0x7003, 0x0002, 0xa006, 0x7012, 0x7016,
+       0x703a, 0x703e, 0x7033, 0x6d7d, 0x7037, 0x6d7d, 0x7007, 0x0001,
+       0x2061, 0x6d9d, 0x6003, 0x0002, 0x007c, 0x0090, 0x21b8, 0x0068,
+       0x21b8, 0x2071, 0x6d6d, 0x2b78, 0x7818, 0xd084, 0x00c0, 0x21b8,
+       0x2a60, 0x7820, 0xa08e, 0x0069, 0x00c0, 0x229c, 0x0079, 0x223c,
+       0x007c, 0x2071, 0x6d6d, 0x7004, 0x0079, 0x21be, 0x21c2, 0x21c3,
+       0x21cd, 0x21df, 0x007c, 0x0090, 0x21cc, 0x0068, 0x21cc, 0x2b78,
+       0x7818, 0xd084, 0x0040, 0x21eb, 0x007c, 0x2b78, 0x2061, 0x6d9d,
+       0x6008, 0xa08e, 0x0100, 0x0040, 0x21da, 0xa086, 0x0200, 0x0040,
+       0x2294, 0x007c, 0x7014, 0x2068, 0x2a60, 0x7018, 0x007a, 0x7010,
+       0x2068, 0x6834, 0xa086, 0x0103, 0x0040, 0x21e7, 0x007c, 0x2a60,
+       0x2b78, 0x7018, 0x007a, 0x2a60, 0x7820, 0xa08a, 0x0040, 0x00c8,
+       0x21f4, 0x61b0, 0x0079, 0x21fc, 0x2100, 0xa08a, 0x0033, 0x00c8,
+       0x2290, 0x61b0, 0x0079, 0x223c, 0x2272, 0x22a4, 0x22ac, 0x22b0,
+       0x22b8, 0x22be, 0x22c2, 0x22cb, 0x22cf, 0x22d7, 0x22db, 0x2290,
+       0x2290, 0x2290, 0x22df, 0x2290, 0x22ef, 0x2306, 0x231d, 0x2399,
+       0x239e, 0x23cb, 0x2416, 0x2425, 0x2446, 0x247c, 0x2486, 0x2493,
+       0x24a6, 0x24be, 0x24c7, 0x2504, 0x250a, 0x2290, 0x251a, 0x2290,
+       0x2290, 0x2290, 0x2290, 0x2290, 0x251e, 0x2524, 0x2290, 0x2290,
+       0x2290, 0x2290, 0x2290, 0x2290, 0x2290, 0x2290, 0x252c, 0x2290,
+       0x2290, 0x2290, 0x2290, 0x2290, 0x2539, 0x253f, 0x2290, 0x2290,
+       0x2290, 0x2290, 0x2290, 0x2290, 0x2290, 0x2290, 0x2290, 0x2290,
+       0x2290, 0x2290, 0x2290, 0x2290, 0x2290, 0x2290, 0x2290, 0x2290,
+       0x2290, 0x2290, 0x2290, 0x2290, 0x22d7, 0x22db, 0x2290, 0x2290,
+       0x2551, 0x2290, 0x2290, 0x2290, 0x2290, 0x2290, 0x2290, 0x2290,
+       0x2290, 0x2290, 0x2290, 0x2290, 0x259e, 0x265d, 0x2671, 0x2678,
+       0x26db, 0x2736, 0x2741, 0x2783, 0x2790, 0x279d, 0x27a0, 0x2555,
+       0x27c9, 0x2811, 0x281e, 0x28fd, 0x29cb, 0x29f2, 0x2ade, 0x713c,
+       0x0078, 0x2272, 0x2021, 0x4000, 0x1078, 0x2a2d, 0x127e, 0x2091,
+       0x8000, 0x0068, 0x227f, 0x7818, 0xd084, 0x0040, 0x2282, 0x127f,
+       0x0078, 0x2276, 0x781b, 0x0001, 0x7c22, 0x7926, 0x7a2a, 0x7b2e,
+       0x2091, 0x4080, 0x7007, 0x0001, 0x2091, 0x5000, 0x127f, 0x007c,
+       0x2021, 0x4001, 0x0078, 0x2274, 0x2021, 0x4002, 0x0078, 0x2274,
+       0x2021, 0x4003, 0x0078, 0x2274, 0x2021, 0x4005, 0x0078, 0x2274,
+       0x2021, 0x4006, 0x0078, 0x2274, 0xa02e, 0x2520, 0x7b28, 0x7a2c,
+       0x7824, 0x7930, 0x0078, 0x2a3c, 0x7823, 0x0004, 0x7824, 0x007a,
+       0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0078, 0x2a40,
+       0x7924, 0x7828, 0x2114, 0x200a, 0x0078, 0x2272, 0x7924, 0x2114,
+       0x0078, 0x2272, 0x2099, 0x0009, 0x20a1, 0x0009, 0x20a9, 0x0007,
+       0x53a3, 0x0078, 0x2272, 0x7824, 0x2060, 0x0078, 0x22e1, 0x2009,
+       0x0001, 0x2011, 0x000d, 0x2019, 0x0000, 0x0078, 0x2272, 0x7d38,
+       0x7c3c, 0x0078, 0x22a6, 0x7d38, 0x7c3c, 0x0078, 0x22b2, 0x2061,
+       0x1000, 0x610c, 0xa006, 0x2c14, 0xa200, 0x8c60, 0x8109, 0x00c0,
+       0x22e3, 0x2010, 0xa005, 0x0040, 0x2272, 0x0078, 0x2298, 0x2061,
+       0x6d51, 0x7824, 0x7930, 0xa11a, 0x00c8, 0x22a0, 0x8019, 0x0040,
+       0x22a0, 0x604a, 0x6142, 0x782c, 0x6052, 0x7828, 0x6056, 0xa006,
+       0x605a, 0x605e, 0x1078, 0x3890, 0x0078, 0x2272, 0x2061, 0x6d51,
+       0x7824, 0x7930, 0xa11a, 0x00c8, 0x22a0, 0x8019, 0x0040, 0x22a0,
+       0x604e, 0x6146, 0x782c, 0x6062, 0x7828, 0x6066, 0xa006, 0x606a,
+       0x606e, 0x1078, 0x366e, 0x0078, 0x2272, 0xa02e, 0x2520, 0x81ff,
+       0x00c0, 0x229c, 0x7924, 0x7b28, 0x7a2c, 0x20a9, 0x0005, 0x20a1,
+       0x6d74, 0x41a1, 0x1078, 0x2a04, 0x0040, 0x229c, 0x2009, 0x0020,
+       0x1078, 0x2a3c, 0x701b, 0x2335, 0x007c, 0x6834, 0x2008, 0xa084,
+       0x00ff, 0xa096, 0x0011, 0x0040, 0x2341, 0xa096, 0x0019, 0x00c0,
+       0x229c, 0x810f, 0xa18c, 0x00ff, 0x0040, 0x229c, 0x710e, 0x700c,
+       0x8001, 0x0040, 0x2372, 0x700e, 0x1078, 0x2a04, 0x0040, 0x229c,
+       0x2009, 0x0020, 0x2061, 0x6d9d, 0x6224, 0x6328, 0x642c, 0x6530,
+       0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000,
+       0x1078, 0x2a3c, 0x701b, 0x2365, 0x007c, 0x6834, 0xa084, 0x00ff,
+       0xa096, 0x0002, 0x0040, 0x2370, 0xa096, 0x000a, 0x00c0, 0x229c,
+       0x0078, 0x2347, 0x7010, 0x2068, 0x6838, 0xc0fd, 0x683a, 0x1078,
+       0x3344, 0x00c0, 0x2380, 0x7007, 0x0003, 0x701b, 0x2382, 0x007c,
+       0x1078, 0x372d, 0x127e, 0x2091, 0x8000, 0x20a9, 0x0005, 0x2099,
+       0x6d74, 0x530a, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000,
+       0xa5a9, 0x0000, 0xad80, 0x000d, 0x2009, 0x0020, 0x127f, 0x0078,
+       0x2a40, 0x6198, 0x7824, 0x609a, 0x0078, 0x2272, 0x2091, 0x8000,
+       0x7823, 0x4000, 0x7827, 0x4953, 0x782b, 0x5020, 0x782f, 0x2020,
+       0x2009, 0x017f, 0x2104, 0x7832, 0x3f00, 0x7836, 0x2061, 0x0100,
+       0x6200, 0x2061, 0x0200, 0x603c, 0x8007, 0xa205, 0x783a, 0x2009,
+       0x04fd, 0x2104, 0x783e, 0x781b, 0x0001, 0x2091, 0x5000, 0x2091,
+       0x4080, 0x2071, 0x0010, 0x20c1, 0x00f0, 0xa08a, 0x0003, 0x00c8,
+       0x0427, 0x0078, 0x0423, 0x81ff, 0x00c0, 0x229c, 0x1078, 0x2a1c,
+       0x0040, 0x22a0, 0x7c28, 0x7d2c, 0x1078, 0x3592, 0xd28c, 0x00c0,
+       0x23dd, 0x1078, 0x3522, 0x0078, 0x23df, 0x1078, 0x355e, 0x00c0,
+       0x2409, 0x2061, 0x7400, 0x127e, 0x2091, 0x8000, 0x6000, 0xa086,
+       0x0000, 0x0040, 0x23f7, 0x6010, 0xa06d, 0x0040, 0x23f7, 0x683c,
+       0xa406, 0x00c0, 0x23f7, 0x6840, 0xa506, 0x0040, 0x2402, 0x127f,
+       0xace0, 0x0008, 0x2001, 0x6d15, 0x2004, 0xac02, 0x00c8, 0x229c,
+       0x0078, 0x23e3, 0x1078, 0x5f5d, 0x127f, 0x0040, 0x229c, 0x0078,
+       0x2272, 0xa00e, 0x2001, 0x0005, 0x1078, 0x372d, 0x127e, 0x2091,
+       0x8000, 0x1078, 0x36a1, 0x127f, 0x0078, 0x2272, 0x81ff, 0x00c0,
+       0x229c, 0x1078, 0x2a1c, 0x0040, 0x22a0, 0x1078, 0x34d7, 0x1078,
+       0x35a3, 0x0040, 0x229c, 0x0078, 0x2272, 0x81ff, 0x00c0, 0x229c,
+       0x1078, 0x2a1c, 0x0040, 0x22a0, 0x2031, 0x000f, 0x1078, 0x34d7,
+       0x8631, 0x00c8, 0x242e, 0x2019, 0x0005, 0x1078, 0x35c4, 0x0040,
+       0x229c, 0x7828, 0xa08a, 0x1000, 0x00c8, 0x22a0, 0x8003, 0x800b,
+       0x810b, 0xa108, 0x1078, 0x40de, 0x0078, 0x2272, 0x127e, 0x2091,
+       0x8000, 0x81ff, 0x00c0, 0x2476, 0x2029, 0x00ff, 0x644c, 0x2400,
+       0xa506, 0x0040, 0x2470, 0x2508, 0x1078, 0x3447, 0x00c0, 0x2470,
+       0x2031, 0x000f, 0x1078, 0x34d7, 0x8631, 0x00c8, 0x245a, 0x2019,
+       0x0004, 0x1078, 0x35c4, 0x0040, 0x2476, 0x7824, 0xa08a, 0x1000,
+       0x00c8, 0x2479, 0x8003, 0x800b, 0x810b, 0xa108, 0x1078, 0x40de,
+       0x8529, 0x00c8, 0x244f, 0x127f, 0x0078, 0x2272, 0x127f, 0x0078,
+       0x229c, 0x127f, 0x0078, 0x22a0, 0x1078, 0x2a1c, 0x0040, 0x22a0,
+       0x1078, 0x3507, 0x1078, 0x3592, 0x0078, 0x2272, 0x81ff, 0x00c0,
+       0x229c, 0x1078, 0x2a1c, 0x0040, 0x22a0, 0x1078, 0x34f0, 0x1078,
+       0x3592, 0x0078, 0x2272, 0x81ff, 0x00c0, 0x229c, 0x1078, 0x2a1c,
+       0x0040, 0x22a0, 0x1078, 0x3561, 0x0040, 0x229c, 0x1078, 0x338c,
+       0x1078, 0x351b, 0x1078, 0x3592, 0x0078, 0x2272, 0x1078, 0x2a1c,
+       0x0040, 0x22a0, 0x1078, 0x34d7, 0x62a0, 0x2019, 0x0005, 0x0c7e,
+       0x1078, 0x35cf, 0x0c7f, 0x1078, 0x445c, 0x1078, 0x43a9, 0x2c08,
+       0x1078, 0x6a57, 0x1078, 0x3592, 0x0078, 0x2272, 0x1078, 0x2a1c,
+       0x0040, 0x22a0, 0x1078, 0x3592, 0x2208, 0x0078, 0x2272, 0x157e,
+       0x0d7e, 0x0e7e, 0x2069, 0x6ddf, 0x6810, 0x6914, 0xa10a, 0x00c8,
+       0x24d3, 0x2009, 0x0000, 0x6816, 0x2011, 0x0000, 0x2019, 0x0000,
+       0x20a9, 0x007e, 0x2069, 0x6e00, 0x2d04, 0xa075, 0x0040, 0x24e8,
+       0x704c, 0x1078, 0x24f2, 0xa210, 0x7080, 0x1078, 0x24f2, 0xa318,
+       0x8d68, 0x00f0, 0x24dc, 0x2300, 0xa218, 0x0e7f, 0x0d7f, 0x157f,
+       0x0078, 0x2272, 0x0f7e, 0x017e, 0xa07d, 0x0040, 0x2501, 0x2001,
+       0x0000, 0x8000, 0x2f0c, 0x81ff, 0x0040, 0x2501, 0x2178, 0x0078,
+       0x24f9, 0x017f, 0x0f7f, 0x007c, 0x2069, 0x6ddf, 0x6910, 0x629c,
+       0x0078, 0x2272, 0x81ff, 0x00c0, 0x229c, 0x614c, 0xa190, 0x2091,
+       0x2214, 0xa294, 0x00ff, 0x6068, 0xa084, 0xff00, 0xa215, 0x6364,
+       0x0078, 0x2272, 0x613c, 0x6240, 0x0078, 0x2272, 0x1078, 0x2a1c,
+       0x0040, 0x22a0, 0x0078, 0x2272, 0x1078, 0x2a1c, 0x0040, 0x22a0,
+       0x6244, 0x6338, 0x0078, 0x2272, 0x613c, 0x6240, 0x7824, 0x603e,
+       0x7b28, 0x6342, 0x2069, 0x6d51, 0x831f, 0xa305, 0x6816, 0x0078,
+       0x2272, 0x1078, 0x2a1c, 0x0040, 0x22a0, 0x0078, 0x2272, 0x1078,
+       0x2a1c, 0x0040, 0x22a0, 0x7828, 0xa00d, 0x0040, 0x22a0, 0x782c,
+       0xa005, 0x0040, 0x22a0, 0x6244, 0x6146, 0x6338, 0x603a, 0x0078,
+       0x2272, 0x7d38, 0x7c3c, 0x0078, 0x231f, 0x7824, 0xa09c, 0x00ff,
+       0xa39a, 0x0003, 0x00c8, 0x229c, 0x624c, 0xa084, 0xff00, 0x8007,
+       0xa206, 0x00c0, 0x256d, 0x2001, 0x6d40, 0x2009, 0x000c, 0x7a2c,
+       0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x2a40, 0x81ff, 0x00c0, 0x229c,
+       0x1078, 0x2a1c, 0x0040, 0x22a0, 0x6004, 0xa084, 0x00ff, 0xa086,
+       0x0006, 0x00c0, 0x229c, 0x0c7e, 0x1078, 0x2a04, 0x0c7f, 0x0040,
+       0x229c, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x1078, 0x6223,
+       0x0040, 0x229c, 0x7007, 0x0003, 0x701b, 0x258f, 0x007c, 0x6830,
+       0xa086, 0x0100, 0x0040, 0x229c, 0xad80, 0x000e, 0x2009, 0x000c,
+       0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x2a40, 0x1078, 0x2a04,
+       0x0040, 0x229c, 0x2009, 0x001c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
+       0x1078, 0x2a3c, 0x701b, 0x25ad, 0x007c, 0xade8, 0x000d, 0x6800,
+       0xa005, 0x0040, 0x22a0, 0x6804, 0xd0ac, 0x0040, 0x25ba, 0xd0a4,
+       0x0040, 0x22a0, 0xd094, 0x0040, 0x25c5, 0x0c7e, 0x2061, 0x0100,
+       0x6104, 0xa18c, 0xffdf, 0x6106, 0x0c7f, 0xd08c, 0x0040, 0x25d0,
+       0x0c7e, 0x2061, 0x0100, 0x6104, 0xa18d, 0x0010, 0x6106, 0x0c7f,
+       0x2009, 0x0100, 0x210c, 0xa18a, 0x0002, 0x0048, 0x25e5, 0xd084,
+       0x0040, 0x25e5, 0x6828, 0xa08a, 0x007f, 0x00c8, 0x22a0, 0xa088,
+       0x2091, 0x210c, 0xa18c, 0x00ff, 0x6152, 0xd0dc, 0x0040, 0x25ee,
+       0x6828, 0xa08a, 0x007f, 0x00c8, 0x22a0, 0x604e, 0x6808, 0xa08a,
+       0x0100, 0x0048, 0x22a0, 0xa08a, 0x0841, 0x00c8, 0x22a0, 0xa084,
+       0x0007, 0x00c0, 0x22a0, 0x680c, 0xa005, 0x0040, 0x22a0, 0x6810,
+       0xa005, 0x0040, 0x22a0, 0x6848, 0x6940, 0xa10a, 0x00c8, 0x22a0,
+       0x8001, 0x0040, 0x22a0, 0x684c, 0x6944, 0xa10a, 0x00c8, 0x22a0,
+       0x8001, 0x0040, 0x22a0, 0x20a9, 0x001c, 0x2d98, 0x2069, 0x6d51,
+       0x2da0, 0x53a3, 0x6814, 0xa08c, 0x00ff, 0x613e, 0x8007, 0xa084,
+       0x00ff, 0x6042, 0x1078, 0x3890, 0x1078, 0x366e, 0x6000, 0xa086,
+       0x0000, 0x00c0, 0x265b, 0x6808, 0x602a, 0x1078, 0x1bcc, 0x6818,
+       0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016,
+       0x611a, 0x621e, 0x6322, 0xa084, 0xf0ff, 0x6006, 0x610a, 0x620e,
+       0x6312, 0x1078, 0x4168, 0x0c7e, 0x2061, 0x0100, 0x602f, 0x0040,
+       0x602f, 0x0000, 0x0c7f, 0x60b4, 0xa005, 0x0040, 0x2657, 0x6003,
+       0x0001, 0x2091, 0x301d, 0x1078, 0x31cb, 0x0078, 0x265b, 0x6003,
+       0x0004, 0x2091, 0x301d, 0x0078, 0x2272, 0x6000, 0xa086, 0x0000,
+       0x0040, 0x229c, 0x2069, 0x6d51, 0x7830, 0x6842, 0x7834, 0x6846,
+       0x2d00, 0x2009, 0x001c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078,
+       0x2a40, 0x81ff, 0x00c0, 0x229c, 0x1078, 0x31cb, 0x0078, 0x2272,
+       0x81ff, 0x00c0, 0x229c, 0x617c, 0x81ff, 0x0040, 0x2692, 0x703f,
+       0x0000, 0x2001, 0x73c0, 0x2009, 0x0040, 0x7a2c, 0x7b28, 0x7c3c,
+       0x7d38, 0x127e, 0x2091, 0x8000, 0x1078, 0x2a40, 0x701b, 0x226f,
+       0x127f, 0x007c, 0x703f, 0x0001, 0x0d7e, 0x2069, 0x73c0, 0x20a9,
+       0x0040, 0x20a1, 0x73c0, 0x2019, 0xffff, 0x43a4, 0x654c, 0xa588,
+       0x2091, 0x210c, 0xa18c, 0x00ff, 0x216a, 0xa00e, 0x2011, 0x0002,
+       0x2100, 0xa506, 0x0040, 0x26c4, 0x1078, 0x3447, 0x00c0, 0x26c4,
+       0x6014, 0x821c, 0x0048, 0x26bc, 0xa398, 0x73c0, 0xa085, 0xff00,
+       0x8007, 0x201a, 0x0078, 0x26c3, 0xa398, 0x73c0, 0x2324, 0xa4a4,
+       0xff00, 0xa405, 0x201a, 0x8210, 0x8108, 0xa182, 0x0080, 0x00c8,
+       0x26cb, 0x0078, 0x26a8, 0x8201, 0x8007, 0x2d0c, 0xa105, 0x206a,
+       0x0d7f, 0x20a9, 0x0040, 0x20a1, 0x73c0, 0x2099, 0x73c0, 0x1078,
+       0x3213, 0x0078, 0x2681, 0x1078, 0x2a1c, 0x0040, 0x22a0, 0x0c7e,
+       0x1078, 0x2a04, 0x0c7f, 0x0040, 0x229c, 0x2001, 0x6d52, 0x2004,
+       0xd0b4, 0x0040, 0x2708, 0x6000, 0xd08c, 0x00c0, 0x2708, 0x6004,
+       0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x2708, 0x6837, 0x0000,
+       0x6838, 0xc0fd, 0x683a, 0x1078, 0x625b, 0x0040, 0x229c, 0x7007,
+       0x0003, 0x701b, 0x2704, 0x007c, 0x1078, 0x2a1c, 0x0040, 0x22a0,
+       0x20a9, 0x0029, 0x2c98, 0xade8, 0x0002, 0x2da0, 0x53a3, 0x20a9,
+       0x0002, 0xac80, 0x0004, 0x2098, 0xad80, 0x0004, 0x20a0, 0x1078,
+       0x3213, 0x20a9, 0x0004, 0xac80, 0x0006, 0x2098, 0xad80, 0x0006,
+       0x20a0, 0x1078, 0x3213, 0x20a9, 0x0004, 0xac80, 0x000a, 0x2098,
+       0xad80, 0x000a, 0x20a0, 0x1078, 0x3213, 0x2d00, 0x2009, 0x0029,
+       0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x2a40, 0x81ff, 0x00c0,
+       0x229c, 0x1078, 0x2a1c, 0x0040, 0x22a0, 0x1078, 0x35ae, 0x0078,
+       0x2272, 0x81ff, 0x00c0, 0x229c, 0x7828, 0xa08a, 0x1000, 0x00c8,
+       0x22a0, 0x1078, 0x2a1c, 0x0040, 0x22a0, 0x2031, 0x000f, 0x1078,
+       0x34d7, 0x8631, 0x00c8, 0x274f, 0x2019, 0x0004, 0x1078, 0x35c4,
+       0x7924, 0x810f, 0x7a28, 0x1078, 0x275f, 0x0078, 0x2272, 0xa186,
+       0x00ff, 0x0040, 0x2767, 0x1078, 0x2777, 0x0078, 0x2776, 0x2029,
+       0x007e, 0x2061, 0x6d00, 0x644c, 0x2400, 0xa506, 0x0040, 0x2773,
+       0x2508, 0x1078, 0x2777, 0x8529, 0x00c8, 0x276c, 0x007c, 0x1078,
+       0x3447, 0x00c0, 0x2782, 0x2200, 0x8003, 0x800b, 0x810b, 0xa108,
+       0x1078, 0x40de, 0x007c, 0x81ff, 0x00c0, 0x229c, 0x1078, 0x2a1c,
+       0x0040, 0x22a0, 0x1078, 0x34d7, 0x1078, 0x35b9, 0x0078, 0x2272,
+       0x81ff, 0x00c0, 0x229c, 0x1078, 0x2a1c, 0x0040, 0x22a0, 0x1078,
+       0x34d7, 0x1078, 0x35a3, 0x0078, 0x2272, 0x6100, 0x0078, 0x2272,
+       0x1078, 0x2a1c, 0x0040, 0x22a0, 0x6004, 0xa086, 0x0707, 0x0040,
+       0x22a0, 0x2001, 0x6d00, 0x2004, 0xa086, 0x0003, 0x00c0, 0x229c,
+       0x0d7e, 0xace8, 0x000a, 0x7924, 0xd184, 0x0040, 0x27b9, 0xace8,
+       0x0006, 0x680c, 0x8007, 0x783e, 0x6808, 0x8007, 0x783a, 0x6b04,
+       0x831f, 0x6a00, 0x8217, 0x0d7f, 0x6100, 0xa18c, 0x0200, 0x0078,
+       0x2272, 0x81ff, 0x00c0, 0x229c, 0x7828, 0xa08a, 0x1000, 0x00c8,
+       0x22a0, 0x7924, 0xa184, 0x00ff, 0xa082, 0x0010, 0x00c8, 0x22a0,
+       0xa18c, 0xff00, 0x810f, 0xa186, 0x00ff, 0x0040, 0x27e6, 0xa182,
+       0x007f, 0x00c8, 0x22a0, 0x2100, 0x1078, 0x1e30, 0x027e, 0x0c7e,
+       0x127e, 0x2091, 0x8000, 0x2061, 0x6f23, 0x601b, 0x0000, 0x601f,
+       0x0000, 0x2061, 0x6d00, 0x6003, 0x0001, 0x2061, 0x0100, 0x6030,
+       0xa084, 0x00ff, 0x810f, 0xa105, 0x604a, 0x6043, 0x0090, 0x6043,
+       0x0010, 0x2009, 0x001e, 0x2011, 0x31f0, 0x1078, 0x415f, 0x7924,
+       0x810f, 0x7a28, 0x1078, 0x275f, 0x127f, 0x0c7f, 0x027f, 0x0078,
+       0x2272, 0x7924, 0xa18c, 0xff00, 0x810f, 0x0c7e, 0x1078, 0x3410,
+       0x2c08, 0x0c7f, 0x00c0, 0x22a0, 0x0078, 0x2272, 0x81ff, 0x00c0,
+       0x229c, 0x60bc, 0xd09c, 0x0040, 0x229c, 0x1078, 0x2a04, 0x0040,
+       0x229c, 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x2a3c,
+       0x701b, 0x2833, 0x007c, 0x2009, 0x0080, 0x1078, 0x3447, 0x00c0,
+       0x229c, 0x0d7e, 0xade8, 0x000d, 0x6900, 0x6a08, 0x6b0c, 0x6c10,
+       0x6d14, 0x6e18, 0x6820, 0xa0be, 0x0100, 0x0040, 0x28a7, 0xa0be,
+       0x0112, 0x0040, 0x28a7, 0xa0be, 0x0113, 0x0040, 0x28a7, 0xa0be,
+       0x0114, 0x0040, 0x28a7, 0xa0be, 0x0117, 0x0040, 0x28a7, 0xa0be,
+       0x011a, 0x0040, 0x28a7, 0xa0be, 0x0121, 0x0040, 0x289d, 0xa0be,
+       0x0131, 0x0040, 0x289d, 0xa0be, 0x0171, 0x0040, 0x28a7, 0xa0be,
+       0x01a1, 0x00c0, 0x2870, 0x6830, 0x8007, 0x6832, 0x0078, 0x28ad,
+       0xa0be, 0x0212, 0x0040, 0x28a3, 0xa0be, 0x0213, 0x0040, 0x28a3,
+       0xa0be, 0x0214, 0x0040, 0x2895, 0xa0be, 0x0217, 0x0040, 0x288f,
+       0xa0be, 0x021a, 0x00c0, 0x2889, 0x6838, 0x8007, 0x683a, 0x0078,
+       0x28a7, 0xa0be, 0x0300, 0x0040, 0x28a7, 0x0078, 0x229c, 0xad80,
+       0x0010, 0x20a9, 0x0007, 0x1078, 0x28d9, 0xad80, 0x000e, 0x20a9,
+       0x0001, 0x1078, 0x28d9, 0x0078, 0x28a7, 0xad80, 0x000c, 0x1078,
+       0x28e7, 0x0078, 0x28ad, 0xad80, 0x000e, 0x1078, 0x28e7, 0xad80,
+       0x000c, 0x20a9, 0x0001, 0x1078, 0x28d9, 0x0c7e, 0x1078, 0x2a04,
+       0x0040, 0x28ce, 0x6837, 0x0119, 0x684f, 0x0020, 0x685b, 0x0001,
+       0x810b, 0x697e, 0x6883, 0x0000, 0x6a86, 0x6b8a, 0x6c8e, 0x6d92,
+       0x6996, 0x689b, 0x0000, 0x0c7f, 0x0d7f, 0x1078, 0x623f, 0x0040,
+       0x229c, 0x7007, 0x0003, 0x701b, 0x28d2, 0x007c, 0x0c7f, 0x0d7f,
+       0x0078, 0x229c, 0x6820, 0xa086, 0x8001, 0x0040, 0x229c, 0x0078,
+       0x2272, 0x017e, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x290a,
+       0x8108, 0x280a, 0x8108, 0x00f0, 0x28db, 0x017f, 0x007c, 0x017e,
+       0x0a7e, 0x0b7e, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x2054,
+       0x8000, 0x205c, 0x2b0a, 0x8108, 0x2a0a, 0x8108, 0x290a, 0x8108,
+       0x280a, 0x0b7f, 0x0a7f, 0x017f, 0x007c, 0x81ff, 0x00c0, 0x229c,
+       0x7924, 0xa18c, 0xff00, 0x810f, 0xa182, 0x0081, 0x0048, 0x22a0,
+       0xa182, 0x00ff, 0x00c8, 0x22a0, 0x7a2c, 0x7b28, 0x6064, 0xa306,
+       0x00c0, 0x2918, 0x6068, 0xa206, 0x00c0, 0x2918, 0x0078, 0x22a0,
+       0x0c7e, 0x1078, 0x297b, 0x2c68, 0x0c7f, 0x0040, 0x2939, 0xa0c6,
+       0x4007, 0x00c0, 0x2926, 0x7c26, 0x0078, 0x2936, 0xa0c6, 0x4008,
+       0x00c0, 0x292e, 0x7f26, 0x7e2a, 0x0078, 0x2936, 0xa0c6, 0x4009,
+       0x00c0, 0x2934, 0x0078, 0x2936, 0x2001, 0x4006, 0x2020, 0x0078,
+       0x2274, 0x017e, 0x0b7e, 0x0c7e, 0x0e7e, 0x2c70, 0x1078, 0x5504,
+       0x0040, 0x2969, 0x2d00, 0x601a, 0x2e58, 0x0e7f, 0x0e7e, 0x0c7e,
+       0x1078, 0x2a04, 0x0c7f, 0x2b70, 0x0040, 0x229c, 0x6837, 0x0000,
+       0x2d00, 0x6012, 0x601f, 0x0001, 0x2001, 0x0000, 0x1078, 0x33df,
+       0x2001, 0x0002, 0x1078, 0x33f3, 0x127e, 0x2091, 0x8000, 0x7088,
+       0x8000, 0x708a, 0x127f, 0x2009, 0x0002, 0x1078, 0x5591, 0xa085,
+       0x0001, 0x0e7f, 0x0c7f, 0x0b7f, 0x017f, 0x0040, 0x229c, 0x7007,
+       0x0003, 0x701b, 0x2974, 0x007c, 0x6830, 0xa086, 0x0100, 0x00c0,
+       0x2272, 0x0078, 0x229c, 0x0e7e, 0x0d7e, 0x2029, 0x0000, 0x2021,
+       0x0081, 0x20a9, 0x007e, 0x2071, 0x6e81, 0x2e04, 0xa005, 0x00c0,
+       0x298f, 0x2100, 0xa406, 0x0040, 0x29c0, 0x0078, 0x29b4, 0x2068,
+       0x6f10, 0x2700, 0xa306, 0x00c0, 0x29a5, 0x6e14, 0x2600, 0xa206,
+       0x00c0, 0x29a5, 0x2400, 0xa106, 0x00c0, 0x29a1, 0x2d60, 0x0078,
+       0x29c6, 0x2001, 0x4007, 0x0078, 0x29c7, 0x2400, 0xa106, 0x00c0,
+       0x29b4, 0x6e14, 0x87ff, 0x00c0, 0x29b0, 0x86ff, 0x0040, 0x29c0,
+       0x2001, 0x4008, 0x0078, 0x29c7, 0x8420, 0x8e70, 0x00f0, 0x2985,
+       0x2001, 0x4009, 0x0078, 0x29c7, 0x2001, 0x0001, 0x0078, 0x29c7,
+       0x1078, 0x3410, 0x00c0, 0x29bc, 0x6312, 0x6216, 0xa006, 0xa005,
+       0x0d7f, 0x0e7f, 0x007c, 0x81ff, 0x00c0, 0x229c, 0x1078, 0x2a04,
+       0x0040, 0x229c, 0x6837, 0x0000, 0x7824, 0xa005, 0x0040, 0x22a0,
+       0xa096, 0x00ff, 0x0040, 0x29e0, 0xa092, 0x0004, 0x00c8, 0x22a0,
+       0x2010, 0x2d18, 0x1078, 0x2013, 0x0040, 0x229c, 0x7007, 0x0003,
+       0x701b, 0x29eb, 0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x229c,
+       0x0078, 0x2272, 0x7924, 0xa18c, 0xff00, 0x810f, 0xa182, 0x0081,
+       0x0048, 0x22a0, 0xa182, 0x00ff, 0x00c8, 0x22a0, 0x1078, 0x615b,
+       0x1078, 0x342f, 0x0078, 0x2272, 0x1078, 0x12f4, 0x0040, 0x2a1b,
+       0xa006, 0x6802, 0x7010, 0xa005, 0x00c0, 0x2a13, 0x2d00, 0x7012,
+       0x7016, 0x0078, 0x2a19, 0x7014, 0x6802, 0x2060, 0x2d00, 0x6006,
+       0x7016, 0xad80, 0x000d, 0x007c, 0x7e24, 0x860f, 0xa18c, 0x00ff,
+       0x1078, 0x3447, 0x00c0, 0x2a2a, 0xa6b4, 0x00ff, 0xa682, 0x0010,
+       0x0048, 0x2a2b, 0xa066, 0x8cff, 0x007c, 0x017e, 0x7110, 0x81ff,
+       0x0040, 0x2a38, 0x2168, 0x6904, 0x1078, 0x1328, 0x0078, 0x2a2f,
+       0x7112, 0x7116, 0x017f, 0x007c, 0x2031, 0x0001, 0x0078, 0x2a42,
+       0x2031, 0x0000, 0x2061, 0x6d9d, 0x6606, 0x6112, 0x600e, 0x6226,
+       0x632a, 0x642e, 0x6532, 0x2c10, 0x1078, 0x135f, 0x7007, 0x0002,
+       0x701b, 0x2272, 0x007c, 0x0f7e, 0x127e, 0x2091, 0x8000, 0x2079,
+       0x0000, 0x2001, 0x6d7b, 0x2004, 0xa005, 0x00c0, 0x2a6e, 0x0068,
+       0x2a6e, 0x7818, 0xd084, 0x00c0, 0x2a6e, 0x781b, 0x0001, 0x7a22,
+       0x7b26, 0x7c2a, 0x2091, 0x4080, 0x0078, 0x2a93, 0x017e, 0x0c7e,
+       0x0e7e, 0x2071, 0x6d6d, 0x7138, 0xa182, 0x0004, 0x0048, 0x2a7c,
+       0x7030, 0x2060, 0x0078, 0x2a8d, 0x7030, 0xa0e0, 0x0008, 0xac82,
+       0x6d9d, 0x0048, 0x2a85, 0x2061, 0x6d7d, 0x2c00, 0x7032, 0x81ff,
+       0x00c0, 0x2a8b, 0x7036, 0x8108, 0x713a, 0x2262, 0x6306, 0x640a,
+       0x0e7f, 0x0c7f, 0x017f, 0x127f, 0x0f7f, 0x007c, 0x0e7e, 0x2071,
+       0x6d6d, 0x7038, 0xa005, 0x0040, 0x2acf, 0x127e, 0x2091, 0x8000,
+       0x0068, 0x2ace, 0x0f7e, 0x2079, 0x0000, 0x7818, 0xd084, 0x00c0,
+       0x2acd, 0x0c7e, 0x781b, 0x0001, 0x7034, 0x2060, 0x2c04, 0x7822,
+       0x6004, 0x7826, 0x6008, 0x782a, 0x2091, 0x4080, 0x7038, 0x8001,
+       0x703a, 0xa005, 0x00c0, 0x2ac3, 0x7033, 0x6d7d, 0x7037, 0x6d7d,
+       0x0c7f, 0x0078, 0x2acd, 0xac80, 0x0008, 0xa0fa, 0x6d9d, 0x0048,
+       0x2acb, 0x2001, 0x6d7d, 0x7036, 0x0c7f, 0x0f7f, 0x127f, 0x0e7f,
+       0x007c, 0x027e, 0x2001, 0x6d52, 0x2004, 0xd0c4, 0x0040, 0x2adc,
+       0x2011, 0x8014, 0x1078, 0x2a53, 0x027f, 0x007c, 0x81ff, 0x00c0,
+       0x229c, 0x127e, 0x2091, 0x8000, 0x6030, 0xc08d, 0x6032, 0x1078,
+       0x31cb, 0x127f, 0x0078, 0x2272, 0x127e, 0x0c7e, 0x0e7e, 0x2061,
+       0x0100, 0x2071, 0x6d00, 0x6044, 0xd0a4, 0x00c0, 0x2b11, 0xd084,
+       0x0040, 0x2afe, 0x1078, 0x2c34, 0x0078, 0x2b11, 0xd08c, 0x0040,
+       0x2b05, 0x1078, 0x2b4b, 0x0078, 0x2b11, 0xd094, 0x0040, 0x2b0c,
+       0x1078, 0x2b2c, 0x0078, 0x2b11, 0xd09c, 0x0040, 0x2b11, 0x1078,
+       0x2b15, 0x0e7f, 0x0c7f, 0x127f, 0x007c, 0x6043, 0x0040, 0x6043,
+       0x0000, 0x706f, 0x0000, 0x7087, 0x0001, 0x70a7, 0x0000, 0x2009,
+       0x73c0, 0x200b, 0x0000, 0x7073, 0x000f, 0x2009, 0x000f, 0x2011,
+       0x3187, 0x1078, 0x415f, 0x007c, 0x7070, 0xa005, 0x00c0, 0x2b4a,
+       0x2011, 0x3187, 0x1078, 0x40d1, 0x6043, 0x0020, 0x6043, 0x0000,
+       0x6044, 0xd08c, 0x00c0, 0x2b46, 0x7003, 0x0001, 0x7083, 0x0000,
+       0x6043, 0x0090, 0x6043, 0x0010, 0x0078, 0x2b4a, 0x7077, 0x0000,
+       0x0078, 0x2b4a, 0x007c, 0x7074, 0xa08a, 0x0003, 0x00c8, 0x2b54,
+       0x1079, 0x2b57, 0x0078, 0x2b56, 0x1078, 0x12b7, 0x007c, 0x2b5a,
+       0x2ba9, 0x2c33, 0x0f7e, 0x7077, 0x0001, 0x20e1, 0xa000, 0x20e1,
+       0x8700, 0x1078, 0x1bcc, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2079,
+       0x7200, 0x207b, 0x2200, 0x7807, 0x00ef, 0x780b, 0x0000, 0x780f,
+       0x00ef, 0x7813, 0x0138, 0x7817, 0x0000, 0x781b, 0x0000, 0x781f,
+       0x0000, 0x7823, 0xffff, 0x7827, 0xffff, 0x782b, 0x0000, 0x782f,
+       0x0000, 0x2079, 0x720c, 0x207b, 0x1101, 0x7807, 0x0000, 0x2099,
+       0x6d05, 0x20a1, 0x720e, 0x20a9, 0x0004, 0x53a3, 0x2079, 0x7212,
+       0x207b, 0x0000, 0x7807, 0x0000, 0x2099, 0x7200, 0x20a1, 0x020b,
+       0x20a9, 0x0014, 0x53a6, 0x60c3, 0x000c, 0x600f, 0x0000, 0x1078,
+       0x31b2, 0x0f7f, 0x707b, 0x0000, 0x6043, 0x0008, 0x6043, 0x0000,
+       0x007c, 0x0d7e, 0x7078, 0x707b, 0x0000, 0xa025, 0x0040, 0x2c1d,
+       0x6020, 0xd0b4, 0x00c0, 0x2c1b, 0x7184, 0x81ff, 0x0040, 0x2c04,
+       0xa486, 0x000c, 0x00c0, 0x2c0f, 0xa480, 0x0018, 0x8004, 0x20a8,
+       0x2011, 0x7280, 0x2019, 0x7200, 0x220c, 0x2304, 0xa106, 0x00c0,
+       0x2bdb, 0x8210, 0x8318, 0x00f0, 0x2bc4, 0x6043, 0x0004, 0x608b,
+       0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006, 0x7077, 0x0002, 0x7083,
+       0x0002, 0x0078, 0x2c1b, 0x2069, 0x7280, 0x6930, 0xa18e, 0x1101,
+       0x00c0, 0x2c0f, 0x6834, 0xa005, 0x00c0, 0x2c0f, 0x6900, 0xa18c,
+       0x00ff, 0x00c0, 0x2bef, 0x6804, 0xa005, 0x0040, 0x2c04, 0x2011,
+       0x728e, 0x2019, 0x6d05, 0x20a9, 0x0004, 0x220c, 0x2304, 0xa102,
+       0x0048, 0x2c02, 0x00c0, 0x2c0f, 0x8210, 0x8318, 0x00f0, 0x2bf5,
+       0x0078, 0x2c0f, 0x7087, 0x0000, 0x20e1, 0x9080, 0x20e1, 0x4000,
+       0x2099, 0x7280, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x6043,
+       0x0008, 0x6043, 0x0000, 0x6020, 0xd0b4, 0x00c0, 0x2c1b, 0x60c3,
+       0x000c, 0x1078, 0x31b2, 0x0d7f, 0x007c, 0x6020, 0xd0b4, 0x00c0,
+       0x2c1b, 0x60c3, 0x000c, 0x2011, 0x6f1a, 0x2013, 0x0000, 0x707b,
+       0x0000, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x1078,
+       0x4fdc, 0x0078, 0x2c1b, 0x007c, 0x7080, 0xa08a, 0x001d, 0x00c8,
+       0x2c3d, 0x1079, 0x2c40, 0x0078, 0x2c3f, 0x1078, 0x12b7, 0x007c,
+       0x2c64, 0x2c73, 0x2ca6, 0x2cbb, 0x2ced, 0x2d17, 0x2d49, 0x2d73,
+       0x2da5, 0x2dcb, 0x2e1a, 0x2e3c, 0x2e60, 0x2e76, 0x2e9c, 0x2eaf,
+       0x2eb8, 0x2ed1, 0x2f01, 0x2f2b, 0x2f5b, 0x2f85, 0x2fce, 0x3003,
+       0x3025, 0x3063, 0x3087, 0x30a0, 0x30ad, 0x7003, 0x0007, 0x6004,
+       0xa084, 0xfff9, 0x6006, 0x007c, 0x608b, 0xbc94, 0x608f, 0xf0f0,
+       0x6043, 0x0002, 0x7083, 0x0001, 0x2009, 0x07d0, 0x2011, 0x318e,
+       0x1078, 0x40c4, 0x007c, 0x0f7e, 0x7078, 0xa086, 0x0014, 0x00c0,
+       0x2ca4, 0x6043, 0x0000, 0x6020, 0xd0b4, 0x00c0, 0x2ca4, 0x2079,
+       0x7280, 0x7a30, 0xa296, 0x1102, 0x00c0, 0x2ca2, 0x7834, 0xa005,
+       0x00c0, 0x2ca2, 0x7a38, 0xd2fc, 0x0040, 0x2c98, 0x70a4, 0xa005,
+       0x00c0, 0x2c98, 0x2019, 0x002a, 0x1078, 0x202f, 0x70a7, 0x0001,
+       0x2011, 0x318e, 0x1078, 0x40d1, 0x7083, 0x0010, 0x1078, 0x2eb8,
+       0x0078, 0x2ca4, 0x707b, 0x0000, 0x0f7f, 0x007c, 0x7083, 0x0003,
+       0x6043, 0x0004, 0x1078, 0x321b, 0x20a3, 0x1102, 0x20a3, 0x0000,
+       0x20a9, 0x000a, 0x20a3, 0x0000, 0x00f0, 0x2cb2, 0x60c3, 0x0014,
+       0x1078, 0x31b2, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x2ceb,
+       0x2011, 0x318e, 0x1078, 0x40d1, 0xa086, 0x0014, 0x00c0, 0x2ce7,
+       0x2079, 0x7280, 0x7a30, 0xa296, 0x1102, 0x00c0, 0x2ce7, 0x7834,
+       0xa005, 0x00c0, 0x2ce7, 0x7a38, 0xd2fc, 0x0040, 0x2ce1, 0x70a4,
+       0xa005, 0x00c0, 0x2ce1, 0x2019, 0x002a, 0x1078, 0x202f, 0x70a7,
+       0x0001, 0x7083, 0x0004, 0x1078, 0x2ced, 0x0078, 0x2ceb, 0x7083,
+       0x0002, 0x707b, 0x0000, 0x0f7f, 0x007c, 0x7083, 0x0005, 0x1078,
+       0x321b, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011, 0x728e,
+       0x706c, 0xa005, 0x00c0, 0x2d09, 0x714c, 0xa186, 0xffff, 0x0040,
+       0x2d09, 0x1078, 0x3152, 0x0040, 0x2d09, 0x2019, 0x002a, 0x1078,
+       0x202f, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x31b2, 0x007c, 0x0f7e,
+       0x7078, 0xa005, 0x0040, 0x2d47, 0x2011, 0x318e, 0x1078, 0x40d1,
+       0xa086, 0x0014, 0x00c0, 0x2d43, 0x2079, 0x7280, 0x7a30, 0xa296,
+       0x1103, 0x00c0, 0x2d43, 0x7834, 0xa005, 0x00c0, 0x2d43, 0x7a38,
+       0xd2fc, 0x0040, 0x2d3d, 0x70a4, 0xa005, 0x00c0, 0x2d3d, 0x2019,
+       0x002a, 0x1078, 0x202f, 0x70a7, 0x0001, 0x7083, 0x0006, 0x1078,
+       0x2d49, 0x0078, 0x2d47, 0x7083, 0x0002, 0x707b, 0x0000, 0x0f7f,
+       0x007c, 0x7083, 0x0007, 0x1078, 0x321b, 0x20a3, 0x1104, 0x20a3,
+       0x0000, 0x3430, 0x2011, 0x728e, 0x706c, 0xa005, 0x00c0, 0x2d65,
+       0x7150, 0xa186, 0xffff, 0x0040, 0x2d65, 0xa180, 0x2091, 0x200c,
+       0xa18c, 0xff00, 0x810f, 0x1078, 0x3152, 0x20a9, 0x0008, 0x2298,
+       0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014,
+       0x1078, 0x31b2, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x2da3,
+       0x2011, 0x318e, 0x1078, 0x40d1, 0xa086, 0x0014, 0x00c0, 0x2d9f,
+       0x2079, 0x7280, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x2d9f, 0x7834,
+       0xa005, 0x00c0, 0x2d9f, 0x7a38, 0xd2fc, 0x0040, 0x2d99, 0x70a4,
+       0xa005, 0x00c0, 0x2d99, 0x2019, 0x002a, 0x1078, 0x202f, 0x70a7,
+       0x0001, 0x7083, 0x0008, 0x1078, 0x2da5, 0x0078, 0x2da3, 0x7083,
+       0x0002, 0x707b, 0x0000, 0x0f7f, 0x007c, 0x7083, 0x0009, 0x1078,
+       0x321b, 0x20a3, 0x1105, 0x20a3, 0x0100, 0x3430, 0x706c, 0xa005,
+       0x00c0, 0x2db8, 0x1078, 0x30bc, 0x0040, 0x2dc8, 0x0078, 0x2dc2,
+       0x20a9, 0x0008, 0x2099, 0x728e, 0x26a0, 0x53a6, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x31b2, 0x0078, 0x2dca,
+       0x1078, 0x2c5d, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x2e18,
+       0x2011, 0x318e, 0x1078, 0x40d1, 0xa086, 0x0014, 0x00c0, 0x2e14,
+       0x2079, 0x7280, 0x7a30, 0xa296, 0x1105, 0x00c0, 0x2e14, 0x7834,
+       0x2011, 0x0100, 0xa21e, 0x00c0, 0x2dfb, 0x7a38, 0xd2fc, 0x0040,
+       0x2df3, 0x70a4, 0xa005, 0x00c0, 0x2df3, 0x2019, 0x002a, 0x1078,
+       0x202f, 0x70a7, 0x0001, 0x707f, 0x0001, 0x7083, 0x000a, 0x1078,
+       0x2e1a, 0x0078, 0x2e18, 0xa005, 0x00c0, 0x2e14, 0x7a38, 0xd2fc,
+       0x0040, 0x2e0c, 0x70a4, 0xa005, 0x00c0, 0x2e0c, 0x2019, 0x002a,
+       0x1078, 0x202f, 0x70a7, 0x0001, 0x707f, 0x0000, 0x7083, 0x000e,
+       0x1078, 0x2e9c, 0x0078, 0x2e18, 0x7083, 0x0002, 0x707b, 0x0000,
+       0x0f7f, 0x007c, 0x7083, 0x000b, 0x2011, 0x720e, 0x22a0, 0x20a9,
+       0x0040, 0x2019, 0xffff, 0x43a4, 0x20a9, 0x0002, 0x2009, 0x0000,
+       0x41a4, 0x1078, 0x321b, 0x20a3, 0x1106, 0x20a3, 0x0000, 0x6030,
+       0xa085, 0x0100, 0x2012, 0x2298, 0x20a9, 0x0042, 0x53a6, 0x60c3,
+       0x0084, 0x1078, 0x31b2, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040,
+       0x2e5e, 0x2011, 0x318e, 0x1078, 0x40d1, 0xa086, 0x0084, 0x00c0,
+       0x2e5a, 0x2079, 0x7280, 0x7a30, 0xa296, 0x1106, 0x00c0, 0x2e5a,
+       0x7834, 0xa005, 0x00c0, 0x2e5a, 0x7083, 0x000c, 0x1078, 0x2e60,
+       0x0078, 0x2e5e, 0x7083, 0x0002, 0x707b, 0x0000, 0x0f7f, 0x007c,
+       0x7083, 0x000d, 0x1078, 0x321b, 0x20a3, 0x1107, 0x20a3, 0x0000,
+       0x2099, 0x728e, 0x20a9, 0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x60c3, 0x0084, 0x1078, 0x31b2, 0x007c, 0x0f7e, 0x7078,
+       0xa005, 0x0040, 0x2e9a, 0x2011, 0x318e, 0x1078, 0x40d1, 0xa086,
+       0x0084, 0x00c0, 0x2e96, 0x2079, 0x7280, 0x7a30, 0xa296, 0x1107,
+       0x00c0, 0x2e96, 0x7834, 0xa005, 0x00c0, 0x2e96, 0x1078, 0x320d,
+       0x7083, 0x000e, 0x1078, 0x2e9c, 0x0078, 0x2e9a, 0x7083, 0x0002,
+       0x707b, 0x0000, 0x0f7f, 0x007c, 0x7083, 0x000f, 0x707b, 0x0000,
+       0x608b, 0xbc85, 0x608f, 0xb5b5, 0x6043, 0x0005, 0x6043, 0x0004,
+       0x2009, 0x07d0, 0x2011, 0x318e, 0x1078, 0x40c4, 0x007c, 0x7078,
+       0xa005, 0x0040, 0x2eb7, 0x2011, 0x318e, 0x1078, 0x40d1, 0x007c,
+       0x7083, 0x0011, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0x7280,
+       0x20a1, 0x020b, 0x7478, 0xa480, 0x0018, 0xa080, 0x0007, 0xa084,
+       0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0014, 0x1078, 0x31b2,
+       0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x2eff, 0x2011, 0x318e,
+       0x1078, 0x40d1, 0xa086, 0x0014, 0x00c0, 0x2efd, 0x2079, 0x7280,
+       0x7a30, 0xa296, 0x1103, 0x00c0, 0x2efd, 0x7834, 0xa005, 0x00c0,
+       0x2efd, 0x7a38, 0xd2fc, 0x0040, 0x2ef7, 0x70a4, 0xa005, 0x00c0,
+       0x2ef7, 0x2019, 0x002a, 0x1078, 0x202f, 0x70a7, 0x0001, 0x7083,
+       0x0012, 0x1078, 0x2f01, 0x0078, 0x2eff, 0x707b, 0x0000, 0x0f7f,
+       0x007c, 0x7083, 0x0013, 0x1078, 0x3227, 0x20a3, 0x1103, 0x20a3,
+       0x0000, 0x3430, 0x2011, 0x728e, 0x706c, 0xa005, 0x00c0, 0x2f1d,
+       0x714c, 0xa186, 0xffff, 0x0040, 0x2f1d, 0x1078, 0x3152, 0x0040,
+       0x2f1d, 0x2019, 0x002a, 0x1078, 0x202f, 0x20a9, 0x0008, 0x2298,
+       0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014,
+       0x1078, 0x31b2, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x2f59,
+       0x2011, 0x318e, 0x1078, 0x40d1, 0xa086, 0x0014, 0x00c0, 0x2f57,
+       0x2079, 0x7280, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x2f57, 0x7834,
+       0xa005, 0x00c0, 0x2f57, 0x7a38, 0xd2fc, 0x0040, 0x2f51, 0x70a4,
+       0xa005, 0x00c0, 0x2f51, 0x2019, 0x002a, 0x1078, 0x202f, 0x70a7,
+       0x0001, 0x7083, 0x0014, 0x1078, 0x2f5b, 0x0078, 0x2f59, 0x707b,
+       0x0000, 0x0f7f, 0x007c, 0x7083, 0x0015, 0x1078, 0x3227, 0x20a3,
+       0x1104, 0x20a3, 0x0000, 0x3430, 0x2011, 0x728e, 0x706c, 0xa006,
+       0x00c0, 0x2f77, 0x7150, 0xa186, 0xffff, 0x0040, 0x2f77, 0xa180,
+       0x2091, 0x200c, 0xa18c, 0xff00, 0x810f, 0x1078, 0x3152, 0x20a9,
+       0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
+       0x60c3, 0x0014, 0x1078, 0x31b2, 0x007c, 0x0f7e, 0x7078, 0xa005,
+       0x0040, 0x2fcc, 0x2011, 0x318e, 0x1078, 0x40d1, 0xa086, 0x0014,
+       0x00c0, 0x2fca, 0x2079, 0x7280, 0x7a30, 0xa296, 0x1105, 0x00c0,
+       0x2fca, 0x7834, 0x2011, 0x0100, 0xa21e, 0x00c0, 0x2fb1, 0x7a38,
+       0xd2fc, 0x0040, 0x2fad, 0x70a4, 0xa005, 0x00c0, 0x2fad, 0x2019,
+       0x002a, 0x1078, 0x202f, 0x70a7, 0x0001, 0x707f, 0x0001, 0x0078,
+       0x2fc4, 0xa005, 0x00c0, 0x2fca, 0x7a38, 0xd2fc, 0x0040, 0x2fc2,
+       0x70a4, 0xa005, 0x00c0, 0x2fc2, 0x2019, 0x002a, 0x1078, 0x202f,
+       0x70a7, 0x0001, 0x707f, 0x0000, 0x7083, 0x0016, 0x1078, 0x2fce,
+       0x0078, 0x2fcc, 0x707b, 0x0000, 0x0f7f, 0x007c, 0x20e1, 0x9080,
+       0x20e1, 0x4000, 0x2099, 0x7280, 0x20a1, 0x020b, 0x20a9, 0x000e,
+       0x53a6, 0x3430, 0x2011, 0x728e, 0x707c, 0xa005, 0x0040, 0x2fe4,
+       0x7083, 0x0017, 0x0078, 0x2fe6, 0x7083, 0x001b, 0x706c, 0xa005,
+       0x00c0, 0x2ff0, 0x1078, 0x30bc, 0x0040, 0x3000, 0x0078, 0x2ffa,
+       0x20a9, 0x0008, 0x2099, 0x728e, 0x26a0, 0x53a6, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x31b2, 0x0078, 0x3002,
+       0x1078, 0x2c5d, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x3023,
+       0x2011, 0x318e, 0x1078, 0x40d1, 0xa086, 0x0084, 0x00c0, 0x3021,
+       0x2079, 0x7280, 0x7a30, 0xa296, 0x1106, 0x00c0, 0x3021, 0x7834,
+       0xa005, 0x00c0, 0x3021, 0x7083, 0x0018, 0x1078, 0x3025, 0x0078,
+       0x3023, 0x707b, 0x0000, 0x0f7f, 0x007c, 0x7083, 0x0019, 0x1078,
+       0x3227, 0x20a3, 0x1106, 0x20a3, 0x0000, 0x3430, 0x2099, 0x728e,
+       0x2039, 0x720e, 0x27a0, 0x20a9, 0x0040, 0x53a3, 0x2728, 0x2514,
+       0x8207, 0xa084, 0x00ff, 0x8000, 0x2018, 0xa294, 0x00ff, 0x8007,
+       0xa205, 0x202a, 0x6030, 0x2310, 0x8214, 0xa2a0, 0x720e, 0x2414,
+       0xa38c, 0x0001, 0x0040, 0x3050, 0xa294, 0xff00, 0x0078, 0x3053,
+       0xa294, 0x00ff, 0x8007, 0xa215, 0x2222, 0x2798, 0x26a0, 0x20a9,
+       0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084,
+       0x1078, 0x31b2, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x3085,
+       0x2011, 0x318e, 0x1078, 0x40d1, 0xa086, 0x0084, 0x00c0, 0x3083,
+       0x2079, 0x7280, 0x7a30, 0xa296, 0x1107, 0x00c0, 0x3083, 0x7834,
+       0xa005, 0x00c0, 0x3083, 0x1078, 0x320d, 0x7083, 0x001a, 0x1078,
+       0x3087, 0x0078, 0x3085, 0x707b, 0x0000, 0x0f7f, 0x007c, 0x7083,
+       0x001b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0x7280, 0x20a1,
+       0x020b, 0x7478, 0xa480, 0x0018, 0xa080, 0x0007, 0xa084, 0x03f8,
+       0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0084, 0x1078, 0x31b2, 0x007c,
+       0x7078, 0xa005, 0x0040, 0x30ac, 0x2011, 0x318e, 0x1078, 0x40d1,
+       0x7083, 0x001c, 0x1078, 0x30ad, 0x007c, 0x707b, 0x0000, 0x608b,
+       0xbc85, 0x608f, 0xb5b5, 0x6043, 0x0001, 0x2009, 0x07d0, 0x2011,
+       0x318e, 0x1078, 0x40c4, 0x007c, 0x087e, 0x097e, 0x2029, 0x6d52,
+       0x252c, 0x20a9, 0x0008, 0x2041, 0x720e, 0x28a0, 0x2099, 0x728e,
+       0x53a3, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0040, 0x30d2,
+       0x2011, 0x0000, 0x2800, 0xa200, 0x200c, 0xa1a6, 0xffff, 0x00c0,
+       0x30e4, 0xd5d4, 0x0040, 0x30df, 0x8210, 0x0078, 0x30e0, 0x8211,
+       0x00f0, 0x30d2, 0x0078, 0x3149, 0x82ff, 0x00c0, 0x30f6, 0xd5d4,
+       0x0040, 0x30f0, 0xa1a6, 0x3fff, 0x0040, 0x30dc, 0x0078, 0x30f4,
+       0xa1a6, 0x3fff, 0x0040, 0x3149, 0xa18d, 0xc000, 0x20a9, 0x0010,
+       0x2019, 0x0001, 0xd5d4, 0x0040, 0x30ff, 0x2019, 0x0010, 0x2120,
+       0xd5d4, 0x0040, 0x3106, 0x8423, 0x0078, 0x3107, 0x8424, 0x00c8,
+       0x3114, 0xd5d4, 0x0040, 0x310f, 0x8319, 0x0078, 0x3110, 0x8318,
+       0x00f0, 0x3100, 0x0078, 0x3149, 0x23a8, 0x2021, 0x0001, 0x8426,
+       0x8425, 0x00f0, 0x3118, 0x2328, 0x8529, 0xa2be, 0x0007, 0x0040,
+       0x312c, 0x007e, 0x2039, 0x0007, 0x2200, 0xa73a, 0x007f, 0x27a8,
+       0xa5a8, 0x0010, 0x00f0, 0x3128, 0x754e, 0xa5c8, 0x2091, 0x292c,
+       0xa5ac, 0x00ff, 0x6532, 0x60e7, 0x0000, 0x65ea, 0x2018, 0x2304,
+       0xa405, 0x201a, 0x706f, 0x0001, 0x26a0, 0x2898, 0x20a9, 0x0008,
+       0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0xa085, 0x0001, 0x0078,
+       0x314f, 0xa006, 0x0078, 0x314f, 0xa006, 0x1078, 0x12b7, 0x097f,
+       0x087f, 0x007c, 0x2118, 0x2021, 0x0000, 0x2001, 0x0007, 0xa39a,
+       0x0010, 0x0048, 0x315f, 0x8420, 0x8001, 0x0078, 0x3157, 0x2118,
+       0x84ff, 0x0040, 0x3168, 0xa39a, 0x0010, 0x8421, 0x00c0, 0x3163,
+       0x2021, 0x0001, 0x83ff, 0x0040, 0x3171, 0x8423, 0x8319, 0x00c0,
+       0x316d, 0xa238, 0x2704, 0xa42c, 0x00c0, 0x3186, 0xa405, 0x203a,
+       0x714e, 0xa1a0, 0x2091, 0x242c, 0xa5ac, 0x00ff, 0x6532, 0x60e7,
+       0x0000, 0x65ea, 0x706f, 0x0001, 0xa084, 0x0000, 0x007c, 0x0e7e,
+       0x2071, 0x6d00, 0x7073, 0x0000, 0x0e7f, 0x007c, 0x0e7e, 0x0f7e,
+       0x2079, 0x0100, 0x2071, 0x0140, 0x1078, 0x4fe5, 0x7004, 0xa084,
+       0x4000, 0x0040, 0x319f, 0x7003, 0x1000, 0x7003, 0x0000, 0x127e,
+       0x2091, 0x8000, 0x2071, 0x6d00, 0x7003, 0x0001, 0x2071, 0x6d20,
+       0x2073, 0x0000, 0x7843, 0x0090, 0x7843, 0x0010, 0x127f, 0x0f7f,
+       0x0e7f, 0x007c, 0x127e, 0x2091, 0x8000, 0x2011, 0x6f1a, 0x2013,
+       0x0000, 0x707b, 0x0000, 0x127f, 0x20e1, 0x9080, 0x60a3, 0x0056,
+       0x60a7, 0x9575, 0x1078, 0x4fdc, 0x2009, 0x07d0, 0x2011, 0x318e,
+       0x1078, 0x415f, 0x007c, 0x017e, 0x027e, 0x0c7e, 0x127e, 0x2091,
+       0x8000, 0x2009, 0x00f7, 0x1078, 0x3233, 0x2061, 0x6f23, 0x601b,
+       0x0000, 0x601f, 0x0000, 0x2061, 0x6d00, 0x6003, 0x0001, 0x2061,
+       0x0100, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x001e, 0x2011,
+       0x31f0, 0x1078, 0x40c4, 0x127f, 0x0c7f, 0x027f, 0x017f, 0x007c,
+       0x0e7e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0x0100, 0x1078,
+       0x4fe5, 0x2071, 0x0140, 0xa084, 0x4000, 0x0040, 0x3203, 0x7003,
+       0x1000, 0x7003, 0x0000, 0x2001, 0x0001, 0x1078, 0x1dc9, 0x1078,
+       0x31cb, 0x127f, 0x007f, 0x0e7f, 0x007c, 0x20a9, 0x0040, 0x20a1,
+       0x73c0, 0x2099, 0x728e, 0x3304, 0x8007, 0x20a2, 0x9398, 0x94a0,
+       0x00f0, 0x3213, 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099,
+       0x7200, 0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6, 0x007c, 0x20e1,
+       0x9080, 0x20e1, 0x4000, 0x2099, 0x7280, 0x20a1, 0x020b, 0x20a9,
+       0x000c, 0x53a6, 0x007c, 0x0c7e, 0x007e, 0x2061, 0x0100, 0x810f,
+       0x2001, 0x6d2c, 0x2004, 0xa005, 0x00c0, 0x3244, 0x6030, 0xa084,
+       0x00ff, 0xa105, 0x0078, 0x3246, 0xa185, 0x00f7, 0x604a, 0x007f,
+       0x0c7f, 0x007c, 0x157e, 0x20a9, 0x00ff, 0x2009, 0x6e00, 0xa006,
+       0x200a, 0x8108, 0x00f0, 0x3250, 0x157f, 0x007c, 0x0d7e, 0x037e,
+       0x157e, 0x137e, 0x147e, 0x2069, 0x6d51, 0xa006, 0x6002, 0x6007,
+       0x0707, 0x600a, 0x600e, 0x6012, 0xa198, 0x2091, 0x231c, 0xa39c,
+       0x00ff, 0x6316, 0x20a9, 0x0004, 0xac98, 0x0006, 0x23a0, 0x40a4,
+       0x20a9, 0x0004, 0xac98, 0x000a, 0x23a0, 0x40a4, 0x603e, 0x6042,
+       0x604e, 0x6052, 0x6056, 0x605a, 0x605e, 0x6062, 0x6066, 0x606a,
+       0x606e, 0x6072, 0x6076, 0x607a, 0x607e, 0x6082, 0x6086, 0x608a,
+       0x608e, 0x6092, 0x6096, 0x609a, 0x609e, 0x61a2, 0x604a, 0x6810,
+       0x603a, 0x680c, 0x6046, 0x147f, 0x137f, 0x157f, 0x037f, 0x0d7f,
+       0x007c, 0x127e, 0x2091, 0x8000, 0x6944, 0xa1b4, 0x00ff, 0xa682,
+       0x0010, 0x00c8, 0x3337, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff,
+       0x00c8, 0x333d, 0xa188, 0x6e00, 0x2104, 0xa065, 0x0040, 0x3316,
+       0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x00c0, 0x331c, 0x6078,
+       0xa00d, 0x0040, 0x32c1, 0xa680, 0x6c84, 0x2004, 0xa10c, 0x00c0,
+       0x3310, 0x607c, 0xa00d, 0x0040, 0x32dd, 0xa680, 0x6c84, 0x2004,
+       0xa10c, 0x0040, 0x32dd, 0x694c, 0xd1fc, 0x00c0, 0x32d3, 0x1078,
+       0x33d0, 0x0078, 0x330b, 0x1078, 0x33a1, 0x694c, 0xd1ec, 0x00c0,
+       0x330b, 0x1078, 0x34f0, 0x0078, 0x330b, 0x694c, 0xa184, 0xa000,
+       0x0040, 0x32fb, 0xd1ec, 0x0040, 0x32f4, 0xd1fc, 0x0040, 0x32ec,
+       0x1078, 0x3507, 0x0078, 0x32f7, 0xa680, 0x6c84, 0x200c, 0x607c,
+       0xa105, 0x607e, 0x0078, 0x32fb, 0xd1fc, 0x0040, 0x32fb, 0x1078,
+       0x33a1, 0x0078, 0x330b, 0x6050, 0xa00d, 0x0040, 0x3306, 0x2d00,
+       0x200a, 0x6803, 0x0000, 0x6052, 0x0078, 0x330b, 0x2d00, 0x6052,
+       0x604e, 0x6803, 0x0000, 0x1078, 0x4346, 0xa006, 0x127f, 0x007c,
+       0x2001, 0x0005, 0x2009, 0x0000, 0x0078, 0x3341, 0x2001, 0x0028,
+       0x2009, 0x0000, 0x0078, 0x3341, 0xa082, 0x0006, 0x0048, 0x32b7,
+       0x2009, 0x6d0c, 0x210c, 0xd18c, 0x0040, 0x332a, 0x2001, 0x0004,
+       0x0078, 0x3333, 0xd184, 0x0040, 0x3331, 0x2001, 0x0004, 0x0078,
+       0x3333, 0x2001, 0x0029, 0x2009, 0x0000, 0x0078, 0x3341, 0x2001,
+       0x0029, 0x2009, 0x0000, 0x0078, 0x3341, 0x2001, 0x0029, 0x2009,
+       0x0000, 0xa005, 0x127f, 0x007c, 0x6944, 0xa1b4, 0x00ff, 0xa682,
+       0x0010, 0x00c8, 0x3386, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff,
+       0x00c8, 0x3376, 0xa188, 0x6e00, 0x2104, 0xa065, 0x0040, 0x3376,
+       0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x00c0, 0x337c, 0x684c,
+       0xd0ec, 0x0040, 0x3369, 0x1078, 0x3507, 0x1078, 0x33a1, 0x0078,
+       0x3371, 0x1078, 0x33a1, 0x684c, 0xd0fc, 0x0040, 0x3371, 0x1078,
+       0x34f0, 0x1078, 0x351b, 0xa006, 0x0078, 0x338a, 0x2001, 0x0028,
+       0x2009, 0x0000, 0x0078, 0x338a, 0xa082, 0x0006, 0x0048, 0x335f,
+       0x2001, 0x0029, 0x2009, 0x0000, 0x0078, 0x338a, 0x2001, 0x0029,
+       0x2009, 0x0000, 0xa005, 0x007c, 0x127e, 0x2091, 0x8000, 0x6050,
+       0xa00d, 0x0040, 0x339a, 0x2d00, 0x200a, 0x6803, 0x0000, 0x6052,
+       0x127f, 0x007c, 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000, 0x0078,
+       0x3398, 0x127e, 0x2091, 0x8000, 0x604c, 0xa005, 0x0040, 0x33ad,
+       0x6802, 0x2d00, 0x604e, 0x127f, 0x007c, 0x2d00, 0x6052, 0x604e,
+       0x6803, 0x0000, 0x0078, 0x33ab, 0x127e, 0x2091, 0x8000, 0x604c,
+       0xa06d, 0x0040, 0x33c2, 0x6800, 0xa005, 0x00c0, 0x33c0, 0x6052,
+       0x604e, 0xad05, 0x127f, 0x007c, 0x604c, 0xa06d, 0x0040, 0x33cf,
+       0x6800, 0xa005, 0x00c0, 0x33cd, 0x6052, 0x604e, 0xad05, 0x007c,
+       0x6803, 0x0000, 0x6084, 0xa00d, 0x0040, 0x33da, 0x2d00, 0x200a,
+       0x6086, 0x007c, 0x2d00, 0x6086, 0x6082, 0x0078, 0x33d9, 0x127e,
+       0x0c7e, 0x027e, 0x2091, 0x8000, 0x6218, 0x2260, 0x6200, 0xa005,
+       0x0040, 0x33ed, 0xc285, 0x0078, 0x33ee, 0xc284, 0x6202, 0x027f,
+       0x0c7f, 0x127f, 0x007c, 0x127e, 0x0c7e, 0x2091, 0x8000, 0x6218,
+       0x2260, 0x6204, 0xa294, 0xff00, 0xa215, 0x6206, 0x0c7f, 0x127f,
+       0x007c, 0x127e, 0x0c7e, 0x2091, 0x8000, 0x6218, 0x2260, 0x6204,
+       0xa294, 0x00ff, 0x8007, 0xa215, 0x6206, 0x0c7f, 0x127f, 0x007c,
+       0x027e, 0xa182, 0x00ff, 0x0048, 0x3419, 0xa085, 0x0001, 0x0078,
+       0x342d, 0xa190, 0x6e00, 0x2204, 0xa065, 0x00c0, 0x342c, 0x017e,
+       0x0d7e, 0x1078, 0x12f4, 0x2d60, 0x0d7f, 0x017f, 0x0040, 0x3415,
+       0x2c00, 0x2012, 0x1078, 0x3256, 0xa006, 0x027f, 0x007c, 0x027e,
+       0xa182, 0x00ff, 0x0048, 0x3438, 0xa085, 0x0001, 0x0078, 0x3445,
+       0x0d7e, 0xa190, 0x6e00, 0x2204, 0xa06d, 0x0040, 0x3443, 0x2013,
+       0x0000, 0x1078, 0x1328, 0x0d7f, 0xa006, 0x027f, 0x007c, 0x017e,
+       0xa182, 0x00ff, 0x0048, 0x3450, 0xa085, 0x0001, 0x0078, 0x3457,
+       0xa188, 0x6e00, 0x2104, 0xa065, 0x0040, 0x344c, 0xa006, 0x017f,
+       0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x600b, 0x0000, 0x600f,
+       0x0000, 0x6000, 0xc08c, 0x6002, 0x2069, 0x728e, 0x6808, 0x605e,
+       0x6810, 0x6062, 0x6138, 0xa10a, 0x0048, 0x346f, 0x603a, 0x6814,
+       0x6066, 0x2099, 0x7296, 0xac88, 0x000a, 0x21a0, 0x20a9, 0x0004,
+       0x53a3, 0x2099, 0x729a, 0xac88, 0x0006, 0x21a0, 0x20a9, 0x0004,
+       0x53a3, 0x2069, 0x72ae, 0x6904, 0xa18c, 0x00ff, 0x810f, 0x6808,
+       0xa084, 0x00ff, 0xa105, 0x606a, 0x690c, 0x616e, 0x6810, 0x6072,
+       0x6818, 0x6076, 0xa182, 0x0211, 0x00c8, 0x349a, 0x2009, 0x0008,
+       0x0078, 0x34c4, 0xa182, 0x0259, 0x00c8, 0x34a2, 0x2009, 0x0007,
+       0x0078, 0x34c4, 0xa182, 0x02c1, 0x00c8, 0x34aa, 0x2009, 0x0006,
+       0x0078, 0x34c4, 0xa182, 0x0349, 0x00c8, 0x34b2, 0x2009, 0x0005,
+       0x0078, 0x34c4, 0xa182, 0x0421, 0x00c8, 0x34ba, 0x2009, 0x0004,
+       0x0078, 0x34c4, 0xa182, 0x0581, 0x00c8, 0x34c2, 0x2009, 0x0003,
+       0x0078, 0x34c4, 0x2009, 0x0002, 0x6192, 0x147f, 0x137f, 0x157f,
+       0x0d7f, 0x007c, 0x0e7e, 0x2071, 0x728d, 0x2e04, 0x6896, 0x2071,
+       0x728e, 0x7004, 0x689a, 0x701c, 0x689e, 0x0e7f, 0x007c, 0x2001,
+       0x6c84, 0xa600, 0x2004, 0x127e, 0x2091, 0x8000, 0x6178, 0xa10d,
+       0x617a, 0x127f, 0x007c, 0x2001, 0x6c84, 0xa600, 0x2004, 0x8002,
+       0x127e, 0x2091, 0x8000, 0x6178, 0xa10c, 0x617a, 0x127f, 0x007c,
+       0x2001, 0x6c84, 0xa600, 0x2004, 0x8002, 0x127e, 0x2091, 0x8000,
+       0x617c, 0xa10c, 0x617e, 0x127f, 0x0078, 0x3500, 0x1078, 0x338c,
+       0x1078, 0x3561, 0x00c0, 0x34fe, 0x1078, 0x351b, 0x007c, 0x2001,
+       0x6c84, 0xa600, 0x2004, 0x127e, 0x2091, 0x8000, 0x617c, 0xa10d,
+       0x617e, 0x127f, 0x0078, 0x3516, 0x1078, 0x33d0, 0x1078, 0x3525,
+       0x00c0, 0x3514, 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x4346,
+       0x127f, 0x007c, 0xa01e, 0x0078, 0x3527, 0x2019, 0x0001, 0xa00e,
+       0x127e, 0x2091, 0x8000, 0x604c, 0x2068, 0x6000, 0xd0dc, 0x00c0,
+       0x3547, 0x8dff, 0x0040, 0x355c, 0x83ff, 0x0040, 0x353f, 0x6844,
+       0xa084, 0x00ff, 0xa606, 0x0040, 0x354c, 0x0078, 0x3547, 0x683c,
+       0xa406, 0x00c0, 0x3547, 0x6840, 0xa506, 0x0040, 0x354c, 0x2d08,
+       0x6800, 0x2068, 0x0078, 0x3531, 0x6a00, 0x604c, 0xad06, 0x00c0,
+       0x3554, 0x624e, 0x0078, 0x3557, 0xa180, 0x0000, 0x2202, 0x82ff,
+       0x00c0, 0x355c, 0x6152, 0x8dff, 0x127f, 0x007c, 0xa01e, 0x0078,
+       0x3563, 0x2019, 0x0001, 0xa00e, 0x6080, 0x2068, 0x8dff, 0x0040,
+       0x3591, 0x83ff, 0x0040, 0x3574, 0x6844, 0xa084, 0x00ff, 0xa606,
+       0x0040, 0x3581, 0x0078, 0x357c, 0x683c, 0xa406, 0x00c0, 0x357c,
+       0x6840, 0xa506, 0x0040, 0x3581, 0x2d08, 0x6800, 0x2068, 0x0078,
+       0x3566, 0x6a00, 0x6080, 0xad06, 0x00c0, 0x3589, 0x6282, 0x0078,
+       0x358c, 0xa180, 0x0000, 0x2202, 0x82ff, 0x00c0, 0x3591, 0x6186,
+       0x8dff, 0x007c, 0x2001, 0x6c84, 0xa600, 0x2004, 0x6178, 0xa10c,
+       0x0040, 0x359c, 0x2011, 0x0001, 0x617c, 0xa10c, 0x0040, 0x35a2,
+       0xa295, 0x0002, 0x007c, 0x1078, 0x35ec, 0x0040, 0x35ab, 0x1078,
+       0x61f8, 0x0078, 0x35ad, 0xa085, 0x0001, 0x007c, 0x1078, 0x35ec,
+       0x0040, 0x35b6, 0x1078, 0x6187, 0x0078, 0x35b8, 0xa085, 0x0001,
+       0x007c, 0x1078, 0x35ec, 0x0040, 0x35c1, 0x1078, 0x61cd, 0x0078,
+       0x35c3, 0xa085, 0x0001, 0x007c, 0x1078, 0x35ec, 0x0040, 0x35cc,
+       0x1078, 0x61a3, 0x0078, 0x35ce, 0xa085, 0x0001, 0x007c, 0x127e,
+       0x007e, 0x0d7e, 0x2091, 0x8000, 0x6080, 0xa06d, 0x0040, 0x35e4,
+       0x6800, 0x007e, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078,
+       0x36a1, 0x007f, 0x0078, 0x35d5, 0x6083, 0x0000, 0x6087, 0x0000,
+       0x0d7f, 0x007f, 0x127f, 0x007c, 0x609c, 0xd0a4, 0x007c, 0x0f7e,
+       0x2079, 0x6d51, 0x7804, 0xd0a4, 0x0040, 0x3618, 0x157e, 0x0c7e,
+       0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x3447, 0x00c0,
+       0x360c, 0x6004, 0xa084, 0xff00, 0x8007, 0xa086, 0x0006, 0x00c0,
+       0x360c, 0x6000, 0xc0ed, 0x6002, 0x017f, 0x8108, 0x00f0, 0x35fc,
+       0x0c7f, 0x157f, 0x2009, 0x07d0, 0x2011, 0x361a, 0x1078, 0x415f,
+       0x0f7f, 0x007c, 0x2011, 0x361a, 0x1078, 0x40d1, 0x157e, 0x0c7e,
+       0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x3447, 0x00c0,
+       0x3646, 0x6000, 0xd0ec, 0x0040, 0x3646, 0x047e, 0x62a0, 0xa294,
+       0x00ff, 0x8227, 0xa006, 0x2009, 0x0029, 0x1078, 0x6bf7, 0x6000,
+       0xc0e5, 0xc0ec, 0x6002, 0x2019, 0x0029, 0x1078, 0x445c, 0x1078,
+       0x43a9, 0x2009, 0x0000, 0x1078, 0x6a57, 0x047f, 0x017f, 0x8108,
+       0x00f0, 0x3624, 0x0c7f, 0x157f, 0x007c, 0x0c7e, 0x6018, 0x2060,
+       0x6000, 0xc0ec, 0x6002, 0x0c7f, 0x007c, 0x2071, 0x6ddf, 0x7003,
+       0x0001, 0x7007, 0x0000, 0x7013, 0x0000, 0x7017, 0x0000, 0x701b,
+       0x0000, 0x701f, 0x0000, 0x704b, 0x0001, 0x704f, 0x0000, 0x705b,
+       0x0020, 0x705f, 0x0040, 0x707f, 0x0000, 0x007c, 0x0e7e, 0x2071,
+       0x6ddf, 0x684c, 0xa005, 0x00c0, 0x367c, 0x7028, 0xc085, 0x702a,
+       0xa085, 0x0001, 0x0078, 0x369f, 0x6a60, 0x7236, 0x6b64, 0x733a,
+       0x6868, 0x703e, 0x7076, 0x686c, 0x7042, 0x707a, 0x684c, 0x702e,
+       0x6844, 0x7032, 0x2009, 0x000d, 0x200a, 0x8007, 0x8006, 0x8006,
+       0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210, 0x2100, 0xa319, 0x726e,
+       0x7372, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0xa006, 0x0e7f,
+       0x007c, 0x0e7e, 0x6838, 0xd0fc, 0x00c0, 0x36f2, 0x6804, 0xa00d,
+       0x0040, 0x36c0, 0x0d7e, 0x0e7e, 0x2071, 0x6d00, 0x027e, 0xa016,
+       0x702c, 0x2168, 0x6904, 0x206a, 0x8210, 0x2d00, 0x81ff, 0x00c0,
+       0x36b1, 0x702e, 0x70a0, 0xa200, 0x70a2, 0x027f, 0x0e7f, 0x0d7f,
+       0x2071, 0x6ddf, 0x701c, 0xa005, 0x00c0, 0x3703, 0x0068, 0x3701,
+       0x2071, 0x6d51, 0x7004, 0xd09c, 0x0040, 0x3701, 0x6934, 0xa186,
+       0x0103, 0x00c0, 0x3714, 0x6948, 0x6844, 0xa105, 0x00c0, 0x36f4,
+       0x2009, 0x8020, 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, 0x3701,
+       0x7122, 0x683c, 0x7026, 0x6840, 0x702a, 0x701b, 0x0001, 0x2091,
+       0x4080, 0x2071, 0x6d00, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70a0,
+       0x8000, 0x70a2, 0x0e7f, 0x007c, 0x6844, 0xa086, 0x0100, 0x00c0,
+       0x3701, 0x6868, 0xa005, 0x00c0, 0x3701, 0x2009, 0x8020, 0x0078,
+       0x36da, 0x2071, 0x6ddf, 0x2d08, 0x206b, 0x0000, 0x7010, 0x8000,
+       0x7012, 0x7018, 0xa06d, 0x711a, 0x0040, 0x3711, 0x6902, 0x0078,
+       0x3712, 0x711e, 0x0078, 0x36f2, 0xa18c, 0x00ff, 0xa18e, 0x0017,
+       0x0040, 0x371e, 0xa18e, 0x001f, 0x00c0, 0x3701, 0x684c, 0xd0cc,
+       0x0040, 0x3701, 0x6850, 0xa084, 0x00ff, 0xa086, 0x0001, 0x00c0,
+       0x3701, 0x2009, 0x8021, 0x0078, 0x36da, 0x007e, 0x6837, 0x0103,
+       0x20a9, 0x001c, 0xad80, 0x0011, 0x20a0, 0x2001, 0x0000, 0x40a4,
+       0x007f, 0x684a, 0x6952, 0x007c, 0x2071, 0x6ddf, 0x7004, 0x0079,
+       0x3741, 0x3749, 0x3758, 0x37e4, 0x37e5, 0x37f5, 0x37fb, 0x374a,
+       0x37d2, 0x007c, 0x127e, 0x2091, 0x8000, 0x0068, 0x3757, 0x2009,
+       0x000d, 0x7030, 0x200a, 0x2091, 0x4080, 0x7007, 0x0001, 0x127f,
+       0x701c, 0xa06d, 0x0040, 0x37d1, 0x0e7e, 0x2071, 0x6d51, 0x7004,
+       0xd09c, 0x0040, 0x37b3, 0x6934, 0xa186, 0x0103, 0x00c0, 0x378d,
+       0x6948, 0x6844, 0xa105, 0x00c0, 0x37a6, 0x2009, 0x8020, 0x127e,
+       0x2091, 0x8000, 0x0068, 0x3789, 0x2071, 0x0000, 0x7018, 0xd084,
+       0x00c0, 0x3789, 0x7122, 0x683c, 0x7026, 0x6840, 0x702a, 0x701b,
+       0x0001, 0x2091, 0x4080, 0x127f, 0x0e7f, 0x1078, 0x382e, 0x0078,
+       0x37d1, 0x127f, 0x0e7f, 0x0078, 0x37d1, 0xa18c, 0x00ff, 0xa18e,
+       0x0017, 0x0040, 0x3797, 0xa18e, 0x001f, 0x00c0, 0x37b3, 0x684c,
+       0xd0cc, 0x0040, 0x37b3, 0x6850, 0xa084, 0x00ff, 0xa086, 0x0001,
+       0x00c0, 0x37b3, 0x2009, 0x8021, 0x0078, 0x376f, 0x6844, 0xa086,
+       0x0100, 0x00c0, 0x37b3, 0x6868, 0xa005, 0x00c0, 0x37b3, 0x2009,
+       0x8020, 0x0078, 0x376f, 0x0e7f, 0x1078, 0x3842, 0x0040, 0x37d1,
+       0x700f, 0x0001, 0x6934, 0xa184, 0x00ff, 0xa086, 0x0003, 0x00c0,
+       0x37c8, 0x810f, 0xa18c, 0x00ff, 0x8101, 0x0040, 0x37c8, 0x710e,
+       0x7007, 0x0003, 0x1078, 0x3862, 0x7050, 0xa086, 0x0100, 0x0040,
+       0x37e5, 0x007c, 0x701c, 0xa06d, 0x0040, 0x37e3, 0x1078, 0x3842,
+       0x0040, 0x37e3, 0x7007, 0x0003, 0x1078, 0x3862, 0x7050, 0xa086,
+       0x0100, 0x0040, 0x37e5, 0x007c, 0x007c, 0x7050, 0xa09e, 0x0100,
+       0x00c0, 0x37ee, 0x7007, 0x0004, 0x0078, 0x37f5, 0xa086, 0x0200,
+       0x00c0, 0x37f4, 0x7007, 0x0005, 0x007c, 0x1078, 0x37fc, 0x7006,
+       0x1078, 0x382e, 0x007c, 0x007c, 0x702c, 0x7130, 0x8108, 0xa102,
+       0x0048, 0x3809, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072, 0x0078,
+       0x3813, 0x706c, 0xa080, 0x0040, 0x706e, 0x00c8, 0x3813, 0x7070,
+       0xa081, 0x0000, 0x7072, 0x7132, 0x700c, 0x8001, 0x700e, 0x00c0,
+       0x3827, 0x127e, 0x2091, 0x8000, 0x0068, 0x382a, 0x2001, 0x000d,
+       0x2102, 0x2091, 0x4080, 0x2001, 0x0001, 0x127f, 0x007c, 0x2001,
+       0x0007, 0x007c, 0x2001, 0x0006, 0x127f, 0x007c, 0x701c, 0xa06d,
+       0x0040, 0x3841, 0x127e, 0x2091, 0x8000, 0x7010, 0x8001, 0x7012,
+       0x2d04, 0x701e, 0xa005, 0x00c0, 0x383e, 0x701a, 0x127f, 0x1078,
+       0x1328, 0x007c, 0x2019, 0x000d, 0x2304, 0x230c, 0xa10e, 0x0040,
+       0x3851, 0x2304, 0x230c, 0xa10e, 0x0040, 0x3851, 0xa006, 0x0078,
+       0x3861, 0x732c, 0x8319, 0x7130, 0xa102, 0x00c0, 0x385b, 0x2300,
+       0xa005, 0x0078, 0x3861, 0x0048, 0x3860, 0xa302, 0x0078, 0x3861,
+       0x8002, 0x007c, 0x2d00, 0x7026, 0xa080, 0x000d, 0x7056, 0x7053,
+       0x0000, 0x127e, 0x2091, 0x8000, 0x2009, 0x6f31, 0x2104, 0xc08d,
+       0x200a, 0x127f, 0x1078, 0x1379, 0x007c, 0x2071, 0x6dad, 0x7003,
+       0x0000, 0x7007, 0x0000, 0x700f, 0x0000, 0x702b, 0x0001, 0x704f,
+       0x0000, 0x7053, 0x0001, 0x705f, 0x0020, 0x7063, 0x0040, 0x7083,
+       0x0000, 0x708b, 0x0000, 0x708f, 0x0001, 0x70bf, 0x0000, 0x007c,
+       0x0e7e, 0x2071, 0x6dad, 0x6848, 0xa005, 0x00c0, 0x389e, 0x7028,
+       0xc085, 0x702a, 0xa085, 0x0001, 0x0078, 0x38c3, 0x6a50, 0x7236,
+       0x6b54, 0x733a, 0x6858, 0x703e, 0x707a, 0x685c, 0x7042, 0x707e,
+       0x6848, 0x702e, 0x6840, 0x7032, 0x2009, 0x000c, 0x200a, 0x8007,
+       0x8006, 0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210, 0x2100,
+       0xa319, 0x7272, 0x7376, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001,
+       0x700f, 0x0000, 0xa006, 0x0e7f, 0x007c, 0x2b78, 0x2071, 0x6dad,
+       0x7004, 0x1079, 0x3923, 0x700c, 0x0079, 0x38ce, 0x38d3, 0x38c8,
+       0x38c8, 0x38c8, 0x38c8, 0x007c, 0x700c, 0x0079, 0x38d7, 0x38dc,
+       0x3921, 0x3921, 0x3922, 0x3922, 0x7830, 0x7930, 0xa106, 0x0040,
+       0x38e6, 0x7830, 0x7930, 0xa106, 0x00c0, 0x390c, 0x7030, 0xa10a,
+       0x0040, 0x390c, 0x00c8, 0x38ee, 0x712c, 0xa10a, 0xa18a, 0x0002,
+       0x00c8, 0x390d, 0x1078, 0x12f4, 0x0040, 0x390c, 0x2d00, 0x705a,
+       0x7063, 0x0040, 0x2001, 0x0003, 0x7057, 0x0000, 0x127e, 0x007e,
+       0x2091, 0x8000, 0x2009, 0x6f31, 0x2104, 0xc085, 0x200a, 0x007f,
+       0x700e, 0x127f, 0x1078, 0x1379, 0x007c, 0x1078, 0x12f4, 0x0040,
+       0x390c, 0x2d00, 0x705a, 0x1078, 0x12f4, 0x00c0, 0x3919, 0x0078,
+       0x38f8, 0x2d00, 0x7086, 0x7063, 0x0080, 0x2001, 0x0004, 0x0078,
+       0x38fc, 0x007c, 0x007c, 0x3934, 0x3935, 0x396c, 0x396d, 0x3921,
+       0x39a3, 0x39a8, 0x39df, 0x39e0, 0x39fb, 0x39fc, 0x39fd, 0x39fe,
+       0x39ff, 0x3a00, 0x3a69, 0x3a93, 0x007c, 0x700c, 0x0079, 0x3938,
+       0x393d, 0x3940, 0x3950, 0x396b, 0x396b, 0x1078, 0x38d4, 0x007c,
+       0x127e, 0x8001, 0x700e, 0x7058, 0x007e, 0x1078, 0x3d52, 0x0040,
+       0x394d, 0x2091, 0x8000, 0x1078, 0x38d4, 0x0d7f, 0x0078, 0x3959,
+       0x127e, 0x8001, 0x700e, 0x1078, 0x3d52, 0x7058, 0x2068, 0x7084,
+       0x705a, 0x6803, 0x0000, 0x6807, 0x0000, 0x6834, 0xa084, 0x00ff,
+       0xa08a, 0x0020, 0x00c8, 0x3968, 0x1079, 0x3983, 0x127f, 0x007c,
+       0x127f, 0x1078, 0x3a01, 0x007c, 0x007c, 0x007c, 0x0e7e, 0x2071,
+       0x6dad, 0x700c, 0x0079, 0x3974, 0x3979, 0x3979, 0x3979, 0x397b,
+       0x397f, 0x0e7f, 0x007c, 0x700f, 0x0001, 0x0078, 0x3981, 0x700f,
+       0x0002, 0x0e7f, 0x007c, 0x3a01, 0x3a01, 0x3a1d, 0x3a01, 0x3aff,
+       0x3a01, 0x3a01, 0x3a01, 0x3a01, 0x3a01, 0x3a1d, 0x3b44, 0x3b8d,
+       0x3be5, 0x3bf8, 0x3a01, 0x3a01, 0x3a39, 0x3a1d, 0x3a01, 0x3a01,
+       0x3a4f, 0x3c74, 0x3c91, 0x3a01, 0x3a39, 0x3a01, 0x3a01, 0x3a01,
+       0x3a01, 0x3a01, 0x3c91, 0x7020, 0x2068, 0x1078, 0x1328, 0x007c,
+       0x700c, 0x0079, 0x39ab, 0x39b0, 0x39b3, 0x39c3, 0x39de, 0x39de,
+       0x1078, 0x38d4, 0x007c, 0x127e, 0x8001, 0x700e, 0x7058, 0x007e,
+       0x1078, 0x3d52, 0x0040, 0x39c0, 0x2091, 0x8000, 0x1078, 0x38d4,
+       0x0d7f, 0x0078, 0x39cc, 0x127e, 0x8001, 0x700e, 0x1078, 0x3d52,
+       0x7058, 0x2068, 0x7084, 0x705a, 0x6803, 0x0000, 0x6807, 0x0000,
+       0x6834, 0xa084, 0x00ff, 0xa08a, 0x001a, 0x00c8, 0x39db, 0x1079,
+       0x39e1, 0x127f, 0x007c, 0x127f, 0x1078, 0x3a01, 0x007c, 0x007c,
+       0x007c, 0x3a01, 0x3a1d, 0x3ae9, 0x3a01, 0x3a1d, 0x3a01, 0x3a1d,
+       0x3a1d, 0x3a01, 0x3a1d, 0x3ae9, 0x3a1d, 0x3a1d, 0x3a1d, 0x3a1d,
+       0x3a1d, 0x3a01, 0x3a1d, 0x3ae9, 0x3a01, 0x3a01, 0x3a1d, 0x3a01,
+       0x3a01, 0x3a01, 0x3a1d, 0x007c, 0x007c, 0x007c, 0x007c, 0x007c,
+       0x007c, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0d5, 0x683a,
+       0x127e, 0x2091, 0x8000, 0x1078, 0x36a1, 0x127f, 0x007c, 0x7007,
+       0x0001, 0x6838, 0xa084, 0x00ff, 0xc0e5, 0x683a, 0x127e, 0x2091,
+       0x8000, 0x1078, 0x36a1, 0x127f, 0x007c, 0x7007, 0x0001, 0x6838,
+       0xa084, 0x00ff, 0xc0ed, 0x683a, 0x127e, 0x2091, 0x8000, 0x1078,
+       0x36a1, 0x127f, 0x007c, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff,
+       0xc0dd, 0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x36a1, 0x127f,
+       0x007c, 0x6834, 0x8007, 0xa084, 0x00ff, 0x0040, 0x3a0f, 0x8001,
+       0x00c0, 0x3a46, 0x7007, 0x0001, 0x0078, 0x3ac8, 0x7007, 0x0006,
+       0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x3ac8, 0x007c, 0x2d00,
+       0x7016, 0x701a, 0x20a9, 0x0004, 0xa080, 0x0024, 0x2098, 0x20a1,
+       0x6dd8, 0x53a3, 0x6858, 0x7012, 0xa082, 0x0401, 0x00c8, 0x3a2b,
+       0x6884, 0xa08a, 0x0003, 0x00c8, 0x3a2b, 0xa080, 0x3ab9, 0x2004,
+       0x70c6, 0x7010, 0xa015, 0x0040, 0x3ab3, 0x1078, 0x12f4, 0x00c0,
+       0x3a74, 0x7007, 0x000f, 0x007c, 0x2d00, 0x7022, 0x70c4, 0x2060,
+       0x6000, 0x6836, 0x6004, 0xad00, 0x7096, 0x6008, 0xa20a, 0x00c8,
+       0x3a83, 0xa00e, 0x2200, 0x7112, 0x620c, 0x8003, 0x800b, 0xa296,
+       0x0004, 0x0040, 0x3a8c, 0xa108, 0x719a, 0x810b, 0x719e, 0xae90,
+       0x0022, 0x1078, 0x135f, 0x7090, 0xa08e, 0x0100, 0x0040, 0x3aa7,
+       0xa086, 0x0200, 0x0040, 0x3a9f, 0x7007, 0x0010, 0x007c, 0x7020,
+       0x2068, 0x1078, 0x1328, 0x7014, 0x2068, 0x0078, 0x3a2b, 0x7020,
+       0x2068, 0x7018, 0x6802, 0x6807, 0x0000, 0x2d08, 0x2068, 0x6906,
+       0x711a, 0x0078, 0x3a69, 0x7014, 0x2068, 0x7007, 0x0001, 0x0078,
+       0x3ac8, 0x3abc, 0x3ac0, 0x3ac4, 0x0002, 0x0011, 0x0007, 0x0004,
+       0x000a, 0x000f, 0x0005, 0x0006, 0x0012, 0x000f, 0x0005, 0x0006,
+       0x2009, 0x6d2c, 0x210c, 0x81ff, 0x00c0, 0x3ae3, 0x6838, 0xa084,
+       0x00ff, 0x683a, 0x6853, 0x0000, 0x1078, 0x3299, 0x00c0, 0x3ad9,
+       0x007c, 0x1078, 0x372d, 0x127e, 0x2091, 0x8000, 0x1078, 0x36a1,
+       0x127f, 0x0078, 0x3ad8, 0x2001, 0x0028, 0x2009, 0x0000, 0x0078,
+       0x3ad9, 0x7018, 0x6802, 0x2d08, 0x2068, 0x6906, 0x711a, 0x7010,
+       0x8001, 0x7012, 0x0040, 0x3af8, 0x7007, 0x0006, 0x0078, 0x3afe,
+       0x7014, 0x2068, 0x7007, 0x0001, 0x7048, 0x107a, 0x007c, 0x7007,
+       0x0001, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x6848, 0xa084, 0x00ff,
+       0x20a9, 0x0001, 0xa096, 0x0001, 0x0040, 0x3b2a, 0x2009, 0x0000,
+       0x20a9, 0x007e, 0xa096, 0x0002, 0x0040, 0x3b2a, 0xa005, 0x00c0,
+       0x3b41, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x1078, 0x3447, 0x00c0,
+       0x3b41, 0x067e, 0x6e44, 0xa6b4, 0x000f, 0x1078, 0x34e3, 0x067f,
+       0x0078, 0x3b41, 0x047e, 0x2011, 0x6d0c, 0x2224, 0xc484, 0xc48c,
+       0x2412, 0x047f, 0x0c7e, 0x1078, 0x3447, 0x00c0, 0x3b3d, 0x2091,
+       0x8000, 0x607b, 0x0000, 0x2091, 0x8001, 0x8108, 0x00f0, 0x3b33,
+       0x0c7f, 0x1078, 0x1328, 0x007c, 0x127e, 0x2091, 0x8000, 0x7007,
+       0x0001, 0x2001, 0x6d52, 0x2004, 0xd0a4, 0x0040, 0x3b84, 0x6944,
+       0x1078, 0x3d6e, 0x6100, 0xd184, 0x0040, 0x3b69, 0x6858, 0xa084,
+       0x00ff, 0x00c0, 0x3b87, 0x6000, 0xd084, 0x0040, 0x3b84, 0x6004,
+       0xa005, 0x00c0, 0x3b8a, 0x6003, 0x0000, 0x600b, 0x0000, 0x0078,
+       0x3b81, 0x2011, 0x0001, 0x6860, 0xa005, 0x00c0, 0x3b71, 0x2001,
+       0x001e, 0x8000, 0x6016, 0x6858, 0xa084, 0x00ff, 0x0040, 0x3b84,
+       0x6006, 0x6858, 0x8007, 0xa084, 0x00ff, 0x0040, 0x3b84, 0x600a,
+       0x6202, 0x127f, 0x0078, 0x3d41, 0x127f, 0x0078, 0x3d39, 0x127f,
+       0x0078, 0x3d31, 0x127f, 0x0078, 0x3d35, 0x127e, 0x2091, 0x8000,
+       0x7007, 0x0001, 0x2001, 0x6d52, 0x2004, 0xd0a4, 0x0040, 0x3be2,
+       0x6944, 0x1078, 0x3d6e, 0x6000, 0xa084, 0x0001, 0x0040, 0x3be2,
+       0x6204, 0x6308, 0x6c48, 0xa484, 0x0003, 0x0040, 0x3bba, 0x6958,
+       0xa18c, 0x00ff, 0x8001, 0x00c0, 0x3bb3, 0x2100, 0xa210, 0x0048,
+       0x3bdf, 0x0078, 0x3bba, 0x8001, 0x00c0, 0x3bdf, 0x2100, 0xa212,
+       0x0048, 0x3bdf, 0xa484, 0x000c, 0x0040, 0x3bd4, 0x6958, 0x810f,
+       0xa18c, 0x00ff, 0xa082, 0x0004, 0x00c0, 0x3bcc, 0x2100, 0xa318,
+       0x0048, 0x3bdf, 0x0078, 0x3bd4, 0xa082, 0x0004, 0x00c0, 0x3bdf,
+       0x2100, 0xa31a, 0x0048, 0x3bdf, 0x6860, 0xa005, 0x0040, 0x3bda,
+       0x8000, 0x6016, 0x6206, 0x630a, 0x127f, 0x0078, 0x3d41, 0x127f,
+       0x0078, 0x3d3d, 0x127f, 0x0078, 0x3d39, 0x127e, 0x2091, 0x8000,
+       0x7007, 0x0001, 0x6944, 0x1078, 0x3d6e, 0x6308, 0x8318, 0x0048,
+       0x3bf5, 0x630a, 0x127f, 0x0078, 0x3d4f, 0x127f, 0x0078, 0x3d3d,
+       0x127e, 0x0c7e, 0x2091, 0x8000, 0x7007, 0x0001, 0x684c, 0xd0ac,
+       0x0040, 0x3c0c, 0x027e, 0x2009, 0x0000, 0x2011, 0xfcff, 0x1078,
+       0x41f4, 0x027f, 0x0078, 0x3c42, 0x6858, 0xa005, 0x0040, 0x3c56,
+       0x685c, 0xa065, 0x0040, 0x3c52, 0x2001, 0x6d2c, 0x2004, 0xa005,
+       0x0040, 0x3c1e, 0x1078, 0x6283, 0x0078, 0x3c24, 0x6013, 0x0400,
+       0x2009, 0x0041, 0x1078, 0x5591, 0x6958, 0xa18c, 0xe600, 0xa186,
+       0x2000, 0x0040, 0x3c3a, 0xa186, 0x0400, 0x0040, 0x3c3a, 0x6944,
+       0x0c7e, 0x1078, 0x416d, 0x6000, 0xa084, 0xfdff, 0x6002, 0x0c7f,
+       0x0078, 0x3c42, 0x027e, 0x2009, 0x0000, 0x2011, 0xfdff, 0x1078,
+       0x41f4, 0x027f, 0x684c, 0xd0c4, 0x0040, 0x3c4e, 0x6944, 0x1078,
+       0x416d, 0x6008, 0x8000, 0x0048, 0x3c4e, 0x600a, 0x0c7f, 0x127f,
+       0x0078, 0x3d41, 0x0c7f, 0x127f, 0x0078, 0x3d39, 0x6954, 0xa186,
+       0x0020, 0x0040, 0x3c6c, 0xa186, 0x0029, 0x00c0, 0x3c52, 0x6944,
+       0xa18c, 0xff00, 0x810f, 0x1078, 0x3447, 0x00c0, 0x3c42, 0x6000,
+       0xc0e4, 0x6002, 0x0078, 0x3c42, 0x685c, 0xa065, 0x0040, 0x3c52,
+       0x6017, 0x0014, 0x0078, 0x3c42, 0x6944, 0x1078, 0x3d6e, 0x6000,
+       0xa084, 0x0001, 0x0040, 0x3c8d, 0x2091, 0x8000, 0x6204, 0x8210,
+       0x0048, 0x3c87, 0x6206, 0x2091, 0x8001, 0x0078, 0x3d4f, 0x2091,
+       0x8001, 0x6853, 0x0016, 0x0078, 0x3d48, 0x6853, 0x0007, 0x0078,
+       0x3d48, 0x6834, 0x8007, 0xa084, 0x00ff, 0x00c0, 0x3c9b, 0x1078,
+       0x3a0f, 0x0078, 0x3cad, 0x2030, 0x8001, 0x00c0, 0x3ca5, 0x7007,
+       0x0001, 0x1078, 0x3cae, 0x0078, 0x3cad, 0x7007, 0x0006, 0x7012,
+       0x2d00, 0x7016, 0x701a, 0x704b, 0x3cae, 0x007c, 0x0e7e, 0x2009,
+       0x6d2c, 0x210c, 0x81ff, 0x00c0, 0x3d28, 0x6848, 0x2070, 0xae82,
+       0x7400, 0x0048, 0x3d18, 0x2001, 0x6d15, 0x2004, 0xae02, 0x00c8,
+       0x3d18, 0x6944, 0x1078, 0x3d6e, 0x6100, 0xa184, 0x0001, 0x0040,
+       0x3cfe, 0xa184, 0x0100, 0x00c0, 0x3d1c, 0xa184, 0x0200, 0x00c0,
+       0x3d20, 0x601c, 0xa005, 0x00c0, 0x3d24, 0x711c, 0xa186, 0x0006,
+       0x00c0, 0x3d03, 0x6853, 0x0000, 0x6803, 0x0000, 0x2d08, 0x127e,
+       0x2091, 0x8000, 0x7010, 0xa005, 0x00c0, 0x3cf5, 0x7112, 0x7018,
+       0xa065, 0x0040, 0x3d28, 0x6000, 0xd0e4, 0x00c0, 0x3d2c, 0x2e60,
+       0x1078, 0x4176, 0x127f, 0x0e7f, 0x007c, 0x2068, 0x6800, 0xa005,
+       0x00c0, 0x3cf5, 0x6902, 0x127f, 0x0e7f, 0x007c, 0x0e7f, 0x6853,
+       0x0006, 0x0078, 0x3d48, 0x6944, 0xa18c, 0xff00, 0x810f, 0x1078,
+       0x3447, 0x00c0, 0x3d2c, 0x6000, 0xd0e4, 0x00c0, 0x3d2c, 0x711c,
+       0xa186, 0x0007, 0x00c0, 0x3d18, 0x6853, 0x0002, 0x0078, 0x3d2e,
+       0x6853, 0x0008, 0x0078, 0x3d2e, 0x6853, 0x000e, 0x0078, 0x3d2e,
+       0x6853, 0x0017, 0x0078, 0x3d2e, 0x6853, 0x0035, 0x0078, 0x3d2e,
+       0x6853, 0x0028, 0x0078, 0x3d2e, 0x6853, 0x0029, 0x0e7f, 0x0078,
+       0x3d48, 0x2009, 0x003e, 0x0078, 0x3d43, 0x2009, 0x0004, 0x0078,
+       0x3d43, 0x2009, 0x0006, 0x0078, 0x3d43, 0x2009, 0x0016, 0x0078,
+       0x3d43, 0x2009, 0x0001, 0x6854, 0xa084, 0xff00, 0xa105, 0x6856,
+       0x2091, 0x8000, 0x1078, 0x36a1, 0x2091, 0x8001, 0x007c, 0x1078,
+       0x1328, 0x007c, 0x702c, 0x7130, 0x8108, 0xa102, 0x0048, 0x3d5f,
+       0xa00e, 0x7034, 0x7072, 0x7038, 0x7076, 0x0078, 0x3d6b, 0x7070,
+       0xa080, 0x0040, 0x7072, 0x00c8, 0x3d6b, 0x7074, 0xa081, 0x0000,
+       0x7076, 0xa085, 0x0001, 0x7932, 0x7132, 0x007c, 0x0d7e, 0x1078,
+       0x416d, 0x0d7f, 0x007c, 0x0d7e, 0x2011, 0x0004, 0x2204, 0xa085,
+       0x8002, 0x2012, 0x0d7f, 0x007c, 0x20e1, 0x0002, 0x3d08, 0x20e1,
+       0x2000, 0x3d00, 0xa084, 0x7000, 0x0040, 0x3d8a, 0xa086, 0x1000,
+       0x00c0, 0x3dab, 0x20e1, 0x0004, 0x3d60, 0xd1bc, 0x00c0, 0x3d91,
+       0x3e60, 0xac84, 0x0007, 0x00c0, 0x3dab, 0xac82, 0x7400, 0x0048,
+       0x3dab, 0x6854, 0xac02, 0x00c8, 0x3dab, 0x2009, 0x0047, 0x1078,
+       0x5591, 0x20e1, 0x0007, 0x20e1, 0x2000, 0x7a28, 0x7a1c, 0xd284,
+       0x00c0, 0x3d7c, 0x007c, 0xa016, 0x1078, 0x1532, 0x0078, 0x3da1,
+       0x157e, 0x137e, 0x147e, 0x20e1, 0x3000, 0x3d20, 0x3e28, 0xa584,
+       0x0070, 0x00c0, 0x3dd9, 0xa484, 0x7000, 0xa086, 0x1000, 0x00c0,
+       0x3dd9, 0x1078, 0x3de6, 0x0040, 0x3dd9, 0x20e1, 0x3000, 0x7828,
+       0x7828, 0x1078, 0x3e04, 0x147f, 0x137f, 0x157f, 0x2009, 0x6f18,
+       0x2104, 0xa005, 0x00c0, 0x3dd5, 0x007c, 0x1078, 0x476a, 0x0078,
+       0x3dd4, 0x1078, 0x6c23, 0x1078, 0x3de6, 0x20e1, 0x3000, 0x7828,
+       0x7828, 0x147f, 0x137f, 0x157f, 0x0078, 0x3dd4, 0xa484, 0x01ff,
+       0x687a, 0xa005, 0x0040, 0x3df8, 0xa080, 0x001f, 0xa084, 0x03f8,
+       0x80ac, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0x007c,
+       0x20a9, 0x000c, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5,
+       0xa085, 0x0001, 0x0078, 0x3df7, 0x7000, 0xa084, 0xff00, 0xa08c,
+       0xf000, 0x8007, 0xa196, 0x0000, 0x00c0, 0x3e11, 0x0078, 0x3f51,
+       0x007c, 0xa196, 0x2000, 0x00c0, 0x3e22, 0x6900, 0xa18e, 0x0001,
+       0x00c0, 0x3e1e, 0x1078, 0x2aec, 0x0078, 0x3e10, 0x1078, 0x3e2a,
+       0x0078, 0x3e10, 0xa196, 0x8000, 0x00c0, 0x3e10, 0x1078, 0x3fd7,
+       0x0078, 0x3e10, 0x0c7e, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa196,
+       0x0001, 0x0040, 0x3e37, 0xa196, 0x0023, 0x00c0, 0x3ef8, 0xa08e,
+       0x0023, 0x00c0, 0x3e68, 0x1078, 0x404e, 0x0040, 0x3ef8, 0x7124,
+       0x610a, 0x7030, 0xa08e, 0x0200, 0x00c0, 0x3e50, 0x7034, 0xa005,
+       0x00c0, 0x3ef8, 0x2009, 0x0015, 0x1078, 0x5591, 0x0078, 0x3ef8,
+       0xa08e, 0x0210, 0x00c0, 0x3e5a, 0x2009, 0x0015, 0x1078, 0x5591,
+       0x0078, 0x3ef8, 0xa08e, 0x0100, 0x00c0, 0x3ef8, 0x7034, 0xa005,
+       0x00c0, 0x3ef8, 0x2009, 0x0016, 0x1078, 0x5591, 0x0078, 0x3ef8,
+       0xa08e, 0x0022, 0x00c0, 0x3ef8, 0x7030, 0xa08e, 0x0300, 0x00c0,
+       0x3e79, 0x7034, 0xa005, 0x00c0, 0x3ef8, 0x2009, 0x0017, 0x0078,
+       0x3eda, 0xa08e, 0x0500, 0x00c0, 0x3e85, 0x7034, 0xa005, 0x00c0,
+       0x3ef8, 0x2009, 0x0018, 0x0078, 0x3eda, 0xa08e, 0x2010, 0x00c0,
+       0x3e8d, 0x2009, 0x0019, 0x0078, 0x3eda, 0xa08e, 0x2110, 0x00c0,
+       0x3e95, 0x2009, 0x001a, 0x0078, 0x3eda, 0xa08e, 0x5200, 0x00c0,
+       0x3ea1, 0x7034, 0xa005, 0x00c0, 0x3ef8, 0x2009, 0x001b, 0x0078,
+       0x3eda, 0xa08e, 0x5000, 0x00c0, 0x3ead, 0x7034, 0xa005, 0x00c0,
+       0x3ef8, 0x2009, 0x001c, 0x0078, 0x3eda, 0xa08e, 0x2400, 0x00c0,
+       0x3eb3, 0x0078, 0x3ed8, 0xa08e, 0x5300, 0x00c0, 0x3eb9, 0x0078,
+       0x3ed8, 0xa08e, 0x0f00, 0x00c0, 0x3ec1, 0x2009, 0x0020, 0x0078,
+       0x3eda, 0xa08e, 0x5300, 0x00c0, 0x3ec7, 0x0078, 0x3ed8, 0xa08e,
+       0x6104, 0x00c0, 0x3ed8, 0x2009, 0x728e, 0x2011, 0x8015, 0x211c,
+       0x8108, 0x2124, 0x1078, 0x2a53, 0x2009, 0x0023, 0x0078, 0x3eda,
+       0x2009, 0x001d, 0x017e, 0x2011, 0x7283, 0x2204, 0x8211, 0x220c,
+       0x1078, 0x1e1b, 0x00c0, 0x3efa, 0x1078, 0x3410, 0x00c0, 0x3efa,
+       0x6612, 0x6516, 0x0c7e, 0x1078, 0x5504, 0x0040, 0x3efd, 0x017f,
+       0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0x017f, 0x1078, 0x5591,
+       0x0c7f, 0x007c, 0x017f, 0x0078, 0x3ef8, 0x0c7f, 0x0078, 0x3efa,
+       0x0e7e, 0x0d7e, 0x2028, 0x2130, 0xa696, 0x00ff, 0x00c0, 0x3f20,
+       0xa596, 0xfffd, 0x00c0, 0x3f10, 0x2009, 0x007f, 0x0078, 0x3f4d,
+       0xa596, 0xfffe, 0x00c0, 0x3f18, 0x2009, 0x007e, 0x0078, 0x3f4d,
+       0xa596, 0xfffc, 0x00c0, 0x3f20, 0x2009, 0x0080, 0x0078, 0x3f4d,
+       0x2011, 0x0000, 0x2021, 0x007e, 0x20a9, 0x0082, 0x2071, 0x6e7e,
+       0x2e1c, 0x83ff, 0x00c0, 0x3f32, 0x82ff, 0x00c0, 0x3f41, 0x2410,
+       0x0078, 0x3f41, 0x2368, 0x6b10, 0x007e, 0x2100, 0xa31e, 0x007f,
+       0x00c0, 0x3f41, 0x6b14, 0xa31e, 0x00c0, 0x3f41, 0x2408, 0x0078,
+       0x3f4d, 0x8420, 0x8e70, 0x00f0, 0x3f28, 0x82ff, 0x00c0, 0x3f4c,
+       0xa085, 0x0001, 0x0078, 0x3f4e, 0x2208, 0xa006, 0x0d7f, 0x0e7f,
+       0x007c, 0xa084, 0x0007, 0x0079, 0x3f56, 0x007c, 0x3f5e, 0x3f5e,
+       0x3f5e, 0x3f5e, 0x3f5e, 0x3f5f, 0x3f78, 0x3fc0, 0x007c, 0x7110,
+       0xd1bc, 0x0040, 0x3f77, 0x7120, 0x2160, 0xac8c, 0x0007, 0x00c0,
+       0x3f77, 0xac8a, 0x7400, 0x0048, 0x3f77, 0x6854, 0xac02, 0x00c8,
+       0x3f77, 0x7124, 0x610a, 0x2009, 0x0046, 0x1078, 0x5591, 0x007c,
+       0x0c7e, 0x7110, 0xd1bc, 0x00c0, 0x3fbe, 0x2011, 0x7283, 0x2204,
+       0x8211, 0x220c, 0x1078, 0x1e1b, 0x00c0, 0x3fbe, 0x1078, 0x3447,
+       0x00c0, 0x3fbe, 0x6204, 0xa294, 0xff00, 0x8217, 0xa286, 0x0006,
+       0x00c0, 0x3fa3, 0x0c7e, 0x1078, 0x5504, 0x017f, 0x0040, 0x3fbe,
+       0x611a, 0x601f, 0x0006, 0x7120, 0x610a, 0x2009, 0x0044, 0x1078,
+       0x5591, 0x0078, 0x3fbe, 0x0c7e, 0x1078, 0x5504, 0x017f, 0x0040,
+       0x3fbe, 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0xa286, 0x0004,
+       0x00c0, 0x3fb6, 0x6007, 0x0005, 0x0078, 0x3fb8, 0x6007, 0x0001,
+       0x6003, 0x0001, 0x1078, 0x4376, 0x1078, 0x476a, 0x0c7f, 0x007c,
+       0x7110, 0xd1bc, 0x0040, 0x3fd6, 0x7020, 0x2060, 0xac84, 0x0007,
+       0x00c0, 0x3fd6, 0xac82, 0x7400, 0x0048, 0x3fd6, 0x6854, 0xac02,
+       0x00c8, 0x3fd6, 0x2009, 0x0045, 0x1078, 0x5591, 0x007c, 0x7110,
+       0xa18c, 0xff00, 0x810f, 0xa18e, 0x0000, 0x00c0, 0x3fe7, 0xa084,
+       0x000f, 0xa08a, 0x0006, 0x10c8, 0x12b7, 0x1079, 0x3fe8, 0x007c,
+       0x3fee, 0x3fef, 0x3fee, 0x3fee, 0x4030, 0x403f, 0x007c, 0x7110,
+       0xd1bc, 0x00c0, 0x402f, 0x700c, 0x7108, 0x1078, 0x1e1b, 0x00c0,
+       0x402f, 0x1078, 0x3410, 0x00c0, 0x402f, 0x6612, 0x6516, 0x6204,
+       0xa294, 0xff00, 0x8217, 0xa286, 0x0006, 0x00c0, 0x4018, 0x0c7e,
+       0x1078, 0x5504, 0x017f, 0x0040, 0x402f, 0x611a, 0x601f, 0x0005,
+       0x7120, 0x610a, 0x2009, 0x0028, 0x1078, 0x5591, 0x0078, 0x402f,
+       0x0c7e, 0x1078, 0x5504, 0x017f, 0x0040, 0x402f, 0x611a, 0x601f,
+       0x0004, 0x7120, 0x610a, 0xa286, 0x0004, 0x00c0, 0x402b, 0x2009,
+       0x0005, 0x0078, 0x402d, 0x2009, 0x0001, 0x1078, 0x5591, 0x007c,
+       0x7110, 0xd1bc, 0x0040, 0x403e, 0x1078, 0x404e, 0x0040, 0x403e,
+       0x7124, 0x610a, 0x2009, 0x0029, 0x1078, 0x5591, 0x007c, 0x7110,
+       0xd1bc, 0x0040, 0x404d, 0x1078, 0x404e, 0x0040, 0x404d, 0x7124,
+       0x610a, 0x2009, 0x002a, 0x1078, 0x5591, 0x007c, 0x7020, 0x2060,
+       0xac84, 0x0007, 0x00c0, 0x4061, 0xac82, 0x7400, 0x0048, 0x4061,
+       0x2001, 0x6d15, 0x2004, 0xac02, 0x00c8, 0x4061, 0xa085, 0x0001,
+       0x007c, 0xa006, 0x0078, 0x4060, 0x2071, 0x6f23, 0x7003, 0x0003,
+       0x700f, 0x0361, 0xa006, 0x701a, 0x7012, 0x7017, 0x7400, 0x7007,
+       0x0000, 0x7026, 0x702b, 0x4ff2, 0x7032, 0x7037, 0x503e, 0x007c,
+       0x2071, 0x6f23, 0x00e0, 0x40be, 0x2091, 0x6000, 0x700c, 0x8001,
+       0x700e, 0x00c0, 0x4087, 0x700f, 0x0361, 0x7007, 0x0001, 0x127e,
+       0x2091, 0x8000, 0x7024, 0xa00d, 0x0040, 0x409b, 0x7020, 0x8001,
+       0x7022, 0x00c0, 0x409b, 0x7023, 0x0009, 0x8109, 0x7126, 0x00c0,
+       0x409b, 0x7028, 0x107a, 0x7030, 0xa00d, 0x0040, 0x40ac, 0x702c,
+       0x8001, 0x702e, 0x00c0, 0x40ac, 0x702f, 0x0009, 0x8109, 0x7132,
+       0x00c0, 0x40ac, 0x7034, 0x107a, 0x7018, 0xa00d, 0x0040, 0x40bd,
+       0x7008, 0x8001, 0x700a, 0x00c0, 0x40bd, 0x700b, 0x0009, 0x8109,
+       0x711a, 0x00c0, 0x40bd, 0x701c, 0x107a, 0x127f, 0x7004, 0x0079,
+       0x40c1, 0x40e8, 0x40e9, 0x4105, 0x0e7e, 0x2071, 0x6f23, 0x7018,
+       0xa005, 0x00c0, 0x40cf, 0x711a, 0x721e, 0x700b, 0x0009, 0x0e7f,
+       0x007c, 0x0e7e, 0x007e, 0x2071, 0x6f23, 0x701c, 0xa206, 0x00c0,
+       0x40db, 0x701a, 0x701e, 0x007f, 0x0e7f, 0x007c, 0x0e7e, 0x2071,
+       0x6f23, 0x6088, 0xa102, 0x0048, 0x40e6, 0x618a, 0x0e7f, 0x007c,
+       0x007c, 0x7110, 0x1078, 0x3447, 0x00c0, 0x40fb, 0x6088, 0x8001,
+       0x0048, 0x40fb, 0x608a, 0x00c0, 0x40fb, 0x127e, 0x2091, 0x8000,
+       0x1078, 0x476a, 0x127f, 0x8108, 0xa182, 0x00ff, 0x0048, 0x4103,
+       0xa00e, 0x7007, 0x0002, 0x7112, 0x007c, 0x7014, 0x2060, 0x127e,
+       0x2091, 0x8000, 0x6014, 0xa005, 0x0040, 0x4134, 0x8001, 0x6016,
+       0x00c0, 0x4134, 0x611c, 0xa186, 0x0003, 0x0040, 0x411b, 0xa186,
+       0x0006, 0x00c0, 0x4132, 0x6010, 0x2068, 0x6854, 0xa08a, 0x199a,
+       0x0048, 0x4132, 0xa082, 0x1999, 0x6856, 0xa08a, 0x199a, 0x0048,
+       0x412b, 0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116,
+       0x0078, 0x4134, 0x1078, 0x5fea, 0x127f, 0xac88, 0x0008, 0x7116,
+       0x2001, 0x6d16, 0x2004, 0xa102, 0x0048, 0x4142, 0x7017, 0x7400,
+       0x7007, 0x0000, 0x007c, 0x0e7e, 0x2071, 0x6f23, 0x7027, 0x07d0,
+       0x7023, 0x0009, 0x0e7f, 0x007c, 0x2001, 0x6f2c, 0x2003, 0x0000,
+       0x007c, 0x0e7e, 0x2071, 0x6f23, 0x7033, 0x07d0, 0x702f, 0x0009,
+       0x0e7f, 0x007c, 0x2011, 0x6f2f, 0x2013, 0x0000, 0x007c, 0x0e7e,
+       0x2071, 0x6f23, 0x711a, 0x721e, 0x700b, 0x0009, 0x0e7f, 0x007c,
+       0x0c7e, 0x2061, 0x6fb2, 0x0c7f, 0x007c, 0xa184, 0x000f, 0x8003,
+       0x8003, 0x8003, 0xa080, 0x6fb2, 0x2060, 0x007c, 0x684c, 0xa08c,
+       0x00c0, 0xa18e, 0x00c0, 0x0040, 0x41ac, 0xd0b4, 0x00c0, 0x4188,
+       0xd0bc, 0x00c0, 0x419a, 0x2009, 0x0006, 0x1078, 0x41cf, 0x007c,
+       0xd0fc, 0x0040, 0x4195, 0xa084, 0x0003, 0xa08e, 0x0003, 0x0040,
+       0x41c8, 0xa08e, 0x0000, 0x00c0, 0x41c8, 0x2009, 0x0043, 0x1078,
+       0x5591, 0x007c, 0xd0fc, 0x0040, 0x41a7, 0xa084, 0x0003, 0xa08e,
+       0x0003, 0x0040, 0x41c8, 0xa08e, 0x0000, 0x00c0, 0x41c8, 0x2009,
+       0x0042, 0x1078, 0x5591, 0x007c, 0xd0fc, 0x0040, 0x41be, 0xa084,
+       0x0003, 0xa08e, 0x0003, 0x0040, 0x41c8, 0xa08e, 0x0002, 0x0040,
+       0x41c2, 0x2009, 0x0041, 0x1078, 0x5591, 0x007c, 0x1078, 0x41cd,
+       0x0078, 0x41bd, 0x2009, 0x0043, 0x1078, 0x5591, 0x0078, 0x41bd,
+       0x2009, 0x0004, 0x1078, 0x41cf, 0x007c, 0x2009, 0x0001, 0x6010,
+       0xa0ec, 0xf000, 0x0040, 0x41f3, 0x2068, 0x6952, 0x6800, 0x6012,
+       0xa186, 0x0001, 0x00c0, 0x41ed, 0x694c, 0xa18c, 0x8100, 0xa18e,
+       0x8100, 0x00c0, 0x41ed, 0x0c7e, 0x6944, 0x1078, 0x416d, 0x6204,
+       0x8210, 0x0048, 0x41ec, 0x6206, 0x0c7f, 0x1078, 0x36a1, 0x6010,
+       0xa06d, 0x10c0, 0x4176, 0x007c, 0x157e, 0x0c7e, 0x20a9, 0x0010,
+       0x2061, 0x6fb2, 0x6000, 0x81ff, 0x0040, 0x4201, 0xa205, 0x0078,
+       0x4202, 0xa204, 0x6002, 0xace0, 0x0008, 0x00f0, 0x41fa, 0x0c7f,
+       0x157f, 0x007c, 0x6808, 0xa005, 0x0040, 0x4212, 0x8001, 0x680a,
+       0xa085, 0x0001, 0x007c, 0x127e, 0x2091, 0x2200, 0x2079, 0x6f10,
+       0x127f, 0x0d7e, 0x2069, 0x6f10, 0x6803, 0x0005, 0x2069, 0x0004,
+       0x2d04, 0xa085, 0x8001, 0x206a, 0x0d7f, 0x007c, 0x0c7e, 0x6027,
+       0x0001, 0x7804, 0xa084, 0x0007, 0x0079, 0x422e, 0x4238, 0x425d,
+       0x428e, 0x423e, 0x425d, 0x4236, 0x4236, 0x4236, 0x1078, 0x12b7,
+       0x1078, 0x414c, 0x1078, 0x476a, 0x0c7f, 0x007c, 0x62c0, 0x82ff,
+       0x00c0, 0x4244, 0x0c7f, 0x007c, 0x2011, 0x318e, 0x1078, 0x40d1,
+       0x7828, 0xa092, 0x0002, 0x00c8, 0x4253, 0x8000, 0x782a, 0x1078,
+       0x31c2, 0x0078, 0x4242, 0x1078, 0x318e, 0x7807, 0x0003, 0x7827,
+       0x0000, 0x782b, 0x0000, 0x0078, 0x4242, 0x1078, 0x414c, 0x62c0,
+       0x82ff, 0x00c0, 0x426f, 0x782b, 0x0000, 0x7824, 0xa065, 0x1040,
+       0x12b7, 0x2009, 0x0013, 0x1078, 0x5591, 0x0c7f, 0x007c, 0x0c7e,
+       0x7824, 0xa065, 0x1040, 0x12b7, 0x7804, 0xa086, 0x0004, 0x0040,
+       0x42cc, 0x7828, 0xa092, 0x2710, 0x00c8, 0x4285, 0x8000, 0x782a,
+       0x0c7f, 0x1078, 0x4fd7, 0x0078, 0x426d, 0x1078, 0x6c76, 0x2009,
+       0x0014, 0x1078, 0x5591, 0x0c7f, 0x0078, 0x426d, 0x2001, 0x6f2c,
+       0x2003, 0x0000, 0x62c0, 0x82ff, 0x00c0, 0x42a2, 0x782b, 0x0000,
+       0x7824, 0xa065, 0x1040, 0x12b7, 0x2009, 0x0013, 0x1078, 0x55df,
+       0x0c7f, 0x007c, 0x0c7e, 0x0d7e, 0x7824, 0xa005, 0x1040, 0x12b7,
+       0x781c, 0xa06d, 0x1040, 0x12b7, 0x6800, 0xc0dc, 0x6802, 0x7924,
+       0x2160, 0x1078, 0x556a, 0x693c, 0x81ff, 0x1040, 0x12b7, 0x8109,
+       0x693e, 0x6854, 0xa015, 0x0040, 0x42c0, 0x7a1e, 0x0078, 0x42c2,
+       0x7918, 0x791e, 0x7807, 0x0000, 0x7827, 0x0000, 0x0d7f, 0x0c7f,
+       0x1078, 0x476a, 0x0078, 0x42a0, 0x6104, 0xa186, 0x0002, 0x0040,
+       0x42d7, 0xa186, 0x0004, 0x0040, 0x42d7, 0x0078, 0x4279, 0x7808,
+       0xac06, 0x0040, 0x4279, 0x1078, 0x4671, 0x1078, 0x4376, 0x0c7f,
+       0x1078, 0x476a, 0x0078, 0x426d, 0x0c7e, 0x6027, 0x0002, 0x2011,
+       0x6f2f, 0x2013, 0x0000, 0x62c8, 0x82ff, 0x00c0, 0x42fe, 0x62c4,
+       0x82ff, 0x00c0, 0x42fe, 0x793c, 0xa1e5, 0x0000, 0x0040, 0x42fc,
+       0x2009, 0x0049, 0x1078, 0x5591, 0x0c7f, 0x007c, 0x6017, 0x0010,
+       0x793c, 0x81ff, 0x0040, 0x42fc, 0x7944, 0xa192, 0x2710, 0x00c8,
+       0x431d, 0x8108, 0x7946, 0x1078, 0x4151, 0x793c, 0xa188, 0x0007,
+       0x210c, 0xa18e, 0x0006, 0x00c0, 0x4319, 0x6017, 0x0012, 0x0078,
+       0x42fc, 0x6017, 0x0016, 0x0078, 0x42fc, 0x1078, 0x6c76, 0x793c,
+       0x2160, 0x2009, 0x004a, 0x1078, 0x5591, 0x0078, 0x42fc, 0x007e,
+       0x017e, 0x0c7e, 0x127e, 0x600f, 0x0000, 0x2c08, 0x2061, 0x6f10,
+       0x2091, 0x8000, 0x6020, 0x8000, 0x6022, 0x6010, 0xa005, 0x0040,
+       0x4342, 0xa080, 0x0003, 0x2102, 0x6112, 0x127f, 0x0c7f, 0x017f,
+       0x007f, 0x007c, 0x6116, 0x6112, 0x0078, 0x433d, 0x0d7e, 0x2069,
+       0x6f10, 0x6000, 0xd0d4, 0x0040, 0x435d, 0x6820, 0x8000, 0x6822,
+       0xa086, 0x0001, 0x00c0, 0x4356, 0x2c00, 0x681e, 0x6804, 0xa084,
+       0x0007, 0x0079, 0x4772, 0x0d7f, 0x007c, 0xc0d5, 0x6002, 0x6818,
+       0xa005, 0x0040, 0x436f, 0x6056, 0x605b, 0x0000, 0x007e, 0x2c00,
+       0x681a, 0x0d7f, 0x685a, 0x2069, 0x6f10, 0x0078, 0x434d, 0x6056,
+       0x605a, 0x2c00, 0x681a, 0x681e, 0x0078, 0x434d, 0x007e, 0x017e,
+       0x0c7e, 0x127e, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061,
+       0x6f10, 0x6020, 0x8000, 0x6022, 0x6008, 0xa005, 0x0040, 0x4391,
+       0xa080, 0x0003, 0x2102, 0x610a, 0x127f, 0x0c7f, 0x017f, 0x007f,
+       0x007c, 0x610e, 0x610a, 0x0078, 0x438c, 0x0c7e, 0x600f, 0x0000,
+       0x2c08, 0x2061, 0x6f10, 0x6034, 0xa005, 0x0040, 0x43a5, 0xa080,
+       0x0003, 0x2102, 0x6136, 0x0c7f, 0x007c, 0x613a, 0x6136, 0x0078,
+       0x43a3, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x027e, 0x007e,
+       0x127e, 0x2071, 0x6f10, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000,
+       0x8cff, 0x0040, 0x4405, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206,
+       0x00c0, 0x4400, 0x703c, 0xac06, 0x00c0, 0x43cb, 0x6003, 0x000a,
+       0x630a, 0x0078, 0x4400, 0x7038, 0xac36, 0x00c0, 0x43d1, 0x660c,
+       0x763a, 0x7034, 0xac36, 0x00c0, 0x43df, 0x2c00, 0xaf36, 0x0040,
+       0x43dd, 0x2f00, 0x7036, 0x0078, 0x43df, 0x7037, 0x0000, 0x660c,
+       0x067e, 0x2c00, 0xaf06, 0x0040, 0x43e8, 0x7e0e, 0x0078, 0x43e9,
+       0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x601c, 0xa086, 0x0003,
+       0x00c0, 0x440e, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078,
+       0x36a1, 0x1078, 0x6276, 0x1078, 0x6283, 0x0c7f, 0x0078, 0x43b8,
+       0x2c78, 0x600c, 0x2060, 0x0078, 0x43b8, 0x127f, 0x007f, 0x027f,
+       0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x601c, 0xa086,
+       0x0006, 0x00c0, 0x43f2, 0x1078, 0x6bb3, 0x0078, 0x43fb, 0x007e,
+       0x067e, 0x0c7e, 0x0d7e, 0x0f7e, 0x2031, 0x0000, 0x127e, 0x2091,
+       0x8000, 0x2079, 0x6f10, 0x7838, 0xa065, 0x0040, 0x444a, 0x600c,
+       0x007e, 0x600f, 0x0000, 0x783c, 0xac06, 0x00c0, 0x4435, 0x6003,
+       0x000a, 0x630a, 0x2c30, 0x0078, 0x4447, 0x6010, 0x2068, 0x601c,
+       0xa086, 0x0003, 0x00c0, 0x4453, 0x6837, 0x0103, 0x6b4a, 0x6847,
+       0x0000, 0x1078, 0x36a1, 0x1078, 0x6276, 0x1078, 0x6283, 0x007f,
+       0x0078, 0x4424, 0x7e3a, 0x7e36, 0x127f, 0x0f7f, 0x0d7f, 0x0c7f,
+       0x067f, 0x007f, 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x443c,
+       0x1078, 0x6bb3, 0x0078, 0x4445, 0x027e, 0x1078, 0x4470, 0x1078,
+       0x4507, 0x027f, 0x007c, 0x0f7e, 0x127e, 0x2079, 0x6f10, 0x2091,
+       0x8000, 0x1078, 0x4599, 0x1078, 0x4601, 0x127f, 0x0f7f, 0x007c,
+       0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x007e, 0x127e, 0x2091,
+       0x8000, 0x2071, 0x6f10, 0x7614, 0x2660, 0x2678, 0x8cff, 0x0040,
+       0x44f6, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x00c0, 0x44f1,
+       0x7024, 0xac06, 0x00c0, 0x44b6, 0x2069, 0x0100, 0x68c0, 0xa005,
+       0x0040, 0x44b1, 0x1078, 0x4fe5, 0x68c3, 0x0000, 0x1078, 0x54a4,
+       0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000,
+       0x0040, 0x44a6, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100,
+       0x6824, 0xd084, 0x0040, 0x44ae, 0x6827, 0x0001, 0x037f, 0x0078,
+       0x44b6, 0x6003, 0x0009, 0x630a, 0x0078, 0x44f1, 0x7014, 0xac36,
+       0x00c0, 0x44bc, 0x660c, 0x7616, 0x7010, 0xac36, 0x00c0, 0x44ca,
+       0x2c00, 0xaf36, 0x0040, 0x44c8, 0x2f00, 0x7012, 0x0078, 0x44ca,
+       0x7013, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, 0x44d3,
+       0x7e0e, 0x0078, 0x44d4, 0x2678, 0x600f, 0x0000, 0x6010, 0x2068,
+       0x1078, 0x6120, 0x0040, 0x44ea, 0x601c, 0xa086, 0x0003, 0x00c0,
+       0x44fe, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x36a1,
+       0x1078, 0x6276, 0x1078, 0x6283, 0x1078, 0x5374, 0x0c7f, 0x0078,
+       0x447e, 0x2c78, 0x600c, 0x2060, 0x0078, 0x447e, 0x127f, 0x007f,
+       0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x601c, 0xa086,
+       0x0006, 0x00c0, 0x44e1, 0x1078, 0x6bb3, 0x0078, 0x44ea, 0x0c7e,
+       0x007e, 0x127e, 0x2091, 0x8000, 0xa280, 0x6e00, 0x2004, 0xa065,
+       0x0040, 0x4595, 0x0f7e, 0x0e7e, 0x0d7e, 0x067e, 0x2071, 0x6f10,
+       0x6654, 0x7018, 0xac06, 0x00c0, 0x451e, 0x761a, 0x701c, 0xac06,
+       0x00c0, 0x452a, 0x86ff, 0x00c0, 0x4529, 0x7018, 0x701e, 0x0078,
+       0x452a, 0x761e, 0x6058, 0xa07d, 0x0040, 0x452f, 0x7e56, 0xa6ed,
+       0x0000, 0x0040, 0x4535, 0x2f00, 0x685a, 0x6057, 0x0000, 0x605b,
+       0x0000, 0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x1078, 0x33c4, 0x0040,
+       0x4591, 0x7624, 0x86ff, 0x0040, 0x4586, 0xa680, 0x0004, 0x2004,
+       0xad06, 0x00c0, 0x4586, 0x0d7e, 0x2069, 0x0100, 0x68c0, 0xa005,
+       0x0040, 0x457d, 0x1078, 0x4fe5, 0x68c3, 0x0000, 0x1078, 0x54a4,
+       0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000,
+       0x0040, 0x4566, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100,
+       0x6824, 0xd084, 0x0040, 0x456e, 0x6827, 0x0001, 0x037f, 0x0d7f,
+       0x0c7e, 0x603c, 0xa005, 0x0040, 0x4577, 0x8001, 0x603e, 0x2660,
+       0x1078, 0x6283, 0x0c7f, 0x0078, 0x4586, 0x0d7f, 0x0c7e, 0x2660,
+       0x6003, 0x0009, 0x630a, 0x0c7f, 0x0078, 0x453d, 0x6837, 0x0103,
+       0x6b4a, 0x6847, 0x0000, 0x1078, 0x36a1, 0x1078, 0x5374, 0x0078,
+       0x453d, 0x067f, 0x0d7f, 0x0e7f, 0x0f7f, 0x127f, 0x007f, 0x0c7f,
+       0x007c, 0x007e, 0x067e, 0x0c7e, 0x0d7e, 0x2031, 0x0000, 0x7814,
+       0xa065, 0x0040, 0x45f1, 0x600c, 0x007e, 0x600f, 0x0000, 0x7824,
+       0xac06, 0x00c0, 0x45d6, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040,
+       0x45d0, 0x1078, 0x4fe5, 0x68c3, 0x0000, 0x1078, 0x54a4, 0x7827,
+       0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040,
+       0x45c5, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824,
+       0xd084, 0x0040, 0x45cd, 0x6827, 0x0001, 0x037f, 0x0078, 0x45d6,
+       0x6003, 0x0009, 0x630a, 0x2c30, 0x0078, 0x45ee, 0x6010, 0x2068,
+       0x1078, 0x6120, 0x0040, 0x45ea, 0x601c, 0xa086, 0x0003, 0x00c0,
+       0x45f8, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x36a1,
+       0x1078, 0x6276, 0x1078, 0x6283, 0x1078, 0x5374, 0x007f, 0x0078,
+       0x45a0, 0x7e16, 0x7e12, 0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c,
+       0x601c, 0xa086, 0x0006, 0x00c0, 0x45e1, 0x1078, 0x6bb3, 0x0078,
+       0x45ea, 0x007e, 0x067e, 0x0c7e, 0x0d7e, 0x7818, 0xa065, 0x0040,
+       0x466a, 0x6054, 0x007e, 0x6057, 0x0000, 0x605b, 0x0000, 0x6000,
+       0xc0d4, 0xc0dc, 0x6002, 0x1078, 0x33c4, 0x0040, 0x4667, 0x7e24,
+       0x86ff, 0x0040, 0x465c, 0xa680, 0x0004, 0x2004, 0xad06, 0x00c0,
+       0x465c, 0x0d7e, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040, 0x4653,
+       0x1078, 0x4fe5, 0x68c3, 0x0000, 0x1078, 0x54a4, 0x7827, 0x0000,
+       0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x463c,
+       0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084,
+       0x0040, 0x4644, 0x6827, 0x0001, 0x037f, 0x0d7f, 0x0c7e, 0x603c,
+       0xa005, 0x0040, 0x464d, 0x8001, 0x603e, 0x2660, 0x1078, 0x6283,
+       0x0c7f, 0x0078, 0x465c, 0x0d7f, 0x0c7e, 0x2660, 0x6003, 0x0009,
+       0x630a, 0x0c7f, 0x0078, 0x4613, 0x6837, 0x0103, 0x6b4a, 0x6847,
+       0x0000, 0x1078, 0x36a1, 0x1078, 0x5374, 0x0078, 0x4613, 0x007f,
+       0x0078, 0x4606, 0x781e, 0x781a, 0x0d7f, 0x0c7f, 0x067f, 0x007f,
+       0x007c, 0x0e7e, 0x0c7e, 0x2071, 0x6f10, 0x7004, 0xa084, 0x0007,
+       0x0079, 0x467a, 0x4684, 0x4687, 0x46a0, 0x46bc, 0x4701, 0x4684,
+       0x4682, 0x4682, 0x1078, 0x12b7, 0x0c7f, 0x0e7f, 0x007c, 0x7024,
+       0xa065, 0x0040, 0x4695, 0x7020, 0x8001, 0x7022, 0x600c, 0xa015,
+       0x0040, 0x469c, 0x7216, 0x600f, 0x0000, 0x7007, 0x0000, 0x7027,
+       0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x7216, 0x7212, 0x0078, 0x4695,
+       0x6018, 0x2060, 0x1078, 0x33c4, 0x6000, 0xc0dc, 0x6002, 0x7020,
+       0x8001, 0x7022, 0x0040, 0x46b1, 0x6054, 0xa015, 0x0040, 0x46b8,
+       0x721e, 0x7007, 0x0000, 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c,
+       0x7218, 0x721e, 0x0078, 0x46b1, 0x7024, 0xa065, 0x0040, 0x46fe,
+       0x700c, 0xac06, 0x00c0, 0x46d3, 0x1078, 0x5374, 0x600c, 0xa015,
+       0x0040, 0x46cf, 0x720e, 0x600f, 0x0000, 0x0078, 0x46fc, 0x720e,
+       0x720a, 0x0078, 0x46fc, 0x7014, 0xac06, 0x00c0, 0x46e6, 0x1078,
+       0x5374, 0x600c, 0xa015, 0x0040, 0x46e2, 0x7216, 0x600f, 0x0000,
+       0x0078, 0x46fc, 0x7216, 0x7212, 0x0078, 0x46fc, 0x6018, 0x2060,
+       0x1078, 0x33c4, 0x6000, 0xc0dc, 0x6002, 0x1078, 0x5374, 0x701c,
+       0xa065, 0x0040, 0x46fc, 0x6054, 0xa015, 0x0040, 0x46fa, 0x721e,
+       0x0078, 0x46fc, 0x7218, 0x721e, 0x7027, 0x0000, 0x0c7f, 0x0e7f,
+       0x007c, 0x7024, 0xa065, 0x0040, 0x470e, 0x1078, 0x5374, 0x600c,
+       0xa015, 0x0040, 0x4715, 0x720e, 0x600f, 0x0000, 0x1078, 0x54a4,
+       0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x720e, 0x720a, 0x0078,
+       0x470e, 0x0d7e, 0x2069, 0x6f10, 0x6830, 0xa084, 0x0003, 0x0079,
+       0x4721, 0x4727, 0x4729, 0x474f, 0x4725, 0x1078, 0x12b7, 0x0d7f,
+       0x007c, 0x0c7e, 0x6840, 0xa086, 0x0001, 0x0040, 0x4745, 0x683c,
+       0xa065, 0x0040, 0x473a, 0x600c, 0xa015, 0x0040, 0x4741, 0x6a3a,
+       0x600f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x0c7f, 0x0d7f,
+       0x007c, 0x683a, 0x6836, 0x0078, 0x473a, 0x6843, 0x0000, 0x6838,
+       0xa065, 0x0040, 0x473a, 0x6003, 0x0003, 0x0078, 0x473a, 0x0c7e,
+       0x6843, 0x0000, 0x6847, 0x0000, 0x683c, 0xa065, 0x0040, 0x4767,
+       0x600c, 0xa015, 0x0040, 0x4763, 0x6a3a, 0x600f, 0x0000, 0x683f,
+       0x0000, 0x0078, 0x4767, 0x683f, 0x0000, 0x683a, 0x6836, 0x0c7f,
+       0x0d7f, 0x007c, 0x0d7e, 0x2069, 0x6f10, 0x6804, 0xa084, 0x0007,
+       0x0079, 0x4772, 0x477c, 0x4810, 0x4810, 0x4810, 0x4810, 0x4812,
+       0x477a, 0x477a, 0x1078, 0x12b7, 0x6820, 0xa005, 0x00c0, 0x4782,
+       0x0d7f, 0x007c, 0x0c7e, 0x680c, 0xa065, 0x0040, 0x4791, 0x6807,
+       0x0004, 0x6826, 0x682b, 0x0000, 0x1078, 0x4858, 0x0c7f, 0x0d7f,
+       0x007c, 0x6814, 0xa065, 0x0040, 0x479f, 0x6807, 0x0001, 0x6826,
+       0x682b, 0x0000, 0x1078, 0x4858, 0x0c7f, 0x0d7f, 0x007c, 0x0e7e,
+       0x037e, 0x6a1c, 0xa2f5, 0x0000, 0x0040, 0x480b, 0x704c, 0xa00d,
+       0x0040, 0x47ae, 0x7088, 0xa005, 0x0040, 0x47c6, 0x7054, 0xa075,
+       0x0040, 0x47b7, 0xa20e, 0x0040, 0x480b, 0x0078, 0x47bc, 0x6818,
+       0xa20e, 0x0040, 0x480b, 0x2070, 0x704c, 0xa00d, 0x0040, 0x47ae,
+       0x7088, 0xa005, 0x00c0, 0x47ae, 0x2e00, 0x681e, 0x733c, 0x7038,
+       0xa302, 0x00c8, 0x47ae, 0x1078, 0x5539, 0x0040, 0x480b, 0x8318,
+       0x733e, 0x6112, 0x2e10, 0x621a, 0xa180, 0x0015, 0x2004, 0xa08a,
+       0x199a, 0x0048, 0x47dd, 0x2001, 0x1999, 0x8003, 0x801b, 0x831b,
+       0xa318, 0x6316, 0x037f, 0x0f7e, 0x2c78, 0x71a0, 0xd1bc, 0x0040,
+       0x47ed, 0x2009, 0x0000, 0x0078, 0x47f2, 0xa1e0, 0x2091, 0x2c0c,
+       0xa18c, 0x00ff, 0x2061, 0x0100, 0x619a, 0x1078, 0x4c44, 0x7300,
+       0xc3dd, 0x7302, 0x6807, 0x0002, 0x2f18, 0x6b26, 0x682b, 0x0000,
+       0x781f, 0x0003, 0x7803, 0x0001, 0x7807, 0x0040, 0x0f7f, 0x0e7f,
+       0x0c7f, 0x0d7f, 0x007c, 0x037f, 0x0e7f, 0x0c7f, 0x0078, 0x4809,
+       0x0d7f, 0x007c, 0x0c7e, 0x680c, 0xa065, 0x0040, 0x481e, 0x6807,
+       0x0004, 0x6826, 0x682b, 0x0000, 0x1078, 0x4858, 0x0c7f, 0x0d7f,
+       0x007c, 0x0f7e, 0x0d7e, 0x2069, 0x6f10, 0x6830, 0xa086, 0x0000,
+       0x00c0, 0x483f, 0x6838, 0xa07d, 0x0040, 0x483f, 0x6833, 0x0001,
+       0x683e, 0x6847, 0x0000, 0x127e, 0x0f7e, 0x2091, 0x2200, 0x027f,
+       0x1078, 0x1838, 0x00c0, 0x4842, 0x127f, 0x1078, 0x4ed5, 0x0d7f,
+       0x0f7f, 0x007c, 0x127f, 0x6843, 0x0000, 0x7803, 0x0002, 0x780c,
+       0xa015, 0x0040, 0x4854, 0x6a3a, 0x780f, 0x0000, 0x6833, 0x0000,
+       0x683f, 0x0000, 0x0078, 0x483f, 0x683a, 0x6836, 0x0078, 0x484e,
+       0x601c, 0xa084, 0x000f, 0x1079, 0x485e, 0x007c, 0x4867, 0x4869,
+       0x4b33, 0x4c15, 0x4869, 0x4b33, 0x4c15, 0x4867, 0x4869, 0x1078,
+       0x12b7, 0x157e, 0x137e, 0x147e, 0x0c7e, 0x0f7e, 0x6004, 0xa08a,
+       0x0024, 0x10c8, 0x12b7, 0x6118, 0x2178, 0x79a0, 0xa1f8, 0x2091,
+       0x2f0c, 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0x1079,
+       0x4887, 0x0f7f, 0x0c7f, 0x147f, 0x137f, 0x157f, 0x007c, 0x48ad,
+       0x48ec, 0x4904, 0x494c, 0x4979, 0x4981, 0x49a2, 0x49b3, 0x49c4,
+       0x49cc, 0x49dd, 0x49cc, 0x4a25, 0x49b3, 0x4a55, 0x4a5d, 0x49c4,
+       0x4a5d, 0x4a6e, 0x48ab, 0x48ab, 0x48ab, 0x48ab, 0x48ab, 0x48ab,
+       0x48ab, 0x48ab, 0x48ab, 0x48ab, 0x48ab, 0x48ab, 0x50b8, 0x50cd,
+       0x50f0, 0x5114, 0x49a2, 0x1078, 0x12b7, 0x20a1, 0x020b, 0x1078,
+       0x4a83, 0x20a3, 0x5200, 0x20a3, 0x0000, 0x0d7e, 0x2069, 0x6d51,
+       0x6804, 0xd084, 0x0040, 0x48ce, 0x6828, 0x017e, 0x2069, 0x6d00,
+       0x694c, 0xa106, 0x017f, 0x00c0, 0x48ce, 0x20a3, 0x0000, 0x6030,
+       0xa084, 0x00ff, 0x20a2, 0x0d7f, 0x0078, 0x48d3, 0x0d7f, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x20a9, 0x0004, 0x2099, 0x6d05, 0x53a6,
+       0x20a9, 0x0004, 0x2099, 0x6d01, 0x53a6, 0x20a3, 0x0000, 0x6030,
+       0xa084, 0x00ff, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
+       0x001c, 0x1078, 0x4fd1, 0x007c, 0x20a1, 0x020b, 0x1078, 0x4a83,
+       0x20a3, 0x0500, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x6030, 0xa084,
+       0x00ff, 0x20a2, 0x20a9, 0x0004, 0x2099, 0x6d05, 0x53a6, 0x60c3,
+       0x0010, 0x1078, 0x4fd1, 0x007c, 0x20a1, 0x020b, 0x1078, 0x4a83,
+       0x7818, 0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x00c0, 0x4917,
+       0x20a3, 0x0400, 0x620c, 0xc2b4, 0x620e, 0x0078, 0x4919, 0x20a3,
+       0x0300, 0x20a3, 0x0000, 0x2099, 0x6f00, 0x20a9, 0x0008, 0x53a6,
+       0x20a9, 0x0004, 0x2099, 0x6d05, 0x53a6, 0x20a9, 0x0004, 0x2099,
+       0x6d01, 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x00f0, 0x492c,
+       0x20a9, 0x0008, 0x20a3, 0x0000, 0x00f0, 0x4932, 0x2099, 0x6f08,
+       0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x00f0,
+       0x493d, 0x20a9, 0x000a, 0x20a3, 0x0000, 0x00f0, 0x4943, 0x60c3,
+       0x0074, 0x1078, 0x4fd1, 0x007c, 0x20a1, 0x020b, 0x1078, 0x4a83,
+       0x20a3, 0x2010, 0x20a3, 0x0014, 0x20a3, 0x0800, 0x20a3, 0x2000,
+       0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x0f7e, 0x2079,
+       0x6d51, 0x7904, 0x0f7f, 0xd1ac, 0x00c0, 0x4968, 0xa085, 0x0020,
+       0xd1a4, 0x0040, 0x496d, 0xa085, 0x0010, 0xa085, 0x0002, 0x20a2,
+       0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x4fd1,
+       0x007c, 0x20a1, 0x020b, 0x1078, 0x4a83, 0x20a3, 0x5000, 0x0078,
+       0x4919, 0x20a1, 0x020b, 0x1078, 0x4a83, 0x20a3, 0x2110, 0x20a3,
+       0x0014, 0x20a3, 0x0800, 0x20a3, 0x2000, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+       0x0022, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078,
+       0x4fd1, 0x007c, 0x20a1, 0x020b, 0x1078, 0x4afa, 0x20a3, 0x0200,
+       0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0004,
+       0x1078, 0x4fd1, 0x007c, 0x20a1, 0x020b, 0x1078, 0x4afa, 0x20a3,
+       0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3,
+       0x0008, 0x1078, 0x4fd1, 0x007c, 0x20a1, 0x020b, 0x1078, 0x4afa,
+       0x20a3, 0x0200, 0x0078, 0x4919, 0x20a1, 0x020b, 0x1078, 0x4afa,
+       0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003, 0x7810, 0x20a2,
+       0x60c3, 0x0008, 0x1078, 0x4fd1, 0x007c, 0x0d7e, 0x20a1, 0x020b,
+       0x1078, 0x4afa, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, 0x0800,
+       0x7818, 0x2068, 0x6894, 0xa086, 0x0014, 0x00c0, 0x4a03, 0x6998,
+       0xa184, 0xc000, 0x00c0, 0x49ff, 0xd1ec, 0x0040, 0x49fb, 0x20a3,
+       0x2100, 0x0078, 0x4a05, 0x20a3, 0x0100, 0x0078, 0x4a05, 0x20a3,
+       0x0400, 0x0078, 0x4a05, 0x20a3, 0x0700, 0xa006, 0x20a2, 0x20a2,
+       0x20a2, 0x20a2, 0x20a2, 0x0f7e, 0x2079, 0x6d51, 0x7904, 0x0f7f,
+       0xd1ac, 0x00c0, 0x4a15, 0xa085, 0x0020, 0xd1a4, 0x0040, 0x4a1a,
+       0xa085, 0x0010, 0xa085, 0x0002, 0x20a2, 0x20a2, 0x20a2, 0x60c3,
+       0x0014, 0x1078, 0x4fd1, 0x0d7f, 0x007c, 0x20a1, 0x020b, 0x1078,
+       0x4afa, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, 0x0000, 0x6018,
+       0x0d7e, 0x2068, 0x6804, 0x0d7f, 0xa084, 0x00ff, 0xa086, 0x0006,
+       0x0040, 0x4a3e, 0x20a3, 0x0400, 0x0078, 0x4a40, 0x20a3, 0x0100,
+       0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
+       0x60c3, 0x0014, 0x1078, 0x4fd1, 0x007c, 0x20a1, 0x020b, 0x1078,
+       0x4afa, 0x20a3, 0x0200, 0x0078, 0x48b3, 0x20a1, 0x020b, 0x1078,
+       0x4afa, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3,
+       0x2a00, 0x60c3, 0x0008, 0x1078, 0x4fd1, 0x007c, 0x20e1, 0x9080,
+       0x20e1, 0x4000, 0x20a1, 0x020b, 0x1078, 0x4afa, 0x20a3, 0x0100,
+       0x20a3, 0x0000, 0x20a3, 0x000b, 0x20a3, 0x0000, 0x60c3, 0x0008,
+       0x1078, 0x4fd1, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000,
+       0x7818, 0xa080, 0x0028, 0x2014, 0xa286, 0x007e, 0x00c0, 0x4a96,
+       0x20a3, 0x22ff, 0x20a3, 0xfffe, 0x0078, 0x4ac4, 0xa286, 0x007f,
+       0x00c0, 0x4aa1, 0x0d7e, 0x20a3, 0x22ff, 0x20a3, 0xfffd, 0x0078,
+       0x4ab8, 0xd2bc, 0x0040, 0x4ac0, 0xa286, 0x0080, 0x0d7e, 0x00c0,
+       0x4aaf, 0x20a3, 0x22ff, 0x20a3, 0xfffc, 0x0078, 0x4ab8, 0xa2e8,
+       0x6e00, 0x2d6c, 0x6810, 0xa085, 0x2200, 0x20a2, 0x6814, 0x20a2,
+       0x2069, 0x6d19, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x4ac8,
+       0x20a3, 0x2200, 0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2,
+       0x20a3, 0x0129, 0x20a3, 0x0000, 0x1078, 0x4fc0, 0x22a2, 0x20a3,
+       0x0000, 0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000,
+       0x027f, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a3,
+       0x02ff, 0x2011, 0xfffc, 0x22a2, 0x0d7e, 0x2069, 0x6d19, 0x2da6,
+       0x8d68, 0x2da6, 0x0d7f, 0x20a3, 0x2029, 0x20a3, 0x0000, 0x0078,
+       0x4acc, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0xfc02, 0x20a3,
+       0x0000, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818,
+       0xa080, 0x0028, 0x2004, 0xa092, 0x007e, 0x0048, 0x4b19, 0x0d7e,
+       0xa0e8, 0x6e00, 0x2d6c, 0x6810, 0xa085, 0x2300, 0x20a2, 0x6814,
+       0x20a2, 0x2069, 0x6d19, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078,
+       0x4b21, 0x20a3, 0x2300, 0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230,
+       0x22a2, 0x20a3, 0x0198, 0x20a3, 0x0000, 0x1078, 0x4fc0, 0x22a2,
+       0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x027f, 0x007c, 0x0c7e, 0x0f7e, 0x6004, 0xa08a, 0x0025,
+       0x1048, 0x12b7, 0xa08a, 0x002c, 0x10c8, 0x12b7, 0x6118, 0x2178,
+       0x79a0, 0xa1f8, 0x2091, 0x2f0c, 0xa18c, 0x00ff, 0x2c78, 0x2061,
+       0x0100, 0x619a, 0xa082, 0x0025, 0x1079, 0x4b51, 0x0f7f, 0x0c7f,
+       0x007c, 0x4b5a, 0x4b65, 0x4b7f, 0x4b58, 0x4b58, 0x4b58, 0x4b5a,
+       0x1078, 0x12b7, 0x147e, 0x20a1, 0x020b, 0x1078, 0x4b8e, 0x60c3,
+       0x0000, 0x1078, 0x4fd1, 0x147f, 0x007c, 0x147e, 0x20a1, 0x020b,
+       0x1078, 0x4bbb, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2,
+       0x2fa2, 0x20a3, 0x0000, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x60c3, 0x000c, 0x1078, 0x4fd1, 0x147f, 0x007c, 0x147e,
+       0x20a1, 0x020b, 0x1078, 0x4be8, 0x20a3, 0x0003, 0x20a3, 0x0300,
+       0x60c3, 0x0004, 0x1078, 0x4fd1, 0x147f, 0x007c, 0x027e, 0x20e1,
+       0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa092,
+       0x007e, 0x0048, 0x4bad, 0x0d7e, 0xa0e8, 0x6e00, 0x2d6c, 0x6810,
+       0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x6d19, 0x2da6,
+       0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x4bb5, 0x20a3, 0x8100, 0x6298,
+       0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0009, 0x20a3,
+       0x0000, 0x0078, 0x4acc, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000,
+       0x7818, 0xa080, 0x0028, 0x2004, 0xa092, 0x007e, 0x0048, 0x4bda,
+       0x0d7e, 0xa0e8, 0x6e00, 0x2d6c, 0x6810, 0xa085, 0x8400, 0x20a2,
+       0x6814, 0x20a2, 0x2069, 0x6d19, 0x2da6, 0x8d68, 0x2da6, 0x0d7f,
+       0x0078, 0x4be2, 0x20a3, 0x8400, 0x6298, 0x22a2, 0x20a3, 0x0000,
+       0x6230, 0x22a2, 0x20a3, 0x00d1, 0x20a3, 0x0000, 0x0078, 0x4b25,
+       0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
+       0x2004, 0xa092, 0x007e, 0x0048, 0x4c07, 0x0d7e, 0xa0e8, 0x6e00,
+       0x2d6c, 0x6810, 0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x2069,
+       0x6d19, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x4c0f, 0x20a3,
+       0x8500, 0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3,
+       0x00d1, 0x20a3, 0x0000, 0x0078, 0x4b25, 0x0c7e, 0x0f7e, 0x2c78,
+       0x7804, 0xa08a, 0x0040, 0x1048, 0x12b7, 0xa08a, 0x004f, 0x10c8,
+       0x12b7, 0x7918, 0x2160, 0x61a0, 0xa1e0, 0x2091, 0x2c0c, 0xa18c,
+       0x00ff, 0x2061, 0x0100, 0x619a, 0xa082, 0x0040, 0x1079, 0x4c33,
+       0x0f7f, 0x0c7f, 0x007c, 0x4c44, 0x4d28, 0x4cd0, 0x4e50, 0x4c42,
+       0x4c42, 0x4c42, 0x4c42, 0x4c42, 0x4c42, 0x4c42, 0x528d, 0x529e,
+       0x52af, 0x52c0, 0x1078, 0x12b7, 0x0d7e, 0x157e, 0x147e, 0x20a1,
+       0x020b, 0x1078, 0x4c93, 0x7910, 0x2168, 0x6944, 0xa18c, 0x00ff,
+       0x21a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x694c, 0xa184, 0x0006,
+       0x8004, 0x20a2, 0xd1ac, 0x0040, 0x4c61, 0x20a3, 0x0002, 0x0078,
+       0x4c6d, 0xd1b4, 0x0040, 0x4c68, 0x20a3, 0x0001, 0x0078, 0x4c6d,
+       0x20a3, 0x0000, 0x2230, 0x0078, 0x4c6f, 0x6a80, 0x6e7c, 0x20a9,
+       0x0008, 0xad80, 0x0017, 0x200c, 0x810f, 0x21a2, 0x8000, 0x00f0,
+       0x4c73, 0x22a2, 0x26a2, 0x60c3, 0x0020, 0x20e1, 0x9080, 0x6014,
+       0xa084, 0x0004, 0xa085, 0x0009, 0x6016, 0x2001, 0x6f2c, 0x2003,
+       0x07d0, 0x2001, 0x6f2b, 0x2003, 0x0009, 0x1078, 0x14e4, 0x147f,
+       0x157f, 0x0d7f, 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7a18,
+       0xa280, 0x0023, 0x2014, 0x8210, 0xa294, 0x00ff, 0x2202, 0x8217,
+       0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x4cb9, 0x0d7e,
+       0xa0e8, 0x6e00, 0x2d6c, 0x6810, 0xa085, 0x0600, 0x20a2, 0x6814,
+       0x20a2, 0x2069, 0x6d19, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078,
+       0x4cc1, 0x20a3, 0x0600, 0x6198, 0x21a2, 0x20a3, 0x0000, 0x6130,
+       0x21a2, 0x20a3, 0x0829, 0x20a3, 0x0000, 0x22a2, 0x20a3, 0x0000,
+       0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x007c,
+       0x0d7e, 0x157e, 0x137e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x4cf0,
+       0x7810, 0x2068, 0x6860, 0x20a2, 0x685c, 0x20a2, 0x6880, 0x20a2,
+       0x687c, 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x60c3,
+       0x000c, 0x1078, 0x4fd1, 0x147f, 0x137f, 0x157f, 0x0d7f, 0x007c,
+       0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
+       0x2004, 0xd0bc, 0x0040, 0x4d0e, 0x0d7e, 0xa0e8, 0x6e00, 0x2d6c,
+       0x6810, 0xa085, 0x0500, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x6d19,
+       0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x4d16, 0x20a3, 0x0500,
+       0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0889,
+       0x20a3, 0x0000, 0x1078, 0x4fc0, 0x22a2, 0x20a3, 0x0000, 0x7a08,
+       0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c,
+       0x0d7e, 0x157e, 0x137e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x4e18,
+       0x7810, 0x2068, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2,
+       0x7810, 0xa084, 0xf000, 0x00c0, 0x4d45, 0x7810, 0xa084, 0x0700,
+       0x8007, 0x1079, 0x4d4d, 0x0078, 0x4d48, 0xa006, 0x1079, 0x4d4d,
+       0x147f, 0x137f, 0x157f, 0x0d7f, 0x007c, 0x4d57, 0x4db9, 0x4dbd,
+       0x4de0, 0x4ded, 0x4dff, 0x4e03, 0x4d55, 0x1078, 0x12b7, 0x017e,
+       0x037e, 0x694c, 0xa18c, 0x0003, 0xa186, 0x0000, 0x00c0, 0x4d6a,
+       0x6b78, 0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x037f, 0x017f,
+       0x0078, 0x4de4, 0xa186, 0x0001, 0x00c0, 0x4db4, 0x6b78, 0x23a2,
+       0x6868, 0x20a2, 0x6864, 0x20a2, 0x22a2, 0x6874, 0x20a2, 0x22a2,
+       0x687c, 0x20a2, 0x2009, 0x0018, 0xa384, 0x0300, 0x0040, 0x4db3,
+       0xd3c4, 0x0040, 0x4d85, 0x687c, 0xa108, 0xd3cc, 0x0040, 0x4d8a,
+       0x6874, 0xa108, 0x157e, 0x20a9, 0x000d, 0xad80, 0x0020, 0x201c,
+       0x831f, 0x23a2, 0x8000, 0x00f0, 0x4d8f, 0x157f, 0x22a2, 0x22a2,
+       0x22a2, 0xa184, 0x0003, 0x0040, 0x4db3, 0x20a1, 0x020b, 0x20e1,
+       0x9080, 0x20e1, 0x4000, 0x20a3, 0x0700, 0x6298, 0x22a2, 0x20a3,
+       0x0000, 0x6230, 0x22a2, 0x20a3, 0x0898, 0x20a2, 0x1078, 0x4fc0,
+       0x22a2, 0x20a3, 0x0000, 0x61c2, 0x037f, 0x017f, 0x1078, 0x4fd1,
+       0x007c, 0x20a3, 0x0008, 0x0078, 0x4de2, 0x20a3, 0x0302, 0x22a2,
+       0x22a2, 0x22a2, 0x20a3, 0x0012, 0x22a2, 0x20a3, 0x0008, 0x22a2,
+       0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x7000, 0x20a3, 0x0500, 0x22a2,
+       0x20a3, 0x000a, 0x22a2, 0x22a2, 0x20a3, 0x2500, 0x22a2, 0x22a2,
+       0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0032, 0x1078, 0x4fd1, 0x007c,
+       0x20a3, 0x0028, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2,
+       0x60c3, 0x0018, 0x1078, 0x4fd1, 0x007c, 0x20a3, 0x0100, 0x22a2,
+       0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x0008, 0x22a2, 0x22a2,
+       0x22a2, 0x22a2, 0x60c3, 0x0020, 0x1078, 0x4fd1, 0x007c, 0x20a3,
+       0x0008, 0x0078, 0x4de2, 0x037e, 0x7b10, 0xa384, 0xff00, 0x7812,
+       0xa384, 0x00ff, 0x8001, 0x00c0, 0x4e11, 0x22a2, 0x037f, 0x0078,
+       0x4de2, 0x20a3, 0x0800, 0x22a2, 0x20a2, 0x037f, 0x0078, 0x4de4,
+       0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
+       0x2004, 0xd0bc, 0x0040, 0x4e36, 0x0d7e, 0xa0e8, 0x6e00, 0x2d6c,
+       0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x6d19,
+       0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x4e3e, 0x20a3, 0x0700,
+       0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0898,
+       0x20a3, 0x0000, 0x1078, 0x4fc0, 0x22a2, 0x20a3, 0x0000, 0x7a08,
+       0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c,
+       0x0d7e, 0x157e, 0x137e, 0x147e, 0x017e, 0x037e, 0x7810, 0xa084,
+       0x0700, 0x8007, 0x1079, 0x4e63, 0x037f, 0x017f, 0x147f, 0x137f,
+       0x157f, 0x0d7f, 0x007c, 0x4e6b, 0x4e6b, 0x4e6d, 0x4e6b, 0x4e6b,
+       0x4e6b, 0x4e92, 0x4e6b, 0x1078, 0x12b7, 0x7910, 0xa18c, 0xf8ff,
+       0xa18d, 0x0600, 0x7912, 0x20a1, 0x020b, 0x2009, 0x0003, 0x1078,
+       0x4e9c, 0x0d7e, 0x2069, 0x6d51, 0x6804, 0xd0bc, 0x0040, 0x4e87,
+       0x682c, 0xa084, 0x00ff, 0x8007, 0x20a2, 0x0078, 0x4e89, 0x20a3,
+       0x3f00, 0x0d7f, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0001, 0x1078,
+       0x4fd1, 0x007c, 0x20a1, 0x020b, 0x2009, 0x0003, 0x1078, 0x4e9c,
+       0x20a3, 0x7f00, 0x0078, 0x4e8a, 0x027e, 0x20e1, 0x9080, 0x20e1,
+       0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x4eba,
+       0x0d7e, 0xa0e8, 0x6e00, 0x2d6c, 0x6810, 0xa085, 0x0100, 0x20a2,
+       0x6814, 0x20a2, 0x2069, 0x6d19, 0x2da6, 0x8d68, 0x2da6, 0x0d7f,
+       0x0078, 0x4ec2, 0x20a3, 0x0100, 0x6298, 0x22a2, 0x20a3, 0x0000,
+       0x6230, 0x22a2, 0x20a3, 0x0888, 0xa18d, 0x0008, 0x21a2, 0x1078,
+       0x4fc0, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x0e7e, 0x0d7e, 0x0c7e,
+       0x057e, 0x047e, 0x037e, 0x2061, 0x0100, 0x2071, 0x6d00, 0x6130,
+       0x7818, 0x2068, 0x68a0, 0x2028, 0xd0bc, 0x00c0, 0x4eee, 0xa080,
+       0x2091, 0x2014, 0xa294, 0x00ff, 0x0078, 0x4ef2, 0x6910, 0x6a14,
+       0x7364, 0x7468, 0x781c, 0xa086, 0x0006, 0x0040, 0x4f3d, 0xd5bc,
+       0x0040, 0x4f02, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e,
+       0x0078, 0x4f08, 0x6063, 0x0100, 0x6266, 0x606b, 0x0000, 0x616e,
+       0x6073, 0x0809, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084, 0x00ff,
+       0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082, 0x7808,
+       0x6086, 0x7810, 0x2070, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c,
+       0x60c6, 0x7008, 0x60ca, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af,
+       0x95d5, 0x60d7, 0x0000, 0xa582, 0x0080, 0x0048, 0x4f31, 0x2011,
+       0x0000, 0x629e, 0x6017, 0x0016, 0x1078, 0x4151, 0x037f, 0x047f,
+       0x057f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x7810, 0x2070, 0x704c,
+       0xa084, 0x0003, 0xa086, 0x0002, 0x0040, 0x4f83, 0xd5bc, 0x0040,
+       0x4f51, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x0078,
+       0x4f57, 0x6063, 0x0100, 0x6266, 0x606b, 0x0000, 0x616e, 0x6073,
+       0x0880, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e,
+       0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086, 0x7808, 0x6082,
+       0x7060, 0x608a, 0x705c, 0x608e, 0x7080, 0x60c6, 0x707c, 0x60ca,
+       0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000,
+       0xa582, 0x0080, 0x0048, 0x4f7e, 0x2011, 0x0000, 0x629e, 0x6017,
+       0x0012, 0x0078, 0x4f34, 0xd5bc, 0x0040, 0x4f8e, 0xa185, 0x0700,
+       0x20a2, 0x6266, 0x636a, 0x646e, 0x0078, 0x4f94, 0x6063, 0x0700,
+       0x6266, 0x606b, 0x0000, 0x616e, 0x6073, 0x0898, 0x6077, 0x0000,
+       0x688c, 0x8000, 0xa084, 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f,
+       0x0000, 0x2f00, 0x6086, 0x7808, 0x6082, 0x7014, 0x608a, 0x7010,
+       0x608e, 0x700c, 0x60c6, 0x7008, 0x60ca, 0x686c, 0x60ce, 0x60ab,
+       0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xa582, 0x0080, 0x0048,
+       0x4fbb, 0x2011, 0x0000, 0x629e, 0x6017, 0x0016, 0x0078, 0x4f34,
+       0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, 0xa294, 0x00ff, 0x2202,
+       0x8217, 0x007c, 0x0d7e, 0x2069, 0x6f10, 0x6843, 0x0001, 0x0d7f,
+       0x007c, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x1078,
+       0x4fdc, 0x1078, 0x4143, 0x007c, 0x007e, 0x6014, 0xa084, 0x0004,
+       0xa085, 0x0009, 0x6016, 0x007f, 0x007c, 0x007e, 0x0c7e, 0x2061,
+       0x0100, 0x6014, 0xa084, 0x0004, 0xa085, 0x0008, 0x6016, 0x0c7f,
+       0x007f, 0x007c, 0x0c7e, 0x0d7e, 0x017e, 0x027e, 0x1078, 0x414c,
+       0x2061, 0x0100, 0x2069, 0x0140, 0x6904, 0xa194, 0x4000, 0x0040,
+       0x503a, 0x1078, 0x4fe5, 0x6803, 0x1000, 0x6803, 0x0000, 0x0c7e,
+       0x2061, 0x6f10, 0x6128, 0xa192, 0x0002, 0x00c8, 0x5027, 0x8108,
+       0x612a, 0x613c, 0x0c7f, 0x81ff, 0x0040, 0x5035, 0x1078, 0x4143,
+       0xa188, 0x0007, 0x210c, 0xa18e, 0x0006, 0x00c0, 0x5023, 0x6017,
+       0x0012, 0x0078, 0x5035, 0x1078, 0x4fdc, 0x0078, 0x5035, 0x6124,
+       0xa1e5, 0x0000, 0x0040, 0x5032, 0x1078, 0x6c76, 0x2009, 0x0014,
+       0x1078, 0x5591, 0x0c7f, 0x0078, 0x5035, 0x027f, 0x017f, 0x0d7f,
+       0x0c7f, 0x007c, 0x1078, 0x31cb, 0x0078, 0x5035, 0x0c7e, 0x0d7e,
+       0x0e7e, 0x017e, 0x027e, 0x1078, 0x415a, 0x2071, 0x6f10, 0x713c,
+       0x81ff, 0x0040, 0x5079, 0x2061, 0x0100, 0x2069, 0x0140, 0x6904,
+       0x017e, 0x017f, 0xa194, 0x4000, 0x0040, 0x507f, 0x6017, 0x0010,
+       0x7144, 0xa192, 0x0002, 0x00c8, 0x5071, 0x8108, 0x7146, 0x1078,
+       0x4151, 0x713c, 0xa188, 0x0007, 0x210c, 0xa18e, 0x0006, 0x00c0,
+       0x506d, 0x6017, 0x0012, 0x0078, 0x5079, 0x6017, 0x0016, 0x0078,
+       0x5079, 0x1078, 0x6c76, 0x2009, 0x004a, 0x1078, 0x5591, 0x0078,
+       0x5079, 0x027f, 0x017f, 0x0e7f, 0x0d7f, 0x0c7f, 0x007c, 0x1078,
+       0x4151, 0x0078, 0x5079, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x057e,
+       0x047e, 0x007e, 0x127e, 0x2091, 0x8000, 0x6018, 0x2068, 0x6ca0,
+       0x2071, 0x6f10, 0x7018, 0x2068, 0x8dff, 0x0040, 0x50af, 0x68a0,
+       0xa406, 0x0040, 0x509f, 0x6854, 0x2068, 0x0078, 0x5094, 0x6010,
+       0x2060, 0x643c, 0x6540, 0x6644, 0xa6b4, 0x000f, 0x2d60, 0x1078,
+       0x3522, 0x0040, 0x50af, 0x1078, 0x5374, 0xa085, 0x0001, 0x127f,
+       0x007f, 0x047f, 0x057f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c,
+       0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x4a83, 0x20a3, 0x0f00,
+       0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2, 0x60c3, 0x0008,
+       0x1078, 0x4fd1, 0x147f, 0x157f, 0x007c, 0x157e, 0x147e, 0x20a1,
+       0x020b, 0x1078, 0x4afa, 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a9,
+       0x0006, 0x2011, 0x6d40, 0x2019, 0x6d40, 0x23a6, 0x22a6, 0xa398,
+       0x0002, 0xa290, 0x0002, 0x00f0, 0x50dd, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x60c3, 0x001c, 0x1078, 0x4fd1, 0x147f, 0x157f, 0x007c,
+       0x157e, 0x147e, 0x017e, 0x027e, 0x20a1, 0x020b, 0x1078, 0x4ada,
+       0x1078, 0x4af1, 0x7810, 0x007e, 0xa080, 0x0015, 0x2098, 0x7808,
+       0xa088, 0x0002, 0x21a8, 0x53a6, 0xa080, 0x0004, 0x8003, 0x60c2,
+       0x007f, 0xa080, 0x0001, 0x2004, 0x7812, 0x1078, 0x4fd1, 0x027f,
+       0x017f, 0x147f, 0x157f, 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b,
+       0x1078, 0x4a83, 0x20a3, 0x6200, 0x20a3, 0x0000, 0x20a3, 0x0000,
+       0x7808, 0x20a2, 0x60c3, 0x0008, 0x1078, 0x4fd1, 0x147f, 0x157f,
+       0x007c, 0x0e7e, 0x0c7e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071,
+       0x6f10, 0x700c, 0x2060, 0x8cff, 0x0040, 0x513f, 0x600c, 0x007e,
+       0x1078, 0x556a, 0x1078, 0x5374, 0x0c7f, 0x0078, 0x5133, 0x700f,
+       0x0000, 0x700b, 0x0000, 0x127f, 0x007f, 0x0c7f, 0x0e7f, 0x007c,
+       0x127e, 0x157e, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x027e, 0x017e,
+       0x007e, 0x2091, 0x8000, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071,
+       0x6f10, 0x7024, 0x2060, 0x8cff, 0x0040, 0x5198, 0x1078, 0x4fe5,
+       0x68c3, 0x0000, 0x1078, 0x414c, 0x2009, 0x0013, 0x1078, 0x5591,
+       0x20a9, 0x01f4, 0x6824, 0xd094, 0x0040, 0x517b, 0x6827, 0x0004,
+       0x7804, 0xa084, 0x4000, 0x0040, 0x518d, 0x7803, 0x1000, 0x7803,
+       0x0000, 0x0078, 0x518d, 0xd084, 0x0040, 0x5182, 0x6827, 0x0001,
+       0x0078, 0x5184, 0x00f0, 0x516a, 0x7804, 0xa084, 0x1000, 0x0040,
+       0x518d, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824, 0x007f, 0x017f,
+       0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f, 0x127f, 0x007c,
+       0x2001, 0x6d00, 0x2004, 0xa096, 0x0001, 0x0040, 0x51d0, 0xa096,
+       0x0004, 0x0040, 0x51d0, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011,
+       0x318e, 0x1078, 0x40d1, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0040,
+       0x51be, 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x0040, 0x51d0,
+       0x7803, 0x1000, 0x7803, 0x0000, 0x0078, 0x51d0, 0xd084, 0x0040,
+       0x51c5, 0x6827, 0x0001, 0x0078, 0x51c7, 0x00f0, 0x51ad, 0x7804,
+       0xa084, 0x1000, 0x0040, 0x51d0, 0x7803, 0x0100, 0x7803, 0x0000,
+       0x007f, 0x017f, 0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f,
+       0x127f, 0x007c, 0x127e, 0x157e, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e,
+       0x027e, 0x017e, 0x007e, 0x2091, 0x8000, 0x2069, 0x0100, 0x2079,
+       0x0140, 0x2071, 0x6f10, 0x703c, 0x2060, 0x8cff, 0x0040, 0x5228,
+       0x6817, 0x0010, 0x68cb, 0x0000, 0x68c7, 0x0000, 0x1078, 0x415a,
+       0x1078, 0x1a20, 0xa39d, 0x0000, 0x00c0, 0x5202, 0x2009, 0x0049,
+       0x1078, 0x5591, 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0040, 0x5215,
+       0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x0040, 0x5227, 0x7803,
+       0x1000, 0x7803, 0x0000, 0x0078, 0x5227, 0xd094, 0x0040, 0x521c,
+       0x6827, 0x0002, 0x0078, 0x521e, 0x00f0, 0x5204, 0x7804, 0xa084,
+       0x1000, 0x0040, 0x5227, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824,
+       0x007f, 0x017f, 0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f,
+       0x127f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x2069, 0x6f10,
+       0x6a06, 0x127f, 0x0d7f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000,
+       0x2069, 0x6f10, 0x6a32, 0x127f, 0x0d7f, 0x007c, 0x0f7e, 0x0e7e,
+       0x0c7e, 0x067e, 0x007e, 0x127e, 0x2071, 0x6f10, 0x7614, 0x2660,
+       0x2678, 0x2091, 0x8000, 0x8cff, 0x0040, 0x5286, 0x601c, 0xa206,
+       0x00c0, 0x5281, 0x7014, 0xac36, 0x00c0, 0x5260, 0x660c, 0x7616,
+       0x7010, 0xac36, 0x00c0, 0x526e, 0x2c00, 0xaf36, 0x0040, 0x526c,
+       0x2f00, 0x7012, 0x0078, 0x526e, 0x7013, 0x0000, 0x660c, 0x067e,
+       0x2c00, 0xaf06, 0x0040, 0x5277, 0x7e0e, 0x0078, 0x5278, 0x2678,
+       0x600f, 0x0000, 0x1078, 0x6283, 0x1078, 0x5374, 0x0c7f, 0x0078,
+       0x5253, 0x2c78, 0x600c, 0x2060, 0x0078, 0x5253, 0x127f, 0x007f,
+       0x067f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0x157e, 0x147e, 0x20a1,
+       0x020b, 0x1078, 0x4c93, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2,
+       0x20a2, 0x20a2, 0x20a3, 0x4000, 0x0078, 0x52cf, 0x157e, 0x147e,
+       0x20a1, 0x020b, 0x1078, 0x4c93, 0x7810, 0x20a2, 0xa006, 0x20a2,
+       0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x2000, 0x0078, 0x52cf, 0x157e,
+       0x147e, 0x20a1, 0x020b, 0x1078, 0x4c93, 0x7810, 0x20a2, 0xa006,
+       0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0400, 0x0078, 0x52cf,
+       0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x4c93, 0x7810, 0x20a2,
+       0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0200, 0x1078,
+       0x537f, 0x60c3, 0x0020, 0x1078, 0x4fd1, 0x147f, 0x157f, 0x007c,
+       0x127e, 0x0c7e, 0x2091, 0x8000, 0x2061, 0x0100, 0x6120, 0xd1b4,
+       0x00c0, 0x52e7, 0xd1bc, 0x00c0, 0x5331, 0x0078, 0x5371, 0x2009,
+       0x017f, 0x200b, 0x00a1, 0x157e, 0x007e, 0x0d7e, 0x2069, 0x0140,
+       0x20a9, 0x001e, 0x2009, 0x0169, 0x6804, 0xa084, 0x4000, 0x0040,
+       0x5328, 0x6020, 0xd0b4, 0x0040, 0x5328, 0x6024, 0xd094, 0x00c0,
+       0x5328, 0x2104, 0xa084, 0x000f, 0xa086, 0x0004, 0x00c0, 0x5328,
+       0x00f0, 0x52f4, 0x027e, 0x6198, 0xa18c, 0x00ff, 0x8107, 0x6130,
+       0xa18c, 0x00ff, 0xa10d, 0x6088, 0x628c, 0x618e, 0x608b, 0xbc91,
+       0x6043, 0x0001, 0x6043, 0x0000, 0x608a, 0x628e, 0x6024, 0xd094,
+       0x00c0, 0x5327, 0x6a04, 0xa294, 0x4000, 0x00c0, 0x531e, 0x027f,
+       0x0d7f, 0x007f, 0x157f, 0x2009, 0x017f, 0x200b, 0x0000, 0x0078,
+       0x5371, 0x2009, 0x017f, 0x200b, 0x00a1, 0x157e, 0x007e, 0x0d7e,
+       0x2069, 0x0140, 0x20a9, 0x001e, 0x2009, 0x0169, 0x6804, 0xa084,
+       0x4000, 0x0040, 0x536a, 0x6020, 0xd0bc, 0x0040, 0x536a, 0x2104,
+       0xa084, 0x000f, 0xa086, 0x0004, 0x00c0, 0x536a, 0x00f0, 0x533e,
+       0x027e, 0x6164, 0xa18c, 0x00ff, 0x8107, 0x6130, 0xa18c, 0x00ff,
+       0xa10d, 0x6088, 0x628c, 0x608b, 0xbc91, 0x618e, 0x6043, 0x0001,
+       0x6043, 0x0000, 0x608a, 0x628e, 0x6a04, 0xa294, 0x4000, 0x00c0,
+       0x5364, 0x027f, 0x0d7f, 0x007f, 0x157f, 0x2009, 0x017f, 0x200b,
+       0x0000, 0x0c7f, 0x127f, 0x007c, 0x0e7e, 0x2071, 0x6f10, 0x7020,
+       0xa005, 0x0040, 0x537d, 0x8001, 0x7022, 0x0e7f, 0x007c, 0x20a9,
+       0x0008, 0x20a2, 0x00f0, 0x5381, 0x20a2, 0x20a2, 0x007c, 0x0f7e,
+       0x0e7e, 0x0d7e, 0x0c7e, 0x077e, 0x067e, 0x007e, 0x127e, 0x2091,
+       0x8000, 0x2071, 0x6f10, 0x7614, 0x2660, 0x2678, 0x2039, 0x0001,
+       0x87ff, 0x0040, 0x5417, 0x8cff, 0x0040, 0x5417, 0x601c, 0xa086,
+       0x0006, 0x00c0, 0x5412, 0x88ff, 0x0040, 0x53ae, 0x2800, 0xac06,
+       0x00c0, 0x5412, 0x2039, 0x0000, 0x0078, 0x53b2, 0x6018, 0xa206,
+       0x00c0, 0x5412, 0x7024, 0xac06, 0x00c0, 0x53e0, 0x2069, 0x0100,
+       0x68c0, 0xa005, 0x0040, 0x53db, 0x6817, 0x0008, 0x68c3, 0x0000,
+       0x1078, 0x54a4, 0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04,
+       0xa384, 0x1000, 0x0040, 0x53d0, 0x6803, 0x0100, 0x6803, 0x0000,
+       0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x53d8, 0x6827, 0x0001,
+       0x037f, 0x0078, 0x53e0, 0x6003, 0x0009, 0x630a, 0x0078, 0x5412,
+       0x7014, 0xac36, 0x00c0, 0x53e6, 0x660c, 0x7616, 0x7010, 0xac36,
+       0x00c0, 0x53f4, 0x2c00, 0xaf36, 0x0040, 0x53f2, 0x2f00, 0x7012,
+       0x0078, 0x53f4, 0x7013, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06,
+       0x0040, 0x53fd, 0x7e0e, 0x0078, 0x53fe, 0x2678, 0x600f, 0x0000,
+       0x6010, 0x2068, 0x1078, 0x6120, 0x0040, 0x5408, 0x1078, 0x6bb3,
+       0x1078, 0x6283, 0x1078, 0x5374, 0x88ff, 0x00c0, 0x5421, 0x0c7f,
+       0x0078, 0x5398, 0x2c78, 0x600c, 0x2060, 0x0078, 0x5398, 0xa006,
+       0x127f, 0x007f, 0x067f, 0x077f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f,
+       0x007c, 0x6017, 0x0000, 0x0c7f, 0xa8c5, 0x0001, 0x0078, 0x5418,
+       0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x027e, 0x007e, 0x127e,
+       0x2091, 0x8000, 0x2071, 0x6f10, 0x7638, 0x2660, 0x2678, 0x8cff,
+       0x0040, 0x5493, 0x601c, 0xa086, 0x0006, 0x00c0, 0x548e, 0x88ff,
+       0x0040, 0x5448, 0x2800, 0xac06, 0x00c0, 0x548e, 0x0078, 0x544c,
+       0x6018, 0xa206, 0x00c0, 0x548e, 0x703c, 0xac06, 0x00c0, 0x545e,
+       0x037e, 0x2019, 0x0001, 0x1078, 0x51da, 0x7033, 0x0000, 0x703f,
+       0x0000, 0x7043, 0x0000, 0x7047, 0x0000, 0x037f, 0x7038, 0xac36,
+       0x00c0, 0x5464, 0x660c, 0x763a, 0x7034, 0xac36, 0x00c0, 0x5472,
+       0x2c00, 0xaf36, 0x0040, 0x5470, 0x2f00, 0x7036, 0x0078, 0x5472,
+       0x7037, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, 0x547b,
+       0x7e0e, 0x0078, 0x547c, 0x2678, 0x600f, 0x0000, 0x6010, 0x2068,
+       0x1078, 0x6120, 0x0040, 0x5486, 0x1078, 0x6bb3, 0x1078, 0x6283,
+       0x88ff, 0x00c0, 0x549d, 0x0c7f, 0x0078, 0x5437, 0x2c78, 0x600c,
+       0x2060, 0x0078, 0x5437, 0xa006, 0x127f, 0x007f, 0x027f, 0x067f,
+       0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x6017, 0x0000, 0x0c7f,
+       0xa8c5, 0x0001, 0x0078, 0x5494, 0x0e7e, 0x2071, 0x6f10, 0x2001,
+       0x6d00, 0x2004, 0xa086, 0x0002, 0x00c0, 0x54b2, 0x7007, 0x0005,
+       0x0078, 0x54b4, 0x7007, 0x0000, 0x0e7f, 0x007c, 0x0f7e, 0x0e7e,
+       0x0c7e, 0x067e, 0x027e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071,
+       0x6f10, 0x2c10, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0040, 0x54f4,
+       0x2200, 0xac06, 0x00c0, 0x54ef, 0x7038, 0xac36, 0x00c0, 0x54d2,
+       0x660c, 0x763a, 0x7034, 0xac36, 0x00c0, 0x54e0, 0x2c00, 0xaf36,
+       0x0040, 0x54de, 0x2f00, 0x7036, 0x0078, 0x54e0, 0x7037, 0x0000,
+       0x660c, 0x2c00, 0xaf06, 0x0040, 0x54e8, 0x7e0e, 0x0078, 0x54e9,
+       0x2678, 0x600f, 0x0000, 0xa085, 0x0001, 0x0078, 0x54f4, 0x2c78,
+       0x600c, 0x2060, 0x0078, 0x54c5, 0x127f, 0x007f, 0x027f, 0x067f,
+       0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0x2061, 0x7400, 0x2a70, 0x7060,
+       0x7046, 0x704b, 0x7400, 0x007c, 0x0e7e, 0x127e, 0x2071, 0x6d00,
+       0x2091, 0x8000, 0x7544, 0xa582, 0x0001, 0x0048, 0x5536, 0x7048,
+       0x2060, 0x6000, 0xa086, 0x0000, 0x0040, 0x5522, 0xace0, 0x0008,
+       0x7054, 0xac02, 0x00c8, 0x551e, 0x0078, 0x5511, 0x2061, 0x7400,
+       0x0078, 0x5511, 0x6003, 0x0008, 0x8529, 0x7546, 0xaca8, 0x0008,
+       0x7054, 0xa502, 0x00c8, 0x5532, 0x754a, 0xa085, 0x0001, 0x127f,
+       0x0e7f, 0x007c, 0x704b, 0x7400, 0x0078, 0x552d, 0xa006, 0x0078,
+       0x552f, 0x0e7e, 0x2071, 0x6d00, 0x7544, 0xa582, 0x0001, 0x0048,
+       0x5567, 0x7048, 0x2060, 0x6000, 0xa086, 0x0000, 0x0040, 0x5554,
+       0xace0, 0x0008, 0x7054, 0xac02, 0x00c8, 0x5550, 0x0078, 0x5543,
+       0x2061, 0x7400, 0x0078, 0x5543, 0x6003, 0x0008, 0x8529, 0x7546,
+       0xaca8, 0x0008, 0x7054, 0xa502, 0x00c8, 0x5563, 0x754a, 0xa085,
+       0x0001, 0x0e7f, 0x007c, 0x704b, 0x7400, 0x0078, 0x555f, 0xa006,
+       0x0078, 0x5561, 0xac82, 0x7400, 0x1048, 0x12b7, 0x2001, 0x6d15,
+       0x2004, 0xac02, 0x10c8, 0x12b7, 0xa006, 0x6006, 0x600a, 0x600e,
+       0x6012, 0x6016, 0x601a, 0x601f, 0x0000, 0x6003, 0x0000, 0x2061,
+       0x6d00, 0x6044, 0x8000, 0x6046, 0xa086, 0x0001, 0x0040, 0x5589,
+       0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x476a, 0x127f, 0x0078,
+       0x5588, 0x601c, 0xa084, 0x000f, 0x0079, 0x5596, 0x559f, 0x55a7,
+       0x55c3, 0x55df, 0x629a, 0x62b6, 0x62d2, 0x559f, 0x55a7, 0xa18e,
+       0x0047, 0x00c0, 0x55a6, 0xa016, 0x1078, 0x1532, 0x007c, 0x067e,
+       0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12b7, 0x1079, 0x55b1, 0x067f,
+       0x007c, 0x55c1, 0x5698, 0x5792, 0x55c1, 0x57d7, 0x55c1, 0x55c1,
+       0x55c1, 0x5653, 0x5a4d, 0x55c1, 0x55c1, 0x55c1, 0x55c1, 0x55c1,
+       0x55c1, 0x1078, 0x12b7, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8,
+       0x12b7, 0x1079, 0x55cd, 0x067f, 0x007c, 0x55dd, 0x55dd, 0x55dd,
+       0x55dd, 0x55dd, 0x55dd, 0x55dd, 0x55dd, 0x5e10, 0x5edd, 0x55dd,
+       0x5e29, 0x5e8f, 0x5e29, 0x5e8f, 0x55dd, 0x1078, 0x12b7, 0x067e,
+       0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12b7, 0x1079, 0x55e9, 0x067f,
+       0x007c, 0x55f9, 0x5a96, 0x5b05, 0x5bbb, 0x5cd2, 0x55f9, 0x55f9,
+       0x55f9, 0x5a75, 0x5dc6, 0x5dca, 0x55f9, 0x55f9, 0x55f9, 0x55f9,
+       0x5df0, 0x1078, 0x12b7, 0x20a9, 0x000e, 0x2e98, 0x6010, 0x20a0,
+       0x53a3, 0x20a9, 0x0006, 0x3310, 0x3420, 0x9398, 0x94a0, 0x3318,
+       0x3428, 0x222e, 0x2326, 0xa290, 0x0002, 0xa5a8, 0x0002, 0xa398,
+       0x0002, 0xa4a0, 0x0002, 0x00f0, 0x5609, 0x0e7e, 0x6010, 0x2070,
+       0x7007, 0x0000, 0x7037, 0x0103, 0x0e7f, 0x1078, 0x556a, 0x007c,
+       0x0d7e, 0x037e, 0x7330, 0xa386, 0x0200, 0x00c0, 0x562d, 0x6018,
+       0x2068, 0x6813, 0x00ff, 0x6817, 0xfffd, 0x6010, 0xa005, 0x0040,
+       0x5637, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6b32, 0x1078,
+       0x556a, 0x037f, 0x0d7f, 0x007c, 0x0d7e, 0x20a9, 0x000e, 0x2e98,
+       0x6010, 0x20a0, 0x53a3, 0xa1b6, 0x0015, 0x00c0, 0x5650, 0x6018,
+       0x2068, 0x7038, 0x680a, 0x703c, 0x680e, 0x6800, 0xc08d, 0x6802,
+       0x0d7f, 0x0078, 0x5615, 0x2100, 0xa1b2, 0x0024, 0x10c8, 0x12b7,
+       0x0079, 0x565a, 0x5680, 0x568c, 0x5680, 0x5680, 0x5680, 0x5680,
+       0x567e, 0x567e, 0x567e, 0x567e, 0x567e, 0x567e, 0x567e, 0x567e,
+       0x567e, 0x567e, 0x567e, 0x567e, 0x567e, 0x567e, 0x567e, 0x567e,
+       0x567e, 0x567e, 0x567e, 0x567e, 0x567e, 0x567e, 0x567e, 0x567e,
+       0x567e, 0x5680, 0x567e, 0x5680, 0x5680, 0x567e, 0x1078, 0x12b7,
+       0x6003, 0x0001, 0x6106, 0x1078, 0x4376, 0x127e, 0x2091, 0x8000,
+       0x1078, 0x476a, 0x127f, 0x007c, 0x6003, 0x0001, 0x6106, 0x1078,
+       0x4376, 0x127e, 0x2091, 0x8000, 0x1078, 0x476a, 0x127f, 0x007c,
+       0x6004, 0xa0b2, 0x0024, 0x10c8, 0x12b7, 0xa1b6, 0x0013, 0x00c0,
+       0x56a4, 0x2008, 0x0079, 0x5706, 0xa1b6, 0x0014, 0x00c0, 0x56fd,
+       0x1078, 0x4671, 0x6004, 0xa08e, 0x0000, 0x0040, 0x56fe, 0xa08e,
+       0x0002, 0x0040, 0x56c9, 0xa08e, 0x0003, 0x0040, 0x56c9, 0xa08e,
+       0x0004, 0x0040, 0x56c9, 0xa08e, 0x001f, 0x0040, 0x56fe, 0xa08e,
+       0x0021, 0x0040, 0x5702, 0xa08e, 0x0022, 0x0040, 0x56fe, 0x0078,
+       0x56f9, 0x1078, 0x206f, 0x2001, 0x0007, 0x1078, 0x33f3, 0x6018,
+       0xa080, 0x0028, 0x200c, 0x1078, 0x5778, 0xa186, 0x007e, 0x00c0,
+       0x56df, 0x2001, 0x6d2f, 0x2014, 0xa295, 0x0001, 0x2202, 0x017e,
+       0x027e, 0x037e, 0x2110, 0x2019, 0x0028, 0x1078, 0x445c, 0x1078,
+       0x43a9, 0x0c7e, 0x6018, 0xa065, 0x0040, 0x56f0, 0x1078, 0x35cf,
+       0x0c7f, 0x2c08, 0x1078, 0x6a57, 0x037f, 0x027f, 0x017f, 0x1078,
+       0x342f, 0x1078, 0x556a, 0x1078, 0x476a, 0x007c, 0x1078, 0x5778,
+       0x0078, 0x56f9, 0x1078, 0x5786, 0x0078, 0x56f9, 0x572c, 0x572e,
+       0x5732, 0x5736, 0x573a, 0x573e, 0x572a, 0x572a, 0x572a, 0x572a,
+       0x572a, 0x572a, 0x572a, 0x572a, 0x572a, 0x572a, 0x572a, 0x572a,
+       0x572a, 0x572a, 0x572a, 0x572a, 0x572a, 0x572a, 0x572a, 0x572a,
+       0x572a, 0x572a, 0x572a, 0x572a, 0x5742, 0x5748, 0x572a, 0x5752,
+       0x5748, 0x572a, 0x1078, 0x12b7, 0x0078, 0x5748, 0x2001, 0x000b,
+       0x0078, 0x575b, 0x2001, 0x0003, 0x0078, 0x575b, 0x2001, 0x0005,
+       0x0078, 0x575b, 0x2001, 0x0001, 0x0078, 0x575b, 0x2001, 0x0009,
+       0x0078, 0x575b, 0x1078, 0x12b7, 0x0078, 0x575a, 0x1078, 0x33f3,
+       0x1078, 0x4671, 0x6003, 0x0002, 0x6017, 0x0028, 0x1078, 0x476a,
+       0x0078, 0x575a, 0x1078, 0x4671, 0x6003, 0x0004, 0x6017, 0x0028,
+       0x1078, 0x476a, 0x007c, 0x1078, 0x33f3, 0x1078, 0x4671, 0x6003,
+       0x0002, 0x037e, 0x2019, 0x6d5c, 0x2304, 0xa084, 0xff00, 0x00c0,
+       0x576d, 0x2019, 0x0028, 0x0078, 0x5772, 0x8007, 0x8003, 0x801b,
+       0x831b, 0xa318, 0x6316, 0x037f, 0x1078, 0x476a, 0x0078, 0x575a,
+       0x0e7e, 0x6010, 0xa005, 0x0040, 0x5784, 0x2070, 0x7007, 0x0000,
+       0x7037, 0x0103, 0x7033, 0x0100, 0x0e7f, 0x007c, 0x0e7e, 0xacf0,
+       0x0004, 0x2e74, 0x7000, 0x2070, 0x7037, 0x0103, 0x7023, 0x8001,
+       0x0e7f, 0x007c, 0x0d7e, 0x6618, 0x2668, 0x6804, 0xa084, 0x00ff,
+       0x0d7f, 0xa0b2, 0x000c, 0x10c8, 0x12b7, 0x6604, 0xa6b6, 0x001f,
+       0x00c0, 0x57a6, 0x1078, 0x55fb, 0x0078, 0x57c6, 0x6604, 0xa6b6,
+       0x0000, 0x00c0, 0x57af, 0x1078, 0x563c, 0x0078, 0x57c6, 0x6604,
+       0xa6b6, 0x0022, 0x00c0, 0x57b8, 0x1078, 0x5620, 0x0078, 0x57c6,
+       0xa1b6, 0x0015, 0x00c0, 0x57c0, 0x1079, 0x57cb, 0x0078, 0x57c6,
+       0xa1b6, 0x0016, 0x00c0, 0x57c7, 0x1079, 0x58f6, 0x007c, 0x1078,
+       0x559f, 0x0078, 0x57c6, 0x57ef, 0x57f2, 0x57ef, 0x5833, 0x57ef,
+       0x5892, 0x57ef, 0x57ef, 0x57ef, 0x58ce, 0x57ef, 0x58e4, 0xa1b6,
+       0x0048, 0x0040, 0x57e3, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10,
+       0x1078, 0x1532, 0x007c, 0x0e7e, 0xacf0, 0x0004, 0x2e74, 0x7000,
+       0x2070, 0x7037, 0x0103, 0x0e7f, 0x1078, 0x556a, 0x007c, 0x0005,
+       0x0005, 0x007c, 0x0e7e, 0x2071, 0x6d00, 0x7078, 0xa086, 0x0074,
+       0x00c0, 0x581c, 0x1078, 0x6a2b, 0x00c0, 0x580e, 0x0d7e, 0x6018,
+       0x2068, 0x1078, 0x5820, 0x0d7f, 0x2001, 0x0006, 0x1078, 0x33f3,
+       0x1078, 0x206f, 0x1078, 0x556a, 0x0078, 0x581e, 0x2001, 0x000a,
+       0x1078, 0x33f3, 0x1078, 0x206f, 0x6003, 0x0001, 0x6007, 0x0001,
+       0x1078, 0x4376, 0x0078, 0x581e, 0x1078, 0x5889, 0x0e7f, 0x007c,
+       0x6800, 0xd084, 0x0040, 0x5832, 0x2001, 0x0000, 0x1078, 0x33df,
+       0x2069, 0x6d51, 0x6804, 0xd0a4, 0x0040, 0x5832, 0x2001, 0x0006,
+       0x1078, 0x3401, 0x007c, 0x0d7e, 0x2011, 0x6d1e, 0x2204, 0xa086,
+       0x0074, 0x00c0, 0x5885, 0x1078, 0x599f, 0x6018, 0x2068, 0xa080,
+       0x0028, 0x2014, 0xa286, 0x007e, 0x0040, 0x5850, 0xa286, 0x0080,
+       0x00c0, 0x5879, 0x6813, 0x00ff, 0x6817, 0xfffc, 0x0078, 0x586f,
+       0x0e7e, 0x0f7e, 0x6813, 0x00ff, 0x6817, 0xfffe, 0x2071, 0x6d2f,
+       0x2e04, 0xa085, 0x0003, 0x2072, 0x2071, 0x7280, 0x2079, 0x0100,
+       0x2e04, 0xa084, 0x00ff, 0x2069, 0x6d19, 0x206a, 0x78e6, 0x8e70,
+       0x2e04, 0x2069, 0x6d1a, 0x206a, 0x78ea, 0x0f7f, 0x0e7f, 0x2001,
+       0x0006, 0x1078, 0x33f3, 0x1078, 0x206f, 0x1078, 0x556a, 0x0078,
+       0x5887, 0x2001, 0x0004, 0x1078, 0x33f3, 0x6003, 0x0001, 0x6007,
+       0x0003, 0x1078, 0x4376, 0x0078, 0x5887, 0x1078, 0x5889, 0x0d7f,
+       0x007c, 0x2001, 0x0007, 0x1078, 0x33f3, 0x1078, 0x206f, 0x1078,
+       0x556a, 0x007c, 0x0e7e, 0x2071, 0x6d00, 0x7078, 0xa086, 0x0014,
+       0x00c0, 0x58c8, 0x7000, 0xa086, 0x0003, 0x00c0, 0x58a5, 0x6010,
+       0xa005, 0x00c0, 0x58a5, 0x1078, 0x2ad1, 0x0d7e, 0x6018, 0x2068,
+       0x1078, 0x34ca, 0x1078, 0x5820, 0x0d7f, 0x1078, 0x59a9, 0x00c0,
+       0x58c8, 0x2001, 0x0006, 0x1078, 0x33f3, 0x0e7e, 0x6010, 0xa005,
+       0x0040, 0x58c1, 0x2070, 0x7007, 0x0000, 0x7037, 0x0103, 0x7033,
+       0x0200, 0x0e7f, 0x1078, 0x206f, 0x1078, 0x556a, 0x0078, 0x58cc,
+       0x1078, 0x5778, 0x1078, 0x5889, 0x0e7f, 0x007c, 0x2011, 0x6d1e,
+       0x2204, 0xa086, 0x0014, 0x00c0, 0x58e1, 0x2001, 0x0002, 0x1078,
+       0x33f3, 0x6003, 0x0001, 0x6007, 0x0001, 0x1078, 0x4376, 0x0078,
+       0x58e3, 0x1078, 0x5889, 0x007c, 0x2011, 0x6d1e, 0x2204, 0xa086,
+       0x0004, 0x00c0, 0x58f3, 0x2001, 0x0007, 0x1078, 0x33f3, 0x1078,
+       0x556a, 0x0078, 0x58f5, 0x1078, 0x5889, 0x007c, 0x57ef, 0x5902,
+       0x57ef, 0x5928, 0x57ef, 0x5952, 0x57ef, 0x57ef, 0x57ef, 0x5967,
+       0x57ef, 0x597a, 0x0c7e, 0x1078, 0x598d, 0x00c0, 0x5917, 0x2001,
+       0x0000, 0x1078, 0x33df, 0x2001, 0x0002, 0x1078, 0x33f3, 0x6003,
+       0x0001, 0x6007, 0x0002, 0x1078, 0x4376, 0x0078, 0x5926, 0x2009,
+       0x728f, 0x2104, 0xa084, 0xff00, 0xa086, 0x1900, 0x00c0, 0x5924,
+       0x1078, 0x556a, 0x0078, 0x5926, 0x1078, 0x5889, 0x0c7f, 0x007c,
+       0x1078, 0x599c, 0x00c0, 0x593c, 0x2001, 0x0000, 0x1078, 0x33df,
+       0x2001, 0x0002, 0x1078, 0x33f3, 0x6003, 0x0001, 0x6007, 0x0002,
+       0x1078, 0x4376, 0x0078, 0x5951, 0x1078, 0x5778, 0x2009, 0x728f,
+       0x2104, 0xa084, 0xff00, 0xa086, 0x1900, 0x00c0, 0x594f, 0x2001,
+       0x0004, 0x1078, 0x33f3, 0x1078, 0x556a, 0x0078, 0x5951, 0x1078,
+       0x5889, 0x007c, 0x1078, 0x599c, 0x00c0, 0x5962, 0x2001, 0x0004,
+       0x1078, 0x33f3, 0x6003, 0x0001, 0x6007, 0x0003, 0x1078, 0x4376,
+       0x0078, 0x5966, 0x1078, 0x5778, 0x1078, 0x5889, 0x007c, 0x1078,
+       0x599c, 0x00c0, 0x5977, 0x2001, 0x0008, 0x1078, 0x33f3, 0x6003,
+       0x0001, 0x6007, 0x0005, 0x1078, 0x4376, 0x0078, 0x5979, 0x1078,
+       0x5889, 0x007c, 0x1078, 0x599c, 0x00c0, 0x598a, 0x2001, 0x000a,
+       0x1078, 0x33f3, 0x6003, 0x0001, 0x6007, 0x0001, 0x1078, 0x4376,
+       0x0078, 0x598c, 0x1078, 0x5889, 0x007c, 0x2009, 0x728e, 0x2104,
+       0xa086, 0x0003, 0x00c0, 0x599b, 0x2009, 0x728f, 0x2104, 0xa084,
+       0xff00, 0xa086, 0x2a00, 0x007c, 0xa085, 0x0001, 0x007c, 0x0c7e,
+       0x017e, 0xac88, 0x0006, 0x2164, 0x1078, 0x3459, 0x017f, 0x0c7f,
+       0x007c, 0x0e7e, 0x2071, 0x728c, 0x7004, 0xa086, 0x0014, 0x00c0,
+       0x59cc, 0x7008, 0xa086, 0x0800, 0x00c0, 0x59cc, 0x700c, 0xd0ec,
+       0x0040, 0x59ca, 0xa084, 0x0f00, 0xa086, 0x0100, 0x00c0, 0x59ca,
+       0x7024, 0xd0a4, 0x0040, 0x59ca, 0xd08c, 0x0040, 0x59ca, 0xa006,
+       0x0078, 0x59cc, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x0e7e, 0x0d7e,
+       0x0c7e, 0x077e, 0x057e, 0x047e, 0x027e, 0x007e, 0x127e, 0x2091,
+       0x8000, 0x2029, 0x6f19, 0x252c, 0x2021, 0x6f1f, 0x2424, 0x2061,
+       0x7400, 0x2071, 0x6d00, 0x7244, 0x7060, 0xa202, 0x00c8, 0x5a23,
+       0x1078, 0x6c0f, 0x0040, 0x5a1b, 0x671c, 0xa786, 0x0001, 0x0040,
+       0x5a1b, 0xa786, 0x0007, 0x0040, 0x5a1b, 0x2500, 0xac06, 0x0040,
+       0x5a1b, 0x2400, 0xac06, 0x0040, 0x5a1b, 0x0c7e, 0x6010, 0x2068,
+       0x1078, 0x6120, 0x0040, 0x5a11, 0xa786, 0x0003, 0x00c0, 0x5a2d,
+       0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x36a1, 0x1078,
+       0x6276, 0x6000, 0xa086, 0x0004, 0x00c0, 0x5a18, 0x1078, 0x15f2,
+       0x1078, 0x6283, 0x0c7f, 0xace0, 0x0008, 0x7054, 0xac02, 0x00c8,
+       0x5a23, 0x0078, 0x59e3, 0x127f, 0x007f, 0x027f, 0x047f, 0x057f,
+       0x077f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0xa786, 0x0006, 0x00c0,
+       0x5a08, 0x1078, 0x6bb3, 0x0078, 0x5a11, 0x220c, 0x2304, 0xa106,
+       0x00c0, 0x5a40, 0x8210, 0x8318, 0x00f0, 0x5a35, 0xa006, 0x007c,
+       0x2304, 0xa102, 0x0048, 0x5a48, 0x2001, 0x0001, 0x0078, 0x5a4a,
+       0x2001, 0x0000, 0xa18d, 0x0001, 0x007c, 0x6004, 0xa08a, 0x0024,
+       0x10c8, 0x12b7, 0xa08e, 0x0000, 0x0040, 0x5a71, 0xa08e, 0x0002,
+       0x0040, 0x5a68, 0xa08e, 0x0003, 0x0040, 0x5a68, 0xa08e, 0x0004,
+       0x0040, 0x5a68, 0xa08e, 0x001f, 0x0040, 0x5a71, 0x0078, 0x5a6a,
+       0x1078, 0x206f, 0x1078, 0x4671, 0x1078, 0x556a, 0x1078, 0x476a,
+       0x007c, 0x1078, 0x5778, 0x0078, 0x5a6a, 0xa182, 0x0040, 0x0079,
+       0x5a79, 0x5a88, 0x5a88, 0x5a88, 0x5a88, 0x5a88, 0x5a88, 0x5a88,
+       0x5a88, 0x5a88, 0x5a88, 0x5a88, 0x5a8a, 0x5a8a, 0x5a8a, 0x5a8a,
+       0x1078, 0x12b7, 0x6003, 0x0001, 0x6106, 0x1078, 0x4327, 0x127e,
+       0x2091, 0x8000, 0x1078, 0x476a, 0x127f, 0x007c, 0xa186, 0x0013,
+       0x00c0, 0x5a9f, 0x6004, 0xa082, 0x0040, 0x0079, 0x5adf, 0xa186,
+       0x0014, 0x10c0, 0x12b7, 0x6004, 0xa082, 0x0040, 0x0079, 0x5aa8,
+       0x5ab9, 0x5ab7, 0x5ab7, 0x5ab7, 0x5ab7, 0x5ab7, 0x5ab7, 0x5ab7,
+       0x5ab7, 0x5ab7, 0x5ab7, 0x5ad4, 0x5ad4, 0x5ad4, 0x5ad4, 0x1078,
+       0x12b7, 0x2001, 0x0007, 0x1078, 0x33f3, 0x1078, 0x4671, 0x0d7e,
+       0x6110, 0x2168, 0x1078, 0x6120, 0x0040, 0x5ace, 0x6837, 0x0103,
+       0x684b, 0x0028, 0x1078, 0x36a1, 0x1078, 0x6276, 0x0d7f, 0x1078,
+       0x556a, 0x1078, 0x476a, 0x007c, 0x2001, 0x0007, 0x1078, 0x33f3,
+       0x1078, 0x4671, 0x1078, 0x556a, 0x1078, 0x476a, 0x007c, 0x5af0,
+       0x5aee, 0x5aee, 0x5aee, 0x5aee, 0x5aee, 0x5aee, 0x5aee, 0x5aee,
+       0x5aee, 0x5aee, 0x5afe, 0x5afe, 0x5afe, 0x5afe, 0x1078, 0x12b7,
+       0x1078, 0x4671, 0x6003, 0x0002, 0x1078, 0x476a, 0x6010, 0xa088,
+       0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x007c, 0x1078, 0x4671,
+       0x6003, 0x000f, 0x1078, 0x476a, 0x007c, 0xa182, 0x0040, 0x0079,
+       0x5b09, 0x5b18, 0x5b18, 0x5b18, 0x5b18, 0x5b18, 0x5b1a, 0x5b98,
+       0x5bb0, 0x5b18, 0x5b18, 0x5b18, 0x5b18, 0x5b18, 0x5b18, 0x5b18,
+       0x1078, 0x12b7, 0x0e7e, 0x0d7e, 0x2071, 0x728c, 0x6110, 0x2168,
+       0x7614, 0xa6b4, 0x0fff, 0x86ff, 0x0040, 0x5b87, 0xa68c, 0x00ff,
+       0xa186, 0x0002, 0x0040, 0x5b4c, 0xa186, 0x0028, 0x00c0, 0x5b36,
+       0x1078, 0x628a, 0x684b, 0x001c, 0x0078, 0x5b4e, 0xd6dc, 0x0040,
+       0x5b41, 0x684b, 0x0015, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0x0078,
+       0x5b4e, 0xd6d4, 0x0040, 0x5b4c, 0x684b, 0x0007, 0x7318, 0x6b62,
+       0x731c, 0x6b5e, 0x0078, 0x5b4e, 0x684b, 0x0000, 0x6837, 0x0103,
+       0x6e46, 0xa01e, 0xd6c4, 0x0040, 0x5b61, 0x7328, 0x732c, 0x6b56,
+       0x037e, 0x2308, 0x2019, 0x7298, 0xad90, 0x0019, 0x1078, 0x5f4c,
+       0x037f, 0xd6cc, 0x0040, 0x5b8c, 0x7124, 0x695a, 0xa192, 0x0021,
+       0x00c8, 0x5b75, 0x2071, 0x7298, 0x831c, 0x2300, 0xae18, 0xad90,
+       0x001d, 0x1078, 0x5f4c, 0x0078, 0x5b8c, 0x6838, 0xd0fc, 0x0040,
+       0x5b7e, 0x2009, 0x0020, 0x695a, 0x0078, 0x5b6a, 0x0f7e, 0x2d78,
+       0x1078, 0x5ee4, 0x0f7f, 0x1078, 0x5f39, 0x0078, 0x5b8e, 0x684b,
+       0x0000, 0x6837, 0x0103, 0x6e46, 0x1078, 0x36a1, 0x6218, 0x2268,
+       0x6a3c, 0x8211, 0x6a3e, 0x0d7f, 0x0e7f, 0x1078, 0x556a, 0x007c,
+       0x0f7e, 0x6003, 0x0003, 0x2079, 0x728c, 0x7c04, 0x7b00, 0x7e0c,
+       0x7d08, 0x6010, 0x2078, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e, 0x0f7f,
+       0x2c10, 0x1078, 0x17de, 0x1078, 0x4395, 0x1078, 0x4821, 0x007c,
+       0x6003, 0x0004, 0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10,
+       0x1078, 0x1532, 0x007c, 0xa182, 0x0040, 0x0079, 0x5bbf, 0x5bce,
+       0x5bce, 0x5bce, 0x5bce, 0x5bce, 0x5bd0, 0x5c5e, 0x5bce, 0x5bce,
+       0x5c74, 0x5cb4, 0x5bce, 0x5bce, 0x5bce, 0x5bce, 0x1078, 0x12b7,
+       0x077e, 0x0f7e, 0x0e7e, 0x0d7e, 0x2071, 0x728c, 0x6110, 0x2178,
+       0x7614, 0xa6b4, 0x0fff, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218,
+       0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0040, 0x5c59, 0xa694,
+       0xff00, 0xa284, 0x0c00, 0x0040, 0x5bf1, 0x7018, 0x7862, 0x701c,
+       0x785e, 0xa284, 0x0300, 0x0040, 0x5c59, 0x1078, 0x130f, 0x1040,
+       0x12b7, 0x2d00, 0x784a, 0x7f4c, 0xc7cd, 0x7f4e, 0x6837, 0x0103,
+       0x7838, 0x683a, 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c,
+       0x00ff, 0xa186, 0x0002, 0x0040, 0x5c2b, 0xa186, 0x0028, 0x00c0,
+       0x5c15, 0x684b, 0x001c, 0x0078, 0x5c2d, 0xd6dc, 0x0040, 0x5c20,
+       0x684b, 0x0015, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0x0078, 0x5c2d,
+       0xd6d4, 0x0040, 0x5c2b, 0x684b, 0x0007, 0x7318, 0x6b62, 0x731c,
+       0x6b5e, 0x0078, 0x5c2d, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852,
+       0x7854, 0x6856, 0xa01e, 0xd6c4, 0x0040, 0x5c42, 0x7328, 0x732c,
+       0x6b56, 0x037e, 0x2308, 0x2019, 0x7298, 0xad90, 0x0019, 0x1078,
+       0x5f4c, 0x037f, 0xd6cc, 0x0040, 0x5c59, 0x7124, 0x695a, 0xa192,
+       0x0021, 0x00c8, 0x5c56, 0x2071, 0x7298, 0x831c, 0x2300, 0xae18,
+       0xad90, 0x001d, 0x1078, 0x5f4c, 0x0078, 0x5c59, 0x2d78, 0x1078,
+       0x5ee4, 0x0d7f, 0x0e7f, 0x0f7f, 0x077f, 0x007c, 0x0f7e, 0x6003,
+       0x0003, 0x2079, 0x728c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6010,
+       0x2078, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e, 0x0f7f, 0x2c10, 0x1078,
+       0x17de, 0x1078, 0x4fca, 0x007c, 0x0d7e, 0x6003, 0x0002, 0x1078,
+       0x4719, 0x1078, 0x4821, 0x6110, 0x2168, 0x694c, 0xd1e4, 0x0040,
+       0x5cb2, 0xd1cc, 0x0040, 0x5c8d, 0x6948, 0x017e, 0x1078, 0x1338,
+       0x0d7f, 0x1078, 0x5f39, 0x0078, 0x5cb0, 0x6837, 0x0103, 0x6944,
+       0xa184, 0x00ff, 0xa186, 0x0002, 0x0040, 0x5cac, 0xa086, 0x0028,
+       0x00c0, 0x5c9e, 0x684b, 0x001c, 0x0078, 0x5cae, 0xd1dc, 0x0040,
+       0x5ca5, 0x684b, 0x0015, 0x0078, 0x5cae, 0xd1d4, 0x0040, 0x5cac,
+       0x684b, 0x0007, 0x0078, 0x5cae, 0x684b, 0x0000, 0x1078, 0x36a1,
+       0x1078, 0x556a, 0x0d7f, 0x007c, 0x2001, 0x0007, 0x1078, 0x33f3,
+       0x1078, 0x4719, 0x0f7e, 0x0d7e, 0x6110, 0x2178, 0x1078, 0x6120,
+       0x0040, 0x5ccb, 0x7837, 0x0103, 0x784b, 0x0028, 0x2f68, 0x1078,
+       0x36a1, 0x1078, 0x6276, 0x0d7f, 0x0f7f, 0x1078, 0x556a, 0x1078,
+       0x4821, 0x007c, 0xa182, 0x0040, 0x0079, 0x5cd6, 0x5ce5, 0x5ce5,
+       0x5ce5, 0x5ce5, 0x5ce5, 0x5ce7, 0x5ce5, 0x5d82, 0x5d8a, 0x5ce5,
+       0x5ce5, 0x5ce5, 0x5ce5, 0x5ce5, 0x5ce5, 0x1078, 0x12b7, 0x077e,
+       0x0f7e, 0x0e7e, 0x0d7e, 0x2071, 0x728c, 0x6110, 0x2178, 0x7614,
+       0xa6b4, 0x0fff, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268,
+       0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0040, 0x5d74, 0xa694, 0xff00,
+       0xa284, 0x0c00, 0x0040, 0x5d08, 0x7018, 0x7862, 0x701c, 0x785e,
+       0xa284, 0x0300, 0x0040, 0x5d71, 0x1078, 0x130f, 0x1040, 0x12b7,
+       0x2d00, 0x784a, 0x7f4c, 0xa7bd, 0x0200, 0x7f4e, 0x6837, 0x0103,
+       0x7838, 0x683a, 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c,
+       0x00ff, 0xa186, 0x0002, 0x0040, 0x5d43, 0xa186, 0x0028, 0x00c0,
+       0x5d2d, 0x684b, 0x001c, 0x0078, 0x5d45, 0xd6dc, 0x0040, 0x5d38,
+       0x684b, 0x0015, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0x0078, 0x5d45,
+       0xd6d4, 0x0040, 0x5d43, 0x684b, 0x0007, 0x7318, 0x6b62, 0x731c,
+       0x6b5e, 0x0078, 0x5d45, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852,
+       0x7854, 0x6856, 0xa01e, 0xd6c4, 0x0040, 0x5d5a, 0x7328, 0x732c,
+       0x6b56, 0x037e, 0x2308, 0x2019, 0x7298, 0xad90, 0x0019, 0x1078,
+       0x5f4c, 0x037f, 0xd6cc, 0x0040, 0x5d71, 0x7124, 0x695a, 0xa192,
+       0x0021, 0x00c8, 0x5d6e, 0x2071, 0x7298, 0x831c, 0x2300, 0xae18,
+       0xad90, 0x001d, 0x1078, 0x5f4c, 0x0078, 0x5d71, 0x2d78, 0x1078,
+       0x5ee4, 0xd6dc, 0x00c0, 0x5d77, 0xa006, 0x0078, 0x5d7b, 0x2001,
+       0x0001, 0x7218, 0x731c, 0x1078, 0x156f, 0x0d7f, 0x0e7f, 0x0f7f,
+       0x077f, 0x007c, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078,
+       0x1532, 0x007c, 0x0d7e, 0x6003, 0x0002, 0x6110, 0x2168, 0x694c,
+       0xd1e4, 0x0040, 0x5dc4, 0xd1cc, 0x0040, 0x5d9f, 0x6948, 0x017e,
+       0x1078, 0x1338, 0x0d7f, 0x1078, 0x5f39, 0x0078, 0x5dc2, 0x6837,
+       0x0103, 0x6944, 0xa184, 0x00ff, 0xa186, 0x0002, 0x0040, 0x5dbe,
+       0xa086, 0x0028, 0x00c0, 0x5db0, 0x684b, 0x001c, 0x0078, 0x5dc0,
+       0xd1dc, 0x0040, 0x5db7, 0x684b, 0x0015, 0x0078, 0x5dc0, 0xd1d4,
+       0x0040, 0x5dbe, 0x684b, 0x0007, 0x0078, 0x5dc0, 0x684b, 0x0000,
+       0x1078, 0x36a1, 0x1078, 0x556a, 0x0d7f, 0x007c, 0x1078, 0x4671,
+       0x0078, 0x5dcc, 0x1078, 0x4719, 0x1078, 0x6120, 0x0040, 0x5de3,
+       0x0d7e, 0x6110, 0x2168, 0x6837, 0x0103, 0x2009, 0x6d0c, 0x210c,
+       0xd18c, 0x00c0, 0x5dec, 0xd184, 0x00c0, 0x5de8, 0x6108, 0x694a,
+       0x1078, 0x36a1, 0x0d7f, 0x1078, 0x556a, 0x1078, 0x476a, 0x007c,
+       0x684b, 0x0004, 0x0078, 0x5de0, 0x684b, 0x0004, 0x0078, 0x5de0,
+       0xa182, 0x0040, 0x0079, 0x5df4, 0x5e03, 0x5e03, 0x5e03, 0x5e03,
+       0x5e03, 0x5e05, 0x5e03, 0x5e08, 0x5e03, 0x5e03, 0x5e03, 0x5e03,
+       0x5e03, 0x5e03, 0x5e03, 0x1078, 0x12b7, 0x1078, 0x556a, 0x007c,
+       0x007e, 0x027e, 0xa016, 0x1078, 0x1532, 0x027f, 0x007f, 0x007c,
+       0xa182, 0x0025, 0x0079, 0x5e14, 0x5e1d, 0x5e1b, 0x5e1b, 0x5e1b,
+       0x5e1b, 0x5e1b, 0x5e1b, 0x1078, 0x12b7, 0x6003, 0x0001, 0x6106,
+       0x1078, 0x4327, 0x127e, 0x2091, 0x8000, 0x1078, 0x476a, 0x127f,
+       0x007c, 0xa186, 0x0013, 0x00c0, 0x5e33, 0x6004, 0xa082, 0x0025,
+       0x2008, 0x0079, 0x5e74, 0xa186, 0x0014, 0x00c0, 0x5e70, 0x1078,
+       0x4671, 0x2001, 0x0007, 0x1078, 0x33f3, 0x6018, 0xa080, 0x0028,
+       0x200c, 0x017e, 0x027e, 0x037e, 0x2110, 0x2019, 0x0028, 0x1078,
+       0x445c, 0x1078, 0x43a9, 0x0c7e, 0x6018, 0xa065, 0x0040, 0x5e52,
+       0x1078, 0x35cf, 0x0c7f, 0x2c08, 0x1078, 0x6a57, 0x037f, 0x027f,
+       0x017f, 0x1078, 0x342f, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x6120,
+       0x0040, 0x5e6a, 0x6837, 0x0103, 0x684b, 0x0006, 0x1078, 0x36a1,
+       0x1078, 0x6276, 0x0d7f, 0x1078, 0x556a, 0x1078, 0x476a, 0x007c,
+       0x1078, 0x559f, 0x0078, 0x5e6f, 0x5e7d, 0x5e7b, 0x5e7b, 0x5e7b,
+       0x5e7b, 0x5e7b, 0x5e86, 0x1078, 0x12b7, 0x1078, 0x4671, 0x6017,
+       0x0014, 0x6003, 0x000c, 0x1078, 0x476a, 0x007c, 0x1078, 0x4671,
+       0x6017, 0x0014, 0x6003, 0x000e, 0x1078, 0x476a, 0x007c, 0xa182,
+       0x002c, 0x00c8, 0x5e99, 0xa182, 0x0025, 0x0048, 0x5e99, 0x0079,
+       0x5e9c, 0x1078, 0x559f, 0x007c, 0x5ea3, 0x5ea3, 0x5ea3, 0x5ea3,
+       0x5ea5, 0x5ebf, 0x5ea3, 0x1078, 0x12b7, 0x0d7e, 0x1078, 0x6276,
+       0x6010, 0x2068, 0x6837, 0x0103, 0x6850, 0xa084, 0x0040, 0x0040,
+       0x5eb5, 0x684b, 0x0006, 0x0078, 0x5eb7, 0x684b, 0x0005, 0x6847,
+       0x0000, 0x1078, 0x36a1, 0x1078, 0x556a, 0x0d7f, 0x007c, 0x0d7e,
+       0x6010, 0x2068, 0x1078, 0x6120, 0x0040, 0x5ed9, 0x6837, 0x0103,
+       0x6850, 0xa084, 0x0040, 0x0040, 0x5ed1, 0x684b, 0x0006, 0x0078,
+       0x5ed3, 0x684b, 0x0005, 0x6847, 0x0000, 0x1078, 0x36a1, 0x1078,
+       0x6276, 0x0d7f, 0x1078, 0x556a, 0x007c, 0x1078, 0x4671, 0x1078,
+       0x556a, 0x1078, 0x476a, 0x007c, 0x057e, 0x067e, 0x0d7e, 0x0f7e,
+       0x2029, 0x0001, 0xa182, 0x0101, 0x00c8, 0x5ef0, 0x0078, 0x5ef2,
+       0x2009, 0x0100, 0x2130, 0x2069, 0x7298, 0x831c, 0x2300, 0xad18,
+       0x2009, 0x0020, 0xaf90, 0x001d, 0x1078, 0x5f4c, 0xa6b2, 0x0020,
+       0x7804, 0xa06d, 0x0040, 0x5f06, 0x1078, 0x1338, 0x1078, 0x130f,
+       0x0040, 0x5f30, 0x8528, 0x6837, 0x0110, 0x683b, 0x0000, 0x2d20,
+       0x7c06, 0xa68a, 0x003d, 0x00c8, 0x5f1c, 0x2608, 0xad90, 0x000f,
+       0x1078, 0x5f4c, 0x0078, 0x5f30, 0xa6b2, 0x003c, 0x2009, 0x003c,
+       0x2d78, 0xad90, 0x000f, 0x1078, 0x5f4c, 0x0078, 0x5f06, 0x0f7f,
+       0x852f, 0xa5ad, 0x0003, 0x7d36, 0xa5ac, 0x0000, 0x0078, 0x5f35,
+       0x0f7f, 0x852f, 0xa5ad, 0x0003, 0x7d36, 0x0d7f, 0x067f, 0x057f,
+       0x007c, 0x0f7e, 0x8dff, 0x0040, 0x5f4a, 0x6804, 0xa07d, 0x0040,
+       0x5f48, 0x6807, 0x0000, 0x1078, 0x36a1, 0x2f68, 0x0078, 0x5f3d,
+       0x1078, 0x36a1, 0x0f7f, 0x007c, 0x157e, 0xa184, 0x0001, 0x0040,
+       0x5f52, 0x8108, 0x810c, 0x21a8, 0x2304, 0x8007, 0x2012, 0x8318,
+       0x8210, 0x00f0, 0x5f54, 0x157f, 0x007c, 0x127e, 0x2091, 0x8000,
+       0x601c, 0xa084, 0x000f, 0x1079, 0x5f67, 0x127f, 0x007c, 0x5f76,
+       0x5f6f, 0x5f71, 0x5f8d, 0x5f6f, 0x5f71, 0x5f71, 0x5f71, 0x1078,
+       0x12b7, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c, 0x0d7e, 0x6010,
+       0x2068, 0x1078, 0x6120, 0x0040, 0x5f8a, 0xa00e, 0x2001, 0x0005,
+       0x1078, 0x372d, 0x1078, 0x36a1, 0x1078, 0x556a, 0xa085, 0x0001,
+       0x0d7f, 0x007c, 0xa006, 0x0078, 0x5f88, 0x6000, 0xa08a, 0x0010,
+       0x10c8, 0x12b7, 0x1079, 0x5f95, 0x007c, 0x5fa5, 0x5fc4, 0x5fa7,
+       0x5fd5, 0x5fc0, 0x5fa5, 0x5f71, 0x5f76, 0x5f76, 0x5f71, 0x5f71,
+       0x5f71, 0x5f71, 0x5f71, 0x5f71, 0x5f71, 0x1078, 0x12b7, 0x0d7e,
+       0x6010, 0x2068, 0x1078, 0x6120, 0x0040, 0x5fb2, 0x6850, 0xa085,
+       0x0005, 0x6852, 0x0d7f, 0x6007, 0x0025, 0x6003, 0x000b, 0x601f,
+       0x0002, 0x1078, 0x4327, 0x1078, 0x476a, 0xa085, 0x0001, 0x007c,
+       0x1078, 0x15f2, 0x0078, 0x5fa7, 0x0e7e, 0x2071, 0x6f10, 0x7024,
+       0xac06, 0x00c0, 0x5fcd, 0x1078, 0x5148, 0x1078, 0x5083, 0x0e7f,
+       0x00c0, 0x5fa7, 0x1078, 0x5f71, 0x007c, 0x037e, 0x0e7e, 0x2071,
+       0x6f10, 0x703c, 0xac06, 0x00c0, 0x5fe1, 0x2019, 0x0000, 0x1078,
+       0x51da, 0x1078, 0x54b6, 0x0e7f, 0x037f, 0x00c0, 0x5fa7, 0x1078,
+       0x5f71, 0x007c, 0x0c7e, 0x601c, 0xa084, 0x000f, 0x1079, 0x5ff2,
+       0x0c7f, 0x007c, 0x5ffb, 0x605b, 0x60c8, 0x5fff, 0x5ffb, 0x5ffb,
+       0x5ffb, 0x556a, 0x605b, 0x007c, 0x6017, 0x0001, 0x007c, 0x6000,
+       0xa08a, 0x0010, 0x10c8, 0x12b7, 0x1079, 0x6007, 0x007c, 0x6017,
+       0x6019, 0x603a, 0x604d, 0x604d, 0x6017, 0x5ffb, 0x5ffb, 0x5ffb,
+       0x604d, 0x604d, 0x6017, 0x6017, 0x6017, 0x6017, 0x6058, 0x1078,
+       0x12b7, 0x0e7e, 0x6010, 0x2070, 0x7050, 0xa085, 0x0040, 0x7052,
+       0x2071, 0x6f10, 0x7024, 0xac06, 0x0040, 0x6036, 0x1078, 0x5083,
+       0x6007, 0x0025, 0x6003, 0x000b, 0x601f, 0x0002, 0x6017, 0x0014,
+       0x1078, 0x4327, 0x1078, 0x476a, 0x0e7f, 0x007c, 0x6017, 0x0001,
+       0x0078, 0x6034, 0x0d7e, 0x6010, 0x2068, 0x6850, 0xa085, 0x0040,
+       0x6852, 0x0d7f, 0x6007, 0x0025, 0x6003, 0x000b, 0x601f, 0x0002,
+       0x1078, 0x4327, 0x1078, 0x476a, 0x007c, 0x0d7e, 0x6017, 0x0001,
+       0x6010, 0x2068, 0x6850, 0xa085, 0x0040, 0x6852, 0x0d7f, 0x007c,
+       0x1078, 0x556a, 0x007c, 0x6000, 0xa08a, 0x0010, 0x10c8, 0x12b7,
+       0x1079, 0x6063, 0x007c, 0x6073, 0x5ffc, 0x6075, 0x6073, 0x6075,
+       0x6073, 0x6073, 0x6073, 0x5ffb, 0x5ffb, 0x6073, 0x6073, 0x6073,
+       0x6073, 0x6073, 0x6073, 0x1078, 0x12b7, 0x0d7e, 0x6018, 0x2068,
+       0x6804, 0xa084, 0x00ff, 0x0d7f, 0xa08a, 0x000c, 0x10c8, 0x12b7,
+       0x1079, 0x6083, 0x007c, 0x608f, 0x60b1, 0x608f, 0x60b1, 0x608f,
+       0x60b1, 0x6091, 0x609a, 0x608f, 0x60b1, 0x608f, 0x60aa, 0x1078,
+       0x12b7, 0x6004, 0xa08e, 0x0004, 0x0040, 0x60ac, 0xa08e, 0x0002,
+       0x0040, 0x60ac, 0xa08e, 0x0000, 0x0040, 0x60c0, 0xa08e, 0x001f,
+       0x0040, 0x60c0, 0xa08e, 0x0021, 0x0040, 0x60c4, 0xa08e, 0x0022,
+       0x0040, 0x60c0, 0x1078, 0x2051, 0x1078, 0x5778, 0x1078, 0x556a,
+       0x007c, 0x1078, 0x5778, 0x1078, 0x2051, 0x0e7e, 0x127e, 0x2091,
+       0x8000, 0x1078, 0x206f, 0x127f, 0x0e7f, 0x1078, 0x556a, 0x007c,
+       0x1078, 0x5778, 0x0078, 0x60ac, 0x1078, 0x5786, 0x0078, 0x60ac,
+       0x6000, 0xa08a, 0x0010, 0x10c8, 0x12b7, 0x1079, 0x60d0, 0x007c,
+       0x60e0, 0x60e0, 0x60e0, 0x60e0, 0x60e0, 0x60e0, 0x60e0, 0x60e0,
+       0x60e0, 0x5ffb, 0x60e0, 0x5ffc, 0x60e2, 0x5ffc, 0x60eb, 0x60e0,
+       0x1078, 0x12b7, 0x6007, 0x002b, 0x6003, 0x000d, 0x1078, 0x4327,
+       0x1078, 0x476a, 0x007c, 0x1078, 0x6276, 0x1078, 0x6120, 0x0040,
+       0x6109, 0x1078, 0x2051, 0x0d7e, 0x6010, 0x2068, 0x6837, 0x0103,
+       0x684b, 0x0006, 0x1078, 0x36a1, 0x0d7f, 0x601f, 0x0001, 0x6007,
+       0x0001, 0x6003, 0x0001, 0x1078, 0x4376, 0x1078, 0x476a, 0x0078,
+       0x610b, 0x1078, 0x556a, 0x007c, 0xa284, 0x0007, 0x00c0, 0x611d,
+       0xa282, 0x7400, 0x0048, 0x611d, 0x2001, 0x6d15, 0x2004, 0xa202,
+       0x00c8, 0x611d, 0xa085, 0x0001, 0x007c, 0xa006, 0x0078, 0x611c,
+       0x027e, 0x0e7e, 0x2071, 0x6d00, 0x6210, 0x7058, 0xa202, 0x0048,
+       0x6132, 0x705c, 0xa202, 0x00c8, 0x6132, 0xa085, 0x0001, 0x0e7f,
+       0x027f, 0x007c, 0xa006, 0x0078, 0x612f, 0x0e7e, 0x0c7e, 0x037e,
+       0x007e, 0x127e, 0x2091, 0x8000, 0x2061, 0x7400, 0x2071, 0x6d00,
+       0x7344, 0x7060, 0xa302, 0x00c8, 0x6155, 0x601c, 0xa206, 0x00c0,
+       0x614d, 0x0c7e, 0x1078, 0x556a, 0x0c7f, 0xace0, 0x0008, 0x7054,
+       0xac02, 0x00c8, 0x6155, 0x0078, 0x6140, 0x127f, 0x007f, 0x037f,
+       0x0c7f, 0x0e7f, 0x007c, 0x0e7e, 0x0c7e, 0x017e, 0x127e, 0x2091,
+       0x8000, 0xa188, 0x6e00, 0x210c, 0x81ff, 0x0040, 0x6182, 0x2061,
+       0x7400, 0x2071, 0x6d00, 0x7344, 0x7060, 0xa302, 0x00c8, 0x6182,
+       0x6018, 0xa106, 0x00c0, 0x617c, 0x1078, 0x2051, 0x017e, 0x0c7e,
+       0x1078, 0x556a, 0x0c7f, 0x017f, 0xace0, 0x0008, 0x7054, 0xac02,
+       0x0048, 0x6170, 0x127f, 0x017f, 0x0c7f, 0x0e7f, 0x007c, 0x0c7e,
+       0x057e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, 0x5504, 0x057f,
+       0x0040, 0x61a0, 0x6612, 0x651a, 0x601f, 0x0003, 0x2009, 0x004b,
+       0x1078, 0x5591, 0xa085, 0x0001, 0x127f, 0x057f, 0x0c7f, 0x007c,
+       0xa006, 0x0078, 0x619c, 0x0c7e, 0x057e, 0x127e, 0x2091, 0x8000,
+       0x62a0, 0x0c7e, 0x1078, 0x5504, 0x057f, 0x0040, 0x61ca, 0x6013,
+       0x0000, 0x651a, 0x601f, 0x0003, 0x0c7e, 0x2560, 0x1078, 0x35cf,
+       0x0c7f, 0x1078, 0x445c, 0x1078, 0x43a9, 0x2c08, 0x1078, 0x6a57,
+       0x2009, 0x004c, 0x1078, 0x5591, 0xa085, 0x0001, 0x127f, 0x057f,
+       0x0c7f, 0x007c, 0xa006, 0x0078, 0x61c6, 0x0c7e, 0x057e, 0x127e,
+       0x2091, 0x8000, 0x62a0, 0x0c7e, 0x1078, 0x5504, 0x057f, 0x0040,
+       0x61f5, 0x6612, 0x651a, 0x601f, 0x0003, 0x2019, 0x0005, 0x0c7e,
+       0x2560, 0x1078, 0x35cf, 0x0c7f, 0x1078, 0x445c, 0x1078, 0x43a9,
+       0x2c08, 0x1078, 0x6a57, 0x2009, 0x004d, 0x1078, 0x5591, 0xa085,
+       0x0001, 0x127f, 0x057f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x61f1,
+       0x0c7e, 0x057e, 0x127e, 0x2091, 0x8000, 0x62a0, 0x0c7e, 0x1078,
+       0x5504, 0x057f, 0x0040, 0x6220, 0x6612, 0x651a, 0x601f, 0x0003,
+       0x2019, 0x0005, 0x0c7e, 0x2560, 0x1078, 0x35cf, 0x0c7f, 0x1078,
+       0x445c, 0x1078, 0x43a9, 0x2c08, 0x1078, 0x6a57, 0x2009, 0x004e,
+       0x1078, 0x5591, 0xa085, 0x0001, 0x127f, 0x057f, 0x0c7f, 0x007c,
+       0xa006, 0x0078, 0x621c, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e,
+       0x1078, 0x5504, 0x017f, 0x0040, 0x623c, 0x660a, 0x611a, 0x601f,
+       0x0001, 0x2d00, 0x6012, 0x2009, 0x001f, 0x1078, 0x5591, 0xa085,
+       0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x6239, 0x0c7e,
+       0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, 0x5504, 0x017f, 0x0040,
+       0x6258, 0x660a, 0x611a, 0x601f, 0x0008, 0x2d00, 0x6012, 0x2009,
+       0x0021, 0x1078, 0x5591, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c,
+       0xa006, 0x0078, 0x6255, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e,
+       0x1078, 0x5504, 0x017f, 0x0040, 0x6273, 0x611a, 0x601f, 0x0001,
+       0x2d00, 0x6012, 0x2009, 0x0000, 0x1078, 0x5591, 0xa085, 0x0001,
+       0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x6270, 0x027e, 0x0d7e,
+       0x6218, 0x2268, 0x6a3c, 0x82ff, 0x0040, 0x6280, 0x8211, 0x6a3e,
+       0x0d7f, 0x027f, 0x007c, 0x6013, 0x0000, 0x601f, 0x0007, 0x6017,
+       0x0014, 0x007c, 0x067e, 0x0c7e, 0x2031, 0x6d52, 0x2634, 0xd6e4,
+       0x0040, 0x6297, 0x6618, 0x2660, 0x6e44, 0x1078, 0x3507, 0x0c7f,
+       0x067f, 0x007c, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12b7,
+       0x1079, 0x62a4, 0x067f, 0x007c, 0x62b4, 0x640b, 0x64d4, 0x62b4,
+       0x62b4, 0x62b4, 0x62b4, 0x62b4, 0x62ee, 0x6542, 0x62b4, 0x62b4,
+       0x62b4, 0x62b4, 0x62b4, 0x62b4, 0x1078, 0x12b7, 0x067e, 0x6000,
+       0xa0b2, 0x0010, 0x10c8, 0x12b7, 0x1079, 0x62c0, 0x067f, 0x007c,
+       0x62d0, 0x6837, 0x62d0, 0x62d0, 0x62d0, 0x62d0, 0x62d0, 0x62d0,
+       0x6812, 0x687d, 0x62d0, 0x62d0, 0x62d0, 0x62d0, 0x62d0, 0x62d0,
+       0x1078, 0x12b7, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12b7,
+       0x1079, 0x62dc, 0x067f, 0x007c, 0x62ec, 0x668f, 0x66fb, 0x671c,
+       0x6769, 0x62ec, 0x62ec, 0x67be, 0x654e, 0x67fa, 0x67fe, 0x62ec,
+       0x62ec, 0x62ec, 0x62ec, 0x62ec, 0x1078, 0x12b7, 0xa1b2, 0x0024,
+       0x10c8, 0x12b7, 0x2100, 0x0079, 0x62f5, 0x6319, 0x63f5, 0x6319,
+       0x6319, 0x6319, 0x6319, 0x6319, 0x6319, 0x6319, 0x6319, 0x6319,
+       0x6319, 0x6319, 0x6319, 0x6319, 0x6319, 0x6319, 0x6319, 0x6319,
+       0x6319, 0x6319, 0x6319, 0x6319, 0x631b, 0x634a, 0x6354, 0x637c,
+       0x6382, 0x63b6, 0x63ee, 0x6319, 0x6319, 0x63fd, 0x6319, 0x6319,
+       0x6404, 0x1078, 0x12b7, 0x1078, 0x364d, 0x6618, 0x0c7e, 0x2660,
+       0x1078, 0x3459, 0x0c7f, 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff,
+       0xa082, 0x0006, 0x0048, 0x633c, 0x1078, 0x6993, 0x00c0, 0x6376,
+       0x1078, 0x6931, 0x00c0, 0x6338, 0x6007, 0x0008, 0x0078, 0x63f0,
+       0x6007, 0x0009, 0x0078, 0x63f0, 0x1078, 0x6b02, 0x0040, 0x6346,
+       0x1078, 0x6993, 0x0040, 0x6330, 0x0078, 0x6376, 0x6013, 0x1900,
+       0x0078, 0x6338, 0x1078, 0x68b7, 0x6007, 0x0006, 0x0078, 0x63f0,
+       0x6007, 0x0007, 0x0078, 0x63f0, 0x0d7e, 0x6618, 0x2668, 0x6e04,
+       0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x6366, 0xa686,
+       0x0004, 0x0040, 0x6366, 0x0d7f, 0x0078, 0x6376, 0x1078, 0x69f1,
+       0x00c0, 0x6371, 0x1078, 0x34ca, 0x6007, 0x000a, 0x0d7f, 0x0078,
+       0x63f0, 0x6007, 0x000b, 0x0d7f, 0x0078, 0x63f0, 0x1078, 0x2051,
+       0x6007, 0x0001, 0x0078, 0x63f0, 0x1078, 0x2051, 0x6007, 0x000c,
+       0x0078, 0x63f0, 0x1078, 0x364d, 0x6618, 0xa6b0, 0x0001, 0x2634,
+       0xa684, 0x00ff, 0xa082, 0x0006, 0x0048, 0x63a3, 0xa6b4, 0xff00,
+       0x8637, 0xa686, 0x0006, 0x00c0, 0x6376, 0x1078, 0x6a00, 0x00c0,
+       0x639d, 0x6007, 0x000e, 0x0078, 0x63f0, 0x1078, 0x2051, 0x6007,
+       0x000f, 0x0078, 0x63f0, 0x1078, 0x6b02, 0x0040, 0x63b0, 0xa6b4,
+       0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x6395, 0x0078, 0x6376,
+       0x6013, 0x1900, 0x6007, 0x0009, 0x0078, 0x63f0, 0x1078, 0x364d,
+       0x6618, 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006,
+       0x0048, 0x63db, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x00c0,
+       0x6376, 0x1078, 0x6a2b, 0x00c0, 0x63d5, 0x1078, 0x6931, 0x00c0,
+       0x63d5, 0x6007, 0x0010, 0x0078, 0x63f0, 0x1078, 0x2051, 0x6007,
+       0x0011, 0x0078, 0x63f0, 0x1078, 0x6b02, 0x0040, 0x63e8, 0xa6b4,
+       0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x63c9, 0x0078, 0x6376,
+       0x6013, 0x1900, 0x6007, 0x0009, 0x0078, 0x63f0, 0x6007, 0x0012,
+       0x6003, 0x0001, 0x1078, 0x4376, 0x007c, 0x6007, 0x0001, 0x6003,
+       0x0001, 0x1078, 0x4376, 0x0078, 0x63f4, 0x6007, 0x0020, 0x6003,
+       0x0001, 0x1078, 0x4376, 0x007c, 0x6007, 0x0023, 0x6003, 0x0001,
+       0x1078, 0x4376, 0x007c, 0x6004, 0xa0b2, 0x0024, 0x10c8, 0x12b7,
+       0xa1b6, 0x0013, 0x00c0, 0x6417, 0x2008, 0x0079, 0x6426, 0xa1b6,
+       0x0014, 0x10c0, 0x12b7, 0x2001, 0x0007, 0x1078, 0x3401, 0x1078,
+       0x4671, 0x1078, 0x6283, 0x1078, 0x476a, 0x007c, 0x644a, 0x644c,
+       0x644a, 0x644a, 0x644a, 0x644c, 0x6454, 0x64af, 0x6472, 0x64af,
+       0x6486, 0x64af, 0x6454, 0x64af, 0x64a7, 0x64af, 0x64a7, 0x64af,
+       0x64af, 0x644a, 0x644a, 0x644a, 0x644a, 0x644a, 0x644a, 0x644a,
+       0x644a, 0x644a, 0x644a, 0x644a, 0x644a, 0x644a, 0x64af, 0x644a,
+       0x644a, 0x64af, 0x1078, 0x12b7, 0x1078, 0x4671, 0x6003, 0x0002,
+       0x1078, 0x476a, 0x0078, 0x64b5, 0x0f7e, 0x2079, 0x6d51, 0x7804,
+       0x0f7f, 0xd0ac, 0x00c0, 0x64af, 0x2001, 0x0000, 0x1078, 0x33df,
+       0x2001, 0x0002, 0x1078, 0x33f3, 0x1078, 0x4671, 0x601f, 0x0001,
+       0x6003, 0x0001, 0x6007, 0x0002, 0x1078, 0x4376, 0x1078, 0x476a,
+       0x0078, 0x64b5, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4,
+       0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x64af, 0xa686, 0x0004,
+       0x0040, 0x64af, 0x2001, 0x0004, 0x0078, 0x64ad, 0x2001, 0x6d00,
+       0x2004, 0xa086, 0x0003, 0x00c0, 0x648f, 0x1078, 0x2ad1, 0x2001,
+       0x0006, 0x1078, 0x64b6, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f,
+       0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x64af, 0x2001,
+       0x0006, 0x0078, 0x64ad, 0x2001, 0x0004, 0x0078, 0x64ad, 0x2001,
+       0x0006, 0x1078, 0x64b6, 0x0078, 0x64af, 0x1078, 0x3401, 0x1078,
+       0x4671, 0x1078, 0x556a, 0x1078, 0x476a, 0x007c, 0x017e, 0x0d7e,
+       0x6118, 0x2168, 0x6900, 0xd184, 0x0040, 0x64d1, 0x6104, 0xa18e,
+       0x000a, 0x00c0, 0x64c9, 0x699c, 0xd1a4, 0x00c0, 0x64c9, 0x2001,
+       0x0007, 0x1078, 0x33f3, 0x2001, 0x0000, 0x1078, 0x33df, 0x1078,
+       0x206f, 0x0d7f, 0x017f, 0x007c, 0x0d7e, 0x6618, 0x2668, 0x6804,
+       0xa084, 0xff00, 0x8007, 0x0d7f, 0xa0b2, 0x000c, 0x10c8, 0x12b7,
+       0xa1b6, 0x0015, 0x00c0, 0x64e8, 0x1079, 0x64ef, 0x0078, 0x64ee,
+       0xa1b6, 0x0016, 0x10c0, 0x12b7, 0x1079, 0x6527, 0x007c, 0x57ef,
+       0x57ef, 0x57ef, 0x57ef, 0x57ef, 0x57ef, 0x57ef, 0x64fb, 0x57ef,
+       0x57ef, 0x57ef, 0x57ef, 0x0f7e, 0x2079, 0x6d51, 0x7804, 0x0f7f,
+       0xd0ac, 0x00c0, 0x6517, 0x2001, 0x0000, 0x1078, 0x33df, 0x2001,
+       0x0002, 0x1078, 0x33f3, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007,
+       0x0002, 0x1078, 0x4376, 0x1078, 0x476a, 0x0078, 0x6526, 0x2011,
+       0x7283, 0x220c, 0x017e, 0x0c7e, 0x1078, 0x3447, 0x00c0, 0x6526,
+       0x1078, 0x3256, 0x0c7f, 0x017f, 0x1078, 0x556a, 0x007c, 0x57ef,
+       0x57ef, 0x57ef, 0x57ef, 0x57ef, 0x57ef, 0x57ef, 0x6533, 0x57ef,
+       0x57ef, 0x57ef, 0x57ef, 0x1078, 0x599c, 0x00c0, 0x653f, 0x6003,
+       0x0001, 0x6007, 0x0001, 0x1078, 0x4376, 0x0078, 0x6541, 0x1078,
+       0x556a, 0x007c, 0x6004, 0xa08a, 0x0024, 0x10c8, 0x12b7, 0x1078,
+       0x4671, 0x1078, 0x6283, 0x1078, 0x476a, 0x007c, 0xa182, 0x0040,
+       0x0079, 0x6552, 0x6561, 0x6561, 0x6561, 0x6561, 0x6563, 0x6561,
+       0x6561, 0x6561, 0x6561, 0x6561, 0x6561, 0x6561, 0x6561, 0x6561,
+       0x6561, 0x1078, 0x12b7, 0x0d7e, 0x0e7e, 0x0f7e, 0x157e, 0x047e,
+       0x027e, 0x2071, 0x7280, 0x7444, 0xa4a4, 0xe600, 0x0040, 0x65d4,
+       0xa486, 0x2000, 0x0040, 0x6592, 0xa486, 0x0400, 0x0040, 0x6592,
+       0x7130, 0xa18c, 0x00ff, 0xa182, 0x0010, 0x00c8, 0x6663, 0x0c7e,
+       0x1078, 0x416d, 0x2c68, 0x0c7f, 0x6a00, 0xa284, 0x0001, 0x0040,
+       0x6644, 0x1078, 0x420a, 0x0040, 0x666f, 0xa295, 0x0200, 0x6a02,
+       0x0078, 0x6598, 0x2009, 0x0001, 0x2011, 0x0200, 0x1078, 0x41f4,
+       0x1078, 0x130f, 0x1040, 0x12b7, 0x6003, 0x0007, 0x6106, 0x2d00,
+       0x6837, 0x010d, 0x6803, 0x0000, 0x683b, 0x0000, 0x6c5a, 0x2c00,
+       0x685e, 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, 0xa18c, 0x00ff,
+       0xa10d, 0x6946, 0x684f, 0x0000, 0x6857, 0x0036, 0x1078, 0x36a1,
+       0xa486, 0x2000, 0x00c0, 0x65c2, 0x2019, 0x0017, 0x1078, 0x6b8f,
+       0x0078, 0x6631, 0xa486, 0x0400, 0x00c0, 0x65cc, 0x2019, 0x0002,
+       0x1078, 0x6b8f, 0x0078, 0x6631, 0xa486, 0x0200, 0x00c0, 0x65d2,
+       0x1078, 0x6b80, 0x0078, 0x6631, 0x7130, 0xa18c, 0x00ff, 0xa182,
+       0x0010, 0x00c8, 0x6687, 0x0c7e, 0x1078, 0x416d, 0x2c68, 0x0c7f,
+       0x6a00, 0xa284, 0x0001, 0x0040, 0x668b, 0xa284, 0x0300, 0x00c0,
+       0x6683, 0x6804, 0xa005, 0x0040, 0x666f, 0x8001, 0x6806, 0x6003,
+       0x0007, 0x6106, 0x1078, 0x12f4, 0x0040, 0x6638, 0x6013, 0x0000,
+       0x6803, 0x0000, 0x6837, 0x0116, 0x683b, 0x0000, 0x2c00, 0x684a,
+       0x6018, 0x2078, 0x78a0, 0x8007, 0xa10d, 0x6946, 0x6853, 0x003d,
+       0x7044, 0xa084, 0x0003, 0xa086, 0x0002, 0x00c0, 0x6613, 0x684f,
+       0x0040, 0x0078, 0x661d, 0xa086, 0x0001, 0x00c0, 0x661b, 0x684f,
+       0x0080, 0x0078, 0x661d, 0x684f, 0x0000, 0x20a9, 0x000a, 0x2001,
+       0x7290, 0xad90, 0x0015, 0x200c, 0x810f, 0x2112, 0x8000, 0x8210,
+       0x00f0, 0x6623, 0x200c, 0x6982, 0x8000, 0x200c, 0x697e, 0x1078,
+       0x36a1, 0x027f, 0x047f, 0x157f, 0x0f7f, 0x0e7f, 0x0d7f, 0x007c,
+       0x6013, 0x0100, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078, 0x4327,
+       0x1078, 0x476a, 0x0078, 0x6631, 0x2069, 0x7292, 0x2d04, 0xa084,
+       0xff00, 0xa086, 0x1200, 0x00c0, 0x6663, 0x2069, 0x7280, 0x686c,
+       0xa084, 0x00ff, 0x017e, 0x6110, 0xa18c, 0x0700, 0xa10d, 0x6112,
+       0x017f, 0x6003, 0x0001, 0x6007, 0x0043, 0x1078, 0x4327, 0x1078,
+       0x476a, 0x0078, 0x6631, 0x6013, 0x0200, 0x6003, 0x0001, 0x6007,
+       0x0041, 0x1078, 0x4327, 0x1078, 0x476a, 0x0078, 0x6631, 0xa284,
+       0x0004, 0x00c0, 0x6677, 0x6013, 0x0300, 0x0078, 0x6679, 0x6013,
+       0x0100, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078, 0x4327, 0x1078,
+       0x476a, 0x0078, 0x6631, 0x6013, 0x0500, 0x0078, 0x6679, 0x6013,
+       0x0600, 0x0078, 0x6644, 0x6013, 0x0200, 0x0078, 0x6644, 0xa186,
+       0x0013, 0x00c0, 0x66a1, 0x6004, 0xa08a, 0x0040, 0x1048, 0x12b7,
+       0xa08a, 0x004f, 0x10c8, 0x12b7, 0xa082, 0x0040, 0x2008, 0x0079,
+       0x66cd, 0xa186, 0x0047, 0x00c0, 0x66a7, 0x0078, 0x66fb, 0xa186,
+       0x0014, 0x10c0, 0x12b7, 0x6004, 0xa082, 0x0040, 0x2008, 0x0079,
+       0x66b1, 0x66c0, 0x66c2, 0x66c2, 0x66c0, 0x66c0, 0x66c0, 0x66c0,
+       0x66c0, 0x66c0, 0x66c0, 0x66c0, 0x66c0, 0x66c0, 0x66c0, 0x66c0,
+       0x1078, 0x12b7, 0x2001, 0x0007, 0x1078, 0x3401, 0x1078, 0x4671,
+       0x1078, 0x6283, 0x1078, 0x476a, 0x007c, 0x66dc, 0x66ec, 0x66e5,
+       0x66f5, 0x66dc, 0x66dc, 0x66dc, 0x66dc, 0x66dc, 0x66dc, 0x66dc,
+       0x66dc, 0x66dc, 0x66dc, 0x66dc, 0x1078, 0x12b7, 0x6010, 0xa088,
+       0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x1078, 0x4671, 0x6003,
+       0x0002, 0x1078, 0x476a, 0x007c, 0x1078, 0x4671, 0x1078, 0x41cd,
+       0x1078, 0x556a, 0x1078, 0x476a, 0x007c, 0x1078, 0x4671, 0x2009,
+       0x0041, 0x0078, 0x67be, 0xa182, 0x0040, 0x0079, 0x66ff, 0x670e,
+       0x6710, 0x670e, 0x670e, 0x670e, 0x670e, 0x670e, 0x6711, 0x670e,
+       0x670e, 0x670e, 0x670e, 0x670e, 0x670e, 0x670e, 0x1078, 0x12b7,
+       0x007c, 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20,
+       0x2c10, 0x1078, 0x1532, 0x007c, 0xa182, 0x0040, 0x0079, 0x6720,
+       0x672f, 0x672f, 0x672f, 0x672f, 0x672f, 0x672f, 0x672f, 0x672f,
+       0x672f, 0x6731, 0x6754, 0x672f, 0x672f, 0x672f, 0x672f, 0x1078,
+       0x12b7, 0x1078, 0x4719, 0x1078, 0x4821, 0x6010, 0x0d7e, 0x2068,
+       0x684c, 0xd0fc, 0x0040, 0x6747, 0xa08c, 0x0003, 0xa18e, 0x0002,
+       0x0040, 0x674d, 0x2009, 0x0041, 0x0d7f, 0x0078, 0x67be, 0x6003,
+       0x0007, 0x1078, 0x41cd, 0x0d7f, 0x007c, 0x1078, 0x41cd, 0x1078,
+       0x556a, 0x0d7f, 0x0078, 0x674c, 0x2001, 0x0007, 0x1078, 0x3401,
+       0x1078, 0x4719, 0x1078, 0x4821, 0x6010, 0x0d7e, 0x2068, 0x037e,
+       0x2019, 0x0004, 0x1078, 0x6bb3, 0x037f, 0x1078, 0x6283, 0x0d7f,
+       0x007c, 0xa186, 0x0013, 0x00c0, 0x6777, 0x6004, 0xa086, 0x0042,
+       0x10c0, 0x12b7, 0x1078, 0x4671, 0x1078, 0x476a, 0x007c, 0xa186,
+       0x0014, 0x00c0, 0x678b, 0x6004, 0xa086, 0x0042, 0x10c0, 0x12b7,
+       0x2001, 0x0007, 0x1078, 0x3401, 0x1078, 0x4671, 0x1078, 0x6283,
+       0x1078, 0x476a, 0x007c, 0xa182, 0x0040, 0x0079, 0x678f, 0x679e,
+       0x679e, 0x679e, 0x679e, 0x679e, 0x679e, 0x679e, 0x67a0, 0x67ac,
+       0x679e, 0x679e, 0x679e, 0x679e, 0x679e, 0x679e, 0x1078, 0x12b7,
+       0x037e, 0x047e, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078,
+       0x1532, 0x047f, 0x037f, 0x007c, 0x6010, 0x0d7e, 0x2068, 0x684c,
+       0xd0fc, 0x0040, 0x67b8, 0x2009, 0x0041, 0x0d7f, 0x0078, 0x67be,
+       0x6003, 0x0007, 0x1078, 0x41cd, 0x0d7f, 0x007c, 0xa182, 0x0040,
+       0x0079, 0x67c2, 0x67d1, 0x67d3, 0x67df, 0x67eb, 0x67d1, 0x67d1,
+       0x67d1, 0x67d1, 0x67d1, 0x67d1, 0x67d1, 0x67d1, 0x67d1, 0x67d1,
+       0x67d1, 0x1078, 0x12b7, 0x6003, 0x0001, 0x6106, 0x1078, 0x4327,
+       0x127e, 0x2091, 0x8000, 0x1078, 0x476a, 0x127f, 0x007c, 0x6003,
+       0x0001, 0x6106, 0x1078, 0x4327, 0x127e, 0x2091, 0x8000, 0x1078,
+       0x476a, 0x127f, 0x007c, 0x6003, 0x0003, 0x6106, 0x2c10, 0x1078,
+       0x17de, 0x127e, 0x2091, 0x8000, 0x1078, 0x4395, 0x1078, 0x4821,
+       0x127f, 0x007c, 0x1078, 0x4671, 0x0078, 0x6800, 0x1078, 0x4719,
+       0x6110, 0x81ff, 0x0040, 0x680d, 0x0d7e, 0x2168, 0x037e, 0x2019,
+       0x0029, 0x1078, 0x6bb3, 0x037f, 0x0d7f, 0x1078, 0x6283, 0x1078,
+       0x476a, 0x007c, 0xa182, 0x0025, 0x0079, 0x6816, 0x681d, 0x681d,
+       0x681d, 0x681f, 0x681d, 0x681d, 0x681d, 0x1078, 0x12b7, 0x027e,
+       0x0e7e, 0x2071, 0x7280, 0x7220, 0x1078, 0x6ad1, 0x0040, 0x682c,
+       0x6007, 0x0026, 0x0078, 0x682e, 0x6007, 0x0027, 0x6003, 0x0001,
+       0x1078, 0x4327, 0x1078, 0x476a, 0x0e7f, 0x027f, 0x007c, 0xa186,
+       0x0013, 0x00c0, 0x6848, 0x6004, 0xa08a, 0x0025, 0x1048, 0x12b7,
+       0xa08a, 0x002c, 0x10c8, 0x12b7, 0xa082, 0x0025, 0x0079, 0x6857,
+       0xa186, 0x0014, 0x10c0, 0x12b7, 0x2001, 0x0007, 0x1078, 0x3401,
+       0x1078, 0x4671, 0x1078, 0x6283, 0x1078, 0x476a, 0x007c, 0x685e,
+       0x6860, 0x6860, 0x685e, 0x685e, 0x685e, 0x685e, 0x1078, 0x12b7,
+       0x1078, 0x4671, 0x1078, 0x556a, 0x1078, 0x476a, 0x007c, 0xa182,
+       0x0025, 0x1048, 0x12b7, 0xa182, 0x002c, 0x10c8, 0x12b7, 0xa182,
+       0x0025, 0x0079, 0x6873, 0x687a, 0x687a, 0x687a, 0x687c, 0x687a,
+       0x687a, 0x687a, 0x1078, 0x12b7, 0x007c, 0x1078, 0x4671, 0x1078,
+       0x6283, 0x1078, 0x476a, 0x007c, 0x127e, 0x037e, 0x087e, 0x2091,
+       0x8000, 0x2c40, 0x2019, 0x0002, 0x1078, 0x5387, 0x00c0, 0x68b3,
+       0x1078, 0x5428, 0x00c0, 0x68b3, 0x6000, 0xa086, 0x0000, 0x0040,
+       0x68b3, 0x601c, 0xa086, 0x0007, 0x0040, 0x68b3, 0x0d7e, 0x6010,
+       0x2068, 0x1078, 0x6120, 0x0040, 0x68a7, 0x1078, 0x6bb3, 0x0d7f,
+       0x6000, 0xa086, 0x0004, 0x00c0, 0x68af, 0x1078, 0x15f2, 0x6013,
+       0x0000, 0x601f, 0x0007, 0x087f, 0x037f, 0x127f, 0x007c, 0x0f7e,
+       0x0c7e, 0x037e, 0x157e, 0x2079, 0x7280, 0x7938, 0x783c, 0x1078,
+       0x1e1b, 0x00c0, 0x68e8, 0x017e, 0x0c7e, 0x1078, 0x3447, 0x00c0,
+       0x68e8, 0x2011, 0x7290, 0xac98, 0x000a, 0x20a9, 0x0004, 0x1078,
+       0x5a35, 0x00c0, 0x68e8, 0x017f, 0x027f, 0x027e, 0x017e, 0x2019,
+       0x0029, 0x1078, 0x445c, 0x1078, 0x43a9, 0x017f, 0x1078, 0x6a57,
+       0x1078, 0x35cf, 0x017f, 0x1078, 0x3256, 0xa006, 0x0078, 0x68ea,
+       0x0c7f, 0x017f, 0x157f, 0x037f, 0x0c7f, 0x0f7f, 0x007c, 0x0e7e,
+       0x0d7e, 0x0c7e, 0x047e, 0x037e, 0x027e, 0x2061, 0x7400, 0x2071,
+       0x6d00, 0x7444, 0x7060, 0x8001, 0xa402, 0x00c8, 0x6929, 0x2100,
+       0xac06, 0x0040, 0x691b, 0x6000, 0xa086, 0x0000, 0x0040, 0x691b,
+       0x6018, 0x2068, 0x68a0, 0xa206, 0x00c0, 0x691b, 0x631c, 0xa386,
+       0x0004, 0x0040, 0x6925, 0xa386, 0x0005, 0x0040, 0x6925, 0xa386,
+       0x0006, 0x0040, 0x6925, 0xace0, 0x0008, 0x2001, 0x6d15, 0x2004,
+       0xac02, 0x00c8, 0x6929, 0x0078, 0x68f7, 0xa085, 0x0001, 0x0078,
+       0x692a, 0xa006, 0x027f, 0x037f, 0x047f, 0x0c7f, 0x0d7f, 0x0e7f,
+       0x007c, 0x0c7e, 0x0d7e, 0x017e, 0x2009, 0x6d1e, 0x2104, 0xa086,
+       0x0074, 0x00c0, 0x6988, 0x2069, 0x728e, 0x690c, 0xa182, 0x0100,
+       0x0048, 0x6978, 0x6908, 0xa184, 0x8000, 0x0040, 0x6984, 0xa184,
+       0x0800, 0x0040, 0x6984, 0x6910, 0xa18a, 0x0001, 0x0048, 0x697c,
+       0x6914, 0x2069, 0x72ae, 0x6904, 0x81ff, 0x00c0, 0x6970, 0x690c,
+       0xa182, 0x0100, 0x0048, 0x6978, 0x6908, 0x81ff, 0x00c0, 0x6974,
+       0x6910, 0xa18a, 0x0001, 0x0048, 0x697c, 0x6918, 0xa18a, 0x0001,
+       0x0048, 0x6984, 0x0078, 0x698e, 0x6013, 0x0100, 0x0078, 0x698a,
+       0x6013, 0x0300, 0x0078, 0x698a, 0x6013, 0x0500, 0x0078, 0x698a,
+       0x6013, 0x0700, 0x0078, 0x698a, 0x6013, 0x0900, 0x0078, 0x698a,
+       0x6013, 0x0b00, 0x0078, 0x698a, 0x6013, 0x0f00, 0x0078, 0x698a,
+       0x6013, 0x2d00, 0xa085, 0x0001, 0x0078, 0x698f, 0xa006, 0x017f,
+       0x0d7f, 0x0c7f, 0x007c, 0x0c7e, 0x0d7e, 0x027e, 0x037e, 0x157e,
+       0x6218, 0x2268, 0x6b04, 0xa394, 0x00ff, 0xa286, 0x0006, 0x0040,
+       0x69b7, 0xa286, 0x0004, 0x0040, 0x69b7, 0xa394, 0xff00, 0x8217,
+       0xa286, 0x0006, 0x0040, 0x69b7, 0xa286, 0x0004, 0x0040, 0x69b7,
+       0x0c7e, 0x2d60, 0x1078, 0x3459, 0x0c7f, 0x0078, 0x69ea, 0x2011,
+       0x7296, 0xad98, 0x000a, 0x20a9, 0x0004, 0x1078, 0x5a35, 0x00c0,
+       0x69eb, 0x2011, 0x729a, 0xad98, 0x0006, 0x20a9, 0x0004, 0x1078,
+       0x5a35, 0x00c0, 0x69eb, 0x047e, 0x017e, 0x6aa0, 0xa294, 0x00ff,
+       0x8227, 0xa006, 0x2009, 0x6d52, 0x210c, 0xd1a4, 0x0040, 0x69df,
+       0x2009, 0x0029, 0x1078, 0x6bf7, 0x6800, 0xc0e5, 0x6802, 0x2019,
+       0x0029, 0x1078, 0x445c, 0x1078, 0x43a9, 0x2c08, 0x1078, 0x6a57,
+       0x017f, 0x047f, 0xa006, 0x157f, 0x037f, 0x027f, 0x0d7f, 0x0c7f,
+       0x007c, 0x0d7e, 0x2069, 0x728e, 0x6800, 0xa086, 0x0800, 0x0040,
+       0x69fd, 0x6013, 0x0000, 0x0078, 0x69fe, 0xa006, 0x0d7f, 0x007c,
+       0x0c7e, 0x0f7e, 0x017e, 0x027e, 0x037e, 0x157e, 0x2079, 0x728c,
+       0x7930, 0x7834, 0x1078, 0x1e1b, 0x00c0, 0x6a24, 0x1078, 0x3447,
+       0x00c0, 0x6a24, 0x2011, 0x7290, 0xac98, 0x000a, 0x20a9, 0x0004,
+       0x1078, 0x5a35, 0x00c0, 0x6a24, 0x2011, 0x7294, 0xac98, 0x0006,
+       0x20a9, 0x0004, 0x1078, 0x5a35, 0x157f, 0x037f, 0x027f, 0x017f,
+       0x0f7f, 0x0c7f, 0x007c, 0x0c7e, 0x007e, 0x017e, 0x027e, 0x037e,
+       0x157e, 0x2011, 0x7283, 0x2204, 0x8211, 0x220c, 0x1078, 0x1e1b,
+       0x00c0, 0x6a50, 0x1078, 0x3447, 0x00c0, 0x6a50, 0x2011, 0x7296,
+       0xac98, 0x000a, 0x20a9, 0x0004, 0x1078, 0x5a35, 0x00c0, 0x6a50,
+       0x2011, 0x729a, 0xac98, 0x0006, 0x20a9, 0x0004, 0x1078, 0x5a35,
+       0x157f, 0x037f, 0x027f, 0x017f, 0x007f, 0x0c7f, 0x007c, 0x0e7e,
+       0x0c7e, 0x077e, 0x067e, 0x057e, 0x047e, 0x027e, 0x127e, 0x2091,
+       0x8000, 0x2029, 0x6f19, 0x252c, 0x2021, 0x6f1f, 0x2424, 0x2061,
+       0x7400, 0x2071, 0x6d00, 0x7644, 0x7060, 0x8001, 0xa602, 0x00c8,
+       0x6abc, 0x2100, 0xac06, 0x0040, 0x6ab2, 0x1078, 0x6c0f, 0x0040,
+       0x6ab2, 0x671c, 0xa786, 0x0001, 0x0040, 0x6ab2, 0xa786, 0x0007,
+       0x0040, 0x6ab2, 0x2500, 0xac06, 0x0040, 0x6ab2, 0x2400, 0xac06,
+       0x0040, 0x6ab2, 0x6018, 0x2070, 0x70a0, 0xa206, 0x00c0, 0x6ab2,
+       0x0d7e, 0x6010, 0x2068, 0x1078, 0x6120, 0x0040, 0x6aa6, 0xa786,
+       0x0003, 0x00c0, 0x6ac5, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000,
+       0x017e, 0x1078, 0x36a1, 0x017f, 0x1078, 0x6276, 0x0d7f, 0x6000,
+       0xa086, 0x0004, 0x00c0, 0x6ab0, 0x017e, 0x1078, 0x15f2, 0x017f,
+       0x1078, 0x6283, 0xace0, 0x0008, 0x2001, 0x6d15, 0x2004, 0xac02,
+       0x00c8, 0x6abc, 0x0078, 0x6a69, 0x127f, 0x027f, 0x047f, 0x057f,
+       0x067f, 0x077f, 0x0c7f, 0x0e7f, 0x007c, 0xa786, 0x0006, 0x00c0,
+       0x6a9b, 0xa386, 0x0005, 0x0040, 0x6ab2, 0x1078, 0x6bb3, 0x0078,
+       0x6aa6, 0x0c7e, 0x0e7e, 0x017e, 0x2c08, 0x2170, 0x1078, 0x6bca,
+       0x017f, 0x0040, 0x6ae0, 0x601c, 0xa084, 0x000f, 0x1079, 0x6ae3,
+       0x0e7f, 0x0c7f, 0x007c, 0x6aeb, 0x6aeb, 0x6aeb, 0x6aeb, 0x6aeb,
+       0x6aeb, 0x6aed, 0x6aeb, 0xa006, 0x007c, 0x047e, 0x017e, 0x7018,
+       0xa080, 0x0028, 0x2024, 0xa4a4, 0x00ff, 0x8427, 0x2c00, 0x2009,
+       0x0020, 0x1078, 0x6bf7, 0x017f, 0x047f, 0x1078, 0x6884, 0xa085,
+       0x0001, 0x007c, 0x2001, 0x0001, 0x1078, 0x33df, 0x157e, 0x017e,
+       0x027e, 0x037e, 0x20a9, 0x0004, 0x2019, 0x6d05, 0x2011, 0x7296,
+       0x1078, 0x5a35, 0x037f, 0x027f, 0x017f, 0x157f, 0xa005, 0x007c,
+       0x0f7e, 0x0e7e, 0x0c7e, 0x077e, 0x067e, 0x027e, 0x127e, 0x2091,
+       0x8000, 0x2061, 0x7400, 0x2079, 0x0001, 0x8fff, 0x0040, 0x6b73,
+       0x2071, 0x6d00, 0x7644, 0x7060, 0x8001, 0xa602, 0x00c8, 0x6b73,
+       0x88ff, 0x0040, 0x6b39, 0x2800, 0xac06, 0x00c0, 0x6b69, 0x2079,
+       0x0000, 0x1078, 0x6c0f, 0x0040, 0x6b69, 0x2400, 0xac06, 0x0040,
+       0x6b69, 0x671c, 0xa786, 0x0006, 0x00c0, 0x6b69, 0xa786, 0x0007,
+       0x0040, 0x6b69, 0x88ff, 0x00c0, 0x6b51, 0x6018, 0xa206, 0x00c0,
+       0x6b69, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x6120, 0x0040, 0x6b5c,
+       0x047e, 0x1078, 0x6bb3, 0x047f, 0x0d7f, 0x6000, 0xa086, 0x0004,
+       0x00c0, 0x6b64, 0x1078, 0x15f2, 0x1078, 0x6283, 0x88ff, 0x00c0,
+       0x6b7c, 0xace0, 0x0008, 0x2001, 0x6d15, 0x2004, 0xac02, 0x00c8,
+       0x6b73, 0x0078, 0x6b25, 0xa006, 0x127f, 0x027f, 0x067f, 0x077f,
+       0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0xa8c5, 0x0001, 0x0078, 0x6b74,
+       0x087e, 0x2041, 0x0000, 0x2c20, 0x2019, 0x0002, 0x6218, 0x1078,
+       0x5387, 0x1078, 0x5428, 0x1078, 0x6b18, 0x087f, 0x007c, 0x027e,
+       0x047e, 0x087e, 0x0c7e, 0x157e, 0x2c20, 0x20a9, 0x007f, 0x2009,
+       0x0000, 0x017e, 0x037e, 0x1078, 0x3447, 0x00c0, 0x6ba8, 0x2c10,
+       0x2041, 0x0000, 0x1078, 0x5387, 0x1078, 0x5428, 0x1078, 0x6b18,
+       0x037f, 0x017f, 0x8108, 0x00f0, 0x6b99, 0x157f, 0x0c7f, 0x087f,
+       0x047f, 0x027f, 0x007c, 0x017e, 0x0f7e, 0x8dff, 0x0040, 0x6bc7,
+       0x6800, 0xa07d, 0x0040, 0x6bc4, 0x6803, 0x0000, 0x6b52, 0x1078,
+       0x36a1, 0x2f68, 0x0078, 0x6bb8, 0x6b52, 0x1078, 0x36a1, 0x0f7f,
+       0x017f, 0x007c, 0x0e7e, 0x047e, 0x037e, 0x2061, 0x7400, 0x2071,
+       0x6d00, 0x7444, 0x7060, 0x8001, 0xa402, 0x00c8, 0x6bf2, 0x2100,
+       0xac06, 0x0040, 0x6be4, 0x6000, 0xa086, 0x0000, 0x0040, 0x6be4,
+       0x6008, 0xa206, 0x0040, 0x6bee, 0xace0, 0x0008, 0x2001, 0x6d15,
+       0x2004, 0xac02, 0x00c8, 0x6bf2, 0x0078, 0x6bcf, 0xa085, 0x0001,
+       0x0078, 0x6bf3, 0xa006, 0x037f, 0x047f, 0x0e7f, 0x007c, 0x0d7e,
+       0x007e, 0x1078, 0x130f, 0x007f, 0x1040, 0x12b7, 0x6837, 0x010d,
+       0x6803, 0x0000, 0x683b, 0x0000, 0x685b, 0x0000, 0x685e, 0x6956,
+       0x6c46, 0x684f, 0x0000, 0x1078, 0x36a1, 0x0d7f, 0x007c, 0x6700,
+       0xa786, 0x0000, 0x0040, 0x6c22, 0xa786, 0x0001, 0x0040, 0x6c22,
+       0xa786, 0x000a, 0x0040, 0x6c22, 0xa786, 0x0009, 0x0040, 0x6c22,
+       0xa085, 0x0001, 0x007c, 0x127e, 0x007e, 0x0e7e, 0x2091, 0x8000,
+       0x2071, 0x6d00, 0xd5a4, 0x0040, 0x6c30, 0x7034, 0x8000, 0x7036,
+       0xd5b4, 0x0040, 0x6c36, 0x7030, 0x8000, 0x7032, 0xd5ac, 0x0040,
+       0x6c3d, 0x2071, 0x6d0a, 0x1078, 0x6c6c, 0x0e7f, 0x007f, 0x127f,
+       0x007c, 0x127e, 0x007e, 0x0e7e, 0x2091, 0x8000, 0x2071, 0x6d00,
+       0xd5a4, 0x0040, 0x6c4e, 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0040,
+       0x6c54, 0x7030, 0x8000, 0x7032, 0xd5ac, 0x0040, 0x6c5b, 0x2071,
+       0x6d0a, 0x1078, 0x6c6c, 0x0e7f, 0x007f, 0x127f, 0x007c, 0x127e,
+       0x007e, 0x0e7e, 0x2091, 0x8000, 0x2071, 0x6d02, 0x1078, 0x6c6c,
+       0x0e7f, 0x007f, 0x127f, 0x007c, 0x2e04, 0x8000, 0x2072, 0x00c8,
+       0x6c75, 0x8e70, 0x2e04, 0x8000, 0x2072, 0x007c, 0x0e7e, 0x2071,
+       0x6d00, 0x1078, 0x6c6c, 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0x6d04,
+       0x1078, 0x6c6c, 0x0e7f, 0x007c, 0x0001, 0x0002, 0x0004, 0x0008,
+       0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800,
+       0x1000, 0x2000, 0x4000, 0x8000, 0x614c
+};
+unsigned short   risc_code_length01 = 0x5c95;
+
index a3d7c3538a589b3f672c86e79c80170b77020c25..bdff5d78c5718401bc3a16e52ed78094e07b293f 100644 (file)
@@ -563,6 +563,7 @@ void scsi_sleep (int timeout)
     struct semaphore sem = MUTEX_LOCKED;
     struct timer_list timer;
 
+    init_timer(&timer);
     timer.data = (unsigned long) &sem;
     timer.expires = jiffies + timeout;
     timer.function = (void (*)(unsigned long))scsi_sleep_done;
index 26ea27a33d36928939523e3f10990044eb572329..ca19c6f6ba3be3c90649a0b2d348ce844ed48ef9 100644 (file)
@@ -108,6 +108,11 @@ int sd_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigne
                 return -EACCES;
        return revalidate_scsidisk(dev, 1);
 
+    case BLKSSZGET:
+       /* Block size of media */
+       return put_user(blksize_size[MAJOR(dev)][MINOR(dev)&0x0F],
+               (int *)arg);
+                               
     RO_IOCTLS(dev, arg);
 
     default:
index 2eaad47d830559cdb9c25373780dbe87295ea851..fd63e42cae7d65fb0eba12ace6fe8359bcbc4f4e 100644 (file)
@@ -872,6 +872,11 @@ int sr_dev_ioctl(struct cdrom_device_info *cdi,
        read_ahead[MAJOR(cdi->dev)] = arg;
        return 0;
 
+    case BLKSSZGET:
+       /* Block size of media */
+       return put_user(blksize_size[MAJOR(cdi->dev)][MINOR(cdi->dev)],
+               (int *)arg);
+
     RO_IOCTLS(cdi->dev,arg);
 
     case BLKFLSBUF:
diff --git a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c
new file mode 100644 (file)
index 0000000..166a66d
--- /dev/null
@@ -0,0 +1,806 @@
+/* 
+ *  sym53c416.c
+ *  Low-level SCSI driver for sym53c416 chip.
+ *  Copyright (C) 1998 Lieven Willems (lw_linux@hotmail.com)
+ * 
+ *  LILO command line usage: sym53c416=<PORTBASE>[,<IRQ>]
+ *
+ *  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.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <asm/dma.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <linux/blk.h>
+#include <linux/version.h>
+#include "scsi.h"
+#include "hosts.h"
+#include "sd.h"
+#include "sym53c416.h"
+
+#define VERSION_STRING        "Version 1.0.0"
+
+#define TC_LOW       0x00     /* Transfer counter low        */
+#define TC_MID       0x01     /* Transfer counter mid        */
+#define SCSI_FIFO    0x02     /* SCSI FIFO register          */
+#define COMMAND_REG  0x03     /* Command Register            */
+#define STATUS_REG   0x04     /* Status Register (READ)      */
+#define DEST_BUS_ID  0x04     /* Destination Bus ID (WRITE)  */
+#define INT_REG      0x05     /* Interrupt Register (READ)   */
+#define TOM          0x05     /* Time out multiplier (WRITE) */
+#define STP          0x06     /* Synchronous Transfer period */
+#define SYNC_OFFSET  0x07     /* Synchronous Offset          */
+#define CONF_REG_1   0x08     /* Configuration register 1    */
+#define CONF_REG_2   0x0B     /* Configuration register 2    */
+#define CONF_REG_3   0x0C     /* Configuration register 3    */
+#define CONF_REG_4   0x0D     /* Configuration register 4    */
+#define TC_HIGH      0x0E     /* Transfer counter high       */
+#define PIO_FIFO_1   0x10     /* PIO FIFO register 1         */
+#define PIO_FIFO_2   0x11     /* PIO FIFO register 2         */
+#define PIO_FIFO_3   0x12     /* PIO FIFO register 3         */
+#define PIO_FIFO_4   0x13     /* PIO FIFO register 4         */
+#define PIO_FIFO_CNT 0x14     /* PIO FIFO count              */
+#define PIO_INT_REG  0x15     /* PIO interrupt register      */
+#define CONF_REG_5   0x16     /* Configuration register 5    */
+#define FEATURE_EN   0x1D     /* Feature Enable register     */
+
+/* Configuration register 1 entries: */
+/* Bits 2-0: SCSI ID of host adapter */
+#define SCM    0x80                     /* Slow Cable Mode              */
+#define SRID   0x40                     /* SCSI Reset Interrupt Disable */
+#define PTM    0x20                     /* Parity Test Mode             */
+#define EPC    0x10                     /* Enable Parity Checking       */
+#define CTME   0x08                     /* Special Test Mode            */
+
+/* Configuration register 2 entries: */
+#define FE     0x40                     /* Features Enable              */
+#define SCSI2  0x08                     /* SCSI 2 Enable                */
+#define TBPA   0x04                     /* Target Bad Parity Abort      */
+
+/* Configuration register 3 entries: */
+#define IDMRC  0x80                     /* ID Message Reserved Check    */
+#define QTE    0x40                     /* Queue Tag Enable             */
+#define CDB10  0x20                     /* Command Descriptor Block 10  */
+#define FSCSI  0x10                     /* FastSCSI                     */
+#define FCLK   0x08                     /* FastClock                    */
+
+/* Configuration register 4 entries: */
+#define RBS    0x08                     /* Register bank select         */
+#define EAN    0x04                     /* Enable Active Negotiation    */
+
+/* Configuration register 5 entries: */
+#define LPSR   0x80                     /* Lower Power SCSI Reset       */
+#define IE     0x20                     /* Interrupt Enable             */
+#define LPM    0x02                     /* Low Power Mode               */
+#define WSE0   0x01                     /* 0WS Enable                   */
+
+/* Interrupt register entries: */
+#define SRST   0x80                     /* SCSI Reset                   */
+#define ILCMD  0x40                     /* Illegal Command              */
+#define DIS    0x20                     /* Disconnect                   */
+#define BS     0x10                     /* Bus Service                  */
+#define FC     0x08                     /* Function Complete            */
+#define RESEL  0x04                     /* Reselected                   */
+#define SI     0x03                     /* Selection Interrupt          */
+
+/* Status Register Entries: */
+#define SCI    0x80                     /* SCSI Core Int                */
+#define GE     0x40                     /* Gross Error                  */
+#define PE     0x20                     /* Parity Error                 */
+#define TC     0x10                     /* Terminal Count               */
+#define VGC    0x08                     /* Valid Group Code             */
+#define PHBITS 0x07                     /* Phase bits                   */
+
+/* PIO Interrupt Register Entries: */
+#define SCI    0x80                     /* SCSI Core Int                */
+#define PFI    0x40                     /* PIO FIFO Interrupt           */
+#define FULL   0x20                     /* PIO FIFO Full                */
+#define EMPTY  0x10                     /* PIO FIFO Empty               */
+#define CE     0x08                     /* Collision Error              */
+#define OUE    0x04                     /* Overflow / Underflow error   */
+#define FIE    0x02                     /* Full Interrupt Enable        */
+#define EIE    0x01                     /* Empty Interrupt Enable       */
+
+/* SYM53C416 SCSI phases (lower 3 bits of SYM53C416_STATUS_REG) */
+#define PHASE_DATA_OUT    0x00
+#define PHASE_DATA_IN     0x01
+#define PHASE_COMMAND     0x02
+#define PHASE_STATUS      0x03
+#define PHASE_RESERVED_1  0x04
+#define PHASE_RESERVED_2  0x05
+#define PHASE_MESSAGE_OUT 0x06
+#define PHASE_MESSAGE_IN  0x07
+
+/* SYM53C416 core commands */
+#define NOOP                      0x00
+#define FLUSH_FIFO                0x01
+#define RESET_CHIP                0x02
+#define RESET_SCSI_BUS            0x03
+#define DISABLE_SEL_RESEL         0x45
+#define RESEL_SEQ                 0x40
+#define SEL_WITHOUT_ATN_SEQ       0x41
+#define SEL_WITH_ATN_SEQ          0x42
+#define SEL_WITH_ATN_AND_STOP_SEQ 0x43
+#define ENABLE_SEL_RESEL          0x44
+#define SEL_WITH_ATN3_SEQ         0x46
+#define RESEL3_SEQ                0x47
+#define SND_MSG                   0x20
+#define SND_STAT                  0x21
+#define SND_DATA                  0x22
+#define DISCONNECT_SEQ            0x23
+#define TERMINATE_SEQ             0x24
+#define TARGET_COMM_COMPLETE_SEQ  0x25
+#define DISCONN                   0x27
+#define RECV_MSG_SEQ              0x28
+#define RECV_CMD                  0x29
+#define RECV_DATA                 0x2A
+#define RECV_CMD_SEQ              0x2B
+#define TARGET_ABORT_PIO          0x04
+#define TRANSFER_INFORMATION      0x10
+#define INIT_COMM_COMPLETE_SEQ    0x11
+#define MSG_ACCEPTED              0x12
+#define TRANSFER_PAD              0x18
+#define SET_ATN                   0x1A
+#define RESET_ATN                 0x1B
+#define ILLEGAL                   0xFF
+
+#define PIO_MODE                  0x80
+
+#define IO_RANGE 0x20         /* 0x00 - 0x1F                   */
+#define ID       "sym53c416"
+#define PIO_SIZE 128          /* Size of PIO fifo is 128 bytes */
+
+#define READ_TIMEOUT              150
+#define WRITE_TIMEOUT             150
+
+#ifdef MODULE
+
+#define sym53c416_base sym53c416
+#define sym53c416_base_1 sym53c416_1
+#define sym53c416_base_2 sym53c416_2
+#define sym53c416_base_3 sym53c416_3
+
+static unsigned short sym53c416_base = 0;
+static unsigned int sym53c416_irq = 0;
+static unsigned short sym53c416_base_1 = 0;
+static unsigned int sym53c416_irq_1 = 0;
+static unsigned short sym53c416_base_2 = 0;
+static unsigned int sym53c416_irq_2 = 0;
+static unsigned short sym53c416_base_3 = 0;
+static unsigned int sym53c416_irq_3 = 0;
+
+#endif
+
+/* #define DEBUG */
+
+/* Macro for debugging purposes */
+
+#ifdef DEBUG
+#define DEB(x) x
+#else
+#define DEB(x)
+#endif
+
+#define MAXHOSTS 4
+
+enum phases
+  {
+  idle,
+  data_out,
+  data_in,
+  command_ph,
+  status_ph,
+  message_out,
+  message_in
+  };
+
+typedef struct
+  {
+  int base;
+  int irq;
+  int scsi_id;
+  } host;
+
+host hosts[MAXHOSTS] = {
+                       {0, 0, SYM53C416_SCSI_ID},
+                       {0, 0, SYM53C416_SCSI_ID},
+                       {0, 0, SYM53C416_SCSI_ID},
+                       {0, 0, SYM53C416_SCSI_ID}
+                       };
+
+static int host_index = 0;
+
+static char info[120];
+
+static Scsi_Cmnd *current_command = NULL;
+
+struct proc_dir_entry proc_scsi_sym53c416 = {PROC_SCSI_SYM53C416, 7, ID, S_IFDIR | S_IRUGO | S_IXUGO, 2};
+
+int fastpio = 1;
+
+int probeaddrs[] = {0x200, 0x220, 0x240, 0};
+
+static void sym53c416_set_transfer_counter(int base, unsigned int len)
+  {
+  /* Program Transfer Counter */
+  outb(len & 0x0000FF, base + TC_LOW);
+  outb((len & 0x00FF00) >> 8, base + TC_MID);
+  outb((len & 0xFF0000) >> 16, base + TC_HIGH);
+  }
+
+/* Returns the number of bytes read */
+static __inline__ unsigned int sym53c416_read(int base, unsigned char *buffer, unsigned int len)
+  {
+  unsigned int orig_len = len;
+  unsigned long flags = 0;
+  unsigned int bytes_left;
+  int i;
+  int timeout = READ_TIMEOUT;
+
+  /* Do transfer */
+  save_flags(flags);
+  cli();
+  while(len && timeout)
+    {
+    bytes_left = inb(base + PIO_FIFO_CNT); /* Number of bytes in the PIO FIFO */
+    if(fastpio && bytes_left > 3)
+      {
+      insl(base + PIO_FIFO_1, buffer, bytes_left >> 2);
+      buffer += bytes_left & 0xFC;
+      len -= bytes_left & 0xFC;
+      }
+    else if(bytes_left > 0)
+      {
+      len -= bytes_left;
+      for(; bytes_left > 0; bytes_left--)
+        *(buffer++) = inb(base + PIO_FIFO_1);
+      }
+    else
+      {
+      i = jiffies + timeout;
+      restore_flags(flags);
+      while(jiffies < i && (inb(base + PIO_INT_REG) & EMPTY) && timeout)
+        if(inb(base + PIO_INT_REG) & SCI)
+          timeout = 0;
+      save_flags(flags);
+      cli();
+      if(inb(base + PIO_INT_REG) & EMPTY)
+        timeout = 0;
+      }
+    }
+  restore_flags(flags);
+  return orig_len - len;
+  }
+
+/* Returns the number of bytes written */
+static __inline__ unsigned int sym53c416_write(int base, unsigned char *buffer, unsigned int len)
+  {
+  unsigned int orig_len = len;
+  unsigned long flags = 0;
+  unsigned int bufferfree;
+  unsigned int i;
+  unsigned int timeout = WRITE_TIMEOUT;
+
+  /* Do transfer */
+  save_flags(flags);
+  cli();
+  while(len && timeout)
+    {
+    bufferfree = PIO_SIZE - inb(base + PIO_FIFO_CNT);
+    if(bufferfree > len)
+      bufferfree = len;
+    if(fastpio && bufferfree > 3)
+      {
+      outsl(base + PIO_FIFO_1, buffer, bufferfree >> 2);
+      buffer += bufferfree & 0xFC;
+      len -= bufferfree & 0xFC;
+      }
+    else if(bufferfree > 0)
+      {
+      len -= bufferfree;
+      for(; bufferfree > 0; bufferfree--)
+        outb(*(buffer++), base + PIO_FIFO_1);
+      }
+    else
+      {
+      i = jiffies + timeout;
+      restore_flags(flags);
+      while(jiffies < i && (inb(base + PIO_INT_REG) & FULL) && timeout)
+        ;
+      save_flags(flags);
+      cli();
+      if(inb(base + PIO_INT_REG) & FULL)
+        timeout = 0;
+      }
+    }
+  restore_flags(flags);
+  return orig_len - len;
+  }
+
+static void sym53c416_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
+  {
+  int base = 0;
+  int i;
+  unsigned long flags = 0;
+  unsigned char status_reg, pio_int_reg, int_reg;
+  struct scatterlist *sglist;
+  unsigned int sgcount;
+  unsigned int tot_trans = 0;
+
+  /* We search the base address of the host adapter which caused the interrupt */
+  for(i = 0; i < host_index && !base; i++)
+    if(irq == hosts[i].irq)
+      base = hosts[i].base;
+  /* If no adapter found, we cannot handle the interrupt. Leave a message */
+  /* and continue. This should never happen...                            */
+  if(!base)
+    {
+    printk("sym53c416: No host adapter defined for interrupt %d\n", irq);
+    return;
+    }
+  /* Now we have the base address and we can start handling the interrupt */
+  save_flags(flags);
+  cli();
+  status_reg = inb(base + STATUS_REG);
+  pio_int_reg = inb(base + PIO_INT_REG);
+  int_reg = inb(base + INT_REG);
+  restore_flags(flags);
+
+  /* First, we handle error conditions */
+  if(int_reg & SCI)         /* SCSI Reset */
+    {
+    printk("sym53c416: Warning: Reset received\n");
+    current_command->SCp.phase = idle;
+    current_command->result = DID_RESET << 16;
+    current_command->scsi_done(current_command);
+    return;
+    }
+  if(int_reg & ILCMD)       /* Illegal Command */
+    {
+    printk("sym53c416: Warning: Illegal Command: 0x%02x\n", inb(base + COMMAND_REG));
+    current_command->SCp.phase = idle;
+    current_command->result = DID_ERROR << 16;
+    current_command->scsi_done(current_command);
+    return;
+    }
+  if(status_reg & GE)         /* Gross Error */
+    {
+    printk("sym53c416: Warning: Gross Error\n");
+    current_command->SCp.phase = idle;
+    current_command->result = DID_ERROR << 16;
+    current_command->scsi_done(current_command);
+    return;
+    }
+  if(status_reg & PE)         /* Parity Error */
+    {
+    printk("sym53c416: Warning: Parity Error\n");
+    current_command->SCp.phase = idle;
+    current_command->result = DID_PARITY << 16;
+    current_command->scsi_done(current_command);
+    return;
+    }
+  if(pio_int_reg & (CE | OUE))
+    {
+    printk("sym53c416: Warning: PIO Interrupt Error\n");
+    current_command->SCp.phase = idle;
+    current_command->result = DID_ERROR << 16;
+    current_command->scsi_done(current_command);
+    return;
+    }
+  if(int_reg & DIS)           /* Disconnect */
+    {
+    if(current_command->SCp.phase != message_in)
+      current_command->result = DID_NO_CONNECT << 16;
+    else
+      current_command->result = (current_command->SCp.Status & 0xFF) | ((current_command->SCp.Message & 0xFF) << 8) | (DID_OK << 16);
+    current_command->SCp.phase = idle;
+    current_command->scsi_done(current_command);
+    return;
+    }
+  /* Now we handle SCSI phases         */
+  switch(status_reg & PHBITS)       /* Filter SCSI phase out of status reg */
+    {
+    case PHASE_DATA_OUT:
+      {
+      if(int_reg & BS)
+        {
+        current_command->SCp.phase = data_out;
+        outb(FLUSH_FIFO, base + COMMAND_REG);
+        sym53c416_set_transfer_counter(base, current_command->request_bufflen);
+        outb(TRANSFER_INFORMATION | PIO_MODE, base + COMMAND_REG);
+        if(!current_command->use_sg)
+          tot_trans = sym53c416_write(base, current_command->request_buffer, current_command->request_bufflen);
+        else
+          {
+          sgcount = current_command->use_sg;
+          sglist = current_command->request_buffer;
+          while(sgcount--)
+            {
+            tot_trans += sym53c416_write(base, sglist->address, sglist->length);
+            sglist++;
+            }
+          }
+        if(tot_trans < current_command->underflow)
+          printk("sym53c416: Warning: underflow, wrote %d bytes, request for %d bytes\n", tot_trans, current_command->underflow);
+        }
+      break;
+      }
+    case PHASE_DATA_IN:
+      {
+      if(int_reg & BS)
+        {
+        current_command->SCp.phase = data_in;
+        outb(FLUSH_FIFO, base + COMMAND_REG);
+        sym53c416_set_transfer_counter(base, current_command->request_bufflen);
+        outb(TRANSFER_INFORMATION | PIO_MODE, base + COMMAND_REG);
+        if(!current_command->use_sg)
+          tot_trans = sym53c416_read(base, current_command->request_buffer, current_command->request_bufflen);
+        else
+          {
+          sgcount = current_command->use_sg;
+          sglist = current_command->request_buffer;
+          while(sgcount--)
+            {
+            tot_trans += sym53c416_read(base, sglist->address, sglist->length);
+            sglist++;
+            }
+          }
+        if(tot_trans < current_command->underflow)
+          printk("sym53c416: Warning: underflow, read %d bytes, request for %d bytes\n", tot_trans, current_command->underflow);
+        }
+      break;
+      }
+    case PHASE_COMMAND:
+      {
+      current_command->SCp.phase = command_ph;
+      printk("sym53c416: Warning: Unknown interrupt in command phase\n");
+      break;
+      }
+    case PHASE_STATUS:
+      {
+      current_command->SCp.phase = status_ph;
+      outb(FLUSH_FIFO, base + COMMAND_REG);
+      outb(INIT_COMM_COMPLETE_SEQ, base + COMMAND_REG);
+      break;
+      }
+    case PHASE_RESERVED_1:
+    case PHASE_RESERVED_2:
+      {
+      printk("sym53c416: Warning: Reserved phase\n");
+      break;
+      }
+    case PHASE_MESSAGE_OUT:
+      {
+      current_command->SCp.phase = message_out;
+      outb(SET_ATN, base + COMMAND_REG);
+      outb(MSG_ACCEPTED, base + COMMAND_REG);
+      break;
+      }
+    case PHASE_MESSAGE_IN:
+      {
+      current_command->SCp.phase = message_in;
+      current_command->SCp.Status = inb(base + SCSI_FIFO);
+      current_command->SCp.Message = inb(base + SCSI_FIFO);
+      if(current_command->SCp.Message == SAVE_POINTERS || current_command->SCp.Message == DISCONNECT)
+        outb(SET_ATN, base + COMMAND_REG);
+      outb(MSG_ACCEPTED, base + COMMAND_REG);
+      break;
+      }
+    }
+  }
+
+static void sym53c416_init(int base, int scsi_id)
+  {
+  outb(RESET_CHIP, base + COMMAND_REG);
+  outb(NOOP, base + COMMAND_REG);
+  outb(0x99, base + TOM); /* Time out of 250 ms */
+  outb(0x05, base + STP);
+  outb(0x00, base + SYNC_OFFSET);
+  outb(EPC | scsi_id, base + CONF_REG_1);
+  outb(FE | SCSI2 | TBPA, base + CONF_REG_2);
+  outb(IDMRC | QTE | CDB10 | FSCSI | FCLK, base + CONF_REG_3);
+  outb(0x83 | EAN, base + CONF_REG_4);
+  outb(IE | WSE0, base + CONF_REG_5);
+  outb(0, base + FEATURE_EN);
+  }
+
+static int sym53c416_probeirq(int base, int scsi_id)
+  {
+  int irq, irqs, i;
+
+  /* Clear interrupt register */
+  inb(base + INT_REG);
+  /* Start probing for irq's */
+  irqs = probe_irq_on();
+  /* Reinit chip */
+  sym53c416_init(base, scsi_id);
+  /* Cause interrupt */
+  outb(NOOP, base + COMMAND_REG);
+  outb(ILLEGAL, base + COMMAND_REG);
+  outb(0x07, base + DEST_BUS_ID);
+  outb(0x00, base + DEST_BUS_ID);
+  /* Wait for interrupt to occur */
+  i = jiffies + 20;
+  while(i > jiffies && !(inb(base + STATUS_REG) & SCI))
+    barrier();
+  if(i <= jiffies) /* timed out */
+    return 0;
+  /* Get occurred irq */
+  irq = probe_irq_off(irqs);
+  sym53c416_init(base, scsi_id);
+  return irq;
+  }
+
+/* Setup: sym53c416=base,irq */
+void sym53c416_setup(char *str, int *ints)
+  {
+  int i;
+
+  if(host_index >= MAXHOSTS)
+    {
+    printk("sym53c416.c: Too many hosts defined\n");
+    }
+  else
+    {
+    if(ints[0] < 1 || ints[0] > 2)
+      {
+      printk("sym53c416.c: Wrong number of parameters:\n");
+      printk("sym53c416.c: usage: sym53c416=<base>[,<irq>]\n");
+      }
+    else
+      {
+      for(i = 0; i < host_index && i >= 0; i++)
+        if(hosts[i].base == ints[1])
+          i = -2;
+      if(i >= 0)
+        {
+        hosts[host_index].base = ints[1];
+        hosts[host_index].irq = (ints[0] == 2)? ints[2] : 0;
+        host_index++;
+        }
+      }
+    }
+  }
+
+static int sym53c416_test(int base)
+  {
+  outb(RESET_CHIP, base + COMMAND_REG);
+  outb(NOOP, base + COMMAND_REG);
+  if(inb(base + COMMAND_REG) != NOOP)
+    return 0;
+  if(!inb(base + TC_HIGH) || inb(base + TC_HIGH) == 0xFF)
+    return 0;
+  if((inb(base + PIO_INT_REG) & (FULL | EMPTY | CE | OUE | FIE | EIE)) != EMPTY)
+    return 0;
+  return 1;
+  }
+
+void sym53c416_probe(void)
+  {
+  int *base = probeaddrs;
+  int ints[2];
+
+  ints[0] = 1;
+  for(; *base; base++)
+    if(!check_region(*base, IO_RANGE) && sym53c416_test(*base))
+      {
+      ints[1] = *base;
+      sym53c416_setup(NULL, ints);
+      }
+  }
+
+int sym53c416_detect(Scsi_Host_Template *tpnt)
+  {
+  unsigned long flags;
+  struct Scsi_Host * shpnt = NULL;
+  int i;
+  int count;
+
+#ifdef MODULE
+  int ints[3];
+
+  ints[0] = 2;
+  if(sym53c416_base)
+    {
+    ints[1] = sym53c416_base;
+    ints[2] = sym53c416_irq;
+    sym53c416_setup(NULL, ints);
+    }
+  if(sym53c416_base_1)
+    {
+    ints[1] = sym53c416_base_1;
+    ints[2] = sym53c416_irq_1;
+    sym53c416_setup(NULL, ints);
+    }
+  if(sym53c416_base_2)
+    {
+    ints[1] = sym53c416_base_2;
+    ints[2] = sym53c416_irq_2;
+    sym53c416_setup(NULL, ints);
+    }
+  if(sym53c416_base_3)
+    {
+    ints[1] = sym53c416_base_3;
+    ints[2] = sym53c416_irq_3;
+    sym53c416_setup(NULL, ints);
+    }
+#endif
+
+  printk("sym53c416.c: %s\n", VERSION_STRING);
+
+  sym53c416_probe();
+
+  /* Now we register and set up each host adapter found... */
+  for(count = 0, i = 0; i < host_index; i++)
+    if(!sym53c416_test(hosts[i].base))
+      printk("No sym53c416 found at address 0x%03x\n", hosts[i].base);
+    else
+      {
+      if(hosts[i].irq == 0)
+        /* We don't have an irq yet, so we should probe for one */
+        if((hosts[i].irq = sym53c416_probeirq(hosts[i].base, hosts[i].scsi_id)) == 0)
+          printk("irq autoprobing failed for sym53c416 at address 0x%03x\n", hosts[i].base);
+      if(hosts[i].irq && !check_region(hosts[i].base, IO_RANGE))
+        {
+        shpnt = scsi_register(tpnt, 0);
+        save_flags(flags);
+        cli();
+        /* Request for specified IRQ */
+        if(request_irq(hosts[i].irq, sym53c416_intr_handle, 0, ID, NULL))
+          {
+          restore_flags(flags);
+          printk("Unable to assign IRQ %d\n", hosts[i].irq);
+          scsi_unregister(shpnt);
+          }
+        else
+          {
+          /* Inform the kernel of our IO range */
+          request_region(hosts[i].base, IO_RANGE, ID);
+          shpnt->unique_id = hosts[i].base;
+          shpnt->io_port = hosts[i].base;
+          shpnt->n_io_port = IO_RANGE;
+          shpnt->irq = hosts[i].irq;
+          shpnt->this_id = hosts[i].scsi_id;
+          sym53c416_init(hosts[i].base, hosts[i].scsi_id);
+          count++;
+          restore_flags(flags);
+          }
+        }
+      }
+  return count;
+  }
+
+const char *sym53c416_info(struct Scsi_Host *SChost)
+  {
+  int i;
+  int base = SChost->io_port;
+  int irq = SChost->irq;
+  int scsi_id = 0;
+  int rev = inb(base + TC_HIGH);
+
+  for(i = 0; i < host_index; i++)
+    if(hosts[i].base == base)
+      scsi_id = hosts[i].scsi_id;
+  sprintf(info, "Symbios Logic 53c416 (rev. %d) at 0x%03x, irq %d, SCSI-ID %d, %s pio", rev, base, irq, scsi_id, (fastpio)? "fast" : "slow");
+  return info;
+  }
+
+int sym53c416_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+  {
+  int base;
+  unsigned long flags = 0;
+  int i;
+
+  /* Store base register as we can have more than one controller in the system */
+  base = SCpnt->host->io_port;
+  current_command = SCpnt;                  /* set current command                */
+  current_command->scsi_done = done;        /* set ptr to done function           */
+  current_command->SCp.phase = command_ph;  /* currect phase is the command phase */
+  current_command->SCp.Status = 0;
+  current_command->SCp.Message = 0;
+
+  save_flags(flags);
+  cli();
+  outb(SCpnt->target, base + DEST_BUS_ID); /* Set scsi id target        */
+  outb(FLUSH_FIFO, base + COMMAND_REG);    /* Flush SCSI and PIO FIFO's */
+  /* Write SCSI command into the SCSI fifo */
+  for(i = 0; i < SCpnt->cmd_len; i++)
+    outb(SCpnt->cmnd[i], base + SCSI_FIFO);
+  /* Start selection sequence */
+  outb(SEL_WITHOUT_ATN_SEQ, base + COMMAND_REG);
+  /* Now an interrupt will be generated which we will catch in out interrupt routine */
+  restore_flags(flags);
+  return 0;
+  }
+
+static void internal_done(Scsi_Cmnd *SCpnt)
+  {
+  SCpnt->SCp.Status++;
+  }
+
+int sym53c416_command(Scsi_Cmnd *SCpnt)
+  {
+  sym53c416_queuecommand(SCpnt, internal_done);
+  SCpnt->SCp.Status = 0;
+  while(!SCpnt->SCp.Status)
+    barrier();
+  return SCpnt->result;
+  }
+
+int sym53c416_abort(Scsi_Cmnd *SCpnt)
+  {
+  printk("sym53c416_abort\n");
+
+  /* We don't know how to abort for the moment */
+  return SCSI_ABORT_SNOOZE;
+  }
+
+int sym53c416_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags)
+  {
+  int base;
+  int scsi_id = -1;
+  int i;
+
+  printk("sym53c416_reset\n");
+  base = SCpnt->host->io_port;
+  /* search scsi_id */
+  for(i = 0; i < host_index && scsi_id != -1; i++)
+    if(hosts[i].base == base)
+      scsi_id = hosts[i].scsi_id;
+  outb(RESET_CHIP, base + COMMAND_REG);
+  outb(NOOP | PIO_MODE, base + COMMAND_REG);
+  outb(RESET_SCSI_BUS, base + COMMAND_REG);
+  sym53c416_init(base, scsi_id);
+  return SCSI_RESET_PENDING;
+  }
+
+int sym53c416_bios_param(Disk *disk, kdev_t dev, int *ip)
+  {
+  int size;
+
+  size = disk->capacity;
+  ip[0] = 64;                         /* heads                        */
+  ip[1] = 32;                         /* sectors                      */
+  if((ip[2] = size >> 11) > 1024)     /* cylinders, test for big disk */
+    {
+    ip[0] = 255;                      /* heads                        */
+    ip[1] = 63;                       /* sectors                      */
+    ip[2] = size / (255 * 63);        /* cylinders                    */
+    }
+  return 0;
+  }
+
+/* Loadable module support */
+#ifdef MODULE
+
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,26)
+MODULE_AUTHOR("Lieven Willems");
+MODULE_PARM(sym53c416, "1-2i");
+MODULE_PARM(sym53c416_1, "1-2i");
+MODULE_PARM(sym53c416_2, "1-2i");
+MODULE_PARM(sym53c416_3, "1-2i");
+#endif
+
+Scsi_Host_Template driver_template = SYM53C416;
+
+#include "scsi_module.c"
+#endif
diff --git a/drivers/scsi/sym53c416.h b/drivers/scsi/sym53c416.h
new file mode 100644 (file)
index 0000000..49abc83
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ *  sym53c416.h
+ * 
+ *  Copyright (C) 1998 Lieven Willems (lw_linux@hotmail.com)
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2, or (at your option) any
+ *  later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ */
+
+#ifndef _SYM53C416_H
+#define _SYM53C416_H
+
+#if !defined(LINUX_VERSION_CODE)
+#include <linux/version.h>
+#endif
+
+#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
+
+#include <linux/types.h>
+#include <linux/kdev_t.h>
+
+#define SYM53C416_SCSI_ID 7
+
+extern struct proc_dir_entry proc_scsi_sym53c416;
+
+extern int sym53c416_detect(Scsi_Host_Template *);
+extern const char *sym53c416_info(struct Scsi_Host *);
+extern int sym53c416_command(Scsi_Cmnd *);
+extern int sym53c416_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+extern int sym53c416_abort(Scsi_Cmnd *);
+extern int sym53c416_reset(Scsi_Cmnd *, unsigned int);
+extern int sym53c416_bios_param(Disk *, kdev_t, int *);
+extern void sym53c416_setup(char *str, int *ints);
+
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,75)
+
+#define SYM53C416 {                                          \
+                  proc_dir:          &proc_scsi_sym53c416,   \
+                  name:              "Symbios Logic 53c416", \
+                  detect:            sym53c416_detect,       \
+                  info:              sym53c416_info,         \
+                  command:           sym53c416_command,      \
+                  queuecommand:      sym53c416_queuecommand, \
+                  abort:             sym53c416_abort,        \
+                  reset:             sym53c416_reset,        \
+                  bios_param:        sym53c416_bios_param,   \
+                  can_queue:         1,                      \
+                  this_id:           SYM53C416_SCSI_ID,      \
+                  sg_tablesize:      32,                     \
+                  cmd_per_lun:       1,                      \
+                  unchecked_isa_dma: 1,                      \
+                  use_clustering:    ENABLE_CLUSTERING       \
+                  }
+
+#else
+
+#define SYM53C416 {                       \
+                  NULL,                   \
+                  NULL,                   \
+                  &proc_scsi_sym53c416,   \
+                  NULL,                   \
+                  "Symbios Logic 53c416", \
+                  sym53c416_detect,       \
+                  NULL,                   \
+                  sym53c416_info,         \
+                  sym53c416_command,      \
+                  sym53c416_queuecommand, \
+                  sym53c416_abort,        \
+                  sym53c416_reset,        \
+                  NULL,                   \
+                  sym53c416_bios_param,   \
+                  1,                      \
+                  SYM53C416_SCSI_ID,      \
+                  32, /* ???? */          \
+                  1,                      \
+                  0,                      \
+                  1,                      \
+                  ENABLE_CLUSTERING       \
+                  }
+
+#endif
+
+#endif
index d1f14333bd94b1450faa194d46a08d5c83e9eb4f..476941c4b5fb613e6947fc1ded89342f4fe0be22 100644 (file)
@@ -4,12 +4,17 @@
 
 if [ "$CONFIG_FB" = "y" ]; then
   define_bool CONFIG_DUMMY_CONSOLE y
-  if [ "$CONFIG_APUS" = "y" ]; then
-    bool 'Permedia2 support' CONFIG_FB_PM2
-    if [ "$CONFIG_FB_PM2" = "y" ]; then
-      bool '  enable FIFO disconnect feature' CONFIG_FB_PM2_FIFO_DISCONNECT
-      if [ "$CONFIG_APUS" = "y" ]; then
-        bool '  Phase5 CVisionPPC/BVisionPPC support' CONFIG_FB_PM2_CVPPC
+  if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+    if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_PCI" = "y" ]; then
+      bool 'Permedia2 support (experimental)' CONFIG_FB_PM2
+      if [ "$CONFIG_FB_PM2" = "y" ]; then
+        if [ "$CONFIG_PCI" = "y" ]; then
+          bool '  enable FIFO disconnect feature' CONFIG_FB_PM2_FIFO_DISCONNECT
+          bool '  generic Permedia2 PCI board support' CONFIG_FB_PM2_PCI
+        fi
+        if [ "$CONFIG_AMIGA" = "y" ]; then
+          bool '  Phase5 CVisionPPC/BVisionPPC support' CONFIG_FB_PM2_CVPPC
+        fi
       fi
     fi
   fi
@@ -19,6 +24,9 @@ if [ "$CONFIG_FB" = "y" ]; then
   if [ "$CONFIG_APOLLO" = "y" ]; then
     define_bool CONFIG_FB_APOLLO y
   fi
+  if [ "$CONFIG_Q40" = "y" ]; then
+    define_bool CONFIG_FB_Q40 y
+  fi
   if [ "$CONFIG_AMIGA" = "y" ]; then
     bool 'Amiga native chipset support' CONFIG_FB_AMIGA
     if [ "$CONFIG_FB_AMIGA" != "n" ]; then
@@ -33,6 +41,7 @@ if [ "$CONFIG_FB" = "y" ]; then
       bool 'Amiga CyberVision3D support (experimental)' CONFIG_FB_VIRGE
       tristate 'Amiga RetinaZ3 support' CONFIG_FB_RETINAZ3
       tristate 'Amiga CLgen driver' CONFIG_FB_CLGEN
+      bool 'Amiga FrameMaster II/Rainbow II support (experimental)' CONFIG_FB_FM2
     fi
   fi
   if [ "$CONFIG_ATARI" = "y" ]; then
@@ -185,6 +194,7 @@ if [ "$CONFIG_FB" = "y" ]; then
     if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATY" = "y" -o \
         "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_VESA" = "y" -o \
         "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_TBOX" = "y" -o \
+        "$CONFIG_FB_Q40" = "y" -o \
         "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
         "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \
         "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
@@ -195,6 +205,7 @@ if [ "$CONFIG_FB" = "y" ]; then
       if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
           "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_VESA" = "m" -o \
           "$CONFIG_FB_VIRTUAL" = "m" -o "$CONFIG_FB_TBOX" = "m" -o \
+        "$CONFIG_FB_Q40" = "m" -o \
           "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
           "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \
           "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
@@ -218,7 +229,8 @@ if [ "$CONFIG_FB" = "y" ]; then
         "$CONFIG_FB_VESA" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
         "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
         "$CONFIG_FB_TGA" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
-        "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" ]; then
+        "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \
+        "$CONFIG_FB_FM2" = "y" ]; then
       define_bool CONFIG_FBCON_CFB32 y
     else
       if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
index 900655e30a4564f3e937ec184643ee1c823093f9..6990e988a26e6d584bd115f4ed4fbc537192adbb 100644 (file)
@@ -88,6 +88,10 @@ ifeq ($(CONFIG_FB_APOLLO),y)
 L_OBJS += dnfb.o
 endif
 
+ifeq ($(CONFIG_FB_Q40),y)
+L_OBJS += q40fb.o
+endif
+
 ifeq ($(CONFIG_FB_ATARI),y)
 L_OBJS += atafb.o
 else
@@ -194,6 +198,10 @@ ifdef CONFIG_FB_G364
 L_OBJS := $(L_OBJS) g364fb.o
 endif
 
+ifdef CONFIG_FB_FM2
+L_OBJS := $(L_OBJS) fm2fb.o
+endif
+
 ifeq ($(CONFIG_FB_SBUS),y)
 L_OBJS += sbusfb.o
   ifeq ($(CONFIG_FB_CREATOR),y)
index f33d118b7bb817e419c2dda34de8cc3a8a82e8f2..e35a79e0ba95695194b9a4ab80091f9c411312e1 100644 (file)
@@ -103,7 +103,7 @@ static int sttt_xres_virtual=640,sttt_yres_virtual=400;
 static int ovsc_offset=0, ovsc_addlen=0;
 
 static struct atafb_par {
-       unsigned long screen_base;
+       void *screen_base;
        int yres_virtual;
 #if defined ATAFB_TT || defined ATAFB_STE
        union {
@@ -167,8 +167,8 @@ static int DontCalcRes = 0;
 
 static struct fb_info fb_info;
 
-static unsigned long screen_base;      /* base address of screen */
-static unsigned long real_screen_base; /* (only for Overscan) */
+static void *screen_base;      /* base address of screen */
+static void *real_screen_base; /* (only for Overscan) */
 
 static int screen_len;
 
@@ -193,7 +193,7 @@ static unsigned                     external_yres;
 
 static unsigned                        external_depth;
 static int                             external_pmode;
-static unsigned long   external_addr = 0;
+static void *external_addr = 0;
 static unsigned long   external_len;
 static unsigned long   external_vgaiobase = 0;
 static unsigned int            external_bitspercol = 6;
@@ -299,7 +299,7 @@ extern unsigned char fontdata_8x16[];
  *   Read a single color register and split it into
  *   colors/transparent. Return != 0 for invalid regno.
  *
- * void (*set_screen_base)( unsigned long s_base )
+ * void (*set_screen_base)(void *s_base)
  *   Set the base address of the displayed frame buffer. Only called
  *   if yres_virtual > yres or xres_virtual > xres.
  *
@@ -328,7 +328,7 @@ static struct fb_hwswitch {
        int  (*setcolreg)( unsigned regno, unsigned red,
                                           unsigned green, unsigned blue,
                                           unsigned transp, struct fb_info *info );
-       void (*set_screen_base)( unsigned long s_base );
+       void (*set_screen_base)(void *s_base);
        int  (*blank)( int blank_mode );
        int  (*pan_display)( struct fb_var_screeninfo *var,
                                                 struct atafb_par *par);
@@ -464,7 +464,7 @@ static int tt_encode_fix( struct fb_fix_screeninfo *fix,
        int mode;
 
        strcpy(fix->id,"Atari Builtin");
-       fix->smem_start = (char *)real_screen_base;
+       fix->smem_start = real_screen_base;
        fix->smem_len = screen_len;
        fix->type=FB_TYPE_INTERLEAVED_PLANES;
        fix->type_aux=2;
@@ -797,7 +797,7 @@ static int falcon_encode_fix( struct fb_fix_screeninfo *fix,
                                                          struct atafb_par *par )
 {
        strcpy(fix->id, "Atari Builtin");
-       fix->smem_start = (char *)real_screen_base;
+       fix->smem_start = real_screen_base;
        fix->smem_len = screen_len;
        fix->type = FB_TYPE_INTERLEAVED_PLANES;
        fix->type_aux = 2;
@@ -1760,7 +1760,7 @@ static int stste_encode_fix( struct fb_fix_screeninfo *fix,
        int mode;
 
        strcpy(fix->id,"Atari Builtin");
-       fix->smem_start = (char *)real_screen_base;
+       fix->smem_start = real_screen_base;
        fix->smem_len = screen_len;
        fix->type = FB_TYPE_INTERLEAVED_PLANES;
        fix->type_aux = 2;
@@ -2024,7 +2024,7 @@ static int stste_detect( void )
        return 1;
 }
 
-static void stste_set_screen_base(unsigned long s_base)
+static void stste_set_screen_base(void *s_base)
 {
        unsigned long addr;
        addr= virt_to_phys(s_base);
@@ -2104,8 +2104,8 @@ static int ext_encode_fix( struct fb_fix_screeninfo *fix,
 
 {
        strcpy(fix->id,"Unknown Extern");
-       fix->smem_start=(char *)external_addr;
-       fix->smem_len=(external_len + PAGE_SIZE -1) & PAGE_MASK;
+       fix->smem_start=external_addr;
+       fix->smem_len = PAGE_ALIGN(external_len);
        if (external_depth == 1) {
                fix->type = FB_TYPE_PACKED_PIXELS;
                /* The letters 'n' and 'i' in the "atavideo=external:" stand
@@ -2295,7 +2295,7 @@ static int ext_detect( void )
 
 /* ------ This is the same for most hardware types -------- */
 
-static void set_screen_base(unsigned long s_base)
+static void set_screen_base(void *s_base)
 {
        unsigned long addr;
        addr= virt_to_phys(s_base);
@@ -2804,15 +2804,13 @@ __initfunc(void atafb_init(void))
 #ifdef ATAFB_EXT
        if (!external_addr) {
 #endif /* ATAFB_EXT */
-               mem_req = default_mem_req + ovsc_offset +
-                       ovsc_addlen;
-               mem_req = ((mem_req + PAGE_SIZE - 1) & PAGE_MASK) + PAGE_SIZE;
-               screen_base = (unsigned long)atari_stram_alloc(mem_req, NULL,
-                                                              "atafb");
+               mem_req = default_mem_req + ovsc_offset + ovsc_addlen;
+               mem_req = PAGE_ALIGN(mem_req) + PAGE_SIZE;
+               screen_base = atari_stram_alloc(mem_req, NULL, "atafb");
                if (!screen_base)
                        panic("Cannot allocate screen memory");
-               memset((char *) screen_base, 0, mem_req);
-               pad = ((screen_base + PAGE_SIZE-1) & PAGE_MASK) - screen_base;
+               memset(screen_base, 0, mem_req);
+               pad = -(unsigned long)screen_base & (PAGE_SIZE-1);
                screen_base+=pad;
                real_screen_base=screen_base+ovsc_offset;
                screen_len = (mem_req - pad - ovsc_offset) & PAGE_MASK;
@@ -2820,9 +2818,9 @@ __initfunc(void atafb_init(void))
                if (CPU_IS_040_OR_060) {
                        /* On a '040+, the cache mode of video RAM must be set to
                         * write-through also for internal video hardware! */
-                       cache_push( virt_to_phys(screen_base), screen_len );
-                       kernel_set_cachemode( screen_base, screen_len,
-                                             IOMAP_WRITETHROUGH );
+                       cache_push(virt_to_phys(screen_base), screen_len);
+                       kernel_set_cachemode(screen_base, screen_len,
+                                            IOMAP_WRITETHROUGH);
                }
 #ifdef ATAFB_EXT
        }
@@ -2836,7 +2834,7 @@ __initfunc(void atafb_init(void))
                screen_base      =
                real_screen_base = external_addr;
                screen_len       = external_len & PAGE_MASK;
-               memset ((char *) screen_base, 0, external_len);
+               memset (screen_base, 0, external_len);
        }
 #endif /* ATAFB_EXT */
 
index 6a3625d23aa4d864ddd4bdd5834577a0228f0bb6..613b5f20c4d52f047cf3fbff10e4eae29103210d 100644 (file)
@@ -1,4 +1,4 @@
-/*  $Id: atyfb.c,v 1.98 1999/01/14 08:50:53 geert Exp $
+/*  $Id: atyfb.c,v 1.102 1999/01/21 22:44:42 geert Exp $
  *  linux/drivers/video/atyfb.c -- Frame buffer device for ATI Mach64
  *
  *     Copyright (C) 1997-1998  Geert Uytterhoeven
@@ -66,6 +66,8 @@
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
 #include <video/macmodes.h>
+#include <asm/adb.h>
+#include <asm/pmu.h>
 #endif
 #ifdef __sparc__
 #include <asm/pbm.h>
@@ -439,10 +441,10 @@ static struct aty_features {
 
     /* mach64CT family / mach64GT (3D RAGE) class */
     { 0x4c42, 0x4c42, "3D RAGE LT PRO (AGP)" },
-    { 0x4c42, 0x4c44, "3D RAGE LT PRO" },
-    { 0x4c42, 0x4c47, "3D RAGE LT PRO" },
-    { 0x4c42, 0x4c49, "3D RAGE LT PRO" },
-    { 0x4c42, 0x4c50, "3D RAGE LT PRO" },
+    { 0x4c44, 0x4c44, "3D RAGE LT PRO" },
+    { 0x4c47, 0x4c47, "3D RAGE LT PRO" },
+    { 0x4c49, 0x4c49, "3D RAGE LT PRO" },
+    { 0x4c50, 0x4c50, "3D RAGE LT PRO" },
     { 0x4c54, 0x4c54, "3D RAGE LT" },
     { 0x4754, 0x4754, "3D RAGE (GT)" },
     { 0x4755, 0x4755, "3D RAGE II+ (GTB)" },
@@ -1282,7 +1284,7 @@ static int aty_crtc_to_var(const struct crtc *crtc,
            bpp = 16;
            var->red.offset = 11;
            var->red.length = 5;
-           var->green.offset = 6;
+           var->green.offset = 5;
            var->green.length = 6;
            var->blue.offset = 0;
            var->blue.length = 5;
@@ -2353,10 +2355,10 @@ static void atyfb_save_palette(struct fb_info *fb, int enter)
 
        for (i = 0; i < 256; i++) {
                tmp = aty_ld_8(DAC_CNTL, info) & 0xfc;
-               if ((Gx == GT_CHIP_ID) || (Gx == GU_CHIP_ID) ||
-                   (Gx == LG_CHIP_ID) || (Gx == GB_CHIP_ID) ||
-                   (Gx == GD_CHIP_ID) || (Gx == GI_CHIP_ID) ||
-                   (Gx == GP_CHIP_ID) || (Gx == GQ_CHIP_ID))
+               if (Gx == GT_CHIP_ID || Gx == GU_CHIP_ID || Gx == GV_CHIP_ID ||
+                   Gx == GW_CHIP_ID || Gx == GZ_CHIP_ID || Gx == LG_CHIP_ID ||
+                   Gx == GB_CHIP_ID || Gx == GD_CHIP_ID || Gx == GI_CHIP_ID ||
+                   Gx == GP_CHIP_ID || Gx == GQ_CHIP_ID)
                        tmp |= 0x2;
                aty_st_8(DAC_CNTL, tmp, info);
                aty_st_8(DAC_MASK, 0xff, info);
@@ -3296,6 +3298,11 @@ static void atyfbcon_blank(int blank, struct fb_info *fb)
     struct fb_info_aty *info = (struct fb_info_aty *)fb;
     u8 gen_cntl;
 
+#if defined(CONFIG_PPC)
+    if ((_machine == _MACH_Pmac) && blank)
+       pmu_enable_backlight(0);
+#endif
+
     gen_cntl = aty_ld_8(CRTC_GEN_CNTL, info);
     if (blank > 0)
        switch (blank-1) {
@@ -3315,6 +3322,11 @@ static void atyfbcon_blank(int blank, struct fb_info *fb)
     else
        gen_cntl &= ~(0x4c);
     aty_st_8(CRTC_GEN_CNTL, gen_cntl, info);
+
+#if defined(CONFIG_PPC)
+    if ((_machine == _MACH_Pmac) && !blank)
+       pmu_enable_backlight(1);
+#endif
 }
 
 
@@ -3359,9 +3371,10 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
     info->palette[regno].green = green;
     info->palette[regno].blue = blue;
     i = aty_ld_8(DAC_CNTL, info) & 0xfc;
-    if ((Gx == GT_CHIP_ID) || (Gx == GU_CHIP_ID) || (Gx == LG_CHIP_ID) ||
-       (Gx == GB_CHIP_ID) || (Gx == GD_CHIP_ID) || (Gx == GI_CHIP_ID) ||
-       (Gx == GP_CHIP_ID) || (Gx == GQ_CHIP_ID))
+    if (Gx == GT_CHIP_ID || Gx == GU_CHIP_ID || Gx == GV_CHIP_ID ||
+       Gx == GW_CHIP_ID || Gx == GZ_CHIP_ID || Gx == LG_CHIP_ID ||
+       Gx == GB_CHIP_ID || Gx == GD_CHIP_ID || Gx == GI_CHIP_ID ||
+       Gx == GP_CHIP_ID || Gx == GQ_CHIP_ID)
        i |= 0x2;       /*DAC_CNTL|0x2 turns off the extra brightness for gt*/
     aty_st_8(DAC_CNTL, i, info);
     aty_st_8(DAC_MASK, 0xff, info);
index 00db47d103bd216a5c1f1ede750d50abaced1088..0735ca1b3854381d869c845a0644ac34ac54ab9f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: bwtwofb.c,v 1.6 1998/09/15 15:45:35 jj Exp $
+/* $Id: bwtwofb.c,v 1.7 1999/01/26 10:55:02 jj Exp $
  * bwtwofb.c: BWtwo frame buffer driver
  *
  * Copyright (C) 1998 Jakub Jelinek   (jj@ultra.linux.cz)
@@ -199,6 +199,7 @@ char __init *bwtwofb_init(struct fb_info_sbusfb *fb)
        strcpy(fb->info.modename, "BWtwo");
        strcpy(fix->id, "BWtwo");
        fix->line_length = fb->var.xres_virtual>>3;
+       fix->accel = FB_ACCEL_SUN_BWTWO;
        
        disp->scrollmode = SCROLL_YREDRAW;
        disp->inverse = 1;
index f22389921d2ee437bc371502d76222ee5d6b04e2..c5dfaad6ee000b51f6c6102825cad8d643b211e2 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: cgfourteenfb.c,v 1.3 1998/09/04 15:43:41 jj Exp $
+/* $Id: cgfourteenfb.c,v 1.4 1999/01/26 10:55:03 jj Exp $
  * cgfourteenfb.c: CGfourteen frame buffer driver
  *
  * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
@@ -355,6 +355,7 @@ __initfunc(char *cgfourteenfb_init(struct fb_info_sbusfb *fb))
        strcpy(fb->info.modename, "CGfourteen");
        strcpy(fix->id, "CGfourteen");
        fix->line_length = fb->var.xres_virtual;
+       fix->accel = FB_ACCEL_SUN_CG14;
        
        disp->scrollmode = SCROLL_YREDRAW;
        disp->screen_base += fix->line_length * fb->y_margin + fb->x_margin;
index 2891b4877419211e889c4e0bac7977f525a32789..0fe3f5b76530d3a53cd8bcbfe36a4fc557594f3f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: cgsixfb.c,v 1.12 1998/11/27 00:02:04 anton Exp $
+/* $Id: cgsixfb.c,v 1.13 1999/01/28 08:19:18 ecd Exp $
  * cgsixfb.c: CGsix (GX,GXplus) frame buffer driver
  *
  * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
@@ -352,8 +352,8 @@ static void cg6_putcs(struct vc_data *conp, struct display *p, const unsigned sh
        do {
                i = fbc->s;
        } while (i & 0x10000000);
-       fbc->fg = attr_fgcol(p,*s);
-       fbc->bg = attr_bgcol(p,*s);
+       fbc->fg = attr_fgcol(p, scr_readw(s));
+       fbc->bg = attr_bgcol(p, scr_readw(s));
        fbc->mode = 0x140000;
        fbc->alu = 0xe880fc30;
        fbc->pixelm = ~(0);
@@ -379,15 +379,15 @@ static void cg6_putcs(struct vc_data *conp, struct display *p, const unsigned sh
                        fbc->x1 = (x += 4 * fontwidth(p)) - 1;
                        fbc->y0 = y;
                        if (fontheightlog(p)) {
-                               fd1 = p->fontdata + ((*s++ & p->charmask) << fontheightlog(p));
-                               fd2 = p->fontdata + ((*s++ & p->charmask) << fontheightlog(p));
-                               fd3 = p->fontdata + ((*s++ & p->charmask) << fontheightlog(p));
-                               fd4 = p->fontdata + ((*s++ & p->charmask) << fontheightlog(p));
+                               fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
+                               fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
+                               fd3 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
+                               fd4 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
                        } else {
-                               fd1 = p->fontdata + ((*s++ & p->charmask) * fontheight(p));
-                               fd2 = p->fontdata + ((*s++ & p->charmask) * fontheight(p));
-                               fd3 = p->fontdata + ((*s++ & p->charmask) * fontheight(p));
-                               fd4 = p->fontdata + ((*s++ & p->charmask) * fontheight(p));
+                               fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
+                               fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
+                               fd3 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
+                               fd4 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
                        }
                        if (fontwidth(p) == 8) {
                                for (i = 0; i < fontheight(p); i++)
@@ -408,11 +408,11 @@ static void cg6_putcs(struct vc_data *conp, struct display *p, const unsigned sh
                        fbc->x1 = (x += 2 * fontwidth(p)) - 1;
                        fbc->y0 = y;
                        if (fontheightlog(p)) {
-                               fd1 = p->fontdata + ((*s++ & p->charmask) << (fontheightlog(p) + 1));
-                               fd2 = p->fontdata + ((*s++ & p->charmask) << (fontheightlog(p) + 1));
+                               fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) << (fontheightlog(p) + 1));
+                               fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) << (fontheightlog(p) + 1));
                        } else {
-                               fd1 = p->fontdata + (((*s++ & p->charmask) * fontheight(p)) << 1);
-                               fd2 = p->fontdata + (((*s++ & p->charmask) * fontheight(p)) << 1);
+                               fd1 = p->fontdata + (((scr_readw(s++) & p->charmask) * fontheight(p)) << 1);
+                               fd2 = p->fontdata + (((scr_readw(s++) & p->charmask) * fontheight(p)) << 1);
                        }
                        for (i = 0; i < fontheight(p); i++) {
                                fbc->font = ((((u32)*(u16 *)fd1) << fontwidth(p)) | ((u32)*(u16 *)fd2)) << (16 - fontwidth(p));
@@ -428,9 +428,9 @@ static void cg6_putcs(struct vc_data *conp, struct display *p, const unsigned sh
                fbc->x1 = (x += fontwidth(p)) - 1;
                fbc->y0 = y;
                if (fontheightlog(p))
-                       i = ((*s++ & p->charmask) << fontheightlog(p));
+                       i = ((scr_readw(s++) & p->charmask) << fontheightlog(p));
                else
-                       i = ((*s++ & p->charmask) * fontheight(p));
+                       i = ((scr_readw(s++) & p->charmask) * fontheight(p));
                if (fontwidth(p) <= 8) {
                        fd1 = p->fontdata + i;
                        for (i = 0; i < fontheight(p); i++)
@@ -535,6 +535,7 @@ static void cg6_reset (struct fb_info_sbusfb *fb)
        struct cg6_tec *tec = fb->s.cg6.tec;
        struct cg6_fbc *fbc = fb->s.cg6.fbc;
        u32 mode;
+       int i;
        
        /* Turn off stuff in the Transform Engine. */
        tec->tec_matrix = 0;
@@ -557,6 +558,9 @@ static void cg6_reset (struct fb_info_sbusfb *fb)
         * back to back store/loads on the mode register, so copy it
         * out instead. */
        mode = fbc->mode;
+       do {
+               i = fbc->s;
+       } while (i & 0x10000000);
        mode &= ~(CG6_FBC_BLIT_MASK | CG6_FBC_MODE_MASK |
                       CG6_FBC_DRAW_MASK | CG6_FBC_BWRITE0_MASK |
                       CG6_FBC_BWRITE1_MASK | CG6_FBC_BREAD_MASK |
index 882669d8fde7ec4d2489ae13fb8083acdeae7bb9..91611c6746444047a617286d56f75f9b42c87cac 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: cgthreefb.c,v 1.3 1998/09/04 15:43:43 jj Exp $
+/* $Id: cgthreefb.c,v 1.4 1999/01/26 10:55:01 jj Exp $
  * cgthreefb.c: CGthree frame buffer driver
  *
  * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
@@ -186,6 +186,7 @@ __initfunc(char *cgthreefb_init(struct fb_info_sbusfb *fb))
        strcpy(fb->info.modename, "CGthree");
        strcpy(fix->id, "CGthree");
        fix->line_length = fb->var.xres_virtual;
+       fix->accel = FB_ACCEL_SUN_CGTHREE;
        
        disp->scrollmode = SCROLL_YREDRAW;
        if (!disp->screen_base)
index 6e09ae6660f05c1c7935fcc253f6792646c21258..3f95ae58cebcea9cf8f02e873075f7a18b844a0e 100644 (file)
@@ -204,8 +204,8 @@ static int  clgen_pan_display(const struct fb_var_screeninfo *var,
                              struct fb_info_gen *info);
 static int  clgen_blank(int blank_mode, struct fb_info_gen *info);
 
-static void clgen_set_dispsw(const void *par, struct display *disp,
-                            struct fb_info_gen *info);
+static void clgen_set_disp(const void *par, struct display *disp,
+                          struct fb_info_gen *info);
 
 /* function table of the above functions */
 static struct fbgen_hwswitch clgen_hwswitch = 
@@ -220,7 +220,7 @@ static struct fbgen_hwswitch clgen_hwswitch =
     clgen_setcolreg,
     clgen_pan_display,
     clgen_blank,
-    clgen_set_dispsw
+    clgen_set_disp
 };
 
 /* Text console acceleration */
@@ -1372,13 +1372,14 @@ static void switch_monitor(int on)
        }
 }
 
-static void clgen_set_dispsw(const void *par, struct display *disp,
-                            struct fb_info_gen *info)
+static void clgen_set_disp(const void *par, struct display *disp,
+                          struct fb_info_gen *info)
 {
     struct clgenfb_par *_par = (struct clgenfb_par*) par;
     struct clgenfb_info *info2 = (struct clgenfb_info *)info;
 
-    printk("clgen_get_dispsw(): ");
+    printk("clgen_set_disp(): ");
+    disp->screen_base = info2->fbmem;
     switch (_par->var.bits_per_pixel)
     {
 #ifdef FBCON_HAS_MFB
@@ -1670,7 +1671,7 @@ __initfunc(void clgenfb_setup(char *options, int *ints))
 int init_module(void)
 {
     printk("init_module()\n");
-    clgenfb_init(0);
+    clgenfb_init();
     return 0;
 }
 
index 129c4e396971bfdd0539854d318beaaceb98f4a9..2a783fc9b32f2543d0ebeea62a5bc5d8c1e827a4 100644 (file)
@@ -377,7 +377,7 @@ static int controlfb_switch(int con, struct fb_info *info)
        control_set_hardware(p, &par);
        control_set_dispsw(&fb_display[con], par.cmode, p);
 
-       if(fb_display[oldcon].var.yoffset != fb_display[con].var.yoffset);
+       if(fb_display[oldcon].var.yoffset != fb_display[con].var.yoffset)
                controlfb_updatevar(con, info);
 
        do_install_cmap(con, info);
@@ -447,21 +447,24 @@ static int controlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
                             u_int transp, struct fb_info *info)
 {
        struct fb_info_control *p = (struct fb_info_control *) info;
-       int i;
+       u_int i;
+       __u8 r, g, b;
 
        if (regno > 255)
                return 1;
-       red >>= 8;
-       green >>= 8;
-       blue >>= 8;
-       p->palette[regno].red = red;
-       p->palette[regno].green = green;
-       p->palette[regno].blue = blue;
+
+       r = red >> 8;
+       g = green >> 8;
+       b = blue >> 8;
+
+       p->palette[regno].red = r;
+       p->palette[regno].green = g;
+       p->palette[regno].blue = b;
 
        out_8(&p->cmap_regs->addr, regno);      /* tell clut what addr to fill  */
-       out_8(&p->cmap_regs->lut, red);         /* send one color channel at    */
-       out_8(&p->cmap_regs->lut, green);       /* a time...                    */
-       out_8(&p->cmap_regs->lut, blue);
+       out_8(&p->cmap_regs->lut, r);           /* send one color channel at    */
+       out_8(&p->cmap_regs->lut, g);           /* a time...                    */
+       out_8(&p->cmap_regs->lut, b);
 
        if (regno < 16)
                switch (p->par.cmode) {
@@ -501,8 +504,9 @@ extern struct fb_info *console_fb_info;
 
 static inline int control_vram_reqd(int video_mode, int color_mode)
 {
-       return control_reg_init[video_mode-1]->vres
-               * control_reg_init[video_mode-1]->hres << color_mode;
+       return (control_reg_init[video_mode-1]->vres
+               * control_reg_init[video_mode-1]->hres << color_mode)
+              + control_reg_init[video_mode-1]->offset[color_mode];
 }
 
 static void set_control_clock(unsigned char *params)
@@ -557,6 +561,7 @@ __initfunc(static void init_control(struct fb_info_control *p))
        par_set = 1;    /* Debug */
        
        control_par_to_var(par, &var);
+       var.activate = FB_ACTIVATE_NOW;
        control_set_var(&var, -1, &p->info);
        
        p->info.flags = FBINFO_FLAG_DEFAULT;
@@ -616,11 +621,11 @@ static void control_set_hardware(struct fb_info_control *p, struct fb_par_contro
        for (i = 0; i < 16; ++i, ++rp)
                out_le32(&rp->r, init->regs[i]);
        
-       out_le32(&p->control_regs->pitch.r, init->hres << cmode);
+       out_le32(&p->control_regs->pitch.r, par->vxres << cmode);
        out_le32(&p->control_regs->mode.r, init->mode[cmode]);
        out_le32(&p->control_regs->flags.r, flags);
        out_le32(&p->control_regs->start_addr.r,
-           par->yoffset * (par->vxres << par->cmode));
+           par->yoffset * (par->vxres << cmode));
        out_le32(&p->control_regs->reg18.r, 0x1e5);
        out_le32(&p->control_regs->reg19.r, 0);
 
@@ -762,8 +767,6 @@ static int control_var_to_par(struct fb_var_screeninfo *var,
        int xres = var->xres;
        int yres = var->yres;
        int bpp = var->bits_per_pixel;
-       
-       struct control_regvals *init;
        struct fb_info_control *p = (struct fb_info_control *) fb_info;
 
     /*
@@ -776,7 +779,7 @@ static int control_var_to_par(struct fb_var_screeninfo *var,
      */
        /* swiped by jonh from atyfb.c */
        if (xres <= 512 && yres <= 384)
-               par->vmode = VMODE_512_384_60;           /* 512x384, 60Hz */
+               par->vmode = VMODE_512_384_60;          /* 512x384, 60Hz */
        else if (xres <= 640 && yres <= 480)
                par->vmode = VMODE_640_480_67;          /* 640x480, 67Hz */
        else if (xres <= 640 && yres <= 870)
@@ -844,8 +847,7 @@ static int control_var_to_par(struct fb_var_screeninfo *var,
        }
 
        /* Check if we know about the wanted video mode */
-       init = control_reg_init[par->vmode-1];
-       if (init == NULL) {
+       if (control_reg_init[par->vmode - 1] == NULL) {
                printk(KERN_ERR "init is null in control_var_to_par().\n");
                /* I'm not sure if control has any specific requirements --     */
                /* if we have a regvals struct, we're good to go?               */
@@ -1010,7 +1012,7 @@ static void control_par_to_fix(struct fb_par_control *par, struct fb_fix_screeni
 
        fix->smem_start = (void *)(p->frame_buffer_phys
                + control_reg_init[par->vmode-1]->offset[par->cmode]);
-       fix->smem_len = p->total_vram;
+       fix->smem_len = p->total_vram - control_reg_init[par->vmode-1]->offset[par->cmode];
        fix->visual = (par->cmode == CMODE_8) ?
                FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
        fix->line_length = par->vxres << par->cmode;
@@ -1046,6 +1048,70 @@ static void control_par_to_display(struct fb_par_control *par,
        control_set_dispsw(disp, par->cmode, p);
 }
 
+static void control_cfb16_revc(struct display *p, int xx, int yy)
+{
+    u8 *dest;
+    int bytes = p->next_line, rows;
+
+    dest = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p)*2;
+    for (rows = fontheight(p); rows--; dest += bytes) {
+       switch (fontwidth(p)) {
+       case 16:
+           ((u32 *)dest)[6] ^= 0x3def3def; ((u32 *)dest)[7] ^= 0x3def3def;
+           /* FALL THROUGH */
+       case 12:
+           ((u32 *)dest)[4] ^= 0x3def3def; ((u32 *)dest)[5] ^= 0x3def3def;
+           /* FALL THROUGH */
+       case 8:
+           ((u32 *)dest)[2] ^= 0x3def3def; ((u32 *)dest)[3] ^= 0x3def3def;
+           /* FALL THROUGH */
+       case 4:
+           ((u32 *)dest)[0] ^= 0x3def3def; ((u32 *)dest)[1] ^= 0x3def3def;
+       }
+    }
+}
+
+static void control_cfb32_revc(struct display *p, int xx, int yy)
+{
+    u8 *dest;
+    int bytes = p->next_line, rows;
+
+    dest = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 4;
+    for (rows = fontheight(p); rows--; dest += bytes) {
+       switch (fontwidth(p)) {
+       case 16:
+           ((u32 *)dest)[12] ^= 0x0f0f0f0f; ((u32 *)dest)[13] ^= 0x0f0f0f0f;
+           ((u32 *)dest)[14] ^= 0x0f0f0f0f; ((u32 *)dest)[15] ^= 0x0f0f0f0f;
+           /* FALL THROUGH */
+       case 12:
+           ((u32 *)dest)[8] ^= 0x0f0f0f0f; ((u32 *)dest)[9] ^= 0x0f0f0f0f;
+           ((u32 *)dest)[10] ^= 0x0f0f0f0f; ((u32 *)dest)[11] ^= 0x0f0f0f0f;
+           /* FALL THROUGH */
+       case 8:
+           ((u32 *)dest)[4] ^= 0x0f0f0f0f; ((u32 *)dest)[5] ^= 0x0f0f0f0f;
+           ((u32 *)dest)[6] ^= 0x0f0f0f0f; ((u32 *)dest)[7] ^= 0x0f0f0f0f;
+           /* FALL THROUGH */
+       case 4:
+           ((u32 *)dest)[0] ^= 0x0f0f0f0f; ((u32 *)dest)[1] ^= 0x0f0f0f0f;
+           ((u32 *)dest)[2] ^= 0x0f0f0f0f; ((u32 *)dest)[3] ^= 0x0f0f0f0f;
+           /* FALL THROUGH */
+       }
+    }
+}
+
+static struct display_switch control_cfb16 = {
+    fbcon_cfb16_setup, fbcon_cfb16_bmove, fbcon_cfb16_clear, fbcon_cfb16_putc,
+    fbcon_cfb16_putcs, control_cfb16_revc, NULL, NULL, fbcon_cfb16_clear_margins,
+    FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+
+static struct display_switch control_cfb32 = {
+    fbcon_cfb32_setup, fbcon_cfb32_bmove, fbcon_cfb32_clear, fbcon_cfb32_putc,
+    fbcon_cfb32_putcs, control_cfb32_revc, NULL, NULL, fbcon_cfb32_clear_margins,
+    FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+
+
 static void control_set_dispsw(struct display *disp, int cmode, struct fb_info_control *p)
 {
        switch (cmode) {
@@ -1056,13 +1122,13 @@ static void control_set_dispsw(struct display *disp, int cmode, struct fb_info_c
 #endif
 #ifdef FBCON_HAS_CFB16
                case CMODE_16:
-                       disp->dispsw = &fbcon_cfb16;
+                       disp->dispsw = &control_cfb16;
                        disp->dispsw_data = p->fbcon_cmap.cfb16;
                        break;
 #endif
 #ifdef FBCON_HAS_CFB32
                case CMODE_32:
-                       disp->dispsw = &fbcon_cfb32;
+                       disp->dispsw = &control_cfb32;
                        disp->dispsw_data = p->fbcon_cmap.cfb32;
                        break;
 #endif
index 69242992df1d76812de0e601669e5990c7817583..857e121ea11e9f85c879015ab59cd75207075b33 100644 (file)
@@ -1,7 +1,7 @@
-/* $Id: creatorfb.c,v 1.17 1998/12/28 11:23:37 jj Exp $
+/* $Id: creatorfb.c,v 1.19 1999/02/22 16:20:25 jj Exp $
  * creatorfb.c: Creator/Creator3D frame buffer driver
  *
- * Copyright (C) 1997,1998 Jakub Jelinek (jj@ultra.linux.cz)
+ * Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@ultra.linux.cz)
  */
 
 #include <linux/module.h>
@@ -276,16 +276,18 @@ struct ffb_fbc {
        volatile u32    mer;
 };
 
-static __inline__ void FFBFifo(struct ffb_fbc *ffb, int n)
+static __inline__ void FFBFifo(struct fb_info_sbusfb *fb, int n)
 {
-       int limit = 10000;
-
-       do {
-               if((ffb->ucsr & FFB_UCSR_FIFO_MASK) >= (n + 4))
-                       break;
-               if((ffb->ucsr & FFB_UCSR_ALL_ERRORS) != 0)
-                       ffb->ucsr = FFB_UCSR_ALL_ERRORS;
-       } while(--limit > 0);
+       struct ffb_fbc *fbc;
+       int cache = fb->s.ffb.fifo_cache;
+
+       if (cache - n < 0) {
+               fbc = fb->s.ffb.fbc;
+               do {
+                       cache = (fbc->ucsr & FFB_UCSR_FIFO_MASK) - 4;
+               } while (cache - n < 0);
+       }
+       fb->s.ffb.fifo_cache = cache - n;
 }
 
 static __inline__ void FFBWait(struct ffb_fbc *ffb)
@@ -340,40 +342,45 @@ static void ffb_clear(struct vc_data *conp, struct display *p, int sy, int sx,
 {
        struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)p->fb_info;
        register struct ffb_fbc *fbc = fb->s.ffb.fbc;
-       int x, y, w, h;
+       u64 yx, hw;
+       int fg;
        
-       FFBWait(fbc);
-       FFBFifo(fbc, 6);
-       fbc->fg = ((u32 *)p->dispsw_data)[attr_bgcol_ec(p,conp)];
-       fbc->drawop = FFB_DRAWOP_RECTANGLE;
+       fg = ((u32 *)p->dispsw_data)[attr_bgcol_ec(p,conp)];
+       if (fg != fb->s.ffb.fg_cache) {
+               FFBFifo(fb, 5);
+               fbc->fg = fg;
+               fb->s.ffb.fg_cache = fg;
+       } else
+               FFBFifo(fb, 4);
 
        if (fontheightlog(p)) {
-               y = sy << fontheightlog(p); h = height << fontheightlog(p);
+               yx = (u64)sy << (fontheightlog(p) + 32); hw = (u64)height << (fontheightlog(p) + 32);
        } else {
-               y = sy * fontheight(p); h = height * fontheight(p);
+               yx = (u64)(sy * fontheight(p)) << 32; hw = (u64)(height * fontheight(p)) << 32;
        }
        if (fontwidthlog(p)) {
-               x = sx << fontwidthlog(p); w = width << fontwidthlog(p);
+               yx += sx << fontwidthlog(p); hw += width << fontwidthlog(p);
        } else {
-               x = sx * fontwidth(p); w = width * fontwidth(p);
+               yx += sx * fontwidth(p); hw += width * fontwidth(p);
        }
-       fbc->by = y + fb->y_margin;
-       fbc->bx = x + fb->x_margin;
-       fbc->bh = h;
-       fbc->bw = w;
+       *(volatile u64 *)&fbc->by = yx + fb->s.ffb.yx_margin;
+       *(volatile u64 *)&fbc->bh = hw;
 }
 
 static void ffb_fill(struct fb_info_sbusfb *fb, struct display *p, int s,
                     int count, unsigned short *boxes)
 {
        register struct ffb_fbc *fbc = fb->s.ffb.fbc;
+       int fg;
 
-       FFBWait(fbc);
-       FFBFifo(fbc, 2);
-       fbc->fg = ((u32 *)p->dispsw_data)[attr_bgcol(p,s)];
-       fbc->drawop = FFB_DRAWOP_RECTANGLE;
+       fg = ((u32 *)p->dispsw_data)[attr_bgcol(p,s)];
+       if (fg != fb->s.ffb.fg_cache) {
+               FFBFifo(fb, 1);
+               fbc->fg = fg;
+               fb->s.ffb.fg_cache = fg;
+       }
        while (count-- > 0) {
-               FFBFifo(fbc, 4);
+               FFBFifo(fb, 4);
                fbc->by = boxes[1];
                fbc->bx = boxes[0];
                fbc->bh = boxes[3] - boxes[1];
@@ -388,6 +395,7 @@ static void ffb_putc(struct vc_data *conp, struct display *p, int c, int yy, int
        register struct ffb_fbc *fbc = fb->s.ffb.fbc;
        int i, xy;
        u8 *fd;
+       u64 fgbg;
 
        if (fontheightlog(p)) {
                xy = (yy << (16 + fontheightlog(p)));
@@ -404,14 +412,16 @@ static void ffb_putc(struct vc_data *conp, struct display *p, int c, int yy, int
                xy += (xx << fontwidthlog(p)) + fb->s.ffb.xy_margin;
        else
                xy += (xx * fontwidth(p)) + fb->s.ffb.xy_margin;
-       FFBWait(fbc);
-       FFBFifo(fbc, 5);
-       fbc->fg = ((u32 *)p->dispsw_data)[attr_fgcol(p,c)];
-       fbc->bg = ((u32 *)p->dispsw_data)[attr_bgcol(p,c)];
-       fbc->fontw = fontwidth(p);
-       fbc->fontinc = 0x10000;
+       fgbg = (((u64)(((u32 *)p->dispsw_data)[attr_fgcol(p,c)])) << 32) |
+              ((u32 *)p->dispsw_data)[attr_bgcol(p,c)];
+       if (fgbg != *(u64 *)&fb->s.ffb.fg_cache) {
+               FFBFifo(fb, 2);
+               *(volatile u64 *)&fbc->fg = fgbg;
+               *(u64 *)&fb->s.ffb.fg_cache = fgbg;
+       }
+       FFBFifo(fb, 2 + fontheight(p));
        fbc->fontxy = xy;
-       FFBFifo(fbc, fontheight(p));
+       fbc->fontw = fontwidth(p);
        if (fontwidth(p) <= 8) {
                for (i = 0; i < fontheight(p); i++)
                        fbc->font = *fd++ << 24;
@@ -430,11 +440,15 @@ static void ffb_putcs(struct vc_data *conp, struct display *p, const unsigned sh
        register struct ffb_fbc *fbc = fb->s.ffb.fbc;
        int i, xy;
        u8 *fd1, *fd2, *fd3, *fd4;
-
-       FFBWait(fbc);
-       FFBFifo(fbc, 2);
-       fbc->fg = ((u32 *)p->dispsw_data)[attr_fgcol(p,*s)];
-       fbc->bg = ((u32 *)p->dispsw_data)[attr_bgcol(p,*s)];
+       u64 fgbg;
+
+       fgbg = (((u64)(((u32 *)p->dispsw_data)[attr_fgcol(p,scr_readw(s))])) << 32) |
+              ((u32 *)p->dispsw_data)[attr_bgcol(p,scr_readw(s))];
+       if (fgbg != *(u64 *)&fb->s.ffb.fg_cache) {
+               FFBFifo(fb, 2);
+               *(volatile u64 *)&fbc->fg = fgbg;
+               *(u64 *)&fb->s.ffb.fg_cache = fgbg;
+       }
        xy = fb->s.ffb.xy_margin;
        if (fontwidthlog(p))
                xy += (xx << fontwidthlog(p));
@@ -447,22 +461,20 @@ static void ffb_putcs(struct vc_data *conp, struct display *p, const unsigned sh
        if (fontwidth(p) <= 8) {
                while (count >= 4) {
                        count -= 4;
-                       FFBFifo(fbc, 3);
+                       FFBFifo(fb, 2 + fontheight(p));
                        fbc->fontw = 4 * fontwidth(p);
-                       fbc->fontinc = 0x10000;
                        fbc->fontxy = xy;
                        if (fontheightlog(p)) {
-                               fd1 = p->fontdata + ((*s++ & p->charmask) << fontheightlog(p));
-                               fd2 = p->fontdata + ((*s++ & p->charmask) << fontheightlog(p));
-                               fd3 = p->fontdata + ((*s++ & p->charmask) << fontheightlog(p));
-                               fd4 = p->fontdata + ((*s++ & p->charmask) << fontheightlog(p));
+                               fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
+                               fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
+                               fd3 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
+                               fd4 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
                        } else {
-                               fd1 = p->fontdata + ((*s++ & p->charmask) * fontheight(p));
-                               fd2 = p->fontdata + ((*s++ & p->charmask) * fontheight(p));
-                               fd3 = p->fontdata + ((*s++ & p->charmask) * fontheight(p));
-                               fd4 = p->fontdata + ((*s++ & p->charmask) * fontheight(p));
+                               fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
+                               fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
+                               fd3 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
+                               fd4 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
                        }
-                       FFBFifo(fbc, fontheight(p));
                        if (fontwidth(p) == 8) {
                                for (i = 0; i < fontheight(p); i++)
                                        fbc->font = ((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++) 
@@ -478,18 +490,16 @@ static void ffb_putcs(struct vc_data *conp, struct display *p, const unsigned sh
        } else {
                while (count >= 2) {
                        count -= 2;
-                       FFBFifo(fbc, 3);
+                       FFBFifo(fb, 2 + fontheight(p));
                        fbc->fontw = 2 * fontwidth(p);
-                       fbc->fontinc = 0x10000;
                        fbc->fontxy = xy;
                        if (fontheightlog(p)) {
-                               fd1 = p->fontdata + ((*s++ & p->charmask) << (fontheightlog(p) + 1));
-                               fd2 = p->fontdata + ((*s++ & p->charmask) << (fontheightlog(p) + 1));
+                               fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) << (fontheightlog(p) + 1));
+                               fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) << (fontheightlog(p) + 1));
                        } else {
-                               fd1 = p->fontdata + (((*s++ & p->charmask) * fontheight(p)) << 1);
-                               fd2 = p->fontdata + (((*s++ & p->charmask) * fontheight(p)) << 1);
+                               fd1 = p->fontdata + (((scr_readw(s++) & p->charmask) * fontheight(p)) << 1);
+                               fd2 = p->fontdata + (((scr_readw(s++) & p->charmask) * fontheight(p)) << 1);
                        }
-                       FFBFifo(fbc, fontheight(p));
                        for (i = 0; i < fontheight(p); i++) {
                                fbc->font = ((((u32)*(u16 *)fd1) << fontwidth(p)) | ((u32)*(u16 *)fd2)) << (16 - fontwidth(p));
                                fd1 += 2; fd2 += 2;
@@ -499,15 +509,13 @@ static void ffb_putcs(struct vc_data *conp, struct display *p, const unsigned sh
        }
        while (count) {
                count--;
-               FFBFifo(fbc, 3);
+               FFBFifo(fb, 2 + fontheight(p));
                fbc->fontw = fontwidth(p);
-               fbc->fontinc = 0x10000;
                fbc->fontxy = xy;
                if (fontheightlog(p))
-                       i = ((*s++ & p->charmask) << fontheightlog(p));
+                       i = ((scr_readw(s++) & p->charmask) << fontheightlog(p));
                else
-                       i = ((*s++ & p->charmask) * fontheight(p));
-               FFBFifo(fbc, fontheight(p));
+                       i = ((scr_readw(s++) & p->charmask) * fontheight(p));
                if (fontwidth(p) <= 8) {
                        fd1 = p->fontdata + i;
                        for (i = 0; i < fontheight(p); i++)
@@ -554,8 +562,12 @@ static struct display_switch ffb_dispsw __initdata = {
 
 static void ffb_margins (struct fb_info_sbusfb *fb, struct display *p, int x_margin, int y_margin)
 {
+       register struct ffb_fbc *fbc = fb->s.ffb.fbc;
+
        fb->s.ffb.xy_margin = (y_margin << 16) + x_margin;
+       fb->s.ffb.yx_margin = (((u64)y_margin) << 32) + x_margin;
        p->screen_base += 8192 * (y_margin - fb->y_margin) + 4 * (x_margin - fb->x_margin);
+       FFBWait(fbc);
 }
 
 static inline void ffb_curs_enable (struct fb_info_sbusfb *fb, int enable)
@@ -619,11 +631,16 @@ static void ffb_switch_from_graph (struct fb_info_sbusfb *fb)
        register struct ffb_fbc *fbc = fb->s.ffb.fbc;
 
        FFBWait(fbc);
-       FFBFifo(fbc, 4);
+       fb->s.ffb.fifo_cache = 0;
+       FFBFifo(fb, 8);
        fbc->ppc = FFB_PPC_VCE_DISABLE|FFB_PPC_TBE_OPAQUE|FFB_PPC_APE_DISABLE|FFB_PPC_CS_CONST;
        fbc->fbc = 0x2000707f;
        fbc->rop = FFB_ROP_NEW;
+       fbc->drawop = FFB_DRAWOP_RECTANGLE;
        fbc->pmask = 0xffffffff;
+       fbc->fontinc = 0x10000;
+       fbc->fg = fb->s.ffb.fg_cache;
+       fbc->bg = fb->s.ffb.bg_cache;
        FFBWait(fbc);
 }                                
 
@@ -675,6 +692,7 @@ __initfunc(char *creatorfb_init(struct fb_info_sbusfb *fb))
        disp->scrollmode = SCROLL_YREDRAW;
        disp->screen_base = (char *)__va(regs[0].phys_addr) + FFB_DFB24_POFF + 8192 * fb->y_margin + 4 * fb->x_margin;
        fb->s.ffb.xy_margin = (fb->y_margin << 16) + fb->x_margin;
+       fb->s.ffb.yx_margin = (((u64)fb->y_margin) << 32) + fb->x_margin;
        fb->s.ffb.fbc = (struct ffb_fbc *)((char *)__va(regs[0].phys_addr) + FFB_FBC_REGS_POFF);
        fb->s.ffb.dac = (struct ffb_dac *)((char *)__va(regs[0].phys_addr) + FFB_DAC_POFF);
        fb->dispsw = ffb_dispsw;
index 4a137548f734b97af4ebfadd4f0c3c42ec36d700..0afc0d04ec0aa5a5543101cfcf8b71301d96b4c5 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Copyright (c) 1998-1999 Ilario Nardinocchi (nardinoc@CS.UniBO.IT)
  * --------------------------------------------------------------------------
- * $Id: cvisionppc.h,v 1.1.2.1 1999/01/12 19:52:59 geert Exp $
+ * $Id: cvisionppc.h,v 1.8 1999/01/28 13:18:07 illo Exp $
  * --------------------------------------------------------------------------
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file README.legal in the main directory of this archive
@@ -21,7 +21,7 @@
 struct cvppc_par {
        unsigned char* pci_config;
        unsigned char* pci_bridge;
-       unsigned long user_flags;
+       u32 user_flags;
 };
 
 #define CSPPC_PCI_BRIDGE               0xfffe0000
index 205c1347d5d6149cf4e6aceba572b74369bb00c7..3b9d4bb937cd9c582ca28937f9b71bacb238e146 100644 (file)
@@ -290,12 +290,12 @@ void fbcon_afb_putcs(struct vc_data *conp, struct display *p,
     int fg0, bg0, fg, bg;
 
     dest0 = p->screen_base+yy*fontheight(p)*p->next_line+xx;
-    fg0 = attr_fgcol(p,*s);
-    bg0 = attr_bgcol(p,*s);
+    fg0 = attr_fgcol(p, scr_readw(s));
+    bg0 = attr_bgcol(p, scr_readw(s));
 
     while (count--)
        if (xx&3 || count < 3) {        /* Slow version */
-           c1 = *s++ & p->charmask;
+           c1 = scr_readw(s++) & p->charmask;
            dest1 = dest0++;
            xx++;
 
@@ -322,10 +322,10 @@ void fbcon_afb_putcs(struct vc_data *conp, struct display *p,
                dest1 += p->next_plane;
            } while (--i);
        } else {                        /* Fast version */
-           c1 = s[0] & p->charmask;
-           c2 = s[1] & p->charmask;
-           c3 = s[2] & p->charmask;
-           c4 = s[3] & p->charmask;
+           c1 = scr_readw(&s[0]) & p->charmask;
+           c2 = scr_readw(&s[1]) & p->charmask;
+           c3 = scr_readw(&s[2]) & p->charmask;
+           c4 = scr_readw(&s[3]) & p->charmask;
 
            dest1 = dest0;
            cdat10 = p->fontdata+c1*fontheight(p);
index a05848f5bd7e3bd71060e76477c0ddc2790383ab..9fef8171ee4aff0074b1fb568975443d4a9df6f5 100644 (file)
@@ -177,8 +177,8 @@ void fbcon_cfb16_putcs(struct vc_data *conp, struct display *p,
     u32 eorx, fgx, bgx;
 
     dest0 = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 2;
-    fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p, *s)];
-    bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p, *s)];
+    fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p, scr_readw(s))];
+    bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p, scr_readw(s))];
     fgx |= (fgx << 16);
     bgx |= (bgx << 16);
     eorx = fgx ^ bgx;
@@ -187,7 +187,7 @@ void fbcon_cfb16_putcs(struct vc_data *conp, struct display *p,
     case 4:
     case 8:
        while (count--) {
-           c = *s++ & p->charmask;
+           c = scr_readw(s++) & p->charmask;
            cdat = p->fontdata + c * fontheight(p);
            for (rows = fontheight(p), dest = dest0; rows--; dest += bytes) {
                u8 bits = *cdat++;
@@ -204,7 +204,7 @@ void fbcon_cfb16_putcs(struct vc_data *conp, struct display *p,
     case 12:
     case 16:
        while (count--) {
-           c = *s++ & p->charmask;
+           c = scr_readw(s++) & p->charmask;
            cdat = p->fontdata + (c * fontheight(p) << 1);
            for (rows = fontheight(p), dest = dest0; rows--; dest += bytes) {
                u8 bits = *cdat++;
index e25fadaaeea3c5500c45960a4d18c68cdb2068a0..668177df091bee492be82ae13482929df48d3480 100644 (file)
@@ -156,15 +156,15 @@ void fbcon_cfb2_putcs(struct vc_data *conp, struct display *p, const unsigned sh
        u32 eorx, fgx, bgx;
 
        dest0 = p->screen_base + yy * fontheight(p) * bytes + xx * 2;
-       fgx=3/*attr_fgcol(p,*s)*/;
-       bgx=attr_bgcol(p,*s);
+       fgx=3/*attr_fgcol(p,scr_readw(s))*/;
+       bgx=attr_bgcol(p,scr_readw(s));
        fgx |= (fgx << 2);
        fgx |= (fgx << 4);
        bgx |= (bgx << 2);
        bgx |= (bgx << 4);
        eorx = fgx ^ bgx;
        while (count--) {
-               c = *s++ & p->charmask;
+               c = scr_readw(s++) & p->charmask;
                cdat = p->fontdata + c * fontheight(p);
 
                for (rows = fontheight(p), dest = dest0; rows-- ; dest += bytes) {
index 488aac2904c0092219eba5d05c9fd86c5e926a40..17e8ee08afa0765782e1372f4ff2d81b99b33ea1 100644 (file)
@@ -187,11 +187,11 @@ void fbcon_cfb24_putcs(struct vc_data *conp, struct display *p,
     u32 eorx, fgx, bgx, d1, d2, d3, d4;
 
     dest0 = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 3;
-    fgx = ((u32 *)p->dispsw_data)[attr_fgcol(p, *s)];
-    bgx = ((u32 *)p->dispsw_data)[attr_bgcol(p, *s)];
+    fgx = ((u32 *)p->dispsw_data)[attr_fgcol(p, scr_readw(s))];
+    bgx = ((u32 *)p->dispsw_data)[attr_bgcol(p, scr_readw(s))];
     eorx = fgx ^ bgx;
     while (count--) {
-       c = *s++ & p->charmask;
+       c = scr_readw(s++) & p->charmask;
        if (fontwidth(p) <= 8)
            cdat = p->fontdata + c * fontheight(p);
          
index cd1e80a7dbf1c04f79d21515069a68adc4dcfdb9..b66ec2badd4f056e4f91e8650f207b8e84ef5d61 100644 (file)
@@ -163,11 +163,11 @@ void fbcon_cfb32_putcs(struct vc_data *conp, struct display *p,
     u32 eorx, fgx, bgx;
 
     dest0 = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 4;
-    fgx = ((u32 *)p->dispsw_data)[attr_fgcol(p, *s)];
-    bgx = ((u32 *)p->dispsw_data)[attr_bgcol(p, *s)];
+    fgx = ((u32 *)p->dispsw_data)[attr_fgcol(p, scr_readw(s))];
+    bgx = ((u32 *)p->dispsw_data)[attr_bgcol(p, scr_readw(s))];
     eorx = fgx ^ bgx;
     while (count--) {
-       c = *s++ & p->charmask;
+       c = scr_readw(s++) & p->charmask;
        if (fontwidth(p) <= 8)
            cdat = p->fontdata + c * fontheight(p);
        else
index 78b87ffe707eda0fb6f3d486350fe0098be76c01..a86ec1596c9d4bfd8d0c3fc587379a72ab5926b4 100644 (file)
@@ -158,8 +158,8 @@ void fbcon_cfb4_putcs(struct vc_data *conp, struct display *p,
        u32 eorx, fgx, bgx;
 
        dest0 = p->screen_base + yy * fontheight(p) * bytes + xx * 4;
-       fgx=attr_fgcol(p,*s);
-       bgx=attr_bgcol(p,*s);
+       fgx=attr_fgcol(p,scr_readw(s));
+       bgx=attr_bgcol(p,scr_readw(s));
        fgx |= (fgx << 4);
        fgx |= (fgx << 8);
        fgx |= (fgx << 16);
@@ -168,7 +168,7 @@ void fbcon_cfb4_putcs(struct vc_data *conp, struct display *p,
        bgx |= (bgx << 16);
        eorx = fgx ^ bgx;
        while (count--) {
-               c = *s++ & p->charmask;
+               c = scr_readw(s++) & p->charmask;
                cdat = p->fontdata + c * fontheight(p);
 
                for (rows = fontheight(p), dest = dest0; rows-- ; dest += bytes) {
index bfa98c71948f4a79113ad4a9a1cabcfcbe68c27e..0acf7c989a88eb18de00bb38f4e084cbc3627de4 100644 (file)
@@ -163,8 +163,8 @@ void fbcon_cfb8_putcs(struct vc_data *conp, struct display *p,
     u32 eorx, fgx, bgx;
 
     dest0 = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p);
-    fgx=attr_fgcol(p,*s);
-    bgx=attr_bgcol(p,*s);
+    fgx=attr_fgcol(p,scr_readw(s));
+    bgx=attr_bgcol(p,scr_readw(s));
     fgx |= (fgx << 8);
     fgx |= (fgx << 16);
     bgx |= (bgx << 8);
@@ -173,7 +173,7 @@ void fbcon_cfb8_putcs(struct vc_data *conp, struct display *p,
     switch (fontwidth(p)) {
     case 4:
        while (count--) {
-           c = *s++ & p->charmask;
+           c = scr_readw(s++) & p->charmask;
            cdat = p->fontdata + c * fontheight(p);
 
            for (rows = fontheight(p), dest = dest0; rows-- ; dest += bytes)
@@ -183,7 +183,7 @@ void fbcon_cfb8_putcs(struct vc_data *conp, struct display *p,
         break;
     case 8:
        while (count--) {
-           c = *s++ & p->charmask;
+           c = scr_readw(s++) & p->charmask;
            cdat = p->fontdata + c * fontheight(p);
 
            for (rows = fontheight(p), dest = dest0; rows-- ; dest += bytes) {
@@ -196,7 +196,7 @@ void fbcon_cfb8_putcs(struct vc_data *conp, struct display *p,
     case 12:
     case 16:
        while (count--) {
-           c = *s++ & p->charmask;
+           c = scr_readw(s++) & p->charmask;
            cdat = p->fontdata + (c * fontheight(p) << 1);
 
            for (rows = fontheight(p), dest = dest0; rows-- ; dest += bytes) {
index 183f05a46669b4741c7686861a4c5c2026bd6b80..fbba519d97349dd9f890458ee6910de043e3fb51 100644 (file)
@@ -154,12 +154,12 @@ void fbcon_ilbm_putcs(struct vc_data *conp, struct display *p,
     int fg0, bg0, fg, bg;
 
     dest0 = p->screen_base+yy*fontheight(p)*p->next_line+xx;
-    fg0 = attr_fgcol(p,*s);
-    bg0 = attr_bgcol(p,*s);
+    fg0 = attr_fgcol(p,scr_readw(s));
+    bg0 = attr_bgcol(p,scr_readw(s));
 
     while (count--)
        if (xx&3 || count < 3) {        /* Slow version */
-           c1 = *s++ & p->charmask;
+           c1 = scr_readw(s++) & p->charmask;
            dest = dest0++;
            xx++;
 
@@ -185,10 +185,10 @@ void fbcon_ilbm_putcs(struct vc_data *conp, struct display *p,
                }
            }
        } else {                /* Fast version */
-           c1 = s[0] & p->charmask;
-           c2 = s[1] & p->charmask;
-           c3 = s[2] & p->charmask;
-           c4 = s[3] & p->charmask;
+           c1 = scr_readw(&s[0]) & p->charmask;
+           c2 = scr_readw(&s[1]) & p->charmask;
+           c3 = scr_readw(&s[2]) & p->charmask;
+           c4 = scr_readw(&s[3]) & p->charmask;
 
            dest = dest0;
            cdat1 = p->fontdata+c1*fontheight(p);
index 0c0bfa21ff4fbe497181e147b3f07758ecf9fd3f..0dfdc6107745936b012c2f5beb97be627037a04b 100644 (file)
@@ -361,12 +361,12 @@ void fbcon_iplan2p2_putcs(struct vc_data *conp, struct display *p,
     else
        dest0 = (p->screen_base + yy * bytes * fontheight(p) +
                 (xx>>1)*4 + (xx & 1));
-    fgx = expand2w(COLOR_2P(attr_fgcol(p,*s)));
-    bgx = expand2w(COLOR_2P(attr_bgcol(p,*s)));
+    fgx = expand2w(COLOR_2P(attr_fgcol(p,scr_readw(s))));
+    bgx = expand2w(COLOR_2P(attr_bgcol(p,scr_readw(s))));
     eorx = fgx ^ bgx;
 
     while (count--) {
-       c = *s++ & p->charmask;
+       c = scr_readw(s++) & p->charmask;
        if (fontheightlog(p))
            cdat = p->fontdata + (c << fontheightlog(p));
        else
index 2c1d67a77ece1cab9df3939c3f7e7f9c1073a81e..805c9170b02a3b5534636286d1a7bc313ce2a882 100644 (file)
@@ -371,8 +371,8 @@ void fbcon_iplan2p4_putcs(struct vc_data *conp, struct display *p,
     else
        dest0 = (p->screen_base + yy * bytes * fontheight(p) +
                 (xx>>1)*8 + (xx & 1));
-    fgx = expand4l(attr_fgcol(p,*s));
-    bgx = expand4l(attr_bgcol(p,*s));
+    fgx = expand4l(attr_fgcol(p,scr_readw(s)));
+    bgx = expand4l(attr_bgcol(p,scr_readw(s)));
     eorx = fgx ^ bgx;
 
     while (count--) {
@@ -383,7 +383,7 @@ void fbcon_iplan2p4_putcs(struct vc_data *conp, struct display *p,
        * cache :-(
        */
 
-       c = *s++ & p->charmask;
+       c = scr_readw(s++) & p->charmask;
        if (fontheightlog(p))
            cdat = p->fontdata + (c << fontheightlog(p));
        else
index c730eb39c00451205886ffd62b9b9c667698134f..411dc5ae94c907813df3d6731dc2c59ac4cbb83a 100644 (file)
@@ -404,8 +404,8 @@ void fbcon_iplan2p8_putcs(struct vc_data *conp, struct display *p,
        dest0 = (p->screen_base + yy * bytes * fontheight(p) +
                 (xx>>1)*16 + (xx & 1));
 
-    expand8dl(attr_fgcol(p,*s), &fgx1, &fgx2);
-    expand8dl(attr_bgcol(p,*s), &bgx1, &bgx2);
+    expand8dl(attr_fgcol(p,scr_readw(s)), &fgx1, &fgx2);
+    expand8dl(attr_bgcol(p,scr_readw(s)), &bgx1, &bgx2);
     eorx1 = fgx1 ^ bgx1; eorx2  = fgx2 ^ bgx2;
 
     while (count--) {
@@ -417,7 +417,7 @@ void fbcon_iplan2p8_putcs(struct vc_data *conp, struct display *p,
        * cache :-(
        */
 
-       c = *s++ & p->charmask;
+       c = scr_readw(s++) & p->charmask;
        if (fontheightlog(p))
            cdat = p->fontdata + (c << fontheightlog(p));
        else
index f2508e4cbcfeeb7ec2b3e16479d5ae43668e1507..2c6486c41d38092cf6280c26d980d87d54b0763c 100644 (file)
@@ -301,7 +301,7 @@ void fbcon_mac_putcs(struct vc_data *conp, struct display *p,
    u16 c;
 
    while (count--) {
-      c = *s++;
+      c = scr_readw(s++);
       fbcon_mac_putc(conp, p, c, yy, xx++);
    }
 }
index 32f1ea8d4b5d47b7b2f3616c6badfe803eae18b9..76caf5cc9ee0a948dd341d623a3a7368f4e12e85 100644 (file)
@@ -117,12 +117,12 @@ void fbcon_mfb_putcs(struct vc_data *conp, struct display *p,
     u16 c;
 
     dest0 = p->screen_base+yy*fontheight(p)*p->next_line+xx;
-    bold = attr_bold(p,*s);
-    revs = attr_reverse(p,*s);
-    underl = attr_underline(p,*s);
+    bold = attr_bold(p,scr_readw(s));
+    revs = attr_reverse(p,scr_readw(s));
+    underl = attr_underline(p,scr_readw(s));
 
     while (count--) {
-       c = *s++ & p->charmask;
+       c = scr_readw(s++) & p->charmask;
        dest = dest0++;
        cdat = p->fontdata+c*fontheight(p);
        for (rows = fontheight(p); rows--; dest += p->next_line) {
index fa4d387b8888bb5e71861763a0d5240aff341674..05f843d257333b33615c469ad24ba3014e4e0cc1 100644 (file)
@@ -155,11 +155,11 @@ void fbcon_vga_putcs(struct vc_data *conp, struct display *p,
     u16 sattr;
     if (conp->vc_can_do_color)
        while (count--)
-           vga_writew(*s++, dst++);
+           vga_writew(scr_readw(s++), dst++);
     else {
-        sattr = fbcon_vga_attr(p, *s);
+        sattr = fbcon_vga_attr(p, scr_readw(s));
         while (count--)
-           vga_writew(sattr | ((int) (*s++) & 0xff), dst++);
+           vga_writew(sattr | ((int) (scr_readw(s++)) & 0xff), dst++);
     }
 }
 
index 033118f6156f248657377cf6280b91e28448b7c9..b38657fae9edaba9a6d2d1942b424a16571626aa 100644 (file)
@@ -26,7 +26,7 @@
  *
  *  Hardware cursor support added by Emmanuel Marty (core@ggi-project.org)
  *  Smart redraw scrolling, arbitrary font width support, 512char font support
- *  added by 
+ *  and software scrollback added by 
  *                         Jakub Jelinek (jj@ultra.linux.cz)
  *
  *  Random hacking by Martin Mares <mj@ucw.cz>
 struct display fb_display[MAX_NR_CONSOLES];
 static int logo_lines;
 static int logo_shown = -1;
+/* Software scrollback */
+extern int fbcon_softback_size;
+static unsigned long softback_buf, softback_curr;
+static unsigned long softback_in;
+static unsigned long softback_top, softback_end;
+static int softback_lines;
 
 #define REFCOUNT(fd)   (((int *)(fd))[-1])
 #define FNTSIZE(fd)    (((int *)(fd))[-2])
@@ -118,7 +124,12 @@ static int logo_shown = -1;
 #define FNTSUM(fd)     (((int *)(fd))[-4])
 #define FONT_EXTRA_WORDS 4
 
-static void fbcon_free_font(struct display *p);
+#define CM_SOFTBACK    (8)
+
+#define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * conp->vc_size_row)
+
+static void fbcon_free_font(struct display *);
+static int fbcon_set_origin(struct vc_data *);
 
 /*
  * Emmanuel: fbcon will now use a hardware cursor if the
@@ -422,6 +433,27 @@ static void fbcon_setup(int con, int init, int logo)
        logo = 0;
 
     p->var.xoffset = p->var.yoffset = p->yscroll = 0;  /* reset wrap/pan */
+
+    if (con == fg_console && p->type != FB_TYPE_TEXT) {   
+       if (fbcon_softback_size) {
+           if (!softback_buf) {
+               softback_buf = (unsigned long)kmalloc(fbcon_softback_size, GFP_KERNEL);
+               if (!softback_buf) {
+                   fbcon_softback_size = 0;
+                   softback_top = 0;
+               }
+           }
+       } else {
+           if (softback_buf) {
+               kfree((void *)softback_buf);
+               softback_buf = 0;
+               softback_top = 0;
+           }
+       }
+       if (softback_buf)
+           softback_in = softback_top = softback_curr = softback_buf;
+       softback_lines = 0;
+    }
     
     for (i = 0; i < MAX_NR_CONSOLES; i++)
        if (i != con && fb_display[i].fb_info == p->fb_info &&
@@ -579,6 +611,17 @@ static void fbcon_setup(int con, int init, int logo)
        logo_shown = -2;
        conp->vc_top = logo_lines;
     }
+    
+    if (con == fg_console && softback_buf) {
+       int l = fbcon_softback_size / conp->vc_size_row;
+       if (l > 5)
+           softback_end = softback_buf + l * conp->vc_size_row;
+       else {
+           /* Smaller scrollback makes no sense, and 0 would screw
+              the operation totally */
+           softback_top = 0;
+       }
+    }
 }
 
 
@@ -703,17 +746,29 @@ static void fbcon_cursor(struct vc_data *conp, int mode)
 {
     int unit = conp->vc_num;
     struct display *p = &fb_display[unit];
+    int y = conp->vc_y;
+    
+    if (mode & CM_SOFTBACK) {
+       mode &= ~CM_SOFTBACK;
+       if (softback_lines) {
+           if (y + softback_lines >= conp->vc_rows)
+               mode = CM_ERASE;
+           else
+               y += softback_lines;
+       }
+    } else if (softback_lines)
+        fbcon_set_origin(conp);
 
     /* do we have a hardware cursor ? */
     if (p->dispsw->cursor) {
        p->cursor_x = conp->vc_x;
-       p->cursor_y = conp->vc_y;
+       p->cursor_y = y;
        p->dispsw->cursor(p, mode, p->cursor_x, real_y(p, p->cursor_y));
        return;
     }
 
     /* Avoid flickering if there's no real change. */
-    if (p->cursor_x == conp->vc_x && p->cursor_y == conp->vc_y &&
+    if (p->cursor_x == conp->vc_x && p->cursor_y == y &&
        (mode == CM_ERASE) == !cursor_on)
        return;
 
@@ -722,7 +777,7 @@ static void fbcon_cursor(struct vc_data *conp, int mode)
         p->dispsw->revc(p, p->cursor_x, real_y(p, p->cursor_y));
 
     p->cursor_x = conp->vc_x;
-    p->cursor_y = conp->vc_y;
+    p->cursor_y = y;
 
     switch (mode) {
         case CM_ERASE:
@@ -836,6 +891,94 @@ static __inline__ void ypan_down(int unit, struct vc_data *conp,
     scrollback_current = 0;
 }
 
+static void fbcon_redraw_softback(struct vc_data *conp, struct display *p, long delta)
+{
+    unsigned short *d, *s;
+    unsigned long n;
+    int line = 0;
+    int count = conp->vc_rows;
+    
+    d = (u16 *)softback_curr;
+    if (d == (u16 *)softback_in)
+       d = (u16 *)conp->vc_origin;
+    n = softback_curr + delta * conp->vc_size_row;
+    softback_lines -= delta;
+    if (delta < 0) {
+        if (softback_curr < softback_top && n < softback_buf) {
+            n += softback_end - softback_buf;
+           if (n < softback_top) {
+               softback_lines -= (softback_top - n) / conp->vc_size_row;
+               n = softback_top;
+           }
+        } else if (softback_curr >= softback_top && n < softback_top) {
+           softback_lines -= (softback_top - n) / conp->vc_size_row;
+           n = softback_top;
+        }
+    } else {
+       if (softback_curr > softback_in && n >= softback_end) {
+           n += softback_buf - softback_end;
+           if (n > softback_in) {
+               n = softback_in;
+               softback_lines = 0;
+           }
+       } else if (softback_curr <= softback_in && n > softback_in) {
+           n = softback_in;
+           softback_lines = 0;
+       }
+    }
+    if (n == softback_curr)
+       return;
+    softback_curr = n;
+    s = (u16 *)softback_curr;
+    if (s == (u16 *)softback_in)
+       s = (u16 *)conp->vc_origin;
+    while (count--) {
+       unsigned short *start;
+       unsigned short *le;
+       unsigned short c;
+       int x = 0;
+       unsigned short attr = 1;
+
+       start = s;
+       le = advance_row(s, 1);
+       do {
+           c = scr_readw(s);
+           if (attr != (c & 0xff00)) {
+               attr = c & 0xff00;
+               if (s > start) {
+                   p->dispsw->putcs(conp, p, start, s - start,
+                                    real_y(p, line), x);
+                   x += s - start;
+                   start = s;
+               }
+           }
+           if (c == scr_readw(d)) {
+               if (s > start) {
+                   p->dispsw->putcs(conp, p, start, s - start,
+                                    real_y(p, line), x);
+                   x += s - start + 1;
+                   start = s + 1;
+               } else {
+                   x++;
+                   start++;
+               }
+           }
+           s++;
+           d++;
+       } while (s < le);
+       if (s > start)
+           p->dispsw->putcs(conp, p, start, s - start, real_y(p, line), x);
+       line++;
+       if (d == (u16 *)softback_end)
+           d = (u16 *)softback_buf;
+       if (d == (u16 *)softback_in)
+           d = (u16 *)conp->vc_origin;
+       if (s == (u16 *)softback_end)
+           s = (u16 *)softback_buf;
+       if (s == (u16 *)softback_in)
+           s = (u16 *)conp->vc_origin;
+    }
+}
 
 static void fbcon_redraw(struct vc_data *conp, struct display *p, 
                         int line, int count, int offset)
@@ -846,8 +989,7 @@ static void fbcon_redraw(struct vc_data *conp, struct display *p,
 
     while (count--) {
        unsigned short *start = s;
-       unsigned short *le = (unsigned short *)
-           ((unsigned long)s + conp->vc_size_row);
+       unsigned short *le = advance_row(s, 1);
        unsigned short c;
        int x = 0;
        unsigned short attr = 1;
@@ -940,13 +1082,32 @@ void fbcon_redraw_bmove(struct display *p, int sy, int sx, int dy, int dx, int h
     }
 }
 
+static inline void fbcon_softback_note(struct vc_data *conp, int t, int count)
+{
+    unsigned short *p = (unsigned short *)
+       (conp->vc_origin + t * conp->vc_size_row);
+    while (count) {
+       scr_memcpyw((u16 *)softback_in, p, conp->vc_size_row);
+       count--;
+       p = advance_row(p, 1);
+       softback_in += conp->vc_size_row;
+       if (softback_in == softback_end)
+           softback_in = softback_buf;
+       if (softback_in == softback_top) {
+           softback_top += conp->vc_size_row;
+           if (softback_top == softback_end)
+               softback_top = softback_buf;
+       }
+    }
+    softback_curr = softback_in;
+}
+
 static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir,
                        int count)
 {
     int unit = conp->vc_num;
     struct display *p = &fb_display[unit];
     int scroll_partial = !(p->scrollmode & __SCROLL_YNOPARTIAL);
-    int logos_left = 0; int logos_width = conp->vc_cols;
 
     if (!p->can_soft_blank && console_blanked)
        return 0;
@@ -955,7 +1116,7 @@ static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir,
        return 0;
 
     fbcon_cursor(conp, CM_ERASE);
-
+    
     /*
      * ++Geert: Only use ywrap/ypan if the console is in text mode
      * ++Andrew: Only use ypan on hardware text mode when scrolling the
@@ -964,34 +1125,25 @@ static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir,
 
     switch (dir) {
        case SM_UP:
-           /* K.Garloff@ping.de, 98/10/21: If logo is diplayed, only save logo
-            * and not the hole top region. In combination with the logo being
-            * displayed on the right side, this allows scrollback feature
-            * when bootlogo is displayed. */
-            if (t != 0 && logo_shown == fg_console) {
-               struct display *p = &fb_display[unit];
-               int lw = (smp_num_cpus * (LOGO_W + 8) - 7) / fontwidth(p) + 1;
-               logos_left = conp->vc_cols - lw;
-               while (logos_left < 0) logos_left += (LOGO_W + 8 - 7) / fontwidth(p);
-               logos_width = conp->vc_cols - logos_left;
-           }
            if (count > conp->vc_rows)  /* Maximum realistic size */
                count = conp->vc_rows;
+           if (softback_top)
+               fbcon_softback_note(conp, t, count);
+           if (logo_shown >= 0) goto redraw_up;
            switch (p->scrollmode & __SCROLL_YMASK) {
            case __SCROLL_YMOVE:
-               if (t > 0) p->dispsw->bmove(p, 0, logos_left, count,
-                                       logos_left, t, logos_width);
-               p->dispsw->bmove(p, count, 0, 0, 0, b-count,
+               p->dispsw->bmove(p, t+count, 0, t, 0, b-t-count,
                                 conp->vc_cols);
-               p->dispsw->clear(conp, p, b-count, 0, count,
+               p->dispsw->clear(conp, p, b-count, 0, count,
                                 conp->vc_cols);
                break;
 
            case __SCROLL_YWRAP:
-               if (b-t-count > 2*conp->vc_rows/3) {
+               if (b-t-count > 3*conp->vc_rows>>2) {
                    if (t > 0)
-                       fbcon_bmove(conp, 0, logos_left, count, logos_left, t, logos_width);
-                   ywrap_up(unit, conp, p, count);
+                       fbcon_bmove(conp, 0, 0, count, 0, t,
+                                   conp->vc_cols);
+                       ywrap_up(unit, conp, p, count);
                    if (conp->vc_rows-b > 0)
                        fbcon_bmove(conp, b-count, 0, b, 0,
                                    conp->vc_rows-b, conp->vc_cols);
@@ -1004,11 +1156,12 @@ static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir,
                break;
 
            case __SCROLL_YPAN:
-               if (( !scroll_partial && (b-t == conp->vc_rows)) ||
-                   ( scroll_partial  && (b-t-count > 3*conp->vc_rows>>2))) {
+               if (( p->yscroll + count <= 2 * (p->vrows - conp->vc_rows)) &&
+                   (( !scroll_partial && (b-t == conp->vc_rows)) ||
+                    ( scroll_partial  && (b-t-count > 3*conp->vc_rows>>2)))) {
                    if (t > 0)
-                       fbcon_bmove(conp, 0, logos_left, count, logos_left, t,
-                                   logos_width);
+                       fbcon_bmove(conp, 0, 0, count, 0, t,
+                                   conp->vc_cols);
                    ypan_up(unit, conp, p, count);
                    if (conp->vc_rows-b > 0)
                        fbcon_bmove(conp, b-count, 0, b, 0,
@@ -1063,8 +1216,9 @@ static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir,
                break;
 
            case __SCROLL_YPAN:
-               if (( !scroll_partial && (b-t == conp->vc_rows)) ||
-                   ( scroll_partial  && (b-t-count > 3*conp->vc_rows>>2))) {
+               if (( count-p->yscroll <= p->vrows-conp->vc_rows) &&
+                   (( !scroll_partial && (b-t == conp->vc_rows)) ||
+                    ( scroll_partial  && (b-t-count > 3*conp->vc_rows>>2)))) {
                    if (conp->vc_rows-b > 0)
                        fbcon_bmove(conp, b, 0, b-count, 0,
                                    conp->vc_rows-b, conp->vc_cols);
@@ -1112,7 +1266,7 @@ static void fbcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
          (sx <= p->cursor_x) && (p->cursor_x < sx+width)) ||
         ((dy <= p->cursor_y) && (p->cursor_y < dy+height) &&
          (dx <= p->cursor_x) && (p->cursor_x < dx+width)))
-       fbcon_cursor(conp, CM_ERASE);
+       fbcon_cursor(conp, CM_ERASE|CM_SOFTBACK);
 
     /*  Split blits that cross physical y_wrap case.
      *  Pathological case involves 4 blits, better to use recursive
@@ -1162,6 +1316,12 @@ static int fbcon_switch(struct vc_data *conp)
     struct display *p = &fb_display[unit];
     struct fb_info *info = p->fb_info;
 
+    if (softback_top) {
+       if (softback_lines)
+           fbcon_set_origin(conp);
+        softback_top = softback_curr = softback_in = softback_buf;
+        softback_lines = 0;
+    }
     if (logo_shown >= 0) {
        struct vc_data *conp2 = vc_cons[logo_shown].d;
        
@@ -1227,8 +1387,22 @@ static int fbcon_blank(struct vc_data *conp, int blank)
                    mymemset(p->screen_base,
                             p->var.xres_virtual*p->var.yres_virtual*
                             p->var.bits_per_pixel>>3);
-            } else
-                p->dispsw->clear(conp, p, 0, 0, conp->vc_rows, conp->vc_cols);
+           } else {
+               unsigned short oldc;
+               u_int height;
+               u_int y_break;
+
+               oldc = conp->vc_video_erase_char;
+               conp->vc_video_erase_char &= p->charmask;
+               height = conp->vc_rows;
+               y_break = p->vrows-p->yscroll;
+               if (height > y_break) {
+                       p->dispsw->clear(conp, p, real_y(p, 0), 0, y_break, conp->vc_cols);
+                       p->dispsw->clear(conp, p, real_y(p, y_break), 0, height-y_break, conp->vc_cols);
+               } else
+                       p->dispsw->clear(conp, p, real_y(p, 0), 0, height, conp->vc_cols);
+               conp->vc_video_erase_char = oldc;
+           }
            return 0;
        } else {
            /* Tell console.c that it has to restore the screen itself */
@@ -1320,6 +1494,9 @@ static int fbcon_do_set_font(int unit, struct console_font_op *op, u8 *data, int
        return -ENXIO;
     }
 
+    if (CON_IS_VISIBLE(p->conp) && softback_lines)
+       fbcon_set_origin(p->conp);
+       
     resize = (w != fontwidth(p)) || (h != fontheight(p));
     if (p->userfont)
         old_data = p->fontdata;
@@ -1390,6 +1567,7 @@ static int fbcon_do_set_font(int unit, struct console_font_op *op, u8 *data, int
     fbcon_font_widths(p);
 
     if (resize) {
+       struct vc_data *conp = p->conp;
        /* reset wrap/pan */
        p->var.xoffset = p->var.yoffset = p->yscroll = 0;
        p->vrows = p->var.yres_virtual/h;
@@ -1397,6 +1575,16 @@ static int fbcon_do_set_font(int unit, struct console_font_op *op, u8 *data, int
            p->vrows--;
        updatescrollmode(p);
        vc_resize_con( p->var.yres/h, p->var.xres/w, unit );
+        if (CON_IS_VISIBLE(conp) && softback_buf) {
+           int l = fbcon_softback_size / conp->vc_size_row;
+           if (l > 5)
+               softback_end += l * conp->vc_size_row;
+           else {
+               /* Smaller scrollback makes no sense, and 0 would screw
+                  the operation totally */
+               softback_top = 0;
+           }
+       }
     } else if (CON_IS_VISIBLE(p->conp) && vt_cons[unit]->vc_mode == KD_TEXT) {
        if (p->dispsw->clear_margins)
            p->dispsw->clear_margins(p->conp, p, 0);
@@ -1476,6 +1664,7 @@ static inline int fbcon_set_font(int unit, struct console_font_op *op)
        }
     } else if (w <= 24) {
        for (i = 0; i < op->charcount; i++) {
+           int j;
            for (j = 0; j < h; j++) {
                memcpy(p, data, 3);
                p[3] = 0;
@@ -1586,10 +1775,120 @@ static int fbcon_set_palette(struct vc_data *conp, unsigned char *table)
     return p->fb_info->fbops->fb_set_cmap(&palette_cmap, 1, unit, p->fb_info);
 }
 
+static u16 *fbcon_screen_pos(struct vc_data *conp, int offset)
+{
+    int line;
+    unsigned long p;
+
+    if (conp->vc_num != fg_console || !softback_lines)
+       return (u16 *)(conp->vc_origin + offset);
+    line = offset / conp->vc_size_row;
+    if (line >= softback_lines)
+       return (u16 *)(conp->vc_origin + offset - softback_lines * conp->vc_size_row);
+    p = softback_curr + offset;
+    if (p >= softback_end)
+       p += softback_buf - softback_end;
+    return (u16 *)p;
+}
+
+static unsigned long fbcon_getxy(struct vc_data *conp, unsigned long pos, int *px, int *py)
+{
+    int x, y;
+    unsigned long ret;
+    if (pos >= conp->vc_origin && pos < conp->vc_scr_end) {
+       unsigned long offset = (pos - conp->vc_origin) / 2;
+       
+       x = offset % conp->vc_cols;
+       y = offset / conp->vc_cols;
+       if (conp->vc_num == fg_console)
+           y += softback_lines;
+       ret = pos + (conp->vc_cols - x) * 2;
+    } else if (conp->vc_num == fg_console && softback_lines) {
+       unsigned long offset = (pos - softback_curr) / 2;
+       
+       x = offset % conp->vc_cols;
+       y = offset / conp->vc_cols;
+       if (pos < softback_curr)
+           y += (softback_end - softback_buf) / conp->vc_size_row;
+       ret = pos + (conp->vc_cols - x) * 2;
+       if (ret == softback_end)
+           ret = softback_buf;
+       if (ret == softback_in)
+           ret = conp->vc_origin;
+    } else {
+       /* Should not happen */
+       x = y = 0;
+       ret = conp->vc_origin;
+    }
+    if (px) *px = x;
+    if (py) *py = y;
+    return ret;
+}
+
+/* As we might be inside of softback, we may work with non-contiguous buffer,
+   that's why we have to use a separate routine. */
+static void fbcon_invert_region(struct vc_data *conp, u16 *p, int cnt)
+{
+    while (cnt--) {
+       if (!conp->vc_can_do_color)
+           *p++ ^= 0x0800;
+       else if (conp->vc_hi_font_mask == 0x100) {
+           u16 a = *p;
+           a = ((a) & 0x11ff) | (((a) & 0xe000) >> 4) | (((a) & 0x0e00) << 4);
+           *p++ = a;
+       } else {
+           u16 a = *p;
+           a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4);
+           *p++ = a;
+       }
+       if (p == (u16 *)softback_end)
+           p = (u16 *)softback_buf;
+       if (p == (u16 *)softback_in)
+           p = (u16 *)conp->vc_origin;
+    }
+}
+
 static int fbcon_scrolldelta(struct vc_data *conp, int lines)
 {
     int unit, offset, limit, scrollback_old;
     struct display *p;
+    
+    unit = fg_console;
+    p = &fb_display[unit];
+    if (softback_top) {
+       if (conp->vc_num != unit)
+           return 0;
+       if (vt_cons[unit]->vc_mode != KD_TEXT || !lines)
+           return 0;
+       if (logo_shown >= 0) {
+               struct vc_data *conp2 = vc_cons[logo_shown].d;
+       
+               if (conp2->vc_top == logo_lines && conp2->vc_bottom == conp2->vc_rows)
+                   conp2->vc_top = 0;
+               if (logo_shown == unit) {
+                   unsigned long p, q;
+                   int i;
+                   
+                   p = softback_in;
+                   q = conp->vc_origin + logo_lines * conp->vc_size_row;
+                   for (i = 0; i < logo_lines; i++) {
+                       if (p == softback_top) break;
+                       if (p == softback_buf) p = softback_end;
+                       p -= conp->vc_size_row;
+                       q -= conp->vc_size_row;
+                       scr_memcpyw((u16 *)q, (u16 *)p, conp->vc_size_row);
+                   }
+                   softback_lines -= i;
+                   softback_in = p;
+                   update_region(unit, conp->vc_origin, logo_lines * conp->vc_cols);
+               }
+               logo_shown = -1;
+       }
+       fbcon_cursor(conp, CM_ERASE|CM_SOFTBACK);
+       fbcon_redraw_softback(conp, p, lines);
+       fbcon_cursor(conp, CM_DRAW|CM_SOFTBACK);
+       return 0;
+    }
 
     if (!scrollback_phys_max)
        return -ENOSYS;
@@ -1603,8 +1902,6 @@ static int fbcon_scrolldelta(struct vc_data *conp, int lines)
     if (scrollback_current == scrollback_old)
        return 0;
 
-    unit = fg_console;
-    p = &fb_display[unit];
     if (!p->can_soft_blank &&
        (console_blanked || vt_cons[unit]->vc_mode != KD_TEXT || !lines))
        return 0;
@@ -1633,6 +1930,13 @@ static int fbcon_scrolldelta(struct vc_data *conp, int lines)
     return 0;
 }
 
+static int fbcon_set_origin(struct vc_data *conp)
+{
+    if (softback_lines && !console_blanked)
+        fbcon_scrolldelta(conp, softback_lines);
+    return 0;
+}
+
 static inline unsigned safe_shift(unsigned d,int n)
 {
     return n<0 ? d>>-n : d<<n;
@@ -1705,8 +2009,8 @@ __initfunc(static int fbcon_show_logo( void ))
        logo_depth = 1;
     }
 
-    for (x = p->var.xres - LOGO_W; x > 0 && x > (int)p->var.xres 
-        - smp_num_cpus * (LOGO_W + 8); x -= (LOGO_W + 8)) {
+    for (x = 0; x < smp_num_cpus * (LOGO_W + 8) &&
+        x < p->var.xres - (LOGO_W + 8); x += (LOGO_W + 8)) {
         
 #if defined(CONFIG_FBCON_CFB16) || defined(CONFIG_FBCON_CFB24) || \
     defined(CONFIG_FBCON_CFB32) || defined(CONFIG_FB_SBUS)
@@ -1939,10 +2243,12 @@ struct consw fb_con = {
     con_font_op:       fbcon_font_op,
     con_set_palette:   fbcon_set_palette,
     con_scrolldelta:   fbcon_scrolldelta,
-    con_set_origin:    NULL,
+    con_set_origin:    fbcon_set_origin,
     con_save_screen:   NULL,
     con_build_attr:    NULL,
-    con_invert_region: NULL,
+    con_invert_region: fbcon_invert_region,
+    con_screen_pos:    fbcon_screen_pos,
+    con_getxy:         fbcon_getxy,
 };
 
 
index c3c42ed5ea982e0ce03619a22f6cf13b8bd0de06..ff14807a0909b7111fe0df0261f632e2f797bdc8 100644 (file)
@@ -244,7 +244,6 @@ void fbgen_set_disp(int con, struct fb_info_gen *info)
     memset(&fix, 0, sizeof(struct fb_fix_screeninfo));
     fbhw->encode_fix(&fix, &par, info);
 
-    display->screen_base = phys_to_virt((unsigned long)fix.smem_start);
     display->visual = fix.visual;
     display->type = fix.type;
     display->type_aux = fix.type_aux;
@@ -256,7 +255,7 @@ void fbgen_set_disp(int con, struct fb_info_gen *info)
        display->can_soft_blank = 1;
     else
        display->can_soft_blank = 0;
-    fbhw->set_dispsw(&par, display, info);
+    fbhw->set_disp(&par, display, info);
 #if 0 /* FIXME: generic inverse is not supported yet */
     display->inverse = (fix.visual == FB_VISUAL_MONO01 ? !inverse : inverse);
 #else
index d8e6b08294aa7b8bcd4c5e16fc0f0542735aa4c8..56f0ac7904bd9e8e64525e89023f8509c79df344 100644 (file)
@@ -88,6 +88,9 @@ extern void sbusfb_setup(char *options, int *ints);
 extern void valkyriefb_init(void);
 extern void valkyriefb_setup(char *options, int *ints);
 extern void g364fb_init(void);
+extern void fm2fb_init(void);
+extern void fm2fb_setup(char *options, int *ints);
+extern void q40fb_init(void);
 
 static struct {
        const char *name;
@@ -136,6 +139,9 @@ static struct {
 #ifdef CONFIG_APOLLO
        { "apollo", dnfb_init, NULL },
 #endif
+#ifdef CONFIG_FB_Q40
+       { "q40fb", q40fb_init, NULL },
+#endif
 #ifdef CONFIG_FB_S3TRIO
        { "s3trio", s3triofb_init, s3triofb_setup },
 #endif 
@@ -160,6 +166,9 @@ static struct {
 #ifdef CONFIG_FB_G364
        { "g364", g364fb_init, NULL },
 #endif
+#ifdef CONFIG_FB_FM2
+       { "fm2fb", fm2fb_init, fm2fb_setup },
+#endif 
 #ifdef CONFIG_GSP_RESOLVER
        /* Not a real frame buffer device... */
        { "resolver", NULL, resolver_video_setup },
@@ -181,6 +190,7 @@ static int num_pref_init_funcs __initdata = 0;
 
 struct fb_info *registered_fb[FB_MAX];
 int num_registered_fb = 0;
+int fbcon_softback_size = 32768;
 
 char con2fb_map[MAX_NR_CONSOLES];
 
@@ -648,6 +658,21 @@ __initfunc(void video_setup(char *options, int *ints))
     if (!options || !*options)
            return;
            
+    if (!strncmp(options, "scrollback:", 11)) {
+           options += 11;
+           if (*options) {
+               fbcon_softback_size = simple_strtoul(options, &options, 0);
+               if (*options == 'k' || *options == 'K') {
+                       fbcon_softback_size *= 1024;
+                       options++;
+               }
+               if (*options != ',')
+                       return;
+               options++;
+           } else
+               return;
+    }
+
     if (!strncmp(options, "map:", 4)) {
            options += 4;
            if (*options)
@@ -658,7 +683,7 @@ __initfunc(void video_setup(char *options, int *ints))
                    }
            return;
     }
-
+    
     if (!strncmp(options, "vc:", 3)) {
            options += 3;
            if (*options)
diff --git a/drivers/video/fm2fb.c b/drivers/video/fm2fb.c
new file mode 100644 (file)
index 0000000..e5ab75e
--- /dev/null
@@ -0,0 +1,572 @@
+/*
+ *  linux/drivers/video/fm2fb.c -- BSC FrameMaster II/Rainbow II frame buffer
+ *                                device
+ *
+ *     Copyright (C) 1998 Steffen A. Mork (mork@ls7.cs.uni-dortmund.de)
+ *     Copyright (C) 1999 Geert Uytterhoeven
+ *
+ *  Written for 2.0.x by Steffen A. Mork
+ *  Ported to 2.1.x by Geert Uytterhoeven
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/zorro.h>
+
+#include <asm/io.h>
+
+#include <video/fbcon.h>
+#include <video/fbcon-cfb32.h>
+
+
+/*
+ *     Some technical notes:
+ *
+ *     The BSC FrameMaster II (or Rainbow II) is a simple very dumb
+ *     frame buffer which allows to display 24 bit true color images.
+ *     Each pixel is 32 bit width so it's very easy to maintain the
+ *     frame buffer. One long word has the following layout:
+ *     AARRGGBB which means: AA the alpha channel byte, RR the red
+ *     channel, GG the green channel and BB the blue channel.
+ *
+ *     The FrameMaster II supports the following video modes.
+ *     - PAL/NTSC
+ *     - interlaced/non interlaced
+ *     - composite sync/sync/sync over green
+ *
+ *     The resolution is to the following both ones:
+ *     - 768x576 (PAL)
+ *     - 768x480 (NTSC)
+ *
+ *     This means that pixel access per line is fixed due to the
+ *     fixed line width. In case of maximal resolution the frame
+ *     buffer needs an amount of memory of 1.769.472 bytes which
+ *     is near to 2 MByte (the allocated address space of Zorro2).
+ *     The memory is channel interleaved. That means every channel
+ *     owns four VRAMs. Unfortunatly most FrameMasters II are
+ *     not assembled with memory for the alpha channel. In this
+ *     case it could be possible to add the frame buffer into the
+ *     normal memory pool.
+ *     
+ *     At relative address 0x1ffff8 of the frame buffers base address
+ *     there exists a control register with the number of
+ *     four control bits. They have the following meaning:
+ *     bit value meaning
+ *
+ *      0    1   0=interlaced/1=non interlaced
+ *      1    2   0=video out disabled/1=video out enabled
+ *      2    4   0=normal mode as jumpered via JP8/1=complement mode
+ *      3    8   0=read  onboard ROM/1 normal operation (required)
+ *
+ *     As mentioned above there are several jumper. I think there
+ *     is not very much information about the FrameMaster II in
+ *     the world so I add these information for completeness.
+ *
+ *     JP1  interlace selection (1-2 non interlaced/2-3 interlaced) 
+ *     JP2  wait state creation (leave as is!)
+ *     JP3  wait state creation (leave as is!)
+ *     JP4  modulate composite sync on green output (1-2 composite
+ *          sync on green channel/2-3 normal composite sync)
+ *     JP5  create test signal, shorting this jumper will create
+ *          a white screen
+ *     JP6  sync creation (1-2 composite sync/2-3 H-sync output)
+ *     JP8  video mode (1-2 PAL/2-3 NTSC)
+ *
+ *     With the following jumpering table you can connect the
+ *     FrameMaster II to a normal TV via SCART connector:
+ *     JP1:  2-3
+ *     JP4:  2-3
+ *     JP6:  2-3
+ *     JP8:  1-2 (means PAL for Europe)
+ *
+ *     NOTE:
+ *     There is no other possibility to change the video timings
+ *     except the interlaced/non interlaced, sync control and the
+ *     video mode PAL (50 Hz)/NTSC (60 Hz). Inside this
+ *     FrameMaster II driver are assumed values to avoid anomalies
+ *     to a future X server. Except the pixel clock is really
+ *     constant at 30 MHz.
+ *
+ *     9 pin female video connector:
+ *
+ *     1  analog red 0.7 Vss
+ *     2  analog green 0.7 Vss
+ *     3  analog blue 0.7 Vss
+ *     4  H-sync TTL
+ *     5  V-sync TTL
+ *     6  ground
+ *     7  ground
+ *     8  ground
+ *     9  ground
+ *
+ *     Some performance notes:
+ *     The FrameMaster II was not designed to display a console
+ *     this driver would do! It was designed to display still true
+ *     color images. Imagine: When scroll up a text line there
+ *     must copied ca. 1.7 MBytes to another place inside this
+ *     frame buffer. This means 1.7 MByte read and 1.7 MByte write
+ *     over the slow 16 bit wide Zorro2 bus! A scroll of one
+ *     line needs 1 second so do not expect to much from this
+ *     driver - he is at the limit!
+ *
+ */
+
+
+/*
+ *     definitions
+ */
+
+#define FRAMEMASTER_SIZE       0x200000
+#define FRAMEMASTER_REG                0x1ffff8
+
+#define FRAMEMASTER_NOLACE     1
+#define FRAMEMASTER_ENABLE     2
+#define FRAMEMASTER_COMPL      4
+#define FRAMEMASTER_ROM                8
+
+
+struct FrameMaster_fb_par
+{
+       int xres;
+       int yres;
+       int bpp;
+       int pixclock;
+};
+
+static unsigned long fm2fb_mem_phys;
+static void *fm2fb_mem;
+static unsigned long fm2fb_reg_phys;
+static volatile unsigned char *fm2fb_reg;
+
+#define arraysize(x)   (sizeof(x)/sizeof(*(x)))
+
+static int currcon = 0;
+static struct display disp;
+static struct fb_info fb_info;
+static struct { u_char red, green, blue, pad; } palette[16];
+#ifdef FBCON_HAS_CFB32
+static u32 fbcon_cfb32_cmap[16];
+#endif
+
+static struct fb_fix_screeninfo fb_fix;
+static struct fb_var_screeninfo fb_var;
+
+static int fm2fb_mode __initdata = -1;
+
+#define FM2FB_MODE_PAL 0
+#define FM2FB_MODE_NTSC        1
+
+static struct fb_var_screeninfo fb_var_modes[] __initdata = {
+    {
+       /* 768 x 576, 32 bpp (PAL) */
+       768, 576, 768, 576, 0, 0, 32, 0,
+       { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 24, 8, 0 },
+       0, FB_ACTIVATE_NOW, -1, -1, FB_ACCEL_NONE,
+       33333, 10, 102, 10, 5, 80, 34, FB_SYNC_COMP_HIGH_ACT, 0
+    }, {
+       /* 768 x 480, 32 bpp (NTSC - not supported yet */
+       768, 480, 768, 480, 0, 0, 32, 0,
+       { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 24, 8, 0 },
+       0, FB_ACTIVATE_NOW, -1, -1, FB_ACCEL_NONE,
+       33333, 10, 102, 10, 5, 80, 34, FB_SYNC_COMP_HIGH_ACT, 0
+    }
+};
+
+
+    /*
+     *  Interface used by the world
+     */
+
+static int fm2fb_open(struct fb_info *info, int user);
+static int fm2fb_release(struct fb_info *info, int user);
+static int fm2fb_get_fix(struct fb_fix_screeninfo *fix, int con,
+                        struct fb_info *info);
+static int fm2fb_get_var(struct fb_var_screeninfo *var, int con,
+                        struct fb_info *info);
+static int fm2fb_set_var(struct fb_var_screeninfo *var, int con,
+                        struct fb_info *info);
+static int fm2fb_pan_display(struct fb_var_screeninfo *var, int con,
+                            struct fb_info *info);
+static int fm2fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+                         struct fb_info *info);
+static int fm2fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+                         struct fb_info *info);
+static int fm2fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+                      u_long arg, int con, struct fb_info *info);
+
+
+    /*
+     *  Interface to the low level console driver
+     */
+
+void fm2fb_init(void);
+static int fm2fbcon_switch(int con, struct fb_info *info);
+static int fm2fbcon_updatevar(int con, struct fb_info *info);
+static void fm2fbcon_blank(int blank, struct fb_info *info);
+
+
+    /*
+     *  Internal routines
+     */
+
+static int fm2fb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+                          u_int *transp, struct fb_info *info);
+static int fm2fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                          u_int transp, struct fb_info *info);
+static void do_install_cmap(int con, struct fb_info *info);
+
+
+static struct fb_ops fm2fb_ops = {
+    fm2fb_open, fm2fb_release, fm2fb_get_fix, fm2fb_get_var, fm2fb_set_var,
+    fm2fb_get_cmap, fm2fb_set_cmap, fm2fb_pan_display, fm2fb_ioctl
+};
+
+
+    /*
+     *  Open/Release the frame buffer device
+     */
+
+static int fm2fb_open(struct fb_info *info, int user)
+{
+    /*                                                                     
+     *  Nothing, only a usage count for the moment                          
+     */                                                                    
+
+    MOD_INC_USE_COUNT;
+    return(0);                              
+}
+        
+static int fm2fb_release(struct fb_info *info, int user)
+{
+    MOD_DEC_USE_COUNT;
+    return(0);                                                    
+}
+
+
+    /*
+     *  Get the Fixed Part of the Display
+     */
+
+static int fm2fb_get_fix(struct fb_fix_screeninfo *fix, int con,
+                        struct fb_info *info)
+{
+    memcpy(fix, &fb_fix, sizeof(fb_fix));
+    return 0;
+}
+
+
+    /*
+     *  Get the User Defined Part of the Display
+     */
+
+static int fm2fb_get_var(struct fb_var_screeninfo *var, int con,
+                        struct fb_info *info)
+{
+    memcpy(var, &fb_var, sizeof(fb_var));
+    return 0;
+}
+
+
+    /*
+     *  Set the User Defined Part of the Display
+     */
+
+static int fm2fb_set_var(struct fb_var_screeninfo *var, int con,
+                        struct fb_info *info)
+{
+    struct display *display;
+    int oldbpp = -1, err;
+
+    if (con >= 0)
+       display = &fb_display[con];
+    else
+       display = &disp;        /* used during initialization */
+
+    if (var->xres > fb_var.xres || var->yres > fb_var.yres ||
+       var->xres_virtual > fb_var.xres_virtual ||
+       var->yres_virtual > fb_var.yres_virtual ||
+       var->bits_per_pixel > fb_var.bits_per_pixel ||
+       var->nonstd ||
+       (var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
+       return -EINVAL;
+    memcpy(var, &fb_var, sizeof(fb_var));
+
+    if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+       oldbpp = display->var.bits_per_pixel;
+       display->var = *var;
+    }
+    if (oldbpp != var->bits_per_pixel) {
+       if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
+           return err;
+       do_install_cmap(con, info);
+    }
+    return 0;
+}
+
+
+    /*
+     *  Pan or Wrap the Display
+     *
+     *  This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+     */
+
+static int fm2fb_pan_display(struct fb_var_screeninfo *var, int con,
+                            struct fb_info *info)
+{
+    if (var->xoffset || var->yoffset)
+       return -EINVAL;
+    else
+       return 0;
+}
+
+    /*
+     *  Get the Colormap
+     */
+
+static int fm2fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+                         struct fb_info *info)
+{
+    if (con == currcon) /* current console? */
+       return fb_get_cmap(cmap, kspc, fm2fb_getcolreg, info);
+    else if (fb_display[con].cmap.len) /* non default colormap? */
+       fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+    else
+       fb_copy_cmap(fb_default_cmap(256), cmap, kspc ? 0 : 2);
+    return 0;
+}
+
+    /*
+     *  Set the Colormap
+     */
+
+static int fm2fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+                         struct fb_info *info)
+{
+    int err;
+
+    if (!fb_display[con].cmap.len) {   /* no colormap allocated? */
+       if ((err = fb_alloc_cmap(&fb_display[con].cmap, 256, 0)))
+           return err;
+    }
+    if (con == currcon) {              /* current console? */
+       err = fb_set_cmap(cmap, kspc, fm2fb_setcolreg, info);
+       return err;
+    } else
+       fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+    return 0;
+}
+
+
+static int fm2fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+                      u_long arg, int con, struct fb_info *info)
+{
+    return -EINVAL;
+}
+
+
+    /*
+     *  Initialisation
+     */
+
+__initfunc(void fm2fb_init(void))
+{
+    int key, is_fm;
+    const struct ConfigDev *cd  = NULL;
+    unsigned long board, *ptr;
+    int x, y;
+
+    if (!(key = is_fm = zorro_find(ZORRO_PROD_BSC_FRAMEMASTER_II, 0, 0)) &&
+       !(key = zorro_find(ZORRO_PROD_HELFRICH_RAINBOW_II, 0, 0)))
+       return;
+    cd = zorro_get_board(key);
+    if (!(board = (u_long)cd->cd_BoardAddr))
+       return;
+    zorro_config_board(key, 0);
+
+    /* assigning memory to kernel space */
+    fm2fb_mem_phys = board;
+    fm2fb_mem  = ioremap(board, FRAMEMASTER_SIZE);
+    fm2fb_reg_phys = fm2fb_mem_phys+FRAMEMASTER_REG;
+    fm2fb_reg  = (unsigned char *)(fm2fb_mem+FRAMEMASTER_REG);
+
+    /* make EBU color bars on display */
+    ptr = (unsigned long *)fm2fb_mem;
+    for (y = 0; y < 576; y++) {
+       for (x = 0; x < 96; x++) *ptr++ = 0xffffff;     /* white */
+       for (x = 0; x < 96; x++) *ptr++ = 0xffff00;     /* yellow */
+       for (x = 0; x < 96; x++) *ptr++ = 0x00ffff;     /* cyan */
+       for (x = 0; x < 96; x++) *ptr++ = 0x00ff00;     /* green */
+       for (x = 0; x < 96; x++) *ptr++ = 0xff00ff;     /* magenta */
+       for (x = 0; x < 96; x++) *ptr++ = 0xff0000;     /* red */
+       for (x = 0; x < 96; x++) *ptr++ = 0x0000ff;     /* blue */
+       for (x = 0; x < 96; x++) *ptr++ = 0x000000;     /* black */
+    }
+    fm2fbcon_blank(0, NULL);
+
+    if (fm2fb_mode == -1)
+       fm2fb_mode = FM2FB_MODE_PAL;
+
+    fb_var = fb_var_modes[fm2fb_mode];
+
+    strcpy(fb_fix.id, is_fm ? "FrameMaster II" : "Rainbow II");
+    fb_fix.smem_start = (char *)fm2fb_mem_phys;
+    fb_fix.smem_len = FRAMEMASTER_REG;
+    fb_fix.type = FB_TYPE_PACKED_PIXELS;
+    fb_fix.type_aux = 0;
+    fb_fix.visual = FB_VISUAL_TRUECOLOR;
+    fb_fix.line_length = 768<<2;
+    fb_fix.mmio_start = (char *)fm2fb_reg_phys;
+    fb_fix.mmio_len = 8;
+    fb_fix.accel = FB_ACCEL_NONE;
+
+    disp.var = fb_var;
+    disp.cmap.start = 0;
+    disp.cmap.len = 0;
+    disp.cmap.red = disp.cmap.green = disp.cmap.blue = disp.cmap.transp = NULL;
+    disp.screen_base = (char *)fm2fb_mem;
+    disp.visual = fb_fix.visual;
+    disp.type = fb_fix.type;
+    disp.type_aux = fb_fix.type_aux;
+    disp.ypanstep = 0;
+    disp.ywrapstep = 0;
+    disp.line_length = fb_fix.line_length;
+    disp.can_soft_blank = 1;
+    disp.inverse = 0;
+#ifdef FBCON_HAS_CFB32
+    disp.dispsw = &fbcon_cfb32;
+    disp.dispsw_data = &fbcon_cfb32_cmap;
+#else
+    disp.dispsw = &fbcon_dummy;
+#endif
+    disp.scrollmode = SCROLL_YREDRAW;
+
+    strcpy(fb_info.modename, fb_fix.id);
+    fb_info.node = -1;
+    fb_info.fbops = &fm2fb_ops;
+    fb_info.disp = &disp;
+    fb_info.fontname[0] = '\0';
+    fb_info.changevar = NULL;
+    fb_info.switch_con = &fm2fbcon_switch;
+    fb_info.updatevar = &fm2fbcon_updatevar;
+    fb_info.blank = &fm2fbcon_blank;
+    fb_info.flags = FBINFO_FLAG_DEFAULT;
+
+    fm2fb_set_var(&fb_var, -1, &fb_info);
+
+    if (register_framebuffer(&fb_info) < 0)
+       return;
+
+    printk("fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.node),
+          fb_fix.id);
+}
+
+__initfunc(void fm2fb_setup(char *options, int *ints))
+{
+    char *this_opt;
+
+    if (!options || !*options)
+       return;
+
+    for (this_opt = strtok(options, ","); this_opt;
+        this_opt = strtok(NULL, ",")) {
+       if (!strncmp(this_opt, "pal", 3))
+           fm2fb_mode = FM2FB_MODE_PAL;
+       else if (!strncmp(this_opt, "ntsc", 4))
+           fm2fb_mode = FM2FB_MODE_NTSC;
+    }
+}
+
+
+static int fm2fbcon_switch(int con, struct fb_info *info)
+{
+    /* Do we have to save the colormap? */
+    if (fb_display[currcon].cmap.len)
+       fb_get_cmap(&fb_display[currcon].cmap, 1, fm2fb_getcolreg, info);
+
+    currcon = con;
+    /* Install new colormap */
+    do_install_cmap(con, info);
+    return 0;
+}
+
+    /*
+     *  Update the `var' structure (called by fbcon.c)
+     */
+
+static int fm2fbcon_updatevar(int con, struct fb_info *info)
+{
+    /* Nothing */
+    return 0;
+}
+
+    /*
+     *  Blank the display.
+     */
+
+static void fm2fbcon_blank(int blank, struct fb_info *info)
+{
+    unsigned char t = FRAMEMASTER_ROM;
+
+    if (!blank)
+       t |= FRAMEMASTER_ENABLE | FRAMEMASTER_NOLACE;
+    fm2fb_reg[0] = t;
+}
+
+    /*
+     *  Read a single color register and split it into
+     *  colors/transparent. Return != 0 for invalid regno.
+     */
+
+static int fm2fb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+                         u_int *transp, struct fb_info *info)
+{
+    if (regno > 15)
+       return 1;
+    *red = (palette[regno].red<<8) | palette[regno].red;
+    *green = (palette[regno].green<<8) | palette[regno].green;
+    *blue = (palette[regno].blue<<8) | palette[regno].blue;
+    *transp = 0;
+    return 0;
+}
+
+
+    /*
+     *  Set a single color register. The values supplied are already
+     *  rounded down to the hardware's capabilities (according to the
+     *  entries in the var structure). Return != 0 for invalid regno.
+     */
+
+static int fm2fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                         u_int transp, struct fb_info *info)
+{
+    if (regno > 15)
+       return 1;
+    red >>= 8;
+    green >>= 8;
+    blue >>= 8;
+    palette[regno].red = red;
+    palette[regno].green = green;
+    palette[regno].blue = blue;
+
+#ifdef FBCON_HAS_CFB32
+    fbcon_cfb32_cmap[regno] = (red << 16) | (green << 8) | blue;
+#endif
+    return 0;
+}
+
+
+static void do_install_cmap(int con, struct fb_info *info)
+{
+    if (con != currcon)
+       return;
+    if (fb_display[con].cmap.len)
+       fb_set_cmap(&fb_display[con].cmap, 1, fm2fb_setcolreg, info);
+    else
+       fb_set_cmap(fb_default_cmap(256), 1, fm2fb_setcolreg, info);
+}
index 6bfd09fd88ad4abb9510eebf316b2b808596e466..2700c1b2d703c996ae437668102d7c97a2447bea 100644 (file)
@@ -265,8 +265,8 @@ static void leo_putcs(struct vc_data *conp, struct display *p, const unsigned sh
        do {
                i = us->csr;
        } while (i & 0x20000000);
-       ss->fg = attr_fgcol(p,*s) << 24;
-       ss->bg = attr_bgcol(p,*s) << 24;
+       ss->fg = attr_fgcol(p,scr_readw(s)) << 24;
+       ss->bg = attr_bgcol(p,scr_readw(s)) << 24;
        ss->rop = 0x310040;
        ss->planemask = 0xff000000;
        us->fontc2 = 0xFFFFFFFE;
@@ -287,15 +287,15 @@ static void leo_putcs(struct vc_data *conp, struct display *p, const unsigned sh
                while (count >= 4) {
                        count -= 4;
                        if (fontheightlog(p)) {
-                               fd1 = p->fontdata + ((*s++ & p->charmask) << fontheightlog(p));
-                               fd2 = p->fontdata + ((*s++ & p->charmask) << fontheightlog(p));
-                               fd3 = p->fontdata + ((*s++ & p->charmask) << fontheightlog(p));
-                               fd4 = p->fontdata + ((*s++ & p->charmask) << fontheightlog(p));
+                               fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
+                               fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
+                               fd3 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
+                               fd4 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
                        } else {
-                               fd1 = p->fontdata + ((*s++ & p->charmask) * fontheight(p));
-                               fd2 = p->fontdata + ((*s++ & p->charmask) * fontheight(p));
-                               fd3 = p->fontdata + ((*s++ & p->charmask) * fontheight(p));
-                               fd4 = p->fontdata + ((*s++ & p->charmask) * fontheight(p));
+                               fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
+                               fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
+                               fd3 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
+                               fd4 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
                        }
                        if (fontwidth(p) == 8) {
                                for (i = 0; i < fontheight(p); i++, u += 2048)
@@ -315,11 +315,11 @@ static void leo_putcs(struct vc_data *conp, struct display *p, const unsigned sh
                while (count >= 2) {
                        count -= 2;
                        if (fontheightlog(p)) {
-                               fd1 = p->fontdata + ((*s++ & p->charmask) << (fontheightlog(p) + 1));
-                               fd2 = p->fontdata + ((*s++ & p->charmask) << (fontheightlog(p) + 1));
+                               fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) << (fontheightlog(p) + 1));
+                               fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) << (fontheightlog(p) + 1));
                        } else {
-                               fd1 = p->fontdata + (((*s++ & p->charmask) * fontheight(p)) << 1);
-                               fd2 = p->fontdata + (((*s++ & p->charmask) * fontheight(p)) << 1);
+                               fd1 = p->fontdata + (((scr_readw(s++) & p->charmask) * fontheight(p)) << 1);
+                               fd2 = p->fontdata + (((scr_readw(s++) & p->charmask) * fontheight(p)) << 1);
                        }
                        for (i = 0; i < fontheight(p); i++, u += 2048) {
                                *u = ((((u32)*(u16 *)fd1) << fontwidth(p)) | ((u32)*(u16 *)fd2)) << (16 - fontwidth(p));
@@ -333,9 +333,9 @@ static void leo_putcs(struct vc_data *conp, struct display *p, const unsigned sh
        while (count) {
                count--;
                if (fontheightlog(p))
-                       i = ((*s++ & p->charmask) << fontheightlog(p));
+                       i = ((scr_readw(s++) & p->charmask) << fontheightlog(p));
                else
-                       i = ((*s++ & p->charmask) * fontheight(p));
+                       i = ((scr_readw(s++) & p->charmask) * fontheight(p));
                if (fontwidth(p) <= 8) {
                        fd1 = p->fontdata + i;
                        for (i = 0; i < fontheight(p); i++, u += 2048)
index 5cfb98f5234b02e062d66e40d2e95866ff695f62..8a58de7cc27d2504e8fcc6c7350d801ed78b099c 100644 (file)
@@ -1473,7 +1473,7 @@ static void matrox_cfbX_fastputcs(u_int32_t fgx, u_int32_t bgx, struct display*
        mga_outl(M_FCOL, fgx);
        mga_outl(M_BCOL, bgx);
        while (count--) {
-               u_int32_t ar3 = ACCESS_FBINFO(fastfont.mgabase) + (*s++ & p->charmask)*charcell;
+               u_int32_t ar3 = ACCESS_FBINFO(fastfont.mgabase) + (scr_readw(s++) & p->charmask)*charcell;
 
                mga_fifo(4);
                mga_outl(M_FXBNDRY, ((xx + fontwidth(p) - 1) << 16) | xx);
@@ -1531,7 +1531,7 @@ static void matrox_cfbX_putcs(u_int32_t fgx, u_int32_t bgx, struct display* p, c
        fxbndry = ((xx + fontwidth(p) - 1) << 16) | xx;
        mmio = ACCESS_FBINFO(mmio.vbase);
        while (count--) {
-               u_int8_t* chardata = p->fontdata + (*s++ & p->charmask)*charcell;
+               u_int8_t* chardata = p->fontdata + (scr_readw(s++) & p->charmask)*charcell;
 
                mga_fifo(5);
                mga_writel(mmio, M_FXBNDRY, fxbndry);
@@ -1586,8 +1586,8 @@ static void matrox_cfb8_putcs(struct vc_data* conp, struct display* p, const uns
 
        DBG_HEAVY("matroxfb_cfb8_putcs");
 
-       fgx = attr_fgcol(p, *s);
-       bgx = attr_bgcol(p, *s);
+       fgx = attr_fgcol(p, scr_readw(s));
+       bgx = attr_bgcol(p, scr_readw(s));
        fgx |= (fgx << 8);
        fgx |= (fgx << 16);
        bgx |= (bgx << 8);
@@ -1603,8 +1603,8 @@ static void matrox_cfb16_putcs(struct vc_data* conp, struct display* p, const un
 
        DBG_HEAVY("matroxfb_cfb16_putcs");
 
-       fgx = ((u_int16_t*)p->dispsw_data)[attr_fgcol(p, *s)];
-       bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol(p, *s)];
+       fgx = ((u_int16_t*)p->dispsw_data)[attr_fgcol(p, scr_readw(s))];
+       bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol(p, scr_readw(s))];
        fgx |= (fgx << 16);
        bgx |= (bgx << 16);
        ACCESS_FBINFO(curr.putcs)(fgx, bgx, p, s, count, yy, xx);
@@ -1618,8 +1618,8 @@ static void matrox_cfb32_putcs(struct vc_data* conp, struct display* p, const un
 
        DBG_HEAVY("matroxfb_cfb32_putcs");
 
-       fgx = ((u_int32_t*)p->dispsw_data)[attr_fgcol(p, *s)];
-       bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol(p, *s)];
+       fgx = ((u_int32_t*)p->dispsw_data)[attr_fgcol(p, scr_readw(s))];
+       bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol(p, scr_readw(s))];
        ACCESS_FBINFO(curr.putcs)(fgx, bgx, p, s, count, yy, xx);
 }
 #endif
@@ -2191,9 +2191,9 @@ static void matrox_text_putcs(struct vc_data* conp, struct display* p, const uns
 
        step = ACCESS_FBINFO(devflags.textstep);
        offs = yy * p->next_line + xx * step;
-       attr = attr_fgcol(p,*s) | (attr_bgcol(p,*s) << 4);
+       attr = attr_fgcol(p,scr_readw(s)) | (attr_bgcol(p,scr_readw(s)) << 4);
        while (count-- > 0) {
-               unsigned int chr = ((*s++) & p->charmask) << 8;
+               unsigned int chr = ((scr_readw(s++)) & p->charmask) << 8;
                if (chr & 0x10000) chr ^= 0x10008;
                mga_writew(ACCESS_FBINFO(video.vbase), offs, ntohs(attr|chr));
                offs += step;
index 177493d6881a7c63cbd5f6e6f69ad767ec3280d4..90dc8568581c1de39abf74c2e82d81aa0fe11aef 100644 (file)
@@ -429,7 +429,7 @@ static void mdacon_putcs(struct vc_data *c, const unsigned short *s,
        u16 *dest = MDA_ADDR(x, y);
 
        for (; count > 0; count--) {
-               scr_writew(mda_convert_attr(*s++), dest++);
+               scr_writew(mda_convert_attr(scr_readw(s++)), dest++);
        }
 }
 
index 281720cef6e0610695d02f58f55b54518d37575b..3199aa8d6703c6281455aa89af7f78f5d9eb3278 100644 (file)
@@ -200,7 +200,7 @@ static void newport_putcs(struct vc_data *vc, const unsigned short *s, int count
                          int ypos, int xpos)
 {
     while (count--)
-       newport_putc (vc, *s++, ypos, xpos++);
+       newport_putc (vc, scr_readw(s++), ypos, xpos++);
 }
 
 static void newport_cursor(struct vc_data *vc, int mode)
index c26958e7bc8a73761f88f46d0f05f820d98c2291..4a2370c761a8e0e4f632c9131ae5d5836fa05ce9 100644 (file)
@@ -3,7 +3,9 @@
  * Copyright (c) 1998-1999 Ilario Nardinocchi (nardinoc@CS.UniBO.IT)
  * Based on linux/drivers/video/skeletonfb.c by Geert Uytterhoeven.
  * --------------------------------------------------------------------------
- * $Id: pm2fb.c,v 1.1.2.1 1999/01/12 19:53:02 geert Exp $
+ * $Id: pm2fb.c,v 1.163 1999/02/21 14:06:49 illo Exp $
+ * --------------------------------------------------------------------------
+ * TODO multiple boards support
  * --------------------------------------------------------------------------
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file README.legal in the main directory of this archive
 #include <linux/console.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
 #include <video/fbcon.h>
 #include <video/fbcon-cfb8.h>
 #include <video/fbcon-cfb16.h>
 #include <video/fbcon-cfb24.h>
 #include <video/fbcon-cfb32.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
 #include "pm2fb.h"
-#ifdef CONFIG_FB_PM2_CVPPC
 #include "cvisionppc.h"
-#endif
 
 #if !defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN)
 #error "The endianness of the target host has not been defined."
 #endif
 
-#undef PM2FB_MASTER_DEBUG
+#if defined(CONFIG_FB_PM2_PCI) && !defined(CONFIG_PCI)
+#undef CONFIG_FB_PM2_PCI
+#warning "support for Permedia2 PCI boards with no generic PCI support!"
+#endif
+
+#define PM2FB_MASTER_DEBUG
 #ifdef PM2FB_MASTER_DEBUG
 #define DPRINTK(a,b...)        printk("pm2fb: %s: " a, __FUNCTION__ , ## b)
 #else
 #define PICOS2KHZ(a) (1000000000UL/(a))
 #define KHZ2PICOS(a) (1000000000UL/(a))
 
-#ifdef CONFIG_APUS
-#define MMAP(a,b)      (unsigned char* )kernel_map((unsigned long )(a), \
-                                       b, KERNELMAP_NOCACHE_SER, NULL)
-#else
-#define MMAP(a,b)      ioremap(a, b)
-#endif
+/*
+ * The _DEFINITIVE_ memory mapping/unmapping functions.
+ * This is due to the fact that they're changing soooo often...
+ */
+#define MMAP(a,b)      ioremap((u32 )(a), b)
+#define UNMAP(a,b)     iounmap(a)
+
+/*
+ * The _DEFINITIVE_ memory i/o barrier functions.
+ * This is due to the fact that they're changing soooo often...
+ */
+#define DEFW()         wmb()
+#define DEFR()         rmb()
+#define DEFRW()                mb()
 
 #ifndef MIN
 #define MIN(a,b) ((a)<(b)?(a):(b))
 #define MAX(a,b) ((a)>(b)?(a):(b))
 #endif
 
-#ifndef __powerpc__
-#define eieio()
-#endif
-
 struct pm2fb_par {
-       unsigned long pixclock;         /* pixclock in KHz */
-       unsigned long width;            /* width of virtual screen */
-       unsigned long height;           /* height of virtual screen */
-       unsigned long hsstart;          /* horiz. sync start */
-       unsigned long hsend;            /* horiz. sync end */
-       unsigned long hbend;            /* horiz. blank end (also gate end) */
-       unsigned long htotal;           /* total width (w/ sync & blank) */
-       unsigned long vsstart;          /* vert. sync start */
-       unsigned long vsend;            /* vert. sync end */
-       unsigned long vbend;            /* vert. blank end */
-       unsigned long vtotal;           /* total height (w/ sync & blank) */
-       unsigned long stride;           /* screen stride */
-       unsigned long base;             /* screen base (xoffset+yoffset) */
-       unsigned long depth;            /* screen depth (8, 16, 24 or 32) */
-       unsigned long video;            /* video control (hsync,vsync) */
+       u32 pixclock;           /* pixclock in KHz */
+       u32 width;              /* width of virtual screen */
+       u32 height;             /* height of virtual screen */
+       u32 hsstart;            /* horiz. sync start */
+       u32 hsend;              /* horiz. sync end */
+       u32 hbend;              /* horiz. blank end (also gate end) */
+       u32 htotal;             /* total width (w/ sync & blank) */
+       u32 vsstart;            /* vert. sync start */
+       u32 vsend;              /* vert. sync end */
+       u32 vbend;              /* vert. blank end */
+       u32 vtotal;             /* total height (w/ sync & blank) */
+       u32 stride;             /* screen stride */
+       u32 base;               /* screen base (xoffset+yoffset) */
+       u32 depth;              /* screen depth (8, 16, 24 or 32) */
+       u32 video;              /* video control (hsync,vsync) */
 };
 
-#define OPTF_OLD_MEM           0x00000001
-#define OPTF_YPAN              0x00000002
+#define OPTF_OLD_MEM           (1L<<0)
+#define OPTF_YPAN              (1L<<1)
+#define OPTF_VIRTUAL           (1L<<2)
 static struct {
        char font[40];
-       unsigned long flags;
+       u32 flags;
        struct pm2fb_par user_mode;
-} pm2fb_options;
+} pm2fb_options =
+       {"\0", 0L, {25174,640,480,4,28,40,199,9,11,45,524,80,0,8,121}};
 
 static const struct {
        char name[16];
@@ -164,6 +176,15 @@ static const struct {
        {"\0", },
 };
 
+#ifdef CONFIG_FB_PM2_PCI
+struct pm2pci_par {
+       u32 mem_config;
+       u32 mem_control;
+       u32 boot_address;
+       struct pci_dev* dev;
+};
+#endif
+
 static const char permedia2_name[16]="Permedia2";
 
 static struct pm2fb_info {
@@ -172,7 +193,7 @@ static struct pm2fb_info {
                                           board_table[] below) */
        struct {
                unsigned char* fb_base; /* framebuffer memory base */
-               unsigned long  fb_size; /* framebuffer memory size */
+               u32 fb_size;            /* framebuffer memory size */
                unsigned char* rg_base; /* register memory base */
                unsigned char* p_fb;    /* physical address of frame buffer */
                unsigned char* v_fb;    /* virtual address of frame buffer */
@@ -185,11 +206,14 @@ static struct pm2fb_info {
        union {                         /* here, the per-board par structs */
 #ifdef CONFIG_FB_PM2_CVPPC
                struct cvppc_par cvppc; /* CVisionPPC data */
+#endif
+#ifdef CONFIG_FB_PM2_PCI
+               struct pm2pci_par pci;  /* Permedia2 PCI boards data */
 #endif
        } board_par;
        struct pm2fb_par current_par;   /* displayed screen */
        int current_par_valid;
-       unsigned long memclock;         /* memclock (set by the per-board
+       u32 memclock;                   /* memclock (set by the per-board
                                                        init routine) */
        struct display disp;
        struct {
@@ -216,6 +240,11 @@ static int cvppc_detect(struct pm2fb_info*);
 static void cvppc_init(struct pm2fb_info*);
 #endif
 
+#ifdef CONFIG_FB_PM2_PCI
+static int pm2pci_detect(struct pm2fb_info*);
+static void pm2pci_init(struct pm2fb_info*);
+#endif
+
 /*
  * Table of the supported Permedia2 based boards.
  * Three hooks are defined for each board:
@@ -236,6 +265,9 @@ static const struct {
        void (*cleanup)(struct pm2fb_info*);
        char name[32];
 } board_table[] = {
+#ifdef CONFIG_FB_PM2_PCI
+       { pm2pci_detect, pm2pci_init, NULL, "Permedia2 PCI board" },
+#endif
 #ifdef CONFIG_FB_PM2_CVPPC
        { cvppc_detect, cvppc_init, NULL, "CVisionPPC/BVisionPPC" },
 #endif
@@ -247,8 +279,8 @@ static const struct {
  */
 #define PACKPP(p0,p1,p2)       (((p2)<<6)|((p1)<<3)|(p0))
 static const struct {
-       unsigned short width;
-       unsigned short pp;
+       u16 width;
+       u16 pp;
 } pp_table[] = {
        { 32,   PACKPP(1, 0, 0) }, { 64,        PACKPP(1, 1, 0) },
        { 96,   PACKPP(1, 1, 1) }, { 128,       PACKPP(2, 1, 1) },
@@ -286,14 +318,14 @@ static int pm2fb_setcolreg(unsigned regno,
 static int pm2fb_blank(int blank_mode, struct fb_info_gen* info);
 static int pm2fb_pan_display(const struct fb_var_screeninfo* var,
                                        struct fb_info_gen* info);
-static void pm2fb_dispsw(const void* par, struct display* disp,
+static void pm2fb_set_disp(const void* par, struct display* disp,
                                                struct fb_info_gen* info);
 
 static struct fbgen_hwswitch pm2fb_hwswitch={
        pm2fb_detect, pm2fb_encode_fix, pm2fb_decode_var,
        pm2fb_encode_var, pm2fb_get_par, pm2fb_set_par,
        pm2fb_getcolreg, pm2fb_setcolreg, pm2fb_pan_display,
-       pm2fb_blank, pm2fb_dispsw
+       pm2fb_blank, pm2fb_set_disp
 };
 
 static int pm2fb_open(struct fb_info* info, int user);
@@ -309,61 +341,61 @@ static struct fb_ops pm2fb_ops={
  * Begin of Permedia2 specific functions
  ***************************************************************************/
 
-inline static unsigned long RD32(unsigned char* base, long off) {
+inline static u32 RD32(unsigned char* base, s32 off) {
 
-       return *((volatile unsigned long* )(base+off));
+       return readl(base+off);
 }
 
-inline static void WR32(unsigned char* base, long off, unsigned long v) {
+inline static void WR32(unsigned char* base, s32 off, u32 v) {
 
-       *((volatile unsigned long* )(base+off))=v;
+       writel(v, base+off);
 }
 
-inline static unsigned long pm2_RD(struct pm2fb_info* p, long off) {
+inline static u32 pm2_RD(struct pm2fb_info* p, s32 off) {
 
        return RD32(p->regions.v_regs, off);
 }
 
-inline static void pm2_WR(struct pm2fb_info* p, long off, unsigned long v) {
+inline static void pm2_WR(struct pm2fb_info* p, s32 off, u32 v) {
 
        WR32(p->regions.v_regs, off, v);
 }
 
-inline static unsigned long pm2_RDAC_RD(struct pm2fb_info* p, long idx) {
+inline static u32 pm2_RDAC_RD(struct pm2fb_info* p, s32 idx) {
 
        pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, idx);
-       eieio();
+       DEFRW();
        return pm2_RD(p, PM2R_RD_INDEXED_DATA);
 }
 
-inline static void pm2_RDAC_WR(struct pm2fb_info* p, long idx,
-                                               unsigned long v) {
+inline static void pm2_RDAC_WR(struct pm2fb_info* p, s32 idx,
+                                               u32 v) {
 
        pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, idx);
-       eieio();
+       DEFW();
        pm2_WR(p, PM2R_RD_INDEXED_DATA, v);
 }
 
 #ifdef CONFIG_FB_PM2_FIFO_DISCONNECT
 #define WAIT_FIFO(p,a)
 #else
-inline static void WAIT_FIFO(struct pm2fb_info* p, unsigned long a) {
+inline static void WAIT_FIFO(struct pm2fb_info* p, u32 a) {
 
        while(pm2_RD(p, PM2R_IN_FIFO_SPACE)<a);
-       eieio();
+       DEFRW();
 }
 #endif
 
-static unsigned long partprod(unsigned long xres) {
+static u32 partprod(u32 xres) {
        int i;
 
        for (i=0; pp_table[i].width && pp_table[i].width!=xres; i++);
        if (!pp_table[i].width)
-               DPRINTK("invalid width %lu\n", xres);
+               DPRINTK("invalid width %u\n", xres);
        return pp_table[i].pp;
 }
 
-static unsigned long to3264(unsigned long timing, int bpp, int is64) {
+static u32 to3264(u32 timing, int bpp, int is64) {
 
        switch (bpp) {
                case 8:
@@ -383,7 +415,7 @@ static unsigned long to3264(unsigned long timing, int bpp, int is64) {
        return timing;
 }
 
-static unsigned long from3264(unsigned long timing, int bpp, int is64) {
+static u32 from3264(u32 timing, int bpp, int is64) {
 
        switch (bpp) {
                case 8:
@@ -403,14 +435,14 @@ static unsigned long from3264(unsigned long timing, int bpp, int is64) {
        return timing;
 }
 
-static void mnp(unsigned long clk, unsigned char* mm, unsigned char* nn,
+static void mnp(u32 clk, unsigned char* mm, unsigned char* nn,
                                                        unsigned char* pp) {
        unsigned char m;
        unsigned char n;
        unsigned char p;
-       unsigned long f;
-       long current;
-       long delta=100000;
+       u32 f;
+       s32 curr;
+       s32 delta=100000;
 
        *mm=*nn=*pp=0;
        for (n=2; n<15; n++) {
@@ -418,9 +450,9 @@ static void mnp(unsigned long clk, unsigned char* mm, unsigned char* nn,
                        f=PM2_REFERENCE_CLOCK*m/n;
                        if (f>=150000 && f<=300000) {
                                for (p=0; p<5; p++, f>>=1) {
-                                       current=clk>f?clk-f:f-clk;
-                                       if (current<delta) {
-                                               delta=current;
+                                       curr=clk>f?clk-f:f-clk;
+                                       if (curr<delta) {
+                                               delta=curr;
                                                *mm=m;
                                                *nn=n;
                                                *pp=p;
@@ -435,62 +467,75 @@ static void wait_pm2(struct pm2fb_info* i) {
 
        WAIT_FIFO(i, 1);
        pm2_WR(i, PM2R_SYNC, 0);
-       eieio();
+       DEFRW();
        do {
                while (pm2_RD(i, PM2R_OUT_FIFO_WORDS)==0);
-               eieio();
+               DEFR();
        } while (pm2_RD(i, PM2R_OUT_FIFO)!=PM2TAG(PM2R_SYNC));
 }
 
-static void set_memclock(struct pm2fb_info* info, unsigned long clk) {
+static void set_memclock(struct pm2fb_info* info, u32 clk) {
        int i;
        unsigned char m, n, p;
 
        mnp(clk, &m, &n, &p);
        WAIT_FIFO(info, 5);
        pm2_RDAC_WR(info, PM2I_RD_MEMORY_CLOCK_3, 6);
-       eieio();
+       DEFW();
        pm2_RDAC_WR(info, PM2I_RD_MEMORY_CLOCK_1, m);
        pm2_RDAC_WR(info, PM2I_RD_MEMORY_CLOCK_2, n);
-       eieio();
+       DEFW();
        pm2_RDAC_WR(info, PM2I_RD_MEMORY_CLOCK_3, 8|p);
-       eieio();
+       DEFW();
        pm2_RDAC_RD(info, PM2I_RD_MEMORY_CLOCK_STATUS);
-       eieio();
+       DEFR();
        for (i=256; i &&
                !(pm2_RD(info, PM2R_RD_INDEXED_DATA)&PM2F_PLL_LOCKED); i--);
 }
 
-static void set_pixclock(struct pm2fb_info* info, unsigned long clk) {
+static void set_pixclock(struct pm2fb_info* info, u32 clk) {
        int i;
        unsigned char m, n, p;
 
        mnp(clk, &m, &n, &p);
        WAIT_FIFO(info, 5);
        pm2_RDAC_WR(info, PM2I_RD_PIXEL_CLOCK_A3, 0);
-       eieio();
+       DEFW();
        pm2_RDAC_WR(info, PM2I_RD_PIXEL_CLOCK_A1, m);
        pm2_RDAC_WR(info, PM2I_RD_PIXEL_CLOCK_A2, n);
-       eieio();
+       DEFW();
        pm2_RDAC_WR(info, PM2I_RD_PIXEL_CLOCK_A3, 8|p);
-       eieio();
+       DEFW();
        pm2_RDAC_RD(info, PM2I_RD_PIXEL_CLOCK_STATUS);
-       eieio();
+       DEFR();
        for (i=256; i &&
                !(pm2_RD(info, PM2R_RD_INDEXED_DATA)&PM2F_PLL_LOCKED); i--);
 }
 
+static void clear_palette(struct pm2fb_info* p) {
+       int i=256;
+
+       WAIT_FIFO(p, 1);
+       pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, 0);
+       DEFW();
+       while (i--) {
+               WAIT_FIFO(p, 3);
+               pm2_WR(p, PM2R_RD_PALETTE_DATA, 0);
+               pm2_WR(p, PM2R_RD_PALETTE_DATA, 0);
+               pm2_WR(p, PM2R_RD_PALETTE_DATA, 0);
+       }
+}
+
 static void set_color(struct pm2fb_info* p, unsigned char regno,
                        unsigned char r, unsigned char g, unsigned char b) {
 
        WAIT_FIFO(p, 4);
-       eieio();
        pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, regno);
-       eieio();
+       DEFW();
        pm2_WR(p, PM2R_RD_PALETTE_DATA, r);
-       eieio();
+       DEFW();
        pm2_WR(p, PM2R_RD_PALETTE_DATA, g);
-       eieio();
+       DEFW();
        pm2_WR(p, PM2R_RD_PALETTE_DATA, b);
 }
 
@@ -520,12 +565,13 @@ static void set_aperture(struct pm2fb_info* i, struct pm2fb_par* p) {
 }
 
 static void set_screen(struct pm2fb_info* i, struct pm2fb_par* p) {
-       unsigned long clrmode=0;
-       unsigned long txtmap=0;
-       unsigned long xres;
+       u32 clrmode=0;
+       u32 txtmap=0;
+       u32 xres;
 
        xres=(p->width+31)&~31;
        set_aperture(i, p);
+       DEFRW();
        WAIT_FIFO(i, 22);
        pm2_RDAC_WR(i, PM2I_RD_COLOR_KEY_CONTROL, p->depth==8?0:
                                                PM2F_COLOR_KEY_TEST_OFF);
@@ -565,7 +611,7 @@ static void set_screen(struct pm2fb_info* i, struct pm2fb_par* p) {
        pm2_WR(i, PM2R_VS_END, p->vsend);
        pm2_WR(i, PM2R_VB_END, p->vbend);
        pm2_WR(i, PM2R_SCREEN_STRIDE, p->stride);
-       eieio();
+       DEFW();
        pm2_WR(i, PM2R_SCREEN_BASE, p->base);
        pm2_RDAC_WR(i, PM2I_RD_COLOR_MODE, PM2F_RD_COLOR_MODE_RGB|
                                                PM2F_RD_GUI_ACTIVE|clrmode);
@@ -573,6 +619,63 @@ static void set_screen(struct pm2fb_info* i, struct pm2fb_par* p) {
        set_pixclock(i, p->pixclock);
 };
 
+/*
+ * copy with packed pixels (8/16bpp only).
+ */
+static void pm2fb_pp_copy(struct pm2fb_info* i, s32 xsrc, s32 ysrc,
+                                       s32 x, s32 y, s32 w, s32 h) {
+       s32 scale=i->current_par.depth==8?2:1;
+       s32 offset;
+
+       if (!w || !h)
+               return;
+       WAIT_FIFO(i, 7);
+       pm2_WR(i, PM2R_CONFIG,  PM2F_CONFIG_FB_WRITE_ENABLE|
+                               PM2F_CONFIG_FB_PACKED_DATA|
+                               PM2F_CONFIG_FB_READ_SOURCE_ENABLE);
+       pm2_WR(i, PM2R_FB_PIXEL_OFFSET, 0);
+       pm2_WR(i, PM2R_FB_SOURCE_DELTA, ((ysrc-y)&0xfff)<<16|
+                                               ((xsrc-x)&0xfff));
+       offset=(x&0x3)-(xsrc&0x3);
+       pm2_WR(i, PM2R_RECTANGLE_ORIGIN, (y<<16)|(x>>scale));
+       pm2_WR(i, PM2R_RECTANGLE_SIZE, (h<<16)|((w+7)>>scale));
+       pm2_WR(i, PM2R_PACKED_DATA_LIMITS, (offset<<29)|(x<<16)|(x+w));
+       DEFW();
+       pm2_WR(i, PM2R_RENDER,  PM2F_RENDER_RECTANGLE|
+                               (x<xsrc?PM2F_INCREASE_X:0)|
+                               (y<ysrc?PM2F_INCREASE_Y:0));
+       wait_pm2(i);
+}
+
+/*
+ * block operation. copy=0: rectangle fill, copy=1: rectangle copy.
+ */
+static void pm2fb_block_op(struct pm2fb_info* i, int copy,
+                                       s32 xsrc, s32 ysrc,
+                                       s32 x, s32 y, s32 w, s32 h,
+                                       u32 color) {
+
+       if (!w || !h)
+               return;
+       WAIT_FIFO(i, 6);
+       pm2_WR(i, PM2R_CONFIG,  PM2F_CONFIG_FB_WRITE_ENABLE|
+                               PM2F_CONFIG_FB_READ_SOURCE_ENABLE);
+       pm2_WR(i, PM2R_FB_PIXEL_OFFSET, 0);
+       if (copy)
+               pm2_WR(i, PM2R_FB_SOURCE_DELTA, ((ysrc-y)&0xfff)<<16|
+                                                       ((xsrc-x)&0xfff));
+       else
+               pm2_WR(i, PM2R_FB_BLOCK_COLOR, color);
+       pm2_WR(i, PM2R_RECTANGLE_ORIGIN, (y<<16)|x);
+       pm2_WR(i, PM2R_RECTANGLE_SIZE, (h<<16)|w);
+       DEFW();
+       pm2_WR(i, PM2R_RENDER,  PM2F_RENDER_RECTANGLE|
+                               (x<xsrc?PM2F_INCREASE_X:0)|
+                               (y<ysrc?PM2F_INCREASE_Y:0)|
+                               (copy?0:PM2F_RENDER_FASTFILL));
+       wait_pm2(i);
+}
+
 /***************************************************************************
  * Begin of generic initialization functions
  ***************************************************************************/
@@ -580,14 +683,14 @@ static void set_screen(struct pm2fb_info* i, struct pm2fb_par* p) {
 static void pm2fb_reset(struct pm2fb_info* p) {
 
        pm2_WR(p, PM2R_RESET_STATUS, 0);
-       eieio();
+       DEFRW();
        while (pm2_RD(p, PM2R_RESET_STATUS)&PM2F_BEING_RESET);
-       eieio();
+       DEFRW();
 #ifdef CONFIG_FB_PM2_FIFO_DISCONNECT
        DPRINTK("FIFO disconnect enabled\n");
        pm2_WR(p, PM2R_FIFO_DISCON, 1);
+       DEFRW();
 #endif
-       eieio();
        if (board_table[p->board].init)
                board_table[p->board].init(p);
        WAIT_FIFO(p, 48);
@@ -633,8 +736,9 @@ static void pm2fb_reset(struct pm2fb_info* p) {
        pm2_RDAC_WR(p, PM2I_RD_RED_KEY, 0);
        pm2_RDAC_WR(p, PM2I_RD_GREEN_KEY, 0);
        pm2_RDAC_WR(p, PM2I_RD_BLUE_KEY, 0);
-       eieio();
-       set_memclock(p, p->memclock);
+       clear_palette(p);
+       if (p->memclock)
+               set_memclock(p, p->memclock);
 }
 
 __initfunc(static int pm2fb_conf(struct pm2fb_info* p)) {
@@ -661,9 +765,12 @@ __initfunc(static int pm2fb_conf(struct pm2fb_info* p)) {
  * Begin of per-board initialization functions
  ***************************************************************************/
 
+/*
+ * Phase5 CvisionPPC/BVisionPPC
+ */
 #ifdef CONFIG_FB_PM2_CVPPC
 static int cvppc_PCI_init(struct cvppc_par* p) {
-       extern unsigned long powerup_PCI_present;
+       extern u32 powerup_PCI_present;
 
        if (!powerup_PCI_present) {
                DPRINTK("no PCI bridge detected\n");
@@ -683,14 +790,14 @@ static int cvppc_PCI_init(struct cvppc_par* p) {
                return 0;
        }
        WR32(p->pci_bridge, CSPPC_BRIDGE_ENDIAN, CSPPCF_BRIDGE_BIG_ENDIAN);
-       eieio();
+       DEFW();
        if (pm2fb_options.flags & OPTF_OLD_MEM)
                WR32(p->pci_config, PCI_CACHE_LINE_SIZE, 0xff00);
        WR32(p->pci_config, PCI_BASE_ADDRESS_0, CVPPC_REGS_REGION);
        WR32(p->pci_config, PCI_BASE_ADDRESS_1, CVPPC_FB_APERTURE_ONE);
        WR32(p->pci_config, PCI_BASE_ADDRESS_2, CVPPC_FB_APERTURE_TWO);
        WR32(p->pci_config, PCI_ROM_ADDRESS, CVPPC_ROM_ADDRESS);
-       eieio();
+       DEFW();
        WR32(p->pci_config, PCI_COMMAND, 0xef000000 |
                                                PCI_COMMAND_IO |
                                                PCI_COMMAND_MEMORY |
@@ -714,7 +821,7 @@ static void cvppc_init(struct pm2fb_info* p) {
        WAIT_FIFO(p, 3);
        pm2_WR(p, PM2R_MEM_CONTROL, 0);
        pm2_WR(p, PM2R_BOOT_ADDRESS, 0x30);
-       eieio();
+       DEFW();
        if (pm2fb_options.flags & OPTF_OLD_MEM)
                pm2_WR(p, PM2R_MEM_CONFIG, CVPPC_MEM_CONFIG_OLD);
        else
@@ -722,70 +829,100 @@ static void cvppc_init(struct pm2fb_info* p) {
 }
 #endif /* CONFIG_FB_PM2_CVPPC */
 
-/***************************************************************************
- * Console hw acceleration
- ***************************************************************************/
-
 /*
- * copy with packed pixels (8/16bpp only).
+ * Generic PCI detection routines
  */
-static void pm2fb_pp_copy(struct pm2fb_info* i, long xsrc, long ysrc,
-                                       long x, long y, long w, long h) {
-       long scale=i->current_par.depth==8?2:1;
-       long offset;
-
-       if (!w || !h)
-               return;
-       WAIT_FIFO(i, 7);
-       pm2_WR(i, PM2R_CONFIG,  PM2F_CONFIG_FB_WRITE_ENABLE|
-                               PM2F_CONFIG_FB_PACKED_DATA|
-                               PM2F_CONFIG_FB_READ_SOURCE_ENABLE);
-       pm2_WR(i, PM2R_FB_PIXEL_OFFSET, 0);
-       pm2_WR(i, PM2R_FB_SOURCE_DELTA, ((ysrc-y)&0xfff)<<16|
-                                               ((xsrc-x)&0xfff));
-       offset=(x&0x3)-(xsrc&0x3);
-       pm2_WR(i, PM2R_RECTANGLE_ORIGIN, (y<<16)|(x>>scale));
-       pm2_WR(i, PM2R_RECTANGLE_SIZE, (h<<16)|((w+7)>>scale));
-       pm2_WR(i, PM2R_PACKED_DATA_LIMITS, (offset<<29)|(x<<16)|(x+w));
-       eieio();
-       pm2_WR(i, PM2R_RENDER,  PM2F_RENDER_RECTANGLE|
-                               (x<xsrc?PM2F_INCREASE_X:0)|
-                               (y<ysrc?PM2F_INCREASE_Y:0));
-       wait_pm2(i);
+#ifdef CONFIG_FB_PM2_PCI
+static int pm2pci_detect(struct pm2fb_info* p) {
+       struct pm2pci_par* pci=&p->board_par.pci;
+       unsigned char* m;
+
+       memset(pci, 0, sizeof(struct pm2pci_par));
+       if (!pci_present()) {
+               DPRINTK("no PCI bus found.\n");
+               return 0;
+       }
+       DPRINTK("scanning PCI bus for known chipsets...\n");
+       if ((pci->dev=pci_find_device(PCI_VENDOR_ID_TI,
+                                       PCI_DEVICE_ID_TI_TVP4020, NULL))) {
+               DPRINTK("... found Texas Instruments TVP4020\n");
+       }
+       if (!pci->dev) {
+               DPRINTK("no PCI board found.\n");
+               return 0;
+       }
+       DPRINTK("PCI board @%08lx %08lx %08lx rom %08lx\n",
+                       pci->dev->base_address[0],
+                       pci->dev->base_address[1],
+                       pci->dev->base_address[2],
+                       pci->dev->rom_address);
+#ifdef __sparc__
+       p->regions.rg_base=(unsigned char* )
+               __pa(pci->dev->base_address[0] & PCI_BASE_ADDRESS_MEM_MASK);
+       p->regions.fb_base=(unsigned char* )
+               __pa(pci->dev->base_address[1] & PCI_BASE_ADDRESS_MEM_MASK);
+#else
+       if (pm2fb_options.flags & OPTF_VIRTUAL) {
+               p->regions.rg_base=(unsigned char* )
+                       __pa(pci->dev->base_address[0] & PCI_BASE_ADDRESS_MEM_MASK);
+               p->regions.fb_base=(unsigned char* )
+                       __pa(pci->dev->base_address[1] & PCI_BASE_ADDRESS_MEM_MASK);
+       }
+       else {
+               p->regions.rg_base=(unsigned char* )
+                       (pci->dev->base_address[0] & PCI_BASE_ADDRESS_MEM_MASK);
+               p->regions.fb_base=(unsigned char* )
+                       (pci->dev->base_address[1] & PCI_BASE_ADDRESS_MEM_MASK);
+       }
+#endif
+#ifdef __BIG_ENDIAN
+       p->regions.rg_base += PM2_REGS_SIZE;
+#endif
+       if ((m=MMAP(p->regions.rg_base, PM2_REGS_SIZE))) {
+               pci->mem_control=RD32(m, PM2R_MEM_CONTROL);
+               pci->boot_address=RD32(m, PM2R_BOOT_ADDRESS);
+               pci->mem_config=RD32(m, PM2R_MEM_CONFIG);
+               switch (pci->mem_config & PM2F_MEM_CONFIG_RAM_MASK) {
+                       case PM2F_MEM_BANKS_1:
+                               p->regions.fb_size=0x200000;
+                               break;
+                       case PM2F_MEM_BANKS_2:
+                               p->regions.fb_size=0x400000;
+                               break;
+                       case PM2F_MEM_BANKS_3:
+                               p->regions.fb_size=0x600000;
+                               break;
+                       case PM2F_MEM_BANKS_4:
+                               p->regions.fb_size=0x800000;
+                               break;
+               }
+               p->memclock=CVPPC_MEMCLOCK;
+               UNMAP(m, PM2_REGS_SIZE);
+               return 1;
+       }
+       DPRINTK("MMAP() failed.\n");
+       return 0;
 }
 
-/*
- * block operation. copy=0: rectangle fill, copy=1: rectangle copy.
- */
-static void pm2fb_block_op(struct pm2fb_info* i, int copy,
-                                       long xsrc, long ysrc,
-                                       long x, long y, long w, long h,
-                                       unsigned long color) {
+static void pm2pci_init(struct pm2fb_info* p) {
+       struct pm2pci_par* pci=&p->board_par.pci;
 
-       if (!w || !h)
-               return;
-       WAIT_FIFO(i, 6);
-       pm2_WR(i, PM2R_CONFIG,  PM2F_CONFIG_FB_WRITE_ENABLE|
-                               PM2F_CONFIG_FB_READ_SOURCE_ENABLE);
-       pm2_WR(i, PM2R_FB_PIXEL_OFFSET, 0);
-       if (copy)
-               pm2_WR(i, PM2R_FB_SOURCE_DELTA, ((ysrc-y)&0xfff)<<16|
-                                                       ((xsrc-x)&0xfff));
-       else
-               pm2_WR(i, PM2R_FB_BLOCK_COLOR, color);
-       pm2_WR(i, PM2R_RECTANGLE_ORIGIN, (y<<16)|x);
-       pm2_WR(i, PM2R_RECTANGLE_SIZE, (h<<16)|w);
-       eieio();
-       pm2_WR(i, PM2R_RENDER,  PM2F_RENDER_RECTANGLE|
-                               (x<xsrc?PM2F_INCREASE_X:0)|
-                               (y<ysrc?PM2F_INCREASE_Y:0)|
-                               (copy?0:PM2F_RENDER_FASTFILL));
-       wait_pm2(i);
+       WAIT_FIFO(p, 3);
+       pm2_WR(p, PM2R_MEM_CONTROL, pci->mem_control);
+       pm2_WR(p, PM2R_BOOT_ADDRESS, pci->boot_address);
+       DEFW();
+       pm2_WR(p, PM2R_MEM_CONFIG, pci->mem_config);
 }
+#endif /* CONFIG_FB_PM2_PCI */
+
+/***************************************************************************
+ * Console hw acceleration
+ ***************************************************************************/
+
 
 static int pm2fb_blank(int blank_mode, struct fb_info_gen* info) {
        struct pm2fb_info* i=(struct pm2fb_info* )info;
-       unsigned long video;
+       u32 video;
 
        if (!i->current_par_valid)
                return 1;
@@ -871,7 +1008,7 @@ static void pm2fb_bmove(struct display* p, int sy, int sx,
 #ifdef FBCON_HAS_CFB8
 static void pm2fb_clear8(struct vc_data* conp, struct display* p,
                                int sy, int sx, int height, int width) {
-       unsigned long c;
+       u32 c;
 
        sx=sx*fontwidth(p);
        width=width*fontwidth(p);
@@ -886,9 +1023,9 @@ static void pm2fb_clear8(struct vc_data* conp, struct display* p,
 
 static void pm2fb_clear_margins8(struct vc_data* conp, struct display* p,
                                                        int bottom_only) {
-       unsigned long c;
-       unsigned long sx;
-       unsigned long sy;
+       u32 c;
+       u32 sx;
+       u32 sy;
 
        c=attr_bgcol_ec(p, conp);
        c|=c<<8;
@@ -913,7 +1050,7 @@ static struct display_switch pm2_cfb8 = {
 #ifdef FBCON_HAS_CFB16
 static void pm2fb_clear16(struct vc_data* conp, struct display* p,
                                int sy, int sx, int height, int width) {
-       unsigned long c;
+       u32 c;
 
        sx=sx*fontwidth(p);
        width=width*fontwidth(p);
@@ -927,9 +1064,9 @@ static void pm2fb_clear16(struct vc_data* conp, struct display* p,
 
 static void pm2fb_clear_margins16(struct vc_data* conp, struct display* p,
                                                        int bottom_only) {
-       unsigned long c;
-       unsigned long sx;
-       unsigned long sy;
+       u32 c;
+       u32 sx;
+       u32 sy;
 
        c = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
        c|=c<<16;
@@ -957,7 +1094,7 @@ static struct display_switch pm2_cfb16 = {
 static void pm2fb_clear24(struct vc_data* conp, struct display* p,
                                int sy, int sx, int height, int width) {
        struct pm2fb_info* i=(struct pm2fb_info* )p->fb_info;
-       unsigned long c;
+       u32 c;
 
        c=attr_bgcol_ec(p, conp);
        if (            i->palette[c].red==i->palette[c].green &&
@@ -978,9 +1115,9 @@ static void pm2fb_clear24(struct vc_data* conp, struct display* p,
 static void pm2fb_clear_margins24(struct vc_data* conp, struct display* p,
                                                        int bottom_only) {
        struct pm2fb_info* i=(struct pm2fb_info* )p->fb_info;
-       unsigned long c;
-       unsigned long sx;
-       unsigned long sy;
+       u32 c;
+       u32 sx;
+       u32 sy;
 
        c=attr_bgcol_ec(p, conp);
        if (            i->palette[c].red==i->palette[c].green &&
@@ -1011,7 +1148,7 @@ static struct display_switch pm2_cfb24 = {
 #ifdef FBCON_HAS_CFB32
 static void pm2fb_clear32(struct vc_data* conp, struct display* p,
                                int sy, int sx, int height, int width) {
-       unsigned long c;
+       u32 c;
 
        sx=sx*fontwidth(p);
        width=width*fontwidth(p);
@@ -1024,9 +1161,9 @@ static void pm2fb_clear32(struct vc_data* conp, struct display* p,
 
 static void pm2fb_clear_margins32(struct vc_data* conp, struct display* p,
                                                        int bottom_only) {
-       unsigned long c;
-       unsigned long sx;
-       unsigned long sy;
+       u32 c;
+       u32 sx;
+       u32 sy;
 
        c = ((u32 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
        sx=conp->vc_cols*fontwidth(p);
@@ -1065,18 +1202,55 @@ static int pm2fb_encode_fix(struct fb_fix_screeninfo* fix,
        fix->accel=FB_ACCEL_3DLABS_PERMEDIA2;
        fix->type=FB_TYPE_PACKED_PIXELS;
        fix->visual=p->depth==8?FB_VISUAL_PSEUDOCOLOR:FB_VISUAL_TRUECOLOR;
-       fix->line_length=0;
+       if (i->current_par_valid)
+               fix->line_length=i->current_par.width*(i->current_par.depth/8);
+       else
+               fix->line_length=0;
        fix->xpanstep=p->depth==24?8:64/p->depth;
        fix->ypanstep=1;
        fix->ywrapstep=0;
        return 0;
 }
 
+#ifdef PM2FB_MASTER_DEBUG
+static void pm2fb_display_var(const struct fb_var_screeninfo* var) {
+
+       printk( KERN_DEBUG
+"- struct fb_var_screeninfo ---------------------------------------------------\n");
+       printk( KERN_DEBUG
+               "resolution: %ux%ux%u (virtual %ux%u+%u+%u)\n",
+                       var->xres, var->yres, var->bits_per_pixel,
+                       var->xres_virtual, var->yres_virtual,
+                       var->xoffset, var->yoffset);
+       printk( KERN_DEBUG
+               "color: %c%c "
+               "R(%u,%u,%u), G(%u,%u,%u), B(%u,%u,%u), T(%u,%u,%u)\n",
+                       var->grayscale?'G':'C', var->nonstd?'N':'S',
+                       var->red.offset, var->red.length, var->red.msb_right,
+                       var->green.offset, var->green.length, var->green.msb_right,
+                       var->blue.offset, var->blue.length, var->blue.msb_right,
+                       var->transp.offset, var->transp.length,
+                       var->transp.msb_right);
+       printk( KERN_DEBUG
+               "timings: %ups (%u,%u)-(%u,%u)+%u+%u\n",
+               var->pixclock,
+               var->left_margin, var->upper_margin, var->right_margin,
+               var->lower_margin, var->hsync_len, var->vsync_len);
+       printk( KERN_DEBUG
+               "activate %08x accel_flags %08x sync %08x vmode %08x\n",
+               var->activate, var->accel_flags, var->sync, var->vmode);
+       printk( KERN_DEBUG
+"------------------------------------------------------------------------------\n");
+}
+
+#define pm2fb_decode_var pm2fb_wrapped_decode_var
+#endif
+
 static int pm2fb_decode_var(const struct fb_var_screeninfo* var,
                                void* par, struct fb_info_gen* info) {
        struct pm2fb_info* i=(struct pm2fb_info* )info;
        struct pm2fb_par p;
-       unsigned long xres;
+       u32 xres;
        int data64;
 
        memset(&p, 0, sizeof(struct pm2fb_par));
@@ -1086,39 +1260,39 @@ static int pm2fb_decode_var(const struct fb_var_screeninfo* var,
        p.depth=p.depth>32?32:p.depth;
        data64=p.depth>8;
        xres=(var->xres+31)&~31;
-       if (p.width==~(0L))
-               p.width=xres;
-       if (p.height==~(0L))
-               p.height=var->yres;
        if (p.width<xres+var->xoffset)
                p.width=xres+var->xoffset;
        if (p.height<var->yres+var->yoffset)
                p.height=var->yres+var->yoffset;
        if (!partprod(xres)) {
-               DPRINTK("width not supported: %lu\n", xres);
+               DPRINTK("width not supported: %u\n", xres);
                return -EINVAL;
        }
        if (p.width>2047) {
-               DPRINTK("virtual width not supported: %lu\n", p.width);
+               DPRINTK("virtual width not supported: %u\n", p.width);
                return -EINVAL;
        }
        if (var->yres<200) {
-               DPRINTK("height not supported: %lu\n",
-                                               (unsigned long )var->yres);
+               DPRINTK("height not supported: %u\n",
+                                               (u32 )var->yres);
                return -EINVAL;
        }
        if (p.height<200 || p.height>2047) {
-               DPRINTK("virtual height not supported: %lu\n", p.height);
+               DPRINTK("virtual height not supported: %u\n", p.height);
+               return -EINVAL;
+       }
+       if (p.depth>32) {
+               DPRINTK("depth not supported: %u\n", p.depth);
                return -EINVAL;
        }
        if (p.width*p.height*p.depth/8>i->regions.fb_size) {
-               DPRINTK("no memory for screen (%lux%lux%lu)\n",
-                                               xres, p.height, p.depth);
+               DPRINTK("no memory for screen (%ux%ux%u)\n",
+                                               p.width, p.height, p.depth);
                return -EINVAL;
        }
        p.pixclock=PICOS2KHZ(var->pixclock);
        if (p.pixclock>PM2_MAX_PIXCLOCK) {
-               DPRINTK("pixclock too high (%luKHz)\n", p.pixclock);
+               DPRINTK("pixclock too high (%uKHz)\n", p.pixclock);
                return -EINVAL;
        }
        p.hsstart=to3264(var->right_margin, p.depth, data64);
@@ -1153,11 +1327,24 @@ static int pm2fb_decode_var(const struct fb_var_screeninfo* var,
        return 0;
 }
 
+#ifdef PM2FB_MASTER_DEBUG
+#undef pm2fb_decode_var
+
+static int pm2fb_decode_var(const struct fb_var_screeninfo* var,
+                               void* par, struct fb_info_gen* info) {
+       int result;
+
+       result=pm2fb_wrapped_decode_var(var, par, info);
+       pm2fb_display_var(var);
+       return result;
+}
+#endif
+
 static int pm2fb_encode_var(struct fb_var_screeninfo* var,
                                const void* par, struct fb_info_gen* info) {
        struct pm2fb_par* p=(struct pm2fb_par* )par;
        struct fb_var_screeninfo v;
-       unsigned long base;
+       u32 base;
 
        memset(&v, 0, sizeof(struct fb_var_screeninfo));
        v.xres_virtual=p->width;
@@ -1266,9 +1453,9 @@ static void pm2fb_set_par(const void* par, struct fb_info_gen* info) {
                        return;
                }
        }
+       set_screen(i, p);
        i->current_par=*p;
        i->current_par_valid=1;
-       set_screen(i, &i->current_par);
 }
 
 static int pm2fb_getcolreg(unsigned regno,
@@ -1322,7 +1509,7 @@ static int pm2fb_setcolreg(unsigned regno,
                                break;
 #endif
                        default:
-                               DPRINTK("bad depth %lu\n",
+                               DPRINTK("bad depth %u\n",
                                                i->current_par.depth);
                                break;
                }
@@ -1338,14 +1525,15 @@ static int pm2fb_setcolreg(unsigned regno,
        return regno>255;
 }
 
-static void pm2fb_dispsw(const void* par, struct display* disp,
+static void pm2fb_set_disp(const void* par, struct display* disp,
                                                struct fb_info_gen* info) {
        struct pm2fb_info* i=(struct pm2fb_info* )info;
-       unsigned long flags;
-       unsigned long depth;
+       u32 flags;
+       u32 depth;
 
        save_flags(flags);
        cli();
+       disp->screen_base=i->regions.v_fb;
        switch (depth=((struct pm2fb_par* )par)->depth) {
 #ifdef FBCON_HAS_CFB8
                case 8:
@@ -1408,6 +1596,7 @@ __initfunc(void pm2fb_init(void)) {
        memset(&fb_info, 0, sizeof(fb_info));
        if (!pm2fb_conf(&fb_info))
                return;
+       pm2fb_reset(&fb_info);
        fb_info.disp.scrollmode=SCROLL_YNOMOVE;
        fb_info.gen.parsize=sizeof(struct pm2fb_par);
        fb_info.gen.fbhw=&pm2fb_hwswitch;
@@ -1420,19 +1609,18 @@ __initfunc(void pm2fb_init(void)) {
        fb_info.gen.info.updatevar=&fbgen_update_var;
        fb_info.gen.info.blank=&fbgen_blank;
        fbgen_get_var(&fb_info.disp.var, -1, &fb_info.gen.info);
-       if (fbgen_do_set_var(&fb_info.disp.var, 1, &fb_info.gen)<0)
-               return;
+       fbgen_do_set_var(&fb_info.disp.var, 1, &fb_info.gen);
        fbgen_set_disp(-1, &fb_info.gen);
        fbgen_install_cmap(0, &fb_info.gen);
        if (register_framebuffer(&fb_info.gen.info)<0) {
                printk("pm2fb: unable to register.\n");
                return;
        }
-       printk("fb%d: %s (%s), using %ldK of video memory.\n",
+       printk("fb%d: %s (%s), using %uK of video memory.\n",
                                GET_FB_IDX(fb_info.gen.info.node),
                                board_table[fb_info.board].name,
                                permedia2_name,
-                               (unsigned long )(fb_info.regions.fb_size>>10));
+                               (u32 )(fb_info.regions.fb_size>>10));
        MOD_INC_USE_COUNT;
 }
 
@@ -1455,9 +1643,6 @@ __initfunc(void pm2fb_font_setup(char* options)) {
 __initfunc(void pm2fb_setup(char* options, int* ints)) {
        char* next;
 
-       memset(&pm2fb_options, 0, sizeof(pm2fb_options));
-       memcpy(&pm2fb_options.user_mode, &user_mode[0].par,
-                               sizeof(pm2fb_options.user_mode));
        while (options) {
                if ((next=strchr(options, ',')))
                        *(next++)='\0';
@@ -1469,6 +1654,8 @@ __initfunc(void pm2fb_setup(char* options, int* ints)) {
                        pm2fb_options.flags |= OPTF_YPAN;
                else if (!strcmp(options, "oldmem"))
                        pm2fb_options.flags |= OPTF_OLD_MEM;
+               else if (!strcmp(options, "virtual"))
+                       pm2fb_options.flags |= OPTF_VIRTUAL;
                options=next;
        }
 }
index 94f3464270c7e6d6542ee8ea01da1f002b889577..f10ab7e93d2e5dd76bab58c9e1644654527a0bc5 100644 (file)
@@ -2,7 +2,7 @@
  * Permedia2 framebuffer driver definitions.
  * Copyright (c) 1998-1999 Ilario Nardinocchi (nardinoc@CS.UniBO.IT)
  * --------------------------------------------------------------------------
- * $Id: pm2fb.h,v 1.1.2.1 1999/01/12 19:53:02 geert Exp $
+ * $Id: pm2fb.h,v 1.21 1999/01/28 13:18:07 illo Exp $
  * --------------------------------------------------------------------------
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file README.legal in the main directory of this archive
@@ -16,7 +16,7 @@
 #define PM2_MAX_PIXCLOCK       230000                  /* in KHz */
 #define PM2_REGS_SIZE          0x10000
 
-#define PM2TAG(r) (unsigned long )(((r)-0x8000)>>3)
+#define PM2TAG(r) (u32 )(((r)-0x8000)>>3)
 
 /*****************************************************************************
  * Permedia2 registers used in the framebuffer
 #define PM2I_RD_BLUE_KEY                               0x44
 
 /* Fields and flags */
-#define PM2F_RENDER_AREASTIPPLE                                (1<<0)
-#define PM2F_RENDER_FASTFILL                           (1<<3)
-#define PM2F_RENDER_PRIMITIVE_MASK                     (0x3<<6)
+#define PM2F_RENDER_AREASTIPPLE                                (1L<<0)
+#define PM2F_RENDER_FASTFILL                           (1L<<3)
+#define PM2F_RENDER_PRIMITIVE_MASK                     (3L<<6)
 #define PM2F_RENDER_LINE                               0
-#define PM2F_RENDER_TRAPEZOID                          (1<<6)
-#define PM2F_RENDER_POINT                              (2<<6)
-#define PM2F_RENDER_RECTANGLE                          (3<<6)
-#define PM2F_SYNCHRONIZATION                           (1<<10)
+#define PM2F_RENDER_TRAPEZOID                          (1L<<6)
+#define PM2F_RENDER_POINT                              (2L<<6)
+#define PM2F_RENDER_RECTANGLE                          (3L<<6)
+#define PM2F_SYNCHRONIZATION                           (1L<<10)
 #define PM2F_PLL_LOCKED                                        0x10
-#define PM2F_BEING_RESET                               (1<<31)
+#define PM2F_BEING_RESET                               (1L<<31)
 #define PM2F_DATATYPE_COLOR                            0x8000
 #define PM2F_VGA_ENABLE                                        0x02
 #define PM2F_VGA_FIXED                                 0x04
 #define PM2F_TEXTEL_SIZE_32                            0x00100000
 #define PM2F_TEXTEL_SIZE_4                             0x00180000
 #define PM2F_TEXTEL_SIZE_24                            0x00200000
-#define PM2F_INCREASE_X                                        (1<<21)
-#define PM2F_INCREASE_Y                                        (1<<22)
-#define PM2F_CONFIG_FB_WRITE_ENABLE                    (1<<3)
-#define PM2F_CONFIG_FB_PACKED_DATA                     (1<<2)
-#define PM2F_CONFIG_FB_READ_DEST_ENABLE                        (1<<1)
-#define PM2F_CONFIG_FB_READ_SOURCE_ENABLE              (1<<0)
-#define PM2F_COLOR_KEY_TEST_OFF                                (1<<4)
+#define PM2F_INCREASE_X                                        (1L<<21)
+#define PM2F_INCREASE_Y                                        (1L<<22)
+#define PM2F_CONFIG_FB_WRITE_ENABLE                    (1L<<3)
+#define PM2F_CONFIG_FB_PACKED_DATA                     (1L<<2)
+#define PM2F_CONFIG_FB_READ_DEST_ENABLE                        (1L<<1)
+#define PM2F_CONFIG_FB_READ_SOURCE_ENABLE              (1L<<0)
+#define PM2F_COLOR_KEY_TEST_OFF                                (1L<<4)
+#define PM2F_MEM_CONFIG_RAM_MASK                       (3L<<29)
+#define PM2F_MEM_BANKS_1                               0L
+#define PM2F_MEM_BANKS_2                               (1L<<29)
+#define PM2F_MEM_BANKS_3                               (2L<<29)
+#define PM2F_MEM_BANKS_4                               (3L<<29)
 
 #endif /* PM2FB_H */
 
index 9148f609edcfb58c8858d9bf0b34509de84f524e..50208f98ce441d8cde0542e410e1e5702d6d09cd 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: promcon.c,v 1.12 1998/08/23 20:19:01 mj Exp $
+/* $Id: promcon.c,v 1.13 1999/01/19 09:56:46 jj Exp $
  * Console driver utilizing PROM sun terminal emulation
  *
  * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
@@ -230,7 +230,7 @@ promcon_putcs(struct vc_data *conp, const unsigned short *s,
              int count, int y, int x)
 {
        unsigned char buf[256], *b = buf;
-       unsigned short attr = *s;
+       unsigned short attr = scr_readw(s);
        unsigned char save;
        int i, last = 0;
 
@@ -256,9 +256,9 @@ promcon_putcs(struct vc_data *conp, const unsigned short *s,
                        }
 
                        if (inverted(attr))
-                               b += sprintf(b, "\033[7m%c\033[m", *s++);
+                               b += sprintf(b, "\033[7m%c\033[m", scr_readw(s++));
                        else
-                               b += sprintf(b, "%c", *s++);
+                               b += sprintf(b, "%c", scr_readw(s++));
 
                        strcpy(b, "\b\033[@");
                        b += 4;
@@ -295,14 +295,14 @@ promcon_putcs(struct vc_data *conp, const unsigned short *s,
                        promcon_puts(buf, b - buf);
                        b = buf;
                }
-               *b++ = *s++;
+               *b++ = scr_readw(s++);
        }
 
        px += count;
 
        if (last) {
-               save = *s++;
-               b += sprintf(b, "%c\b\033[@%c", *s++, save);
+               save = scr_readw(s++);
+               b += sprintf(b, "%c\b\033[@%c", scr_readw(s++), save);
                px++;
        }
 
@@ -318,11 +318,12 @@ promcon_putcs(struct vc_data *conp, const unsigned short *s,
 static void
 promcon_putc(struct vc_data *conp, int c, int y, int x)
 {
-       unsigned short s = c;
+       unsigned short s;
 
        if (console_blanked)
                return;
        
+       scr_writew(c, &s);
        promcon_putcs(conp, &s, 1, y, x);
 }
 
@@ -591,8 +592,11 @@ struct consw prom_con = {
 
 __initfunc(void prom_con_init(void))
 {
+#ifdef CONFIG_DUMMY_CONSOLE
        if (conswitchp == &dummy_con)
                take_over_console(&prom_con, 0, MAX_NR_CONSOLES-1, 1);
-       else if (conswitchp == &prom_con)
+       else
+#endif
+       if (conswitchp == &prom_con)
                promcon_init_unimap(vc_cons[fg_console].d);
 }
diff --git a/drivers/video/q40fb.c b/drivers/video/q40fb.c
new file mode 100644 (file)
index 0000000..8cacf59
--- /dev/null
@@ -0,0 +1,362 @@
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/system.h>
+/*#include <asm/irq.h>*/
+#include <asm/q40_master.h>
+#include <linux/fb.h>
+#include <linux/module.h>
+#include <asm/pgtable.h>
+
+#include <video/fbcon-cfb16.h>
+
+
+#define Q40_PHYS_SCREEN_ADDR 0xFE800000
+static unsigned long q40_screen_addr;
+
+static u16 fbcon_cmap_cfb16[16];
+
+/* frame buffer operations */
+
+static int q40fb_open(struct fb_info *info, int user);
+static int q40fb_release(struct fb_info *info, int user);
+static int q40fb_get_fix(struct fb_fix_screeninfo *fix, int con,
+                       struct fb_info *info);
+static int q40fb_get_var(struct fb_var_screeninfo *var, int con,
+                       struct fb_info *info);
+static int q40fb_set_var(struct fb_var_screeninfo *var, int con,
+                       struct fb_info *info);
+static int q40fb_get_cmap(struct fb_cmap *cmap,int kspc,int con,
+                        struct fb_info *info);
+static int q40fb_set_cmap(struct fb_cmap *cmap,int kspc,int con,
+                        struct fb_info *info);
+static int q40fb_pan_display(struct fb_var_screeninfo *var, int con,
+                           struct fb_info *info);
+static int q40fb_ioctl(struct inode *inode, struct file *file,
+                     unsigned int cmd, unsigned long arg, int con,
+                     struct fb_info *info);
+
+static int q40con_switch(int con, struct fb_info *info);
+static int q40con_updatevar(int con, struct fb_info *info);
+static void q40con_blank(int blank, struct fb_info *info);
+
+static void q40fb_set_disp(int con, struct fb_info *info);
+
+static struct display disp[MAX_NR_CONSOLES];
+static struct fb_info fb_info;
+static struct fb_ops q40fb_ops = { 
+       q40fb_open,q40fb_release, q40fb_get_fix, q40fb_get_var, q40fb_set_var,
+       q40fb_get_cmap, q40fb_set_cmap, q40fb_pan_display, q40fb_ioctl
+};
+
+static int currcon=0;
+
+static char q40fb_name[]="Q40";
+
+static int q40fb_open(struct fb_info *info, int user)
+{
+        /*
+         * Nothing, only a usage count for the moment
+         */
+
+        MOD_INC_USE_COUNT;
+        return(0);
+}
+
+static int q40fb_release(struct fb_info *info, int user)
+{
+        MOD_DEC_USE_COUNT;
+        return(0);
+}
+
+static int q40fb_get_fix(struct fb_fix_screeninfo *fix, int con,
+                       struct fb_info *info)
+{
+       memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+
+       strcpy(fix->id,"Q40");
+       fix->smem_start=(char*)q40_screen_addr;
+       fix->smem_len=1024*1024;
+       fix->type=FB_TYPE_PACKED_PIXELS;
+       fix->type_aux=0;
+       fix->visual=FB_VISUAL_TRUECOLOR;  /* good approximation so far ..*/;
+       fix->xpanstep=0;
+       fix->ypanstep=0;
+       fix->ywrapstep=0;
+        fix->line_length=1024*2;
+
+       /* no mmio,accel ...*/
+
+       return 0;
+
+}
+        
+static int q40fb_get_var(struct fb_var_screeninfo *var, int con,
+                       struct fb_info *info)
+{
+       memset(var, 0, sizeof(struct fb_var_screeninfo));
+
+       var->xres=1024;
+       var->yres=512;
+       var->xres_virtual=1024;
+       var->yres_virtual=512;
+       var->xoffset=0;
+       var->yoffset=0;
+       var->bits_per_pixel=16;
+       var->grayscale=0;
+       var->nonstd=0;
+       var->activate=FB_ACTIVATE_NOW;
+       var->height=230;     /* approx for my 17" monitor, more important */
+       var->width=300;      /* than the absolute values is the unusual aspect ratio*/
+
+       var->red.offset=6; /*6*/
+       var->red.length=5;
+       var->green.offset=11; /*11*/
+       var->green.length=5;
+       var->blue.offset=0;
+       var->blue.length=6;
+       var->transp.length=0;
+
+       var->pixclock=0;
+       var->left_margin=0;
+       var->right_margin=0;
+       var->hsync_len=0;
+       var->vsync_len=0;
+       var->sync=0;
+       var->vmode=FB_VMODE_NONINTERLACED;
+
+       return 0;
+
+}
+
+static int q40fb_set_var(struct fb_var_screeninfo *var, int con,
+                       struct fb_info *info)
+{
+       if(var->xres!=1024) 
+               return -EINVAL;
+       if(var->yres!=512)
+               return -EINVAL;
+       if(var->xres_virtual!=1024)
+               return -EINVAL;
+       if(var->yres_virtual!=512)
+               return -EINVAL;
+       if(var->xoffset!=0)
+               return -EINVAL;
+       if(var->yoffset!=0)
+               return -EINVAL;
+       if(var->bits_per_pixel!=16)
+               return -EINVAL;
+       if(var->grayscale!=0)
+               return -EINVAL;
+       if(var->nonstd!=0)
+               return -EINVAL;
+       if(var->activate!=FB_ACTIVATE_NOW)
+               return -EINVAL;
+       if(var->pixclock!=0)
+               return -EINVAL;
+       if(var->left_margin!=0)
+               return -EINVAL;
+       if(var->right_margin!=0)
+               return -EINVAL;
+       if(var->hsync_len!=0)
+               return -EINVAL;
+       if(var->vsync_len!=0)
+               return -EINVAL;
+       if(var->sync!=0)
+               return -EINVAL;
+       if(var->vmode!=FB_VMODE_NONINTERLACED)
+               return -EINVAL;
+
+       return 0;
+
+}
+
+static int q40_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+                        unsigned *blue, unsigned *transp,
+                        struct fb_info *info)
+{
+    /*
+     *  Read a single color register and split it into colors/transparent.
+     *  The return values must have a 16 bit magnitude.
+     *  Return != 0 for invalid regno.
+     */
+    if (regno>=16) return 1;
+
+    *transp=0;
+    *green = ((fbcon_cmap_cfb16[regno]>>11) & 31)<<11;
+    *red   = ((fbcon_cmap_cfb16[regno]>>6) & 31)<<11;
+    *blue  = ((fbcon_cmap_cfb16[regno]) & 63)<<10;
+
+    return 0;
+}
+
+static int q40_setcolreg(unsigned regno, unsigned red, unsigned green,
+                        unsigned blue, unsigned transp,
+                        const struct fb_info *info)
+{
+    /*
+     *  Set a single color register. The values supplied have a 16 bit
+     *  magnitude.
+     *  Return != 0 for invalid regno.
+     */
+  
+  red>>=11;
+  green>>=11;
+  blue>>=10;
+
+    if (regno < 16) {
+      fbcon_cmap_cfb16[regno] = ((red & 31) <<5) |
+                                ((green & 31) << 11) |
+                                (blue & 63);
+    }
+    return 0;
+}
+
+static int q40fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+                        struct fb_info *info)
+{
+#if 1
+       if (con == currcon) /* current console? */
+               return fb_get_cmap(cmap, kspc, q40_getcolreg, info);
+       else if (fb_display[con].cmap.len) /* non default colormap? */
+               fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+       else
+               fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+                            cmap, kspc ? 0 : 2);
+       return 0;
+#else
+       printk("get cmap not supported\n");
+
+       return -EINVAL;
+#endif
+}
+
+static int q40fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+                        struct fb_info *info)
+{
+#if 1
+       int err;
+
+       if (!fb_display[con].cmap.len) {        /* no colormap allocated? */
+               if ((err = fb_alloc_cmap(&fb_display[con].cmap,
+                                        1<<fb_display[con].var.bits_per_pixel,
+                                        0)))
+                       return err;
+       }
+       if (con == currcon)                     /* current console? */
+               return fb_set_cmap(cmap, kspc, q40_setcolreg, info);
+       else
+               fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+       return 0;
+#else
+       printk("set cmap not supported\n");
+
+       return -EINVAL;
+#endif
+}
+
+static int q40fb_pan_display(struct fb_var_screeninfo *var, int con,
+                           struct fb_info *info)
+{
+       printk("panning not supported\n");
+
+       return -EINVAL;
+
+}
+
+static int q40fb_ioctl(struct inode *inode, struct file *file,
+                     unsigned int cmd, unsigned long arg, int con,
+                     struct fb_info *info)
+{
+       return -EINVAL;
+}
+
+static void q40fb_set_disp(int con, struct fb_info *info)
+{
+  struct fb_fix_screeninfo fix;
+  struct display *display;
+
+  q40fb_get_fix(&fix, con, info);
+
+  if (con>=0)
+    display = &fb_display[con];
+  else         
+    display = &disp[0];
+
+  if (con<0) con=0;
+
+   display->screen_base = fix.smem_start;
+   display->visual = fix.visual;
+   display->type = fix.type;
+   display->type_aux = fix.type_aux;
+   display->ypanstep = fix.ypanstep;
+   display->ywrapstep = fix.ywrapstep;
+   display->can_soft_blank = 0;
+   display->inverse = 0;
+   display->line_length = fix.line_length;
+
+#ifdef FBCON_HAS_CFB16
+   display->dispsw = &fbcon_cfb16;
+   disp->dispsw_data = fbcon_cmap_cfb16;
+#else
+   display->dispsw = &fbcon_dummy;
+#endif
+}
+  
+void q40fb_init(void)
+{
+#if 0
+        q40_screen_addr = kernel_map(Q40_PHYS_SCREEN_ADDR, 1024*1024,
+                                          KERNELMAP_NO_COPYBACK, NULL);
+#else
+       q40_screen_addr = Q40_PHYS_SCREEN_ADDR; /* mapped in q40/config.c */
+#endif
+
+       fb_info.changevar=NULL;
+       strcpy(&fb_info.modename[0],q40fb_name);
+       fb_info.fontname[0]=0;
+       fb_info.disp=disp;
+       fb_info.switch_con=&q40con_switch;
+       fb_info.updatevar=&q40con_updatevar;
+       fb_info.blank=&q40con_blank;    
+       fb_info.node = -1;
+       fb_info.fbops = &q40fb_ops;
+       fb_info.flags = FBINFO_FLAG_DEFAULT;  /* not as module for now */
+       
+       master_outb(3,DISPLAY_CONTROL_REG);
+
+        q40fb_get_var(&disp[0].var, 0, &fb_info);
+       q40fb_set_disp(-1, &fb_info);
+
+       if (register_framebuffer(&fb_info) < 0)
+               panic("unable to register Q40 frame buffer\n");
+
+        printk("fb%d: Q40 frame buffer alive and kicking !\n",
+              GET_FB_IDX(fb_info.node));
+}      
+
+       
+static int q40con_switch(int con, struct fb_info *info)
+{ 
+       currcon=con;
+       
+       return 0;
+
+}
+
+static int q40con_updatevar(int con, struct fb_info *info)
+{
+       return 0;
+}
+
+static void q40con_blank(int blank, struct fb_info *info)
+{
+}
index 995e86506d4c7dbdacaf1c891adb0d6c90012f25..1ee42692f349b4649750f9b3ce6d9e56b764da10 100644 (file)
@@ -101,8 +101,8 @@ struct display_data {
 
 struct retz3_fb_info {
        struct fb_info info;
-       unsigned long base;
-       unsigned long fbmem;
+       unsigned char *base;
+       unsigned char *fbmem;
        unsigned long fbsize;
        volatile unsigned char *regs;
        unsigned long physfbmem;
@@ -1209,7 +1209,7 @@ static void retz3fb_set_disp(int con, struct fb_info *info)
        if (con == -1)
                con = 0;
 
-       display->screen_base = (char *)zinfo->fbmem;
+       display->screen_base = zinfo->fbmem;
        display->visual = fix.visual;
        display->type = fix.type;
        display->type_aux = fix.type_aux;
@@ -1282,7 +1282,7 @@ static int retz3fb_set_var(struct fb_var_screeninfo *var, int con,
                        struct fb_fix_screeninfo fix;
                        retz3fb_get_fix(&fix, con, info);
 
-                       display->screen_base = (char *)zinfo->fbmem;
+                       display->screen_base = zinfo->fbmem;
                        display->visual = fix.visual;
                        display->type = fix.type;
                        display->type_aux = fix.type_aux;
@@ -1456,7 +1456,7 @@ __initfunc(void retz3fb_init(void))
        board_size = (unsigned long)cd->cd_BoardSize;
 
        zinfo->base = ioremap(board_addr, board_size);
-       zinfo->regs = (unsigned char *)(zinfo->base);
+       zinfo->regs = zinfo->base;
        zinfo->fbmem = zinfo->base + VIDEO_MEM_OFFSET;
        /* Get memory size - for now we asume its a 4MB board */
        zinfo->fbsize = 0x00400000; /* 4 MB */
index a99a3a0cdfd38e81b537296221f3588bb11129be..59a2da71632a9b06845aa9898c77a36dbe0322a0 100644 (file)
@@ -240,12 +240,11 @@ static int xxx_blank(int blank_mode, const struct fb_info *info)
     return 0;
 }
 
-static void xxx_set_dispsw(const void *par, struct display *disp,
-                          struct fb_info_gen *info)
+static void xxx_set_disp(const void *par, struct display *disp,
+                        struct fb_info_gen *info)
 {
-    unsigned long flags;
-
     /*
+     *  Fill in a pointer with the virtual address of the mapped frame buffer.
      *  Fill in a pointer to appropriate low level text console operations (and
      *  optionally a pointer to help data) for the video mode `par' of your
      *  video hardware. These can be generic software routines, or hardware
@@ -253,7 +252,7 @@ static void xxx_set_dispsw(const void *par, struct display *disp,
      *  If you don't have any appropriate operations, you must fill in a
      *  pointer to dummy operations, and there will be no text output.
      */
-    save_flags(flags); cli();
+    disp->screen_base = virtual_frame_buffer_address;
 #ifdef FBCON_HAS_CFB8
     if (is_cfb8) {
        disp->dispsw = fbcon_cfb8;
@@ -278,7 +277,6 @@ static void xxx_set_dispsw(const void *par, struct display *disp,
     } else
 #endif
        disp->dispsw = &fbcon_dummy;
-    restore_flags(flags);
 }
 
 
index 90d6152fa03c3c8b49aa9c27ca4a85288c991c1c..8e9d2fc41541963c2cf3ab506319f9f0ff0da3ca 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tcxfb.c,v 1.6 1998/09/04 15:43:46 jj Exp $
+/* $Id: tcxfb.c,v 1.7 1999/01/26 10:55:03 jj Exp $
  * tcxfb.c: TCX 24/8bit frame buffer driver
  *
  * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
@@ -228,6 +228,7 @@ __initfunc(char *tcxfb_init(struct fb_info_sbusfb *fb))
                strcpy(fix->id, "TCX24");
        }
        fix->line_length = fb->var.xres_virtual;
+       fix->accel = FB_ACCEL_SUN_TCX;
        
        disp->scrollmode = SCROLL_YREDRAW;
        if (!disp->screen_base)
index cbad38a82fba81d7f91fe66910679939f6233346..47c0582135c8058d321404515a06d4077864db1b 100644 (file)
@@ -254,6 +254,7 @@ static void vesafb_set_disp(int con)
 static int vesafb_set_var(struct fb_var_screeninfo *var, int con,
                          struct fb_info *info)
 {
+       static int first = 1;
 
        if (var->xres           != vesafb_defined.xres           ||
            var->yres           != vesafb_defined.yres           ||
@@ -262,8 +263,13 @@ static int vesafb_set_var(struct fb_var_screeninfo *var, int con,
            var->yres_virtual   <  video_height                  ||
            var->xoffset                                         ||
            var->bits_per_pixel != vesafb_defined.bits_per_pixel ||
-           var->nonstd)
+           var->nonstd) {
+               if (first) {
+                       printk("Vesafb does not support changing the video mode\n");
+                       first = 0;
+               }
                return -EINVAL;
+       }
 
        if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST)
                return 0;
index ba4bf5ea0857e928264669457842919829e7a5af..a19c1c9e507854ed06f764dfa23d0bc1602c2f0c 100644 (file)
 #define rl_3d(reg) \
                 (*((unsigned long volatile *)(CyberRegs + reg)))
 
-
-
-
-
-
 struct virgefb_par {
    int xres;
    int yres;
@@ -109,6 +104,11 @@ static int currcon = 0;
 static struct display disp;
 static struct fb_info fb_info;
 
+static union {
+#ifdef FBCON_HAS_CFB16
+    u16 cfb16[16];
+#endif
+} fbcon_cmap;
 
 /*
  *    Switch for Chipset Independency
@@ -132,6 +132,7 @@ static struct fb_hwswitch {
    void (*blank)(int blank);
 } *fbhw;
 
+static int blit_maybe_busy = 0;
 
 /*
  *    Frame Buffer Name
@@ -148,7 +149,7 @@ static char virgefb_name[16] = "Cybervision/3D";
 #define VIRGE8_HEIGHT 886
 #define VIRGE8_PIXCLOCK 12500    /* ++Geert: Just a guess */
 
-#if 0
+#if 1
 #define VIRGE16_WIDTH 800
 #define VIRGE16_HEIGHT 600
 #endif
@@ -167,6 +168,8 @@ static unsigned long Cyber_register_base;
 static unsigned long Cyber_vcode_switch_base;
 static unsigned char cv3d_on_zorro2;
  
+#define CYBMEM_OFFSET_8  0x800000      /* offsets from start of video - */ 
+#define CYBMEM_OFFSET_16 0x400000      /* ram to appropriate aperture */
 
 /*
  *    Predefined Video Modes
@@ -215,11 +218,18 @@ static struct fb_videomode virgefb_predefined[] __initdata = {
            0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
            FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
        }
+    }, {
+       "640x480-16", {         /* Cybervision 16 bpp */
+           640, 480, 640, 480, 0, 0, 16, 0,
+           {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+           0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+           FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+       }
     }, {
        "800x600-16", {         /* Cybervision 16 bpp */
            800, 600, 800, 600, 0, 0, 16, 0,
            {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
-           0, 0, -1, -1, 0, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+           0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
            FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
        }
     }, {
@@ -229,6 +239,27 @@ static struct fb_videomode virgefb_predefined[] __initdata = {
            0, 0, -1, -1, 0, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
            FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
        }
+    }, {
+       "1152x886-16", {         /* Cybervision 16 bpp */
+           1152, 886, 1152, 886, 0, 0, 16, 0,
+           {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+           0, 0, -1, -1, 0, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+           FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+       }
+    }, {
+       "1280x1024-16", {         /* Cybervision 16 bpp */
+           1280, 1024, 1280, 1024, 0, 0, 16, 0,
+           {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+           0, 0, -1, -1, 0, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+           FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+       }
+    }, {
+       "1600x1200-16", {         /* Cybervision 16 bpp */
+           1600, 1200, 1600, 1200, 0, 0, 16, 0,
+           {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+           0, 0, -1, -1, 0, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+           FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+       }
     }
 };
 
@@ -246,8 +277,8 @@ static int Cyberfb_Cyber16 = 0;       /* Use Cybervision board */
  *    Some default modes
  */
 
-#define VIRGE8_DEFMODE     (0)
-#define VIRGE16_DEFMODE    (6)
+#define VIRGE8_DEFMODE     (1)
+#define VIRGE16_DEFMODE    (7)
 
 static struct fb_var_screeninfo virgefb_default;
 
@@ -294,6 +325,9 @@ static void Cyberfb_blank(int blank, struct fb_info *info);
 static struct display_switch fbcon_virge8;
 #endif
 
+#ifdef FBCON_HAS_CFB16
+static struct display_switch fbcon_virge16;
+#endif
 
 /*
  *   Hardware Specific Routines
@@ -353,15 +387,14 @@ static int Cyber_init(void)
         *                (the 3D penguin might need texture memory :-) )
         */
 
-       memset ((char*)CyberMem, 0, 1600 * 1200);
-
-       /* Disable hardware cursor */
        if (cv3d_on_zorro2) {
                CyberSize = 0x00380000; /* 3.5 MB , we need some space for the registers? */
        } else {
                CyberSize = 0x00400000; /* 4 MB */
        }
+       memset ((char*)CyberMem, 0, CyberSize);
 
+       /* Disable hardware cursor */
        vgawb_3d(0x3c8, 255);
        vgawb_3d(0x3c9, 56);
        vgawb_3d(0x3c9, 100);
@@ -396,7 +429,18 @@ static int Cyber_encode_fix(struct fb_fix_screeninfo *fix,
 {
        memset(fix, 0, sizeof(struct fb_fix_screeninfo));
        strcpy(fix->id, virgefb_name);
-       fix->smem_start = (char*) CyberMem_phys;
+       if (cv3d_on_zorro2) {
+               fix->smem_start = (char*) CyberMem_phys;
+       } else {
+               switch (par->bpp) {
+                       case 8:
+                               fix->smem_start = (char*) (CyberMem_phys + CYBMEM_OFFSET_8);
+                               break;
+                       case 16:
+                               fix->smem_start = (char*) (CyberMem_phys + CYBMEM_OFFSET_16);
+                               break;
+               }
+       }
        fix->smem_len = CyberSize;
        fix->mmio_start = (char*) CyberRegs_phys;
        fix->mmio_len = 0x10000; /* TODO: verify this for the CV64/3D */
@@ -467,24 +511,27 @@ static int Cyber_encode_var(struct fb_var_screeninfo *var,
        var->bits_per_pixel = par->bpp;
        var->grayscale = 0;
 
-       if (par->bpp == 8) {
-               var->red.offset = 0;
-               var->red.length = 6;
-               var->red.msb_right = 0;
-               var->blue = var->green = var->red;
-       } else {
-               var->red.offset = 11;
-               var->red.length = 5;
-               var->red.msb_right = 0;
-               var->green.offset = 5;
-               var->green.length = 6;
-               var->green.msb_right = 0;
-               var->blue.offset = 0;
-               var->blue.length = 5;
-               var->blue.msb_right = 0;
+       switch (var->bits_per_pixel) {
+               case 8:         /* CLUT */
+                       var->red.offset = 0;
+                       var->red.length = 6;
+                       var->red.msb_right = 0;
+                       var->blue = var->green = var->red;
+                       break;
+               case 16:        /* RGB 565 */
+                       var->red.offset = 11;
+                       var->red.length = 5;
+                       var->green.offset = 5;
+                       var->green.length = 6;
+                       var->blue.offset = 0;
+                       var->blue.length = 5;
+                       var->transp.offset = 0;
+                       var->transp.length = 0;
+                       break;
        }
-       var->transp.offset = 0;
-       var->transp.length = 0;
+       var->red.msb_right = 0;
+       var->green.msb_right = 0;
+       var->blue.msb_right = 0;
        var->transp.msb_right = 0;
 
        var->nonstd = 0;
@@ -493,8 +540,10 @@ static int Cyber_encode_var(struct fb_var_screeninfo *var,
        var->height = -1;
        var->width = -1;
 
-       var->accel_flags = (par->accel && par->bpp == 8) ? FB_ACCELF_TEXT : 0;
-       DPRINTK("accel CV64/3D\n");
+       var->accel_flags = (par->accel &&
+               ((par->bpp == 8) || (par->bpp == 16))) ? FB_ACCELF_TEXT : 0;
+
+/*     printk("CV64/3D : %s\n",(var->accel_flags ? "accel" : "no accel")); */
 
        var->vmode = FB_VMODE_NONINTERLACED;
 
@@ -525,28 +574,34 @@ static int Cyber_encode_var(struct fb_var_screeninfo *var,
 static int Cyber_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
                           u_int transp, struct fb_info *info)
 {
-       if (regno > 255)
-       {
-               return (1);
+       if (((current_par.bpp==8) && (regno>255)) ||
+               ((current_par.bpp!=8) && (regno>15)))
+                       return (1);
+
+       if (((current_par.bpp==8) && (regno<256)) || ((current_par.bpp==16) &&(regno<16))) {
+               Cyber_colour_table [regno][0] = red >> 10;
+               Cyber_colour_table [regno][1] = green >> 10;
+               Cyber_colour_table [regno][2] = blue >> 10;
        }
 
-       /*
-        * No colors on the CV3D yet.
-        */
-
-       vgawb_3d(0x3c8, (unsigned char) regno);
-       red >>= 10;
-       green >>= 10;
-       blue >>= 10;
-
-       Cyber_colour_table [regno][0] = red;
-       Cyber_colour_table [regno][1] = green;
-       Cyber_colour_table [regno][2] = blue;
-
-       vgawb_3d(0x3c9, red);
-       vgawb_3d(0x3c9, green);
-       vgawb_3d(0x3c9, blue);
-
+       switch (current_par.bpp) {
+#ifdef FBCON_HAS_CFB8
+               case 8:
+                       vgawb_3d(0x3c8, (unsigned char) regno);
+                       vgawb_3d(0x3c9, ((unsigned char) (red >> 10)));
+                       vgawb_3d(0x3c9, ((unsigned char) (green >> 10)));
+                       vgawb_3d(0x3c9, ((unsigned char) (blue >> 10)));
+                       break;
+#endif
+#ifdef FBCON_HAS_CFB16
+               case 16:
+                       fbcon_cmap.cfb16[regno] =
+                               ((red  & 0xf800) |
+                               ((green & 0xfc00) >> 5) |
+                               ((blue  & 0xf800) >> 11));
+                       break;
+#endif
+       }
        return (0);
 }
 
@@ -561,14 +616,18 @@ static int Cyber_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
 {
        int t;
 
-       if (regno >= 256)
+       if (regno > 255)
                return (1);
-       t       = Cyber_colour_table [regno][0];
-       *red    = (t<<10) | (t<<4) | (t>>2);
-       t       = Cyber_colour_table [regno][1];
-       *green  = (t<<10) | (t<<4) | (t>>2);
-       t       = Cyber_colour_table [regno][2];
-       *blue   = (t<<10) | (t<<4) | (t>>2);
+
+       if (((current_par.bpp==8) && (regno<256)) || ((current_par.bpp==16) && (regno<16))) {
+
+               t = Cyber_colour_table [regno][0];
+               *red    = (t<<10) | (t<<4) | (t>>2);
+               t = Cyber_colour_table [regno][1];
+               *green  = (t<<10) | (t<<4) | (t>>2);
+               t = Cyber_colour_table [regno][2];
+               *blue   = (t<<10) | (t<<4) | (t>>2);
+       }
        *transp = 0;
        return (0);
 }
@@ -615,8 +674,10 @@ static inline void Cyber3D_WaitBusy(void)
 unsigned long status;
 
        do {
+               mb();
                status = rl_3d(0x8504);
        } while (!(status & (1 << 13)));
+       blit_maybe_busy = 0;
 }
 
 #define S3V_BITBLT     (0x0 << 27)
@@ -666,6 +727,10 @@ static void Cyber3D_BitBLT(u_short curx, u_short cury, u_short destx,
                desty += (height - 1);
        }
 
+       if (blit_maybe_busy)
+               Cyber3D_WaitBusy();
+       blit_maybe_busy = 1;
+
        wl_3d(0xa4f4, 1); /* pattern fb color */
 
        wl_3d(0xa4e8, ~0); /* mono pat 0 */
@@ -676,8 +741,6 @@ static void Cyber3D_BitBLT(u_short curx, u_short cury, u_short destx,
        wl_3d(0xa50c, ((destx << 16) | desty));         /* rdest_xy */
 
        wl_3d(0xa500, blitcmd);                         /* GO! */
-
-       Cyber3D_WaitBusy();
 }
 
 /*
@@ -691,6 +754,10 @@ static void Cyber3D_RectFill(u_short x, u_short y, u_short width,
        unsigned int blitcmd = S3V_RECTFILL | S3V_DRAW | S3V_DST_8BPP |
                S3V_BLT_CLEAR | S3V_MONO_PAT | (1 << 26) | (1 << 25);
 
+       if (blit_maybe_busy)
+               Cyber3D_WaitBusy();
+       blit_maybe_busy = 1;
+
        tmp = color & 0xff;
        wl_3d(0xa4f4, tmp);
 
@@ -698,19 +765,20 @@ static void Cyber3D_RectFill(u_short x, u_short y, u_short width,
        wl_3d(0xa50c, ((x << 16) | y));                 /* rdest_xy */
 
        wl_3d(0xa500, blitcmd);                         /* GO! */
-       Cyber3D_WaitBusy();
 }
 
 
 /**************************************************************
  * Move cursor to x, y
  */
+
+#if 0
 static void Cyber_MoveCursor (u_short x, u_short y)
 {
        printk("Yuck .... MoveCursor on a 3D\n");
        return;
 }
-
+#endif
 
 /* -------------------- Interfaces to hardware functions -------------------- */
 
@@ -868,7 +936,18 @@ static void virgefb_set_disp(int con, struct fb_info *info)
        virgefb_get_fix(&fix, con, info);
        if (con == -1)
                con = 0;
-       display->screen_base = (char*) CyberMem;
+       if (cv3d_on_zorro2) {
+               display->screen_base = (char*) CyberMem;
+       } else {
+               switch (display->var.bits_per_pixel) {
+                       case 8:
+                               display->screen_base = (char*) (CyberMem + CYBMEM_OFFSET_8);
+                               break;
+                       case 16:
+                               display->screen_base = (char*) (CyberMem + CYBMEM_OFFSET_16);
+                               break;
+               }
+       }
        display->visual = fix.visual;
        display->type = fix.type;
        display->type_aux = fix.type_aux;
@@ -878,22 +957,26 @@ static void virgefb_set_disp(int con, struct fb_info *info)
        display->inverse = Cyberfb_inverse;
        switch (display->var.bits_per_pixel) {
 #ifdef FBCON_HAS_CFB8
-           case 8:
-               if (display->var.accel_flags & FB_ACCELF_TEXT) {
-                   display->dispsw = &fbcon_virge8;
+               case 8:
+                       if (display->var.accel_flags & FB_ACCELF_TEXT) {
+                               display->dispsw = &fbcon_virge8;
 #warning FIXME: We should reinit the graphics engine here
-               } else
-                   display->dispsw = &fbcon_virge8;
-               break;
+                       } else
+                               display->dispsw = &fbcon_cfb8;
+                       break;
 #endif
 #ifdef FBCON_HAS_CFB16
-           case 16:
-               display->dispsw = &fbcon_cfb16;
-               break;
+               case 16:
+                       if (display->var.accel_flags & FB_ACCELF_TEXT) {
+                               display->dispsw = &fbcon_virge16;
+                       } else
+                               display->dispsw = &fbcon_cfb16;
+                       display->dispsw_data = &fbcon_cmap.cfb16;
+                       break;
 #endif
-           default:
-               display->dispsw = &fbcon_dummy;
-               break;
+               default:
+                       display->dispsw = &fbcon_dummy;
+                       break;
        }
 }
 
@@ -962,7 +1045,7 @@ static int virgefb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
 
        if (!fb_display[con].cmap.len) {       /* no colormap allocated? */
                if ((err = fb_alloc_cmap(&fb_display[con].cmap,
-                                1<<fb_display[con].var.bits_per_pixel, 0)))
+                               1<<fb_display[con].var.bits_per_pixel, 0)))
                        return(err);
        }
        if (con == currcon)              /* current console? */
@@ -987,8 +1070,8 @@ static int virgefb_pan_display(struct fb_var_screeninfo *var, int con,
 
 
 /*
   *   Cybervision Frame Buffer Specific ioctls
   */
*      Cybervision Frame Buffer Specific ioctls
+ */
 
 static int virgefb_ioctl(struct inode *inode, struct file *file,
                         u_int cmd, u_long arg, int con, struct fb_info *info)
@@ -1073,12 +1156,12 @@ __initfunc(void virgefb_init(void))
        }
        else
        {
-               CyberVGARegs = ioremap(board_addr +0x0c000000, 0x00010000);
+               CyberVGARegs = (unsigned long)ioremap(board_addr +0x0c000000, 0x00010000);
 
                CyberRegs_phys = board_addr + 0x05000000;
-               CyberMem_phys  = board_addr + 0x04800000;
+               CyberMem_phys  = board_addr + 0x04000000;       /* was 0x04800000 */
                CyberRegs = ioremap(CyberRegs_phys, 0x00010000);
-               CyberMem = ioremap(CyberMem_phys, 0x00400000);
+               CyberMem = (unsigned long)ioremap(CyberMem_phys, 0x01000000);   /* was 0x00400000 */
                cv3d_on_zorro2 = 0;
                printk("CV3D detected running in Z3 mode\n");
        }
@@ -1146,8 +1229,8 @@ static int Cyberfb_updatevar(int con, struct fb_info *info)
 
 
 /*
   *    Blank the display.
   */
+ *    Blank the display.
+ */
 
 static void Cyberfb_blank(int blank, struct fb_info *info)
 {
@@ -1201,13 +1284,103 @@ static void fbcon_virge8_clear(struct vc_data *conp, struct display *p, int sy,
                          (u_short)bg);
 }
 
+static void fbcon_virge8_putc(struct vc_data *conp, struct display *p, int c, int yy,
+                              int xx)
+{
+       if (blit_maybe_busy)
+               Cyber3D_WaitBusy();
+       fbcon_cfb8_putc(conp, p, c, yy, xx);
+}
+
+static void fbcon_virge8_putcs(struct vc_data *conp, struct display *p,
+                      const unsigned short *s, int count, int yy, int xx)
+{
+       if (blit_maybe_busy)
+               Cyber3D_WaitBusy();
+       fbcon_cfb8_putcs(conp, p, s, count, yy, xx);
+}
+
+static void fbcon_virge8_revc(struct display *p, int xx, int yy)
+{
+       if (blit_maybe_busy)
+               Cyber3D_WaitBusy();
+       fbcon_cfb8_revc(p, xx, yy);
+}
+
+static void fbcon_virge8_clear_margins(struct vc_data *conp, struct display *p,
+                              int bottom_only)
+{
+       if (blit_maybe_busy)
+               Cyber3D_WaitBusy();
+       fbcon_cfb8_clear_margins(conp, p, bottom_only);
+}
+
 static struct display_switch fbcon_virge8 = {
-   fbcon_cfb8_setup, fbcon_virge8_bmove, fbcon_virge8_clear, fbcon_cfb8_putc,
-   fbcon_cfb8_putcs, fbcon_cfb8_revc, NULL, NULL, fbcon_cfb8_clear_margins,
-   FONTWIDTH(8)
+   fbcon_cfb8_setup, fbcon_virge8_bmove, fbcon_virge8_clear, fbcon_virge8_putc,
+   fbcon_virge8_putcs, fbcon_virge8_revc, NULL, NULL, fbcon_virge8_clear_margins,
+   FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
 };
 #endif
 
+#ifdef FBCON_HAS_CFB16
+static void fbcon_virge16_bmove(struct display *p, int sy, int sx, int dy,
+                               int dx, int height, int width)
+{
+        sx *= 16; dx *= 16; width *= 16;
+        Cyber3D_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx,
+                       (u_short)(dy*fontheight(p)), (u_short)width,
+                       (u_short)(height*fontheight(p)));
+}
+                
+static void fbcon_virge16_clear(struct vc_data *conp, struct display *p, int sy,
+                               int sx, int height, int width)
+{
+        unsigned char bg;   
+                
+        sx *= 16; width *= 16;
+        bg = attr_bgcol_ec(p,conp);
+        Cyber3D_RectFill((u_short)sx, (u_short)(sy*fontheight(p)),
+                         (u_short)width, (u_short)(height*fontheight(p)),
+                         (u_short)bg);
+}
+   
+static void fbcon_virge16_putc(struct vc_data *conp, struct display *p, int c, int yy,
+                              int xx)
+{
+       if (blit_maybe_busy)
+               Cyber3D_WaitBusy();
+       fbcon_cfb16_putc(conp, p, c, yy, xx);
+}
+
+static void fbcon_virge16_putcs(struct vc_data *conp, struct display *p,
+                      const unsigned short *s, int count, int yy, int xx)
+{
+       if (blit_maybe_busy)
+               Cyber3D_WaitBusy();
+       fbcon_cfb16_putcs(conp, p, s, count, yy, xx);
+}
+
+static void fbcon_virge16_revc(struct display *p, int xx, int yy)
+{
+       if (blit_maybe_busy)
+               Cyber3D_WaitBusy();
+       fbcon_cfb16_revc(p, xx, yy);
+}
+
+static void fbcon_virge16_clear_margins(struct vc_data *conp, struct display *p,
+                              int bottom_only)
+{
+       if (blit_maybe_busy)
+               Cyber3D_WaitBusy();
+       fbcon_cfb16_clear_margins(conp, p, bottom_only);
+}
+
+static struct display_switch fbcon_virge16 = {
+   fbcon_cfb16_setup, fbcon_virge16_bmove, fbcon_virge16_clear, fbcon_virge16_putc,
+   fbcon_virge16_putcs, fbcon_virge16_revc, NULL, NULL, fbcon_virge16_clear_margins,
+   FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
 
 #ifdef MODULE
 int init_module(void)
index 51c7869b3ef721fe1bdba5b0011cc739fd524df1..143e65254a53e90e206e6b8ebb08d028df31ec63 100644 (file)
@@ -470,7 +470,8 @@ void shrink_dcache_parent(struct dentry * parent)
  */
 void shrink_dcache_memory(int priority, unsigned int gfp_mask)
 {
-       prune_dcache(0);
+       if (gfp_mask & __GFP_IO)
+               prune_dcache(0);
 }
 
 #define NAME_ALLOC_LEN(len)    ((len+16) & ~15)
index 62b70b1602203c729adc0f451e4009727b9a99a7..9dd70f8c51cb0724e4fb7c3a9ba9847b95895172 100644 (file)
@@ -1,8 +1,11 @@
-/*
+/* 
  * CVF extensions for fat-based filesystems
  *
  * written 1997,1998 by Frank Gockel <gockel@sent13.uni-duisburg.de>
  *
+ * please do not remove the next line, dmsdos needs it for verifying patches
+ * CVF-FAT-VERSION-ID: 1.2.0
+ *
  */
  
 #include<linux/sched.h>
 #include<linux/msdos_fs_sb.h>
 #include<linux/string.h>
 #include<linux/fat_cvf.h>
+#include<linux/config.h>
+#ifdef CONFIG_KMOD
+#include<linux/kmod.h>
+#endif
 
 #define MAX_CVF_FORMATS 3
 
@@ -94,6 +101,24 @@ int detect_cvf(struct super_block*sb,char*force)
   int found=0;
   int found_i=-1;
 
+  if(force)
+    if(strcmp(force,"autoload")==0)
+    {
+#ifdef CONFIG_KMOD
+      request_module("cvf_autoload");
+      force=NULL;
+#else
+      printk("cannot autoload CVF modules: kmod support is not compiled into kernel\n");
+      return -1;
+#endif
+    }
+    
+#ifdef CONFIG_KMOD
+  if(force)
+    if(*force)
+      request_module(force);
+#endif
+
   if(force)
   { if(*force)
     { for(i=0;i<MAX_CVF_FORMATS;++i)
@@ -102,6 +127,8 @@ int detect_cvf(struct super_block*sb,char*force)
             return i;
         }
       }
+      printk("CVF format %s unknown (module not loaded?)\n",force);
+      return -1;
     }
   }
 
@@ -115,6 +142,6 @@ int detect_cvf(struct super_block*sb,char*force)
   }
   
   if(found==1)return found_i;
-  if(found>1)printk("CVF detection ambiguous, use cvf_format=xxx option\n"); 
+  if(found>1)printk("CVF detection ambiguous, please use cvf_format=xxx option\n"); 
   return -1;
 }
index 0ff5f187f76b95217d682a82c6bb1fb6109727be..7c95181819f6185321c6e0e4e25ec7e52bce3cd8 100644 (file)
@@ -456,6 +456,10 @@ void fat_truncate(struct inode *inode)
        /* Why no return value?  Surely the disk could fail... */
        if (IS_IMMUTABLE(inode))
                return /* -EPERM */;
+       if(inode->i_sb->s_flags&MS_RDONLY) {
+               printk("FAT: fat_truncate called though fs is read-only, uhh...\n");
+               return /* -EROFS */;
+       }
        cluster = SECTOR_SIZE*MSDOS_SB(inode->i_sb)->cluster_size;
        (void) fat_free(inode,(inode->i_size+(cluster-1))/cluster);
        MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
index cbc33634aa4eb3be93377aff77fc45294efe9995..f7679dba374dead68e8843b0bc93aaca31a07046 100644 (file)
@@ -81,6 +81,8 @@ struct file * get_empty_filp(void)
                memset(f, 0, sizeof(*f));
                f->f_count = 1;
                f->f_version = ++event;
+               f->f_uid = current->fsuid;
+               f->f_gid = current->fsgid;
                put_inuse(f);
                return f;
        }
@@ -119,6 +121,8 @@ int init_private_file(struct file *filp, struct dentry *dentry, int mode)
        filp->f_mode   = mode;
        filp->f_count  = 1;
        filp->f_dentry = dentry;
+       filp->f_uid    = current->fsuid;
+       filp->f_gid    = current->fsgid;
        filp->f_op     = dentry->d_inode->i_op->default_file_ops;
        if (filp->f_op->open)
                return filp->f_op->open(dentry->d_inode, filp);
index 2bbc005cee0e584972accc3c36e690334d99338f..4072221af2566aebb712822bc86d194942ee7371 100644 (file)
@@ -134,7 +134,7 @@ nlm_lookup_host(struct svc_client *clnt, struct sockaddr_in *sin,
        host->h_addr.sin_port = 0;      /* ouch! */
        host->h_version    = version;
        host->h_proto      = proto;
-       host->h_authflavor = RPC_AUTH_NULL;
+       host->h_authflavor = RPC_AUTH_UNIX;
        host->h_rpcclnt    = NULL;
        host->h_sema       = MUTEX;
        host->h_nextrebind = jiffies + NLM_HOST_REBIND;
index 0c3306d43a669320b6dd987bf6aa4c0a4b8e13a6..dcd54ee3fcfb0b9b37c5bf1bf4f5fc8ecfaa10c4 100644 (file)
@@ -52,8 +52,6 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result,
        struct nlm_file *file;
        unsigned int    hash;
        u32             nfserr;
-       uid_t           saved_cr_uid;
-       struct svc_cred *cred;
 
        dprintk("lockd: nlm_file_lookup(%s/%u)\n",
                kdevname(u32_to_kdev_t(fh->fh_dev)), fh->fh_ino);
@@ -86,15 +84,10 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result,
         * We have to make sure we have the right credential to open
         * the file.
         */
-       cred = &rqstp->rq_cred;
-       saved_cr_uid = cred->cr_uid;
-       cred->cr_uid = 0;
        if ((nfserr = nlmsvc_ops->fopen(rqstp, fh, &file->f_file)) != 0) {
                dprintk("lockd: open failed (nfserr %ld)\n", ntohl(nfserr));
-               cred->cr_uid = saved_cr_uid;
                goto out_free;
        }
-       cred->cr_uid = saved_cr_uid;
 
        file->f_next = nlm_files[hash];
        nlm_files[hash] = file;
index 25caa03d32abc8482f94a07952ab858f2ecb9a01..309dffdb5dccf8358c5966c45cf8ceb28bc59828 100644 (file)
@@ -97,7 +97,7 @@ nfs_file_close(struct inode *inode, struct file *file)
 
        status = nfs_wb_all(inode);
        if (!status)
-               status = nfs_write_error(inode);
+               status = file->f_error;
        return status;
 }
 
@@ -161,9 +161,11 @@ nfs_fsync(struct file *file, struct dentry *dentry)
 
        dfprintk(VFS, "nfs: fsync(%x/%ld)\n", inode->i_dev, inode->i_ino);
 
-       status = nfs_wb_pid(inode, current->pid);
-       if (!status)
-               status = nfs_write_error(inode);
+       status = nfs_wb_file(inode, file);
+       if (!status) {
+               status = file->f_error;
+               file->f_error = 0;
+       }
        return status;
 }
 
@@ -193,10 +195,7 @@ nfs_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
        if (!count)
                goto out;
 
-       /* Check for an error from a previous async call */
-       result = nfs_write_error(inode);
-       if (!result)
-               result = generic_file_write(file, buf, count, ppos);
+       result = generic_file_write(file, buf, count, ppos);
 out:
        return result;
 
index 72130244aee5cfb95ed3339a58866b924c87af82..579506ad4b9da2676ae7a1d2426fd1f2c041998f 100644 (file)
@@ -597,10 +597,8 @@ printk("nfs_notify_change: revalidate failed, error=%d\n", error);
                sattr.gid = attr->ia_gid;
 
        sattr.size = (u32) -1;
-       if ((attr->ia_valid & ATTR_SIZE) && S_ISREG(inode->i_mode)) {
+       if ((attr->ia_valid & ATTR_SIZE) && S_ISREG(inode->i_mode))
                sattr.size = attr->ia_size;
-               nfs_flush_trunc(inode, sattr.size);
-       }
 
        sattr.mtime.seconds = sattr.mtime.useconds = (u32) -1;
        if (attr->ia_valid & ATTR_MTIME) {
@@ -614,6 +612,10 @@ printk("nfs_notify_change: revalidate failed, error=%d\n", error);
                sattr.atime.useconds = 0;
        }
 
+       error = nfs_wb_all(inode);
+       if (error)
+               goto out;
+
        error = nfs_proc_setattr(NFS_DSERVER(dentry), NFS_FH(dentry),
                                &sattr, &fattr);
        if (error)
index 3b30a6a5a6d3d2688ea0055e751776d3e61f1398..276064c5e5026da6614e2e59a7085dd464e6e80c 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/malloc.h>
 #include <linux/swap.h>
 #include <linux/pagemap.h>
+#include <linux/file.h>
 
 #include <linux/sunrpc/clnt.h>
 #include <linux/nfs_fs.h>
@@ -237,17 +238,6 @@ update_write_request(struct nfs_wreq *req, unsigned int first,
        if (rqlast < first || last < rqfirst)
                return 0;
 
-       /* Check the credentials associated with this write request.
-        * If the buffer is owned by the same user, we can happily
-        * add our data without risking server permission problems.
-        * Note that I'm not messing around with RPC root override creds
-        * here, because they're used by swap requests only which
-        * always write out full pages. */
-       if (!rpcauth_matchcred(&req->wb_task, req->wb_task.tk_cred)) {
-               dprintk("NFS:      update failed (cred mismatch)\n");
-               return 0;
-       }
-
        if (first < rqfirst)
                rqfirst = first;
        if (rqlast < last)
@@ -271,9 +261,10 @@ free_write_request(struct nfs_wreq * req)
  * Create and initialize a writeback request
  */
 static inline struct nfs_wreq *
-create_write_request(struct dentry *dentry, struct inode *inode,
-               struct page *page, unsigned int offset, unsigned int bytes)
+create_write_request(struct file * file, struct page *page, unsigned int offset, unsigned int bytes)
 {
+       struct dentry   *dentry = file->f_dentry;
+       struct inode    *inode = dentry->d_inode;
        struct rpc_clnt *clnt = NFS_CLIENT(inode);
        struct nfs_wreq *wreq;
        struct rpc_task *task;
@@ -298,8 +289,7 @@ create_write_request(struct dentry *dentry, struct inode *inode,
                goto out_req;
 
        /* Put the task on inode's writeback request list. */
-       wreq->wb_dentry = dentry;
-       wreq->wb_inode  = inode;
+       wreq->wb_file = file;
        wreq->wb_pid    = current->pid;
        wreq->wb_page   = page;
        wreq->wb_offset = offset;
@@ -336,7 +326,9 @@ static inline int
 schedule_write_request(struct nfs_wreq *req, int sync)
 {
        struct rpc_task *task = &req->wb_task;
-       struct inode    *inode = req->wb_inode;
+       struct file     *file = req->wb_file;
+       struct dentry   *dentry = file->f_dentry;
+       struct inode    *inode = dentry->d_inode;
 
        if (NFS_CONGESTED(inode) || nr_write_requests >= NFS_WRITEBACK_MAX)
                sync = 1;
@@ -367,7 +359,10 @@ schedule_write_request(struct nfs_wreq *req, int sync)
 static int
 wait_on_write_request(struct nfs_wreq *req)
 {
-       struct rpc_clnt         *clnt = NFS_CLIENT(req->wb_inode);
+       struct file             *file = req->wb_file;
+       struct dentry           *dentry = file->f_dentry;
+       struct inode            *inode = dentry->d_inode;
+       struct rpc_clnt         *clnt = NFS_CLIENT(inode);
        struct wait_queue       wait = { current, NULL };
        sigset_t                oldmask;
        int retval;
@@ -435,7 +430,7 @@ nfs_updatepage(struct file *file, struct page *page, unsigned long offset, unsig
         * page and retry the update.
         */
        req = find_write_request(inode, page);
-       if (req && update_write_request(req, offset, count))
+       if (req && req->wb_file == file && update_write_request(req, offset, count))
                goto updated;
 
        /*
@@ -446,7 +441,7 @@ nfs_updatepage(struct file *file, struct page *page, unsigned long offset, unsig
                return nfs_writepage_sync(dentry, inode, page, offset, count);
 
        /* Create the write request. */
-       req = create_write_request(dentry, inode, page, offset, count);
+       req = create_write_request(file, page, offset, count);
        if (!req)
                return -ENOBUFS;
 
@@ -455,7 +450,7 @@ nfs_updatepage(struct file *file, struct page *page, unsigned long offset, unsig
         * The IO completion will then free the page and the dentry.
         */
        atomic_inc(&page->count);
-       dget(dentry);
+       file->f_count++;
 
        /* Schedule request */
        synchronous = schedule_write_request(req, sync);
@@ -571,24 +566,12 @@ nfs_wb_page(struct inode *inode, struct page *page)
 }
 
 /*
- * Write back all pending writes for one user.. 
+ * Write back all pending writes from one file descriptor..
  */
 int
-nfs_wb_pid(struct inode *inode, pid_t pid)
+nfs_wb_file(struct inode *inode, struct file *file)
 {
-       NFS_WB(inode, req->wb_pid == pid);
-}
-
-/*
- * Flush all write requests for truncation:
- *     Simplification of the comparison has the side-effect of
- *     causing all writes in an infested page to be waited upon.
- */
-int
-nfs_flush_trunc(struct inode *inode, unsigned long from)
-{
-       from &= PAGE_MASK;
-       NFS_WB(inode, req->wb_page->offset >= from);
+       NFS_WB(inode, req->wb_file == file);
 }
 
 void
@@ -597,16 +580,6 @@ nfs_inval(struct inode *inode)
        nfs_cancel_dirty(inode,0);
 }
 
-/*
- * Check if a previous write operation returned an error
- */
-int
-nfs_check_error(struct inode *inode)
-{
-       /* FIXME! */
-       return 0;
-}
-
 /*
  * The following procedures make up the writeback finite state machinery:
  *
@@ -618,7 +591,8 @@ nfs_wback_begin(struct rpc_task *task)
 {
        struct nfs_wreq *req = (struct nfs_wreq *) task->tk_calldata;
        struct page     *page = req->wb_page;
-       struct dentry   *dentry = req->wb_dentry;
+       struct file     *file = req->wb_file;
+       struct dentry   *dentry = file->f_dentry;
 
        dprintk("NFS: %4d nfs_wback_begin (%s/%s, status=%d flags=%x)\n",
                task->tk_pid, dentry->d_parent->d_name.name,
@@ -645,13 +619,15 @@ static void
 nfs_wback_result(struct rpc_task *task)
 {
        struct nfs_wreq *req = (struct nfs_wreq *) task->tk_calldata;
-       struct inode    *inode = req->wb_inode;
-       struct page     *page  = req->wb_page;
+       struct file     *file = req->wb_file;
+       struct page     *page = req->wb_page;
        int             status = task->tk_status;
+       struct dentry   *dentry = file->f_dentry;
+       struct inode    *inode = dentry->d_inode;
 
        dprintk("NFS: %4d nfs_wback_result (%s/%s, status=%d, flags=%x)\n",
-               task->tk_pid, req->wb_dentry->d_parent->d_name.name,
-               req->wb_dentry->d_name.name, status, req->wb_flags);
+               task->tk_pid, dentry->d_parent->d_name.name,
+               dentry->d_name.name, status, req->wb_flags);
 
        /* Set the WRITE_COMPLETE flag, but leave WRITE_INPROGRESS set */
        req->wb_flags |= NFS_WRITE_COMPLETE;
@@ -659,6 +635,7 @@ nfs_wback_result(struct rpc_task *task)
 
        if (status < 0) {
                req->wb_flags |= NFS_WRITE_INVALIDATE;
+               file->f_error = status;
        } else if (!WB_CANCELLED(req)) {
                struct nfs_fattr *fattr = &req->wb_fattr;
                /* Update attributes as result of writeback. 
@@ -696,22 +673,8 @@ nfs_wback_result(struct rpc_task *task)
        __free_page(page);
        remove_write_request(&NFS_WRITEBACK(inode), req);
        nr_write_requests--;
-       dput(req->wb_dentry);
+       fput(req->wb_file);
 
        wake_up(&req->wb_wait);
-       
-       /*
-        * FIXME!
-        *
-        * We should not free the request here if it has pending
-        * error status on it. We should just leave it around, to
-        * let the error be collected later. However, the error
-        * collecting routines are too stupid for that right now,
-        * so we just drop the error on the floor at this point
-        * for any async writes.
-        *
-        * This should not be a major headache to fix, but I want
-        * to validate basic operations first.
-        */
        free_write_request(req);
 }
index d832bd99c45b24f88673d6df58c47ffd0b6f566d..14943c52e0610d3df8b2c6ddb1caaca1764e8f0d 100644 (file)
@@ -506,10 +506,10 @@ static int vfat_find_form(struct inode *dir,char *name)
                        continue;
                if (memcmp(de->name,name,MSDOS_NAME))
                        continue;
-               brelse(bh);
+               fat_brelse(dir->i_sb,bh);
                return 0;
        }
-       brelse(bh);
+       fat_brelse(dir->i_sb,bh);
        return -ENOENT;
 }
 
@@ -1659,6 +1659,9 @@ int vfat_rename(struct inode *old_dir,struct dentry *old_dentry,
                res = vfat_remove_entry(new_dir,&sinfo,new_inode);
                if (res)
                        goto rename_done;
+
+               if (is_dir)
+                       new_dir->i_nlink--;
        }
 
        /* Serious lossage here. FAT uses braindead inode numbers scheme,
@@ -1670,9 +1673,6 @@ int vfat_rename(struct inode *old_dir,struct dentry *old_dentry,
         * 'busy' stuff on the spot. Later.
         */
 
-       if (is_dir)
-               new_dir->i_nlink--;
-
        res = vfat_find(new_dir,&new_dentry->d_name,1,is_dir,&sinfo);
 
        if (res < 0) goto rename_done;
diff --git a/include/asm-alpha/semaphore-helper.h b/include/asm-alpha/semaphore-helper.h
new file mode 100644 (file)
index 0000000..89c4afa
--- /dev/null
@@ -0,0 +1,122 @@
+#ifndef _ALPHA_SEMAPHORE_HELPER_H
+#define _ALPHA_SEMAPHORE_HELPER_H
+
+/*
+ * SMP- and interrupt-safe semaphores helper functions.
+ *
+ * (C) Copyright 1996 Linus Torvalds
+ * (C) Copyright 1999 Richard Henderson
+ */
+
+/*
+ * These two _must_ execute atomically wrt each other.
+ *
+ * This is trivially done with load_locked/store_cond,
+ * which we have.  Let the rest of the losers suck eggs.
+ */
+
+static inline void
+wake_one_more(struct semaphore * sem)
+{
+       atomic_inc(&sem->waking);
+}
+
+static inline int
+waking_non_zero(struct semaphore *sem)
+{
+       long ret, tmp;
+
+       /* An atomic conditional decrement.  */
+       __asm__ __volatile__(
+               "1:     ldl_l   %1,%2\n"
+               "       blt     %1,2f\n"
+               "       subl    %1,1,%0\n"
+               "       stl_c   %0,%2\n"
+               "       beq     %0,3f\n"
+               "2:\n"
+               ".section .text2,\"ax\"\n"
+               "3:     br      1b\n"
+               ".previous"
+               : "=r"(ret), "=r"(tmp), "=m"(__atomic_fool_gcc(&sem->waking))
+               : "0"(0));
+
+       return ret > 0;
+}
+
+
+/*
+ * waking_non_zero_interruptible:
+ *     1       got the lock
+ *     0       go to sleep
+ *     -EINTR  interrupted
+ *
+ * We must undo the sem->count down_interruptible increment
+ * simultaneously and atomicly with the sem->waking adjustment,
+ * otherwise we can race with wake_one_more.
+ *
+ * This is accomplished by doing a 64-bit ll/sc on the 2 32-bit words.
+ */
+
+static inline int
+waking_non_zero_interruptible(struct semaphore *sem, struct task_struct *tsk)
+{
+       long ret, tmp, tmp2, tmp3;
+
+       /* "Equivalent" C.  Note that we have to do this all without
+          (taken) branches in order to be a valid ll/sc sequence.
+
+          do {
+              tmp = ldq_l;
+              ret = 0;
+              if (tmp >= 0) {
+                  tmp += 0xffffffff00000000;
+                  ret = 1;
+              }
+              else if (pending) {
+                  tmp += 1;
+                  ret = -EINTR;
+              }
+              else {
+                  break;       // ideally.  we don't actually break 
+                               // since this is a predicate we don't
+                               // have, and is more trouble to build
+                               // than to elide the noop stq_c.
+              }
+              tmp = stq_c = tmp;
+          } while (tmp == 0);
+       */
+
+       __asm__ __volatile__(
+               "1:     ldq_l   %1,%4\n"
+               "       lda     %0,0\n"
+               "       addq    %1,1,%2\n"
+               "       ldah    %3,0x8000(%1)\n"
+               "       cmovne  %5,%6,%0\n"
+               "       ldah    %3,0x8000(%3)\n"
+               "       cmovge  %1,1,%0\n"
+               "       cmovne  %5,%2,%1\n"
+               "       cmovge  %2,%3,%1\n"
+               "       stq_c   %1,%4\n"
+               "       beq     %1,3f\n"
+               "2:\n"
+               ".section .text2,\"ax\"\n"
+               "3:     br      1b\n"
+               ".previous"
+               : "=&r"(ret), "=&r"(tmp), "=&r"(tmp2), "=&r"(tmp3), "=m"(*sem)
+               : "r"(signal_pending(tsk)), "r"(-EINTR));
+
+       return ret;
+}
+
+/*
+ * waking_non_zero_trylock is unused.  we do everything in 
+ * down_trylock and let non-ll/sc hosts bounce around.
+ */
+
+static inline int
+waking_non_zero_trylock(struct semaphore *sem)
+{
+       return 0;
+}
+
+#endif
index a172211c1862a2382bb779880ad79ae1a86396f7..1cb6aad468911a51a26e595b99a1a2813dbfc85f 100644 (file)
  * SMP- and interrupt-safe semaphores..
  *
  * (C) Copyright 1996 Linus Torvalds
+ * (C) Copyright 1996 Richard Henderson
  */
 
 #include <asm/current.h>
 #include <asm/system.h>
 #include <asm/atomic.h>
 
-/*
- * Semaphores are recursive: we allow the holder process to recursively do
- * down() operations on a semaphore that the process already owns. In order
- * to do that, we need to keep a semaphore-local copy of the owner and the
- * "depth of ownership".
- *
- * NOTE! Nasty memory ordering rules:
- *  - "owner" and "owner_count" may only be modified once you hold the lock.
- *  - "owner_count" must be written _after_ modifying owner, and must be
- *  read _before_ reading owner. There must be appropriate write and read
- *  barriers to enforce this.
- */
-
 struct semaphore {
+       /* Careful, inline assembly knows about the position of these two.  */
        atomic_t count;
-       atomic_t waking;
-       struct task_struct *owner;
-       long owner_depth;
-       struct wait_queue * wait;
+       atomic_t waking;                /* biased by -1 */
+       struct wait_queue *wait;
 };
 
 #define MUTEX ((struct semaphore) \
- { ATOMIC_INIT(1), ATOMIC_INIT(0), NULL, 0, NULL })
+ { ATOMIC_INIT(1), ATOMIC_INIT(-1), NULL })
 #define MUTEX_LOCKED ((struct semaphore) \
- { ATOMIC_INIT(0), ATOMIC_INIT(0), NULL, 1, NULL })
+ { ATOMIC_INIT(0), ATOMIC_INIT(-1), NULL })
 
-#define semaphore_owner(sem)   ((sem)->owner)
 #define sema_init(sem, val)    atomic_set(&((sem)->count), val)
 
 extern void __down(struct semaphore * sem);
 extern int  __down_interruptible(struct semaphore * sem);
+extern int  __down_trylock(struct semaphore * sem);
 extern void __up(struct semaphore * sem);
 
-/* All three have custom assembly linkages.  */
+/* All have custom assembly linkages.  */
 extern void __down_failed(struct semaphore * sem);
 extern void __down_failed_interruptible(struct semaphore * sem);
+extern void __down_failed_trylock(struct semaphore * sem);
 extern void __up_wakeup(struct semaphore * sem);
 
-
-/*
- * These two _must_ execute atomically wrt each other.
- *
- * This is trivially done with load_locked/store_cond,
- * which we have.  Let the rest of the losers suck eggs.
- *
- * Tricky bits --
- *
- * (1) One task does two downs, no other contention
- *     initial state:
- *             count = 1, waking = 0, depth = undef;
- *     down(&sem)
- *             count = 0, waking = 0, depth = 1;
- *     down(&sem)
- *             atomic dec and test sends us to waking_non_zero via __down
- *                     count = -1, waking = 0;
- *             conditional atomic dec on waking discovers no free slots
- *                     count = -1, waking = 0;
- *             test for owner succeeeds and we return ok.
- *                     count = -1, waking = 0, depth = 2;
- *     up(&sem)
- *             dec depth
- *                     count = -1, waking = 0, depth = 1;
- *             atomic inc and test sends us to slow path
- *                     count = 0, waking = 0, depth = 1;
- *             notice !(depth < 0) and don't call __up.
- *     up(&sem)
- *             dec depth
- *                     count = 0, waking = 0, depth = 0;
- *             atomic inc and test succeeds.
- *                     count = 1, waking = 0, depth = 0;
- */
-
-static inline void wake_one_more(struct semaphore * sem)
-{
-       atomic_inc(&sem->waking);
-}
-
-static inline int waking_non_zero(struct semaphore *sem,
-                                 struct task_struct *tsk)
-{
-       long owner_depth;
-       int ret, tmp;
-
-       owner_depth = sem->owner_depth;
-       
-       /* Atomic decrement, iff the value is > 0.  */
-       __asm__ __volatile__(
-       "1:     ldl_l   %1,%2\n"
-       "       ble     %1,2f\n"
-       "       subl    %1,1,%0\n"
-       "       stl_c   %0,%2\n"
-       "       beq     %0,3f\n"
-       "2:     mb\n"
-       ".section .text2,\"ax\"\n"
-       "3:     br      1b\n"
-       ".previous"
-       : "=r"(ret), "=r"(tmp), "=m"(__atomic_fool_gcc(&sem->waking))
-       : "0"(0));
-
-       ret |= ((owner_depth != 0) & (sem->owner == tsk));
-       if (ret) {
-               sem->owner = tsk;
-               wmb();
-               /* Don't use the old value, which is stale in the
-                  !owner case.  */
-               sem->owner_depth++;
-       }
-
-       return ret;
-}
-
 /*
  * Whee.  Hidden out of line code is fun.  The contention cases are
  * handled out of line in kernel/sched.c; arch/alpha/lib/semaphore.S
@@ -140,27 +55,21 @@ extern inline void down(struct semaphore * sem)
 
        __asm__ __volatile__ (
                "/* semaphore down operation */\n"
-               "1:     ldl_l   $27,%3\n"
+               "1:     ldl_l   $27,%0\n"
                "       subl    $27,1,$27\n"
                "       mov     $27,$28\n"
                "       stl_c   $28,%0\n"
                "       beq     $28,2f\n"
                "       blt     $27,3f\n"
-               /* Got the semaphore no contention.  Set owner and depth.  */
-               "       stq     $8,%1\n"
-               "       lda     $28,1\n"
-               "       wmb\n"
-               "       stq     $28,%2\n"
                "4:     mb\n"
                ".section .text2,\"ax\"\n"
                "2:     br      1b\n"
-               "3:     lda     $24,%3\n"
+               "3:     lda     $24,%0\n"
                "       jsr     $28,__down_failed\n"
                "       ldgp    $29,0($28)\n"
                "       br      4b\n"
                ".previous"
-               : "=m"(sem->count), "=m"(sem->owner), "=m"(sem->owner_depth)
-               : "m"(sem->count)
+               : : "m"(sem->count)
                : "$24", "$27", "$28", "memory");
 }
 
@@ -175,34 +84,79 @@ extern inline int down_interruptible(struct semaphore * sem)
 
        __asm__ __volatile__ (
                "/* semaphore down interruptible operation */\n"
-               "1:     ldl_l   $27,%4\n"
+               "1:     ldl_l   $27,%1\n"
                "       subl    $27,1,$27\n"
                "       mov     $27,$28\n"
                "       stl_c   $28,%1\n"
                "       beq     $28,2f\n"
                "       blt     $27,3f\n"
-               /* Got the semaphore no contention.  Set owner and depth.  */
-               "       stq     $8,%2\n"
-               "       lda     $28,1\n"
-               "       wmb\n"
-               "       stq     $28,%3\n"
-               "       mov     $31,$24\n"
+               "       mov     $31,%0\n"
                "4:     mb\n"
                ".section .text2,\"ax\"\n"
                "2:     br      1b\n"
-               "3:     lda     $24,%4\n"
+               "3:     lda     $24,%1\n"
                "       jsr     $28,__down_failed_interruptible\n"
                "       ldgp    $29,0($28)\n"
                "       br      4b\n"
                ".previous"
-               : "=r"(ret), "=m"(sem->count), "=m"(sem->owner),
-                 "=m"(sem->owner_depth)
+               : "=r"(ret)
                : "m"(sem->count)
                : "$27", "$28", "memory");
 
        return ret;
 }
 
+/*
+ * down_trylock returns 0 on success, 1 if we failed to get the lock.
+ *
+ * We must manipulate count and waking simultaneously and atomically.
+ * Do this by using ll/sc on the pair of 32-bit words.
+ */
+
+extern inline int down_trylock(struct semaphore * sem)
+{
+       long ret, tmp, tmp2;
+
+       /* "Equivalent" C.  Note that we have to do this all without
+          (taken) branches in order to be a valid ll/sc sequence.
+
+          do {
+              tmp = ldq_l;
+              ret = 0;
+              tmp -= 1;
+              if ((int)tmp < 0)                // count
+                  break;
+              if ((long)tmp < 0)               // waking
+                  break;
+              tmp += 0xffffffff00000000;
+              ret = 1;
+              tmp = stq_c = tmp;
+          } while (tmp == 0);
+       */
+
+       __asm__ __volatile__(
+               "1:     ldq_l   %1,%3\n"
+               "       lda     %0,0\n"
+               "       subl    %1,1,%2\n"
+               "       subq    %1,1,%1\n"
+               "       blt     %2,2f\n"
+               "       blt     %1,2f\n"
+               "       ldah    %1,0x8000(%1)\n"
+               "       ldah    %1,0x8000(%1)\n"
+               "       lda     %0,1\n"
+               "       stq_c   %1,%3\n"
+               "       beq     %1,3f\n"
+               "2:     mb\n"
+               ".section .text2,\"ax\"\n"
+               "3:     br      1b\n"
+               ".previous"
+               : "=&r"(ret), "=&r"(tmp), "=&r"(tmp2)
+               : "m"(*sem)
+               : "memory");
+
+       return ret;
+}
+
 extern inline void up(struct semaphore * sem)
 {
        /* Given that we have to use particular hard registers to 
@@ -216,7 +170,7 @@ extern inline void up(struct semaphore * sem)
        __asm__ __volatile__ (
                "/* semaphore up operation */\n"
                "       mb\n"
-               "1:     ldl_l   $27,%1\n"
+               "1:     ldl_l   $27,%0\n"
                "       addl    $27,1,$27\n"
                "       mov     $27,$28\n"
                "       stl_c   $28,%0\n"
@@ -226,14 +180,12 @@ extern inline void up(struct semaphore * sem)
                "4:\n"
                ".section .text2,\"ax\"\n"
                "2:     br      1b\n"
-               "3:     lda     $24,%1\n"
-               "       bgt     %2,4b\n"
+               "3:     lda     $24,%0\n"
                "       jsr     $28,__up_wakeup\n"
                "       ldgp    $29,0($28)\n"
                "       br      4b\n"
                ".previous"
-               : "=m"(sem->count)
-               : "m"(sem->count), "r"(--sem->owner_depth)
+               : : "m"(sem->count)
                : "$24", "$27", "$28", "memory");
 }
 
index 733fe41c719961e6a0e78f7b187a2e5f0d061b43..7e66f50d3664017da7e9f4b343e9b61793103030 100644 (file)
@@ -21,7 +21,7 @@ extern inline void scr_writew(u16 val, u16 *addr)
                writew(val, (unsigned long) addr);
 }
 
-extern inline u16 scr_readw(u16 *addr)
+extern inline u16 scr_readw(const u16 *addr)
 {
        if ((long) addr < 0)
                return *addr;
@@ -37,12 +37,12 @@ extern inline void scr_memsetw(u16 *s, u16 c, unsigned int count)
                memsetw_io(s, c, count);
 }
 
-extern inline void scr_memcpyw_from(u16 *d, u16 *s, unsigned int count)
+extern inline void scr_memcpyw_from(u16 *d, const u16 *s, unsigned int count)
 {
        memcpy_fromio(d, s, count);
 }
 
-extern inline void scr_memcpyw_to(u16 *d, u16 *s, unsigned int count)
+extern inline void scr_memcpyw_to(u16 *d, const u16 *s, unsigned int count)
 {
        memcpy_toio(d, s, count);
 }
index 5fc680563727130b178384b0cef9d1224c63de6d..1ead6fab7150c10da88b7c111d71e74362b31a34 100644 (file)
@@ -19,7 +19,7 @@ extern inline void scr_writew(u16 val, u16 *addr)
                writew(val, (unsigned long) addr);
 }
 
-extern inline u16 scr_readw(u16 *addr)
+extern inline u16 scr_readw(const u16 *addr)
 {
        if ((long) addr < 0)
                return *addr;
index 1ab739772e6b52ec15af6e7802e3d670a25257cf..3ccc0e92c99cb3f2a33bc3be9e3fae2cf6c33ff5 100644 (file)
@@ -16,7 +16,7 @@ extern inline void scr_writew(u16 val, u16 *addr)
        st_le16(addr, val);
 }
 
-extern inline u16 scr_readw(u16 *addr)
+extern inline u16 scr_readw(const u16 *addr)
 {
        return ld_le16(addr);
 }
index 14ae757a427150874493fb8f110e7544f8bf713e..b637522eb768d5200b7e50e3c1de7a8d0c085a62 100644 (file)
@@ -17,7 +17,7 @@ static inline void scr_writew(u16 val, u16 *addr)
                writew(val, (unsigned long) addr);
 }
 
-static inline u16 scr_readw(u16 *addr)
+static inline u16 scr_readw(const u16 *addr)
 {
        if ((long) addr < 0)
                return *addr;
index 6a197b19ab86c0efee0b98c66ec2d1ceffad8c21..ee0272dff2fe0b65a1ad9c98a695e0e76ef89468 100644 (file)
@@ -42,6 +42,8 @@ struct consw {
        void    (*con_save_screen)(struct vc_data *);
        u8      (*con_build_attr)(struct vc_data *, u8, u8, u8, u8, u8);
        void    (*con_invert_region)(struct vc_data *, u16 *, int);
+       u16    *(*con_screen_pos)(struct vc_data *, int);
+       unsigned long (*con_getxy)(struct vc_data *, unsigned long, int *, int *);
 };
 
 extern struct consw *conswitchp;
index f4c775db405f231f192da67ab9e573c318bfa7ea..5cbc66b3dd9f3f3c64374235fe0ba4f580f1b352 100644 (file)
 #define FB_ACCEL_MATROX_MGA2164W_AGP 19        /* Matrox MGA2164W (Millenium II) */
 #define FB_ACCEL_MATROX_MGAG100        20      /* Matrox G100 (Productiva G100) */
 #define FB_ACCEL_MATROX_MGAG200        21      /* Matrox G200 (Myst, Mill, ...) */
+#define FB_ACCEL_SUN_CG14      22      /* Sun cgfourteen                */
+#define FB_ACCEL_SUN_BWTWO     23      /* Sun bwtwo                     */
+#define FB_ACCEL_SUN_CGTHREE   24      /* Sun cgthree                   */
+#define FB_ACCEL_SUN_TCX       25      /* Sun tcx                       */
 
 struct fb_fix_screeninfo {
        char id[16];                    /* identification string eg "TT Builtin" */
@@ -340,8 +344,8 @@ struct fbgen_hwswitch {
     int (*pan_display)(const struct fb_var_screeninfo *var,
                       struct fb_info_gen *info);
     int (*blank)(int blank_mode, struct fb_info_gen *info);
-    void (*set_dispsw)(const void *par, struct display *disp,
-                      struct fb_info_gen *info);
+    void (*set_disp)(const void *par, struct display *disp,
+                    struct fb_info_gen *info);
 };
 
 struct fb_info_gen {
index dcf33554e15a75373b18219038eeb272dfcae5e9..4c016a90995b3364c68cdb8db93f091fd9dd1f90 100644 (file)
  
 struct sock_filter     /* Filter block */
 {
-        u16    code;   /* Actual filter code */
-        u8     jt;     /* Jump true */
-        u8     jf;     /* Jump false */
-        u32    k;      /* Generic multiuse field */
+        __u16  code;   /* Actual filter code */
+        __u8   jt;     /* Jump true */
+        __u8   jf;     /* Jump false */
+        __u32  k;      /* Generic multiuse field */
 };
 
 struct sock_fprog      /* Required for SO_ATTACH_FILTER. */
 {
-        unsigned short         len;    /* Number of filter blocks */
+        unsigned int           len;    /* Number of filter blocks */
         struct sock_filter     *filter;
 };
 
+#ifdef __KERNEL__
+struct sk_filter
+{
+       atomic_t                refcnt;
+        unsigned int           len;    /* Number of filter blocks */
+        struct sock_filter             insns[0];
+};
+
+extern __inline__ unsigned int sk_filter_len(struct sk_filter *fp)
+{
+       return fp->len*sizeof(struct sock_filter) + sizeof(*fp);
+}
+#endif
+
 /*
  * Instruction classes
  */
@@ -86,21 +100,40 @@ struct sock_fprog  /* Required for SO_ATTACH_FILTER. */
 #define         BPF_TAX         0x00
 #define         BPF_TXA         0x80
 
-#define BPF_MAXINSNS 512
+#ifndef BPF_MAXINSNS
+#define BPF_MAXINSNS 4096
+#endif
 
 /*
  * Macros for filter block array initializers.
  */
+#ifndef BPF_STMT
 #define BPF_STMT(code, k) { (unsigned short)(code), 0, 0, k }
+#endif
+#ifndef BPF_JUMP
 #define BPF_JUMP(code, k, jt, jf) { (unsigned short)(code), jt, jf, k }
+#endif
 
 /*
  * Number of scratch memory words for: BPF_ST and BPF_STX
  */
 #define BPF_MEMWORDS 16
 
+/* RATIONALE. Negative offsets are invalid in BPF.
+   We use them to reference ancillary data.
+   Unlike introduction new instructions, it does not break
+   existing compilers/optimizers.
+ */
+#define SKF_AD_OFF    (-0x1000)
+#define SKF_AD_PROTOCOL 0
+#define SKF_AD_PKTTYPE         4
+#define SKF_AD_IFINDEX         8
+#define SKF_AD_MAX     12
+#define SKF_NET_OFF   (-0x100000)
+#define SKF_LL_OFF    (-0x200000)
+
 #ifdef __KERNEL__
-extern int sk_run_filter(unsigned char *data, int len, struct sock_filter *filter, int flen);
+extern int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen);
 extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk);
 #endif /* __KERNEL__ */
 
index 1caeb606b2100d0af2913500edd93c998a0b2036..62987be7e4d7ec973c17c81a95f157e781c737ea 100644 (file)
@@ -373,6 +373,7 @@ struct inode {
 
        int                     i_writecount;
        unsigned int            i_attr_flags;
+       __u32                   i_generation;
        union {
                struct pipe_inode_info          pipe_i;
                struct minix_inode_info         minix_i;
@@ -424,6 +425,8 @@ struct file {
        unsigned int            f_count, f_flags;
        unsigned long           f_reada, f_ramax, f_raend, f_ralen, f_rawin;
        struct fown_struct      f_owner;
+       unsigned int            f_uid, f_gid;
+       int                     f_error;
 
        unsigned long           f_version;
 
index 57ffd730ae2a004e0336fe65e7e7752b7ddc8c45..8a3cbce1b9e02f8e03109305b8325f77e1f9541e 100644 (file)
@@ -23,7 +23,7 @@ struct shaper
        __u32 shapeclock;
        __u32 recovery;         /* Time we can next clock a packet out on
                                   an empty queue */
-       char locked;
+       unsigned long locked;
        struct device *dev;
        int  (*hard_start_xmit) (struct sk_buff *skb,
                struct device *dev);
index afd52c619ef04b6d80979b413c8ae1b8701bda65..64aa54eaeb348465b3c552a7c598f28596e52697 100644 (file)
@@ -98,8 +98,7 @@ do { \
 struct nfs_wreq {
        struct rpc_listitem     wb_list;        /* linked list of req's */
        struct rpc_task         wb_task;        /* RPC task */
-       struct dentry *         wb_dentry;      /* dentry referenced */
-       struct inode *          wb_inode;       /* inode referenced */
+       struct file *           wb_file;        /* dentry referenced */
        struct page *           wb_page;        /* page to be written */
        struct wait_queue *     wb_wait;        /* wait for completion */
        unsigned int            wb_offset;      /* offset within page */
@@ -213,7 +212,6 @@ extern int nfs_lock(struct file *, int, struct file_lock *);
  */
 extern int  nfs_writepage(struct file *, struct page *);
 extern int  nfs_check_failed_request(struct inode *);
-extern int  nfs_check_error(struct inode *);
 
 /*
  * Try to write back everything synchronously (but check the
@@ -221,8 +219,7 @@ extern int  nfs_check_error(struct inode *);
  */
 extern int  nfs_wb_all(struct inode *);
 extern int  nfs_wb_page(struct inode *, struct page *);
-extern int  nfs_wb_pid(struct inode *, pid_t);
-extern int  nfs_flush_trunc(struct inode *, unsigned long);
+extern int  nfs_wb_file(struct inode *, struct file *);
 
 /*
  * Invalidate write-backs, possibly trying to write them
@@ -254,12 +251,6 @@ nfs_revalidate_inode(struct nfs_server *server, struct dentry *dentry)
        return _nfs_revalidate_inode(server, dentry);
 }
 
-static inline int
-nfs_write_error(struct inode *inode)
-{
-       return NFS_WRITEBACK(inode) && nfs_check_error(inode);
-}
-
 /* NFS root */
 
 extern int nfs_root_mount(struct super_block *sb);
index b1c2d61ed632e69edd4ecbcd2f0188b7994ebdb9..8abb05d4fcbbed7ddea913afd652a35ba722eb8f 100644 (file)
@@ -184,6 +184,7 @@ enum scsi_directory_inos {
        PROC_SCSI_AM53C974,
        PROC_SCSI_SSC,
        PROC_SCSI_NCR53C406A,
+       PROC_SCSI_SYM53C416,
        PROC_SCSI_MEGARAID,
        PROC_SCSI_PPA,
        PROC_SCSI_ATP870U,
@@ -202,6 +203,7 @@ enum scsi_directory_inos {
        PROC_SCSI_53C94,
        PROC_SCSI_PLUTO,
        PROC_SCSI_INI9100U,
+       PROC_SCSI_INIA100,
        PROC_SCSI_SCSI_DEBUG,   
        PROC_SCSI_NOT_PRESENT,
        PROC_SCSI_FILE,                        /* I'm assuming here that we */
index 45e4712b41a3817d017d21dcfe2cd6591a9d60c2..74d1b24d6292c08b7b2f472baabb43d9bc422701 100644 (file)
@@ -38,7 +38,7 @@ extern void invert_screen(int currcons, int offset, int count, int shift);
 extern void getconsxy(int currcons, char *p);
 extern void putconsxy(int currcons, char *p);
 
-extern u16 vcs_scr_readw(int currcons, u16 *org);
+extern u16 vcs_scr_readw(int currcons, const u16 *org);
 extern void vcs_scr_writew(int currcons, u16 val, u16 *org);
 
 #endif
index df0ee6ef1928eaac05230951d4b8811fb20424b3..ca1ec519db7d801634c5ea3e72e08199c99ad7fe 100644 (file)
@@ -41,7 +41,7 @@ extern inline void scr_memsetw(u16 *s, u16 c, unsigned int count)
 #endif
 
 #ifndef VT_BUF_HAVE_MEMCPYW
-extern inline void scr_memcpyw(u16 *d, u16 *s, unsigned int count)
+extern inline void scr_memcpyw(u16 *d, const u16 *s, unsigned int count)
 {
        count /= 2;
        while (count--)
@@ -50,7 +50,7 @@ extern inline void scr_memcpyw(u16 *d, u16 *s, unsigned int count)
 #endif
 
 #ifndef VT_BUF_HAVE_MEMMOVEW
-extern inline void scr_memmovew(u16 *d, u16 *s, unsigned int count)
+extern inline void scr_memmovew(u16 *d, const u16 *s, unsigned int count)
 {
        if (d < s)
                scr_memcpyw(d, s, count);
@@ -65,14 +65,14 @@ extern inline void scr_memmovew(u16 *d, u16 *s, unsigned int count)
 #endif
 
 #ifndef VT_BUF_HAVE_MEMCPYF
-extern inline void scr_memcpyw_from(u16 *d, u16 *s, unsigned int count)
+extern inline void scr_memcpyw_from(u16 *d, const u16 *s, unsigned int count)
 {
        count /= 2;
        while (count--)
                *d++ = scr_readw(s++);
 }
 
-extern inline void scr_memcpyw_to(u16 *d, u16 *s, unsigned int count)
+extern inline void scr_memcpyw_to(u16 *d, const u16 *s, unsigned int count)
 {
        count /= 2;
        while (count--)
index d2b68111f5573003d314c74fbe4165820a5e3c4b..9ec9ca7194c1069fdc6dac877213d4756a3393b7 100644 (file)
@@ -301,7 +301,7 @@ typedef __u32 zorro_id;
 #define  ZORRO_PROD_BSC_MULTIFACE_I                            ZORRO_ID(BSC_ALFADATA_3, 0x10, 0)
 #define  ZORRO_PROD_BSC_MULTIFACE_II                           ZORRO_ID(BSC_ALFADATA_3, 0x11, 0)
 #define  ZORRO_PROD_BSC_MULTIFACE_III                          ZORRO_ID(BSC_ALFADATA_3, 0x12, 0)
-#define  ZORRO_PROD_BSC_FRAMEBUFFER                            ZORRO_ID(BSC_ALFADATA_3, 0x20, 0)
+#define  ZORRO_PROD_BSC_FRAMEMASTER_II                         ZORRO_ID(BSC_ALFADATA_3, 0x20, 0)
 #define  ZORRO_PROD_BSC_GRAFFITI_RAM                           ZORRO_ID(BSC_ALFADATA_3, 0x21, 0)
 #define  ZORRO_PROD_BSC_GRAFFITI_REG                           ZORRO_ID(BSC_ALFADATA_3, 0x22, 0)
 #define  ZORRO_PROD_BSC_ISDN_MASTERCARD                                ZORRO_ID(BSC_ALFADATA_3, 0x40, 0)
index 837abf2b0369a4e5257d9b7f946f6317dfa6647e..e46f2bc2045f85a44336f06addc0c319e5ef20e8 100644 (file)
@@ -99,8 +99,7 @@ struct unix_opt {
        struct semaphore        readsem;
        struct sock *           other;
        struct sock **          list;
-       int                     marksweep;
-#define MARKED                 1
+       struct sock *           gc_tree;
        int                     inflight;
 };
 
index 4fe4eb7eb9ec2b3c7a4c1d7d0ac590d5e4722b4a..812a2ff9bc0ed2f7692b5049e1ae63925b265fac 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/config.h>
 #include <linux/console_struct.h>
+#include <linux/vt_buffer.h>
 
 
     /*                                  
index 2a6d91215ab266aa2adbaf50520db58d0f12cd38..2511cbd5f316346a32f0609e3d2f3c0546139626 100644 (file)
@@ -15,8 +15,12 @@ struct bt_regs {
 struct fb_info_creator {
        struct ffb_fbc *fbc;
        struct ffb_dac *dac;
-       int dac_rev;
        int xy_margin;
+       int fifo_cache;
+       u64 yx_margin;
+       int fg_cache;
+       int bg_cache;
+       int dac_rev;
 };
 struct fb_info_cgsix {
        struct bt_regs *bt;
index 9b37f328ecc1fbb917e0a4f947ca380648403b86..e046c4635c16ee68392e243ac304ca26d3f108ab 100644 (file)
@@ -185,6 +185,7 @@ extern void fdomain_setup(char *str, int *ints);
 extern void ibmmca_scsi_setup(char *str, int *ints);
 extern void in2000_setup(char *str, int *ints);
 extern void NCR53c406a_setup(char *str, int *ints);
+extern void sym53c416_setup(char *str, int *ints);
 extern void wd7000_setup(char *str, int *ints);
 extern void dc390_setup(char* str, int *ints);
 extern void scsi_luns_setup(char *str, int *ints);
@@ -689,6 +690,9 @@ static struct kernel_param cooked_params[] __initdata = {
 #ifdef CONFIG_SCSI_NCR53C406A
        { "ncr53c406a=", NCR53c406a_setup},
 #endif
+#ifdef CONFIG_SCSI_SYM53C416
+       { "sym53c416=", sym53c416_setup},
+#endif
 #ifdef CONFIG_SCSI_FUTURE_DOMAIN
        { "fdomain=", fdomain_setup},
 #endif
@@ -961,7 +965,7 @@ void __init calibrate_delay(void)
                ticks = jiffies - ticks;
                if (ticks)
                        break;
-               }
+       }
 
 /* Do a binary approximation to get loops_per_second set to equal one clock
    (up to lps_precision bits) */
index 5c714fe73d1795b8b296c6b065723ef99a07f1cc..3c61d950a59488476f91e15318fb3c3050568b89 100644 (file)
@@ -172,8 +172,8 @@ inside:
                                        if(last_pid & 0xffff8000)
                                                last_pid = 300;
                                        next_safe = PID_MAX;
-                                       goto repeat;
                                }
+                               goto repeat;
                        }
                        if(p->pid > last_pid && next_safe > p->pid)
                                next_safe = p->pid;
index 71bfcf8a960343928d6d63372d1a15db1fd024d9..7bdb5d57a8e1540d45918630e6e4f92951ee2ede 100644 (file)
@@ -1456,6 +1456,12 @@ generic_file_write(struct file *file, const char *buf,
        if (!inode->i_op || !inode->i_op->updatepage)
                return -EIO;
 
+       if (file->f_error) {
+               int error = file->f_error;
+               file->f_error = 0;
+               return error;
+       }
+
        sync    = file->f_flags & O_SYNC;
        written = 0;
 
index ae9abe2e5c61cb44421214d7f481ddcc6db008a9..ed8510209a731bed5dc40a3e3cc406f306517edb 100644 (file)
@@ -10,7 +10,6 @@ if [ "$CONFIG_NETLINK" = "y" ]; then
   tristate 'Netlink device emulation' CONFIG_NETLINK_DEV
 fi
 bool 'Network firewalls' CONFIG_FIREWALL
-bool 'Network aliasing'  CONFIG_NET_ALIAS
 bool 'Socket Filtering'  CONFIG_FILTER
 tristate 'Unix domain sockets' CONFIG_UNIX
 bool 'TCP/IP networking' CONFIG_INET
index 204b00ca08e606e3e2c6bef34191f38037b8161f..9a18af09a96a4536ebde8fbc9bce8f4c2f142416 100644 (file)
@@ -1238,6 +1238,12 @@ static int send_config_bpdu(int port_no, Config_bpdu *config_bpdu)
 {
        struct sk_buff *skb;
        
+       /*
+        *      Keep silent when disabled
+        */
+        
+       if(!(br_stats.flags & BR_UP))
+               return -1;
        /*
         *      Create and send the message
         */
@@ -1270,6 +1276,14 @@ static int send_config_bpdu(int port_no, Config_bpdu *config_bpdu)
 static int send_tcn_bpdu(int port_no, Tcn_bpdu *bpdu)
 {
        struct sk_buff *skb;
+       
+       /*
+        *      Keep silent when disabled
+        */
+        
+       if(!(br_stats.flags & BR_UP))
+               return -1;
+       
        
        skb = alloc_bridge_skb(port_no, sizeof(Tcn_bpdu), "tcn");
        if (skb == NULL)
index 9d4bcb1182e710080974b141b91edc48823fcdd6..c6c6d4773264abd64fdaa59806590a51b81f6f1d 100644 (file)
@@ -1000,8 +1000,8 @@ void rpc_show_tasks(void)
                        wreq->wb_flags, wreq->wb_pid, wreq->wb_page,
                        wreq->wb_offset, wreq->wb_bytes);
                printk("          name=%s/%s\n",
-                       wreq->wb_dentry->d_parent->d_name.name,
-                       wreq->wb_dentry->d_name.name);
+                       wreq->wb_file->f_dentry->d_parent->d_name.name,
+                       wreq->wb_file->f_dentry->d_name.name);
        }
 }
 #endif
index 3dcc2cada2d46443d089ab0158ae87d662c420e3..4aff3f7b78447e3e466348f9422392cf623799bb 100644 (file)
  *
  *  - explicit stack instead of recursion
  *  - tail recurse on first born instead of immediate push/pop
+ *  - we gather the stuff that should not be killed into tree
+ *    and stack is just a path from root to the current pointer.
  *
  *  Future optimizations:
  *
  *  - don't just push entire root set; process in place
- *  - use linked list for internal stack
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License
  *             That might be the reason of random oopses on close_fp() in
  *             unrelated processes.
  *
+ *     AV              28 Feb 1999
+ *             Kill the explicit allocation of stack. Now we keep the tree
+ *             with root in dummy + pointer (gc_current) to one of the nodes.
+ *             Stack is represented as path from gc_current to dummy. Unmark
+ *             now means "add to tree". Push == "make it a son of gc_current".
+ *             Pop == "move gc_current to parent". We keep only pointers to
+ *             parents (->gc_tree).
+ *     AV              1 Mar 1999
+ *             Damn. Added missing check for ->dead in listen queues scanning.
+ *
  */
  
 #include <linux/kernel.h>
@@ -65,7 +76,6 @@
 #include <linux/netdevice.h>
 #include <linux/file.h>
 #include <linux/proc_fs.h>
-#include <linux/vmalloc.h>
 
 #include <net/sock.h>
 #include <net/tcp.h>
@@ -74,9 +84,8 @@
 
 /* Internal data structures and random procedures: */
 
-static unix_socket **stack;    /* stack of objects to mark */
-static int in_stack = 0;       /* first free entry in stack */
-static int max_stack;          /* Top of stack */
+#define GC_HEAD ((unix_socket *)(-1))
+static unix_socket *gc_current=GC_HEAD;        /* stack of objects to mark */
 
 extern inline unix_socket *unix_get_socket(struct file *filp)
 {
@@ -122,32 +131,25 @@ void unix_notinflight(struct file *fp)
 /*
  *     Garbage Collector Support Functions
  */
-extern inline void push_stack(unix_socket *x)
-{
-       if (in_stack == max_stack)
-               panic("can't push onto full stack");
-       stack[in_stack++] = x;
-}
 
 extern inline unix_socket *pop_stack(void)
 {
-       if (in_stack == 0)
-               panic("can't pop empty gc stack");
-       return stack[--in_stack];
+       unix_socket *p=gc_current;
+       gc_current = p->protinfo.af_unix.gc_tree;
+       return p;
 }
 
 extern inline int empty_stack(void)
 {
-       return in_stack == 0;
+       return gc_current == GC_HEAD;
 }
 
 extern inline void maybe_unmark_and_push(unix_socket *x)
 {
-       if (!(x->protinfo.af_unix.marksweep&MARKED))
+       if (x->protinfo.af_unix.gc_tree)
                return;
-       x->protinfo.af_unix.marksweep&=~MARKED;
-       push_stack(x);
+       x->protinfo.af_unix.gc_tree = gc_current;
+       gc_current = x;
 }
 
 
@@ -169,23 +171,9 @@ void unix_gc(void)
                return;
        in_unix_gc=1;
        
-       if(stack==NULL || max_files>max_stack)
-       {
-               if(stack)
-                       vfree(stack);
-               stack=(unix_socket **)vmalloc(max_files*sizeof(struct unix_socket *));
-               if(stack==NULL)
-               {
-                       printk(KERN_NOTICE "unix_gc: deferred due to low memory.\n");
-                       in_unix_gc=0;
-                       return;
-               }
-               max_stack=max_files;
-       }
-       
        forall_unix_sockets(i, s)
        {
-               s->protinfo.af_unix.marksweep|=MARKED;
+               s->protinfo.af_unix.gc_tree=NULL;
        }
        /*
         *      Everything is now marked 
@@ -262,7 +250,7 @@ tail:
                                }
                        }
                        /* We have to scan not-yet-accepted ones too */
-                       if (UNIXCB(skb).attr & MSG_SYN) {
+                       if ((UNIXCB(skb).attr & MSG_SYN) && !skb->sk->dead) {
                                if (f==NULL)
                                        f=skb->sk;
                                else
@@ -276,9 +264,9 @@ tail:
 
                if (f) 
                {
-                       if ((f->protinfo.af_unix.marksweep&MARKED))
+                       if (!f->protinfo.af_unix.gc_tree)
                        {
-                               f->protinfo.af_unix.marksweep&=~MARKED;
+                               f->protinfo.af_unix.gc_tree=GC_HEAD;
                                x=f;
                                f=NULL;
                                goto tail;
@@ -290,7 +278,7 @@ tail:
 
        forall_unix_sockets(i, s)
        {
-               if (s->protinfo.af_unix.marksweep&MARKED)
+               if (!s->protinfo.af_unix.gc_tree)
                {
                        struct sk_buff *nextsk;
                        skb=skb_peek(&s->receive_queue);
index 1df01f40c1b4d72b6aae66957b12c9fc029d7a14..e7c41a9e6872f37b707bb1245c77d031579d5a64 100644 (file)
@@ -976,7 +976,7 @@ static const char *Oops_code(const char *line, char ***string, int string_max)
                        "("                                             /*  4 */
                          "(general protection.*)"
                          "|(<[0-9]+>)"
-                         "|(([<(]?[0-9a-fA-F]+[>)]?[ \t]*)+)"
+                         "|(([<(]?[0-9a-fA-F]+[>)]?[ \t]+)+[<(]?[0-9a-fA-F]+[>)]?)"
                        ")"
                        "(.*)$"                         /* trailing garbage */
                        ,