]> git.neil.brown.name Git - history.git/commitdiff
Linux 2.2.13pre5 2.2.13pre5
authorAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 23 Nov 2007 20:19:43 +0000 (15:19 -0500)
committerAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 23 Nov 2007 20:19:43 +0000 (15:19 -0500)
o Fix 3c527 multicast crash (Alan Cox)
o VIA Apollo Pro needs DMA workaround (Takehiro TOMINAGA)
o bttv ADS data update (Karl Heinz Kremer)
o Clean potential kernel->user data leak (Rpbert de Vries)
o Advansys driver update (Bob Frey, Advansys)
o Optimise the memory zoning changes (Ben LaHaise)
o Fix memory tracking bug in sk_buffs (Henner Eisen)
o strnlen_user/exec fixes (Solar Designer)
| sparc,ppc fixes to follow
o Always defragment is now a sysctl
o Documentation update for SG (Doug Gilbert)
o Module parameters for tlan (spotted by Keith Owens)
o Fix qnx memory corruption (Andries Brouwer)
o Masquerade list fixes (Julian Anastasov)
o CD-ROM update (Jens Axboe)
o Fix task counting race (Curtis Regentin)

40 files changed:
CREDITS
Documentation/Configure.help
MAINTAINERS
Makefile
arch/alpha/kernel/alpha_ksyms.c
arch/alpha/lib/strlen_user.S
arch/i386/kernel/i386_ksyms.c
arch/i386/lib/usercopy.c
drivers/block/ide-cd.c
drivers/block/ide-cd.h
drivers/cdrom/cdrom.c
drivers/char/bttv.c
drivers/net/3c527.c
drivers/net/tlan.c
drivers/pci/oldproc.c
drivers/pci/quirks.c
drivers/scsi/advansys.c
fs/binfmt_elf.c
fs/exec.c
fs/proc/root.c
fs/qnx4/inode.c
include/asm-alpha/uaccess.h
include/asm-i386/uaccess.h
include/linux/capability.h
include/linux/pci.h
include/linux/sysctl.h
kernel/exit.c
kernel/fork.c
kernel/signal.c
mm/page_alloc.c
net/ipv4/Config.in
net/ipv4/icmp.c
net/ipv4/ip_fw.c
net/ipv4/ip_input.c
net/ipv4/ip_masq.c
net/ipv4/ip_masq_mfw.c
net/ipv4/ip_masq_portfw.c
net/ipv4/ip_output.c
net/ipv4/sysctl_net_ipv4.c
net/netsyms.c

diff --git a/CREDITS b/CREDITS
index f6879c094fb0b6a37633963df04c24a4ecb4d246..da3ebb183f6d6f6c128a6d7ab084134a6a2565a3 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -458,11 +458,11 @@ S: Warrendale, Pennsylvania 15086
 S: USA
 
 N: Alex deVries
-E: puffin@redhat.com
-D: Various SGI parts, bits of HAL2 and Newport
-S: 18 Bernier Terrace
-S: Kanata, Ontario
-S: K2L 2V@
+E: adevries@thepuffingroup.com
+D: Various SGI parts, bits of HAL2 and Newport, PA-RISC Linux.
+S: 41.5 William Street
+S: Ottawa, Ontario
+S: K1N 6Z9
 S: CANADA
 
 N: Eddie C. Dost
index d9b489a18ad98839bfc3baebbb816debc0bb6da5..18f77e6d068657afcb289045ea638e251a6a9776 100644 (file)
@@ -3629,14 +3629,15 @@ CONFIG_CHR_DEV_SG
   about anything having "SCSI" in its name other than hard disks,
   CDROMs or tapes, say Y here. These won't be supported by the kernel
   directly, so you need some additional software which knows how to
-  talk to these devices using the SCSI protocol. For CD-writers, you
-  would need the program cdwrite, available via FTP (user: anonymous)
-  from ftp://metalab.unc.edu/pub/Linux/utils/disk-management; for
-  other devices, it's possible that you'll have to write the driver
-  software yourself, so have a look at the SCSI-HOWTO and at the
-  SCSI-Programming-HOWTO, both available via FTP (user: anonymous) in
-  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Please read the file
-  Documentation/scsi-generic.txt for more information.
+  talk to these devices using the SCSI protocol. For scanners, look at
+  SANE (www.mostang.com/sane). For CD writer software look at cdrecord
+  (www.fokus.gmd.de/research/cc/glone/employees/joerg.schilling/private
+  /cdrecord.html) and for burning a "disk at once": cdrdao
+  (www.ping.de/sites/daneb/cdrdao.html). Cdparanoia is a high quality
+  digital reader of audio CDs (www.xiph.org/paranoia).
+  For other devices, it's possible that you'll have to write the driver
+  software yourself. Please read the file Documentation/scsi-generic.txt
+  for more information.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
index c5d1cc4f39462a87442bf3581e45c950a318ce55..b1ddf79491c5d78b958df7a3ffe1033e0308a996 100644 (file)
@@ -104,7 +104,8 @@ S:  Maintained
 ADVANSYS SCSI DRIVER
 P:     Bob Frey
 M:     Bob Frey <bobf@advansys.com>
-W:     http://www.advansys.com/linux
+W:     http://www.advansys.com/linux.html
+L:     linux-scsi@vger.rutgers.edu
 S:     Maintained
 
 AEDSP16 DRIVER
index 251b9cb1db155734bb1b8c9f66ee4395f5818b6f..10fe191b93b2c96ef75152dc684596e2c9fc321d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 2
 SUBLEVEL = 13
-EXTRAVERSION = pre4
+EXTRAVERSION = pre5
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
 
index cf8911e743f8f4ca1d9808ede77d5a88100a23a3..8b1fb14e12ab490c7b77bb8670806bcf65d12d70 100644 (file)
@@ -142,7 +142,7 @@ EXPORT_SYMBOL(alpha_fp_emul);
 EXPORT_SYMBOL_NOVERS(__copy_user);
 EXPORT_SYMBOL_NOVERS(__do_clear_user);
 EXPORT_SYMBOL(__strncpy_from_user);
-EXPORT_SYMBOL(__strlen_user);
+EXPORT_SYMBOL(__strnlen_user);
 
 /*
  * The following are specially called from the semaphore assembly stubs.
index 1f4fb07f589a4fd906d9da611b12f32168b97173..80094e18a26746c8a2a70b66f1f8ca9ebba480f7 100644 (file)
@@ -3,6 +3,13 @@
  *
  * Return the length of the string including the NUL terminator
  * (strlen+1) or zero if an error occurred.
+ *
+ * In places where it is critical to limit the processing time,
+ * and the data is not trusted, strnlen_user() should be used.
+ * It will return a value greater than its second argument if
+ * that limit would be exceeded. This implementation is allowed
+ * to access memory beyond the limit, but will not cross a page
+ * boundary when doing so.
  */
 
 #include <alpha/regdef.h>
 
        .align 3
 __strlen_user:
+       ldah    a1, 32767(zero) # do not use plain strlen_user() for strings
+                               # that might be almost 2 GB long; you should
+                               # be using strnlen_user() instead
+
+       .globl __strnlen_user
+
+       .align 3
+__strnlen_user:
        ldgp    $29,0($27)      # we do exceptions -- we need the gp.
        .prologue 1
 
@@ -37,9 +52,17 @@ __strlen_user:
        or      t1, t0, t0
        subq    a0, 1, a0       # get our +1 for the return 
        cmpbge  zero, t0, t1    # t1 <- bitmask: bit i == 1 <==> i-th byte == 0
+       subq    a1, 7, t2
+       subq    a0, v0, t0
        bne     t1, $found
 
-$loop: EX( ldq t0, 8(v0) )
+       addq    t2, t0, t2
+       addq    a1, 1, a1
+
+       .align 3
+$loop: ble     t2, $limit
+       EX( ldq t0, 8(v0) )
+       subq    t2, 8, t2
        addq    v0, 8, v0       # addr += 8
        cmpbge  zero, t0, t1
        beq     t1, $loop
@@ -61,4 +84,9 @@ $found:       negq    t1, t2          # clear all but least set bit
 $exception:
        ret
 
+       .align 3                # currently redundant
+$limit:
+       subq    a1, t2, v0
+       ret
+
        .end __strlen_user
index e9562e91ddc4faf4c1c7b053d3ad114146a04f5a..b5b4b8a64c4ccdb23ad8da935afa02a1119275c8 100644 (file)
@@ -72,7 +72,7 @@ EXPORT_SYMBOL(clear_user);
 EXPORT_SYMBOL(__clear_user);
 EXPORT_SYMBOL(__generic_copy_from_user);
 EXPORT_SYMBOL(__generic_copy_to_user);
-EXPORT_SYMBOL(strlen_user);
+EXPORT_SYMBOL(strnlen_user);
 
 #ifdef __SMP__
 EXPORT_SYMBOL(cpu_data);
index f43be511f34a67848ac4a9544d30e2d12def883b..e2fe4aad24c0a186ce3b5dc40fe3aa2a652f16e5 100644 (file)
@@ -117,26 +117,31 @@ __clear_user(void *to, unsigned long n)
 /*
  * Return the size of a string (including the ending 0)
  *
- * Return 0 for error
+ * Return 0 on exception, a value greater than N if too long
  */
 
-long strlen_user(const char *s)
+long strnlen_user(const char *s, long n)
 {
+       unsigned long mask = -__addr_ok(s);
        unsigned long res;
 
        __asm__ __volatile__(
+               "       andl %0,%%ecx\n"
                "0:     repne; scasb\n"
-               "       notl %0\n"
+               "       setne %%al\n"
+               "       subl %%ecx,%0\n"
+               "       addl %0,%%eax\n"
                "1:\n"
                ".section .fixup,\"ax\"\n"
-               "2:     xorl %0,%0\n"
+               "2:     xorl %%eax,%%eax\n"
                "       jmp 1b\n"
                ".previous\n"
                ".section __ex_table,\"a\"\n"
                "       .align 4\n"
                "       .long 0b,2b\n"
                ".previous"
-               :"=c" (res), "=D" (s)
-               :"1" (s), "a" (0), "0" (-__addr_ok(s)));
-       return res & -__addr_ok(s);
+               :"=r" (n), "=D" (s), "=a" (res)
+               :"0" (n), "1" (s), "2" (0), "c" (mask)
+               :"cx", "cc");
+       return res & mask;
 }
index 8b2879204ddfcd49afed44a7237e051fb0a740ce..7ccc83543f96b9862cae088531bec7a0ec70e06e 100644 (file)
  *                         ide-scsi. TODO: non-modular way of doing the
  *                         same.
  *                         
+ * 4.54  Sep 09, 1999  - Fixed start/stop error on some drives if the
+ *                        drive was locked.
+ *                     - Fixed read_toc header, size given was too large.
+ *                     - Fixed possible leaks in ioctl.
+ *                     - CDROMREADTOCENTRY now honors the cdte_format
+ *                        field, instead of forcing CDROM_LBA.
+ *                     - Mask out things the drive can't do instead of
+ *                        just telling people what the driver can do.
  *
  *************************************************************************/
 
-#define IDECD_VERSION "4.53"
+#define IDECD_VERSION "4.54"
 
 #include <linux/module.h>
 #include <linux/types.h>
@@ -1564,6 +1572,10 @@ cdrom_eject (ide_drive_t *drive, int ejectflag,
        if (CDROM_CONFIG_FLAGS (drive)->no_eject==1 && ejectflag==0)
                return -EDRIVE_CANT_DO_THIS;
 
+       /* reload fails on some drives, if the tray is locked */
+       if (CDROM_STATE_FLAGS (drive)->door_locked && ejectflag)
+               return 0;
+
        memset (&pc, 0, sizeof (pc));
        pc.sense_data = reqbuf;
 
@@ -1669,14 +1681,13 @@ cdrom_read_toc (ide_drive_t *drive,
                /* Try to allocate space. */
                toc = (struct atapi_toc *) kmalloc (sizeof (struct atapi_toc),
                                                    GFP_KERNEL);
+               if (toc == NULL) {
+                       printk ("%s: No cdrom TOC buffer!\n", drive->name);
+                       return -ENOMEM;
+               }
                info->toc = toc;
        }
 
-       if (toc == NULL) {
-               printk ("%s: No cdrom TOC buffer!\n", drive->name);
-               return -EIO;
-       }
-
        /* Check to see if the existing data is still valid.
           If it is, just return. */
        if (CDROM_STATE_FLAGS (drive)->toc_valid)
@@ -1686,8 +1697,7 @@ cdrom_read_toc (ide_drive_t *drive,
 
        /* First read just the header, so we know how long the TOC is. */
        stat = cdrom_read_tocentry (drive, 0, 1, 0, (char *)&toc->hdr,
-                                   sizeof (struct atapi_toc_header) +
-                                   sizeof (struct atapi_toc_entry),
+                                   sizeof (struct atapi_toc_header),
                                    reqbuf);
        if (stat) return stat;
 
@@ -1889,7 +1899,7 @@ static int
 cdrom_play_lba_range (ide_drive_t *drive, int lba_start, int lba_end,
                      struct atapi_request_sense *reqbuf)
 {
-       int i, stat;
+       int i, stat = 0;
        struct atapi_request_sense my_reqbuf;
 
        if (reqbuf == NULL)
@@ -2142,9 +2152,11 @@ int ide_cdrom_dev_ioctl (struct cdrom_device_info *cdi,
                if (stat == 0) {
                        if (cmd == CDROMREADMODE2) {
                                /* For Mode2, skip the Sync, Header, and Subheader */
-                               copy_to_user_ret((char *)arg, buf+16, CD_FRAMESIZE_RAW0, -EFAULT);
+                               if (copy_to_user((char *)arg, buf+16, CD_FRAMESIZE_RAW0))
+                                       stat = -EFAULT;
                        } else {
-                               copy_to_user_ret((char *)arg, buf, blocksize, -EFAULT);
+                               if (copy_to_user((char *)arg, buf, blocksize))
+                                       stat = -EFAULT;
                        }
                }
 
@@ -2392,8 +2404,14 @@ int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
 
                tocentry->cdte_ctrl = toce->control;
                tocentry->cdte_adr  = toce->adr;
-               tocentry->cdte_format = CDROM_LBA;
-               tocentry->cdte_addr.lba = toce->addr.lba;
+               if (tocentry->cdte_format == CDROM_MSF) {
+                       lba_to_msf (toce->addr.lba,
+                                  &tocentry->cdte_addr.msf.minute,
+                                  &tocentry->cdte_addr.msf.second,
+                                  &tocentry->cdte_addr.msf.frame);
+               } else {
+                       tocentry->cdte_addr.lba = toce->addr.lba;
+               }
 
                return 0;
        }
@@ -2850,6 +2868,15 @@ static int ide_cdrom_register (ide_drive_t *drive, int nslots)
        *(int *)&devinfo->capacity = nslots;
        devinfo->handle = (void *) drive;
        strcpy(devinfo->name, drive->name);
+
+       /* set capability mask to match the probe. */
+       if (!CDROM_CONFIG_FLAGS (drive)->is_changer)
+               devinfo->mask |= CDC_SELECT_DISC;
+       if (!CDROM_CONFIG_FLAGS (drive)->audio_play)
+               devinfo->mask |= CDC_PLAY_AUDIO;
+       if (!CDROM_CONFIG_FLAGS (drive)->close_tray)
+               devinfo->mask |= CDC_CLOSE_TRAY;
+
        return register_cdrom (devinfo);
 }
 
@@ -2889,6 +2916,10 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
                CDROM_CONFIG_FLAGS (drive)->dvd_r = 1;
        if (buf.cap.dvd_r_write)
                CDROM_CONFIG_FLAGS (drive)->dvd_rw = 1;
+       if (buf.cap.audio_play)
+               CDROM_CONFIG_FLAGS (drive)->audio_play = 1;
+       if (buf.cap.mechtype == 0)
+               CDROM_CONFIG_FLAGS (drive)->close_tray = 0;
 
 #if ! STANDARD_ATAPI
        if (CDROM_STATE_FLAGS (drive)->sanyo_slot > 0) {
@@ -3000,7 +3031,9 @@ int ide_cdrom_setup (ide_drive_t *drive)
        CDROM_CONFIG_FLAGS (drive)->dvd_rw = 0;
        CDROM_CONFIG_FLAGS (drive)->no_eject = 1;
        CDROM_CONFIG_FLAGS (drive)->supp_disc_present = 0;
-       
+       CDROM_CONFIG_FLAGS (drive)->audio_play = 0;
+       CDROM_CONFIG_FLAGS (drive)->close_tray = 1;
+
        /* limit transfer size per interrupt. */
        CDROM_CONFIG_FLAGS (drive)->limit_nframes = 0;
        if (drive->id != NULL) {
index 553013b9df0c9e371cba28ce56c7e110bce4fa3a..95bd483c39efd5c8bad1f771befd3a05db11ee3f 100644 (file)
@@ -141,7 +141,9 @@ struct ide_cd_config_flags {
                                      multiples of SECTOR_SIZE when more
                                      than one interrupt is needed. */
        __u8 seeking          : 1; /* Seeking in progress */
-       __u8 reserved         : 6;
+       __u8 audio_play       : 1; /* can do audio related commands */
+       __u8 close_tray       : 1; /* can close the tray */
+       __u8 reserved         : 4;
        byte max_speed;            /* Max speed of the drive */
 };
 #define CDROM_CONFIG_FLAGS(drive) (&(((struct cdrom_info *)(drive->driver_data))->config_flags))
@@ -518,9 +520,11 @@ struct atapi_mechstat_header {
 
 #if defined(__BIG_ENDIAN_BITFIELD)
        __u8 mech_state    : 3;
-       __u8 reserved1     : 5;
+       __u8 door_open     : 1;
+       __u8 reserved1     : 4;
 #elif defined(__LITTLE_ENDIAN_BITFIELD)
        __u8 reserved1     : 5;
+       __u8 door_open     : 1;
        __u8 mech_state    : 3;
 #else
 #error "Please fix <asm/byteorder.h>"
index a370b951bc96a54701ffac7475b0ac2c81beec80..048ea34a8661c15a0a327c1a0aeb525fa644ebcb 100644 (file)
   -- autoclose was mistakenly checked against CDC_OPEN_TRAY instead of
   CDC_CLOSE_TRAY.
   -- proc info didn't mask against capabilities mask.
+  
+  2.56 Sep 9, 1999 - Jens Axboe <axboe@image.dk>
+  -- Define CDROM_CAN() for checking capabilities.
+  -- Fix up capability reporting, for proc and ioctl.
 
 -------------------------------------------------------------------------*/
 
-#define REVISION "Revision: 2.55"
-#define VERSION "Id: cdrom.c 2.55 1999/04/25"
+#define REVISION "Revision: 2.56"
+#define VERSION "Id: cdrom.c 2.56 1999/09/09"
 
 /* I use an error-log mask to give fine grain control over the type of
    messages dumped to the system logs.  The available masks include: */
@@ -194,6 +198,9 @@ MODULE_PARM(check_media_type, "i");
 #define IOCTL_OUT(arg, type, out) \
        copy_to_user_ret((type *) arg, &out, sizeof out, -EFAULT)
 
+/* The (cdo->capability & ~cdi->mask & CDC_XXX) construct was used in
+   a lot of places. This macro makes the code more clear. */
+#define CDROM_CAN(type) (cdi->ops->capability & ~cdi->mask & type)
 
 #define FM_WRITE       0x2                 /* file mode write bit */
 
@@ -273,9 +280,9 @@ int register_cdrom(struct cdrom_device_info *cdi)
        cdo->n_minors = 0;
         cdi->options = CDO_USE_FFLAGS;
        
-       if (autoclose==1 && cdo->capability & ~cdi->mask & CDC_CLOSE_TRAY)
+       if (autoclose==1 && CDROM_CAN(CDC_CLOSE_TRAY))
                cdi->options |= (int) CDO_AUTO_CLOSE;
-       if (autoeject==1 && cdo->capability & ~cdi->mask & CDC_OPEN_TRAY)
+       if (autoeject==1 && CDROM_CAN(CDC_OPEN_TRAY))
                cdi->options |= (int) CDO_AUTO_EJECT;
        if (lockdoor==1)
                cdi->options |= (int) CDO_LOCK;
@@ -377,7 +384,7 @@ int open_for_data(struct cdrom_device_info * cdi)
                if (ret == CDS_TRAY_OPEN) {
                        cdinfo(CD_OPEN, "the tray is open...\n"); 
                        /* can/may i close it? */
-                       if (cdo->capability & ~cdi->mask & CDC_CLOSE_TRAY &&
+                       if (CDROM_CAN(CDC_CLOSE_TRAY) &&
                            cdi->options & CDO_AUTO_CLOSE) {
                                cdinfo(CD_OPEN, "trying to close the tray.\n"); 
                                ret=cdo->tray_move(cdi,0);
@@ -442,8 +449,7 @@ int open_for_data(struct cdrom_device_info * cdi)
                cdinfo(CD_OPEN, "open device failed.\n"); 
                goto clean_up_and_return;
        }
-       if (cdo->capability & ~cdi->mask & CDC_LOCK && 
-               cdi->options & CDO_LOCK) {
+       if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) {
                        cdo->lock_door(cdi, 1);
                        cdinfo(CD_OPEN, "door locked.\n");
        }       
@@ -457,8 +463,7 @@ int open_for_data(struct cdrom_device_info * cdi)
        is a goto to avoid bloating the driver with redundant code. */ 
 clean_up_and_return:
        cdinfo(CD_WARNING, "open failed.\n"); 
-       if (cdo->capability & ~cdi->mask & CDC_LOCK && 
-               cdi->options & CDO_LOCK) {
+       if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) {
                        cdo->lock_door(cdi, 0);
                        cdinfo(CD_OPEN, "door unlocked.\n");
        }
@@ -482,7 +487,7 @@ int check_for_audio_disc(struct cdrom_device_info * cdi,
                if (ret == CDS_TRAY_OPEN) {
                        cdinfo(CD_OPEN, "the tray is open...\n"); 
                        /* can/may i close it? */
-                       if (cdo->capability & ~cdi->mask & CDC_CLOSE_TRAY &&
+                       if (CDROM_CAN(CDC_CLOSE_TRAY) &&
                            cdi->options & CDO_AUTO_CLOSE) {
                                cdinfo(CD_OPEN, "trying to close the tray.\n"); 
                                ret=cdo->tray_move(cdi,0);
@@ -552,9 +557,8 @@ int cdrom_release(struct inode *ip, struct file *fp)
                sb = get_super(dev);
                if (sb) invalidate_inodes(sb);
                invalidate_buffers(dev);
-               if (opened_for_data &&
-                   cdi->options & CDO_AUTO_EJECT &&
-                   cdo->capability & ~cdi->mask & CDC_OPEN_TRAY)
+               if (opened_for_data && (cdi->options & CDO_AUTO_EJECT) &&
+                   CDROM_CAN(CDC_OPEN_TRAY))
                        cdo->tray_move(cdi, 1);
        }
        return 0;
@@ -572,7 +576,7 @@ int media_changed(struct cdrom_device_info *cdi, int queue)
        unsigned int mask = (1 << (queue & 1));
        int ret = !!(cdi->mc_flags & mask);
 
-       if (!(cdi->ops->capability & ~cdi->mask & CDC_MEDIA_CHANGED))
+       if (!CDROM_CAN(CDC_MEDIA_CHANGED))
            return ret;
        /* changed since last call? */
        if (cdi->ops->media_changed(cdi, CDSL_CURRENT)) {
@@ -594,7 +598,7 @@ int cdrom_media_changed(kdev_t dev)
                return 0;
        if (cdi->ops->media_changed == NULL)
                return 0;
-       if (!(cdi->ops->capability & ~cdi->mask & CDC_MEDIA_CHANGED))
+       if (!CDROM_CAN(CDC_MEDIA_CHANGED))
            return 0;
        return (media_changed(cdi, 0));
 }
@@ -739,26 +743,27 @@ int cdrom_ioctl(struct inode *ip, struct file *fp,
        case CDROMEJECT: {
                int ret;
                cdinfo(CD_DO_IOCTL, "entering CDROMEJECT\n"); 
-               if (!(cdo->capability & ~cdi->mask & CDC_OPEN_TRAY))
+               if (!CDROM_CAN(CDC_OPEN_TRAY))
                        return -ENOSYS;
                if (cdi->use_count != 1 || keeplocked)
                        return -EBUSY;
-               if (cdo->capability & ~cdi->mask & CDC_LOCK)
+               if (CDROM_CAN(CDC_LOCK))
                        if ((ret=cdo->lock_door(cdi, 0)))
                                return ret;
 
                return cdo->tray_move(cdi, 1);
                }
 
-       case CDROMCLOSETRAY:
+       case CDROMCLOSETRAY: {
                cdinfo(CD_DO_IOCTL, "entering CDROMCLOSETRAY\n"); 
-               if (!(cdo->capability & ~cdi->mask & CDC_CLOSE_TRAY))
+               if (!CDROM_CAN(CDC_CLOSE_TRAY))
                        return -ENOSYS;
                return cdo->tray_move(cdi, 0);
+               }
 
-       case CDROMEJECT_SW:
+       case CDROMEJECT_SW: {
                cdinfo(CD_DO_IOCTL, "entering CDROMEJECT_SW\n"); 
-               if (!(cdo->capability & ~cdi->mask & CDC_OPEN_TRAY))
+               if (!CDROM_CAN(CDC_OPEN_TRAY))
                        return -ENOSYS;
                if (keeplocked)
                        return -EBUSY;
@@ -766,12 +771,13 @@ int cdrom_ioctl(struct inode *ip, struct file *fp,
                if (arg)
                        cdi->options |= CDO_AUTO_CLOSE | CDO_AUTO_EJECT;
                return 0;
+               }
 
        case CDROM_MEDIA_CHANGED: {
                cdinfo(CD_DO_IOCTL, "entering CDROM_MEDIA_CHANGED\n"); 
-               if (!(cdo->capability & ~cdi->mask & CDC_MEDIA_CHANGED))
+               if (!CDROM_CAN(CDC_MEDIA_CHANGED))
                        return -ENOSYS;
-               if (!(cdo->capability & ~cdi->mask & CDC_SELECT_DISC)
+               if (!CDROM_CAN(CDC_SELECT_DISC)
                    || arg == CDSL_CURRENT)
                        /* cannot select disc or select current disc */
                        return media_changed(cdi, 1);
@@ -780,7 +786,7 @@ int cdrom_ioctl(struct inode *ip, struct file *fp,
                return cdo->media_changed (cdi, arg);
                }
 
-       case CDROM_SET_OPTIONS:
+       case CDROM_SET_OPTIONS: {
                cdinfo(CD_DO_IOCTL, "entering CDROM_SET_OPTIONS\n"); 
                /* options need to be in sync with capability. too late for
                   that, so we have to check each one separately... */
@@ -789,27 +795,29 @@ int cdrom_ioctl(struct inode *ip, struct file *fp,
                case CDO_CHECK_TYPE:
                        break;
                case CDO_LOCK:
-                       if (!(cdo->capability & ~cdi->mask & CDC_LOCK))
+                       if (!CDROM_CAN(CDC_LOCK))
                                return -ENOSYS;
                        break;
                case 0:
                        return cdi->options;
                /* default is basically CDO_[AUTO_CLOSE|AUTO_EJECT] */
                default:
-                       if (!(cdo->capability & ~cdi->mask & arg))
+                       if (!CDROM_CAN(arg))
                                return -ENOSYS;
                }
                cdi->options |= (int) arg;
                return cdi->options;
+               }
 
-       case CDROM_CLEAR_OPTIONS:
+       case CDROM_CLEAR_OPTIONS: {
                cdinfo(CD_DO_IOCTL, "entering CDROM_CLEAR_OPTIONS\n"); 
                cdi->options &= ~(int) arg;
                return cdi->options;
+               }
 
        case CDROM_SELECT_SPEED: {
                cdinfo(CD_DO_IOCTL, "entering CDROM_SELECT_SPEED\n"); 
-               if (!(cdo->capability & ~cdi->mask & CDC_SELECT_SPEED))
+               if (!CDROM_CAN(CDC_SELECT_SPEED))
                        return -ENOSYS;
                return cdo->select_speed(cdi, arg);
                }
@@ -827,14 +835,14 @@ int cdrom_ioctl(struct inode *ip, struct file *fp,
 
        case CDROMRESET: {
                cdinfo(CD_DO_IOCTL, "entering CDROM_RESET\n");
-               if (!(cdo->capability & ~cdi->mask & CDC_RESET))
+               if (!CDROM_CAN(CDC_RESET))
                        return -ENOSYS;
                return cdo->reset(cdi);
                }
 
        case CDROM_LOCKDOOR: {
                cdinfo(CD_DO_IOCTL, "%socking door.\n",arg?"L":"Unl");
-               if (!(cdo->capability & ~cdi->mask & CDC_LOCK)) {
+               if (!CDROM_CAN(CDC_LOCK)) {
                        return -EDRIVE_CANT_DO_THIS;
                } else {
                        keeplocked = arg ? 1 : 0;
@@ -852,7 +860,7 @@ int cdrom_ioctl(struct inode *ip, struct file *fp,
 
        case CDROM_GET_CAPABILITY: {
                cdinfo(CD_DO_IOCTL, "entering CDROM_GET_CAPABILITY\n");
-               return cdo->capability;
+               return (cdo->capability & ~cdi->mask);
                }
 
 /* The following function is implemented, although very few audio
@@ -864,7 +872,7 @@ int cdrom_ioctl(struct inode *ip, struct file *fp,
                int ret;
                struct cdrom_mcn mcn;
                cdinfo(CD_DO_IOCTL, "entering CDROM_GET_MCN\n"); 
-               if (!(cdo->capability & CDC_MCN))
+               if (!CDROM_CAN(CDC_MCN))
                        return -ENOSYS;
                if ((ret=cdo->get_mcn(cdi, &mcn)))
                        return ret;
@@ -875,7 +883,7 @@ int cdrom_ioctl(struct inode *ip, struct file *fp,
 
        case CDROM_DRIVE_STATUS: {
                cdinfo(CD_DO_IOCTL, "entering CDROM_DRIVE_STATUS\n"); 
-               if (!(cdo->capability & CDC_DRIVE_STATUS))
+               if (!CDROM_CAN(CDC_DRIVE_STATUS))
                        return -ENOSYS;
                 if ((arg == CDSL_CURRENT) || (arg == CDSL_NONE)) 
                        return cdo->drive_status(cdi, arg);
@@ -952,7 +960,7 @@ int cdrom_ioctl(struct inode *ip, struct file *fp,
 
 #define CHECKAUDIO if ((ret=check_for_audio_disc(cdi, cdo))) return ret
 
-       if (!(cdo->capability & CDC_PLAY_AUDIO))
+       if (!CDROM_CAN(CDC_PLAY_AUDIO))
                return -ENOSYS;
        else {
                switch (cmd) {
@@ -1079,6 +1087,7 @@ int cdrom_sysctl_info(ctl_table *ctl, int write, struct file * filp,
 {
         int pos;
        struct cdrom_device_info *cdi;
+       char *info = cdrom_drive_info;
        
        if (!*lenp || (filp->f_pos && !write)) {
                *lenp = 0;
@@ -1089,62 +1098,53 @@ int cdrom_sysctl_info(ctl_table *ctl, int write, struct file * filp,
        
        pos += sprintf(cdrom_drive_info+pos, "\ndrive name:\t");
        for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(cdrom_drive_info+pos, "\t%s", cdi->name);
+           pos += sprintf(info+pos, "\t%s", cdi->name);
 
        pos += sprintf(cdrom_drive_info+pos, "\ndrive speed:\t");
        for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(cdrom_drive_info+pos, "\t%d", cdi->speed);
+           pos += sprintf(info+pos, "\t%d", cdi->speed);
 
        pos += sprintf(cdrom_drive_info+pos, "\ndrive # of slots:");
        for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(cdrom_drive_info+pos, "\t%d", cdi->capacity);
+           pos += sprintf(info+pos, "\t%d", cdi->capacity);
 
        pos += sprintf(cdrom_drive_info+pos, "\nCan close tray:\t");
        for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(cdrom_drive_info+pos, "\t%d",
-               ((cdi->ops->capability & ~cdi->mask & CDC_CLOSE_TRAY)!=0));
+           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_CLOSE_TRAY)!=0);
 
        pos += sprintf(cdrom_drive_info+pos, "\nCan open tray:\t");
        for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(cdrom_drive_info+pos, "\t%d",
-                  ((cdi->ops->capability & ~cdi->mask & CDC_OPEN_TRAY)!=0));
+           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_OPEN_TRAY)!=0);
 
        pos += sprintf(cdrom_drive_info+pos, "\nCan lock tray:\t");
        for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(cdrom_drive_info+pos, "\t%d",
-                  ((cdi->ops->capability & ~cdi->mask & CDC_LOCK)!=0));
+           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_LOCK)!=0);
 
        pos += sprintf(cdrom_drive_info+pos, "\nCan change speed:");
        for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(cdrom_drive_info+pos, "\t%d",
-                  ((cdi->ops->capability & ~cdi->mask & CDC_SELECT_SPEED)!=0));
+           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_SELECT_SPEED)!=0);
 
        pos += sprintf(cdrom_drive_info+pos, "\nCan select disk:");
        for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(cdrom_drive_info+pos, "\t%d",
-                  ((cdi->ops->capability & ~cdi->mask & CDC_SELECT_DISC)!=0));
+           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_SELECT_DISC)!=0);
 
        pos += sprintf(cdrom_drive_info+pos, "\nCan read multisession:");
        for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(cdrom_drive_info+pos, "\t%d",
-                          ((cdi->ops->capability & CDC_MULTI_SESSION)!=0));
+           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MULTI_SESSION)!=0);
 
        pos += sprintf(cdrom_drive_info+pos, "\nCan read MCN:\t");
        for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(cdrom_drive_info+pos, "\t%d",
-                          ((cdi->ops->capability & CDC_MCN)!=0));
+           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MCN)!=0);
 
        pos += sprintf(cdrom_drive_info+pos, "\nReports media changed:");
        for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(cdrom_drive_info+pos, "\t%d",
-                          ((cdi->ops->capability & CDC_MEDIA_CHANGED)!=0));
+           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MEDIA_CHANGED)!=0);
 
        pos += sprintf(cdrom_drive_info+pos, "\nCan play audio:\t");
        for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
-           pos += sprintf(cdrom_drive_info+pos, "\t%d",
-                  ((cdi->ops->capability & ~cdi->mask & CDC_PLAY_AUDIO)!=0));
+           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_PLAY_AUDIO)!=0);
 
-        strcpy(cdrom_drive_info+pos,"\n\n");
+        strcpy(info+pos,"\n\n");
        pos += 3;
        if (*lenp > pos)
                *lenp = pos;
index d74959adef0ff38c75ced38909aa7c50847a0306..68c2640774c6c5d91535fabf7a56d08bc7e50958 100644 (file)
@@ -563,7 +563,7 @@ static struct tvcard tvcards[] =
         /* MIRO PCTV pro */
         { 3, 1, 0, 2, 65551, { 2, 3, 1, 1}, {1,65537, 0, 0,10}},
        /* ADS Technologies Channel Surfer TV (and maybe TV+FM) */
-       { 3, 4, 2, 2, 15, { 2, 3, 1, 1}, { 13, 14, 11, 7, 0, 0}, 0},
+       { 3, 4, 0, 2, 15, { 2, 3, 1, 1}, { 13, 14, 11, 7, 0, 0}, 0},
         /* AVerMedia TVCapture 98 */
        { 3, 4, 0, 2, 15, { 2, 3, 1, 1}, { 13, 14, 11, 7, 0, 0}, 0},
         /* Aimslab VHX */
index ca199597e2137e3cea5c02d9c232b84c445129b5..15c207f651b4d0ebd2c965ee1f05da6299396caa 100644 (file)
@@ -1,3 +1,4 @@
+
 /* 3c527.c: 3Com Etherlink/MC32 driver for Linux
  *
  *     (c) Copyright 1998 Red Hat Software Inc
@@ -15,7 +16,7 @@
  */
 
 static const char *version =
-       "3c527.c:v0.04 1999/03/16 Alan Cox (alan@redhat.com)\n";
+       "3c527.c:v0.05 1999/09/06 Alan Cox (alan@redhat.com)\n";
 
 /*
  *     Things you need
@@ -108,6 +109,7 @@ struct mc32_local
        u16 tx_skb_end;
        struct sk_buff *rx_skb[RX_RING_MAX];    /* Receive ring */
        void *rx_ptr[RX_RING_MAX];              /* Data pointers */
+       u32 mc_list_valid;                      /* True when the mclist is set */
 };
 
 /* The station (ethernet) address prefix, used for a sanity check. */
@@ -136,8 +138,9 @@ static int  mc32_open(struct device *dev);
 static int     mc32_send_packet(struct sk_buff *skb, struct device *dev);
 static void    mc32_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static int     mc32_close(struct device *dev);
-static struct  net_device_stats *mc32_get_stats(struct device *dev);
+static struct  device_stats *mc32_get_stats(struct device *dev);
 static void    mc32_set_multicast_list(struct device *dev);
+static void    mc32_reset_multicast_list(struct device *dev);
 
 /*
  * Check for a network adaptor of this type, and return '0' iff one exists.
@@ -445,15 +448,55 @@ static void mc32_ring_poll(struct device *dev)
  *     Send exec commands
  */
  
+
+/*
+ *     Send command from interrupt state
+ */
+
+static int mc32_command_nowait(struct device *dev, u16 cmd, void *data, int len)
+{
+       struct mc32_local *lp = (struct mc32_local *)dev->priv;
+       int ioaddr = dev->base_addr;
+       
+       if(lp->exec_pending)
+               return -1;
+               
+       lp->exec_pending=1;
+       lp->exec_box->mbox=0;
+       lp->exec_box->mbox=cmd;
+       memcpy((void *)lp->exec_box->data, data, len);
+       barrier();      /* the memcpy forgot the volatile so be sure */
+
+       /* Send the command */
+       while(!(inb(ioaddr+HOST_STATUS)&HOST_STATUS_CRR));
+       outb(1<<6, ioaddr+HOST_CMD);    
+       return 0;
+}
+
+
+/*
+ *     Send command and block for results. On completion spot and reissue
+ *     multicasts
+ */
+  
 static int mc32_command(struct device *dev, u16 cmd, void *data, int len)
 {
        struct mc32_local *lp = (struct mc32_local *)dev->priv;
        int ioaddr = dev->base_addr;
        unsigned long flags;
+       int ret = 0;
        
+       /*
+        *      Wait for a command
+        */
+        
        while(lp->exec_pending)
                sleep_on(&lp->event);
                
+       /*
+        *      Issue mine
+        */
+
        lp->exec_pending=1;
        lp->exec_box->mbox=0;
        lp->exec_box->mbox=cmd;
@@ -471,18 +514,20 @@ static int mc32_command(struct device *dev, u16 cmd, void *data, int len)
        lp->exec_pending=0;
        restore_flags(flags);
        
+        
+       if(lp->exec_box->data[0]&(1<<13))
+               ret = -1;
        /*
         *      A multicast set got blocked - do it now
         */
-        
+               
        if(lp->mc_reload_wait)
-               mc32_set_multicast_list(dev);
+               mc32_reset_multicast_list(dev);
 
-       if(lp->exec_box->data[0]&(1<<13))
-               return -1;
-       return 0;
+       return ret;
 }
 
+
 /*
  *     RX abort
  */
@@ -1049,7 +1094,7 @@ static int mc32_close(struct device *dev)
  * This may be called with the card open or closed.
  */
 
-static struct net_device_stats *mc32_get_stats(struct device *dev)
+static struct device_stats *mc32_get_stats(struct device *dev)
 {
        struct mc32_local *lp = (struct mc32_local *)dev->priv;
        return &lp->net_stats;
@@ -1062,20 +1107,18 @@ static struct net_device_stats *mc32_get_stats(struct device *dev)
  * num_addrs > 0       Multicast mode, receive normal and MC packets,
  *                     and do best-effort filtering.
  */
-static void mc32_set_multicast_list(struct device *dev)
+static void do_mc32_set_multicast_list(struct device *dev, int retry)
 {
+       struct mc32_local *lp = (struct mc32_local *)dev->priv;
        u16 filt;
+
        if (dev->flags&IFF_PROMISC)
-       {
                /* Enable promiscuous mode */
                filt = 1;
-               mc32_command(dev, 0, &filt, 2);
-       }
        else if((dev->flags&IFF_ALLMULTI) || dev->mc_count > 10)
        {
                dev->flags|=IFF_PROMISC;
                filt = 1;
-               mc32_command(dev, 0, &filt, 2);
        }
        else if(dev->mc_count)
        {
@@ -1086,24 +1129,47 @@ static void mc32_set_multicast_list(struct device *dev)
                int i;
                
                filt = 0;
-               block[1]=0;
-               block[0]=dev->mc_count;
-               bp=block+2;
                
-               for(i=0;i<dev->mc_count;i++)
+               if(retry==0)
+                       lp->mc_list_valid = 0;
+               if(!lp->mc_list_valid)
                {
-                       memcpy(bp, dmc->dmi_addr, 6);
-                       bp+=6;
-                       dmc=dmc->next;
+                       block[1]=0;
+                       block[0]=dev->mc_count;
+                       bp=block+2;
+               
+                       for(i=0;i<dev->mc_count;i++)
+                       {
+                               memcpy(bp, dmc->dmi_addr, 6);
+                               bp+=6;
+                               dmc=dmc->next;
+                       }
+                       if(mc32_command_nowait(dev, 2, block, 2+6*dev->mc_count)==-1)
+                       {
+                               lp->mc_reload_wait = 1;
+                               return;
+                       }
+                       lp->mc_list_valid=1;
                }
-               mc32_command(dev, 2, block, 2+6*dev->mc_count);
-               mc32_command(dev, 0, &filt, 2);
        }
        else 
        {
                filt = 0;
-               mc32_command(dev, 0, &filt, 2);
        }
+       if(mc32_command_nowait(dev, 0, &filt, 2)==-1)
+       {
+               lp->mc_reload_wait = 1;
+       }
+}
+
+static void mc32_set_multicast_list(struct device *dev)
+{
+       do_mc32_set_multicast_list(dev,0);
+}
+
+static void mc32_reset_multicast_list(struct device *dev)
+{
+       do_mc32_set_multicast_list(dev,1);
 }
 
 #ifdef MODULE
index eec9c97a1b99d6acabfb2fa62e08270ec050502e..621f3c5835ad1e20d3f2f9a2dda74fc73e8e2e7e 100644 (file)
@@ -59,6 +59,13 @@ static       int             sa_int = 0;
 static int             duplex = 0;
 static int             speed = 0;
 
+MODULE_PARM(aui, "i");
+MODULE_PARM(sa_int, "i");
+MODULE_PARM(duplex, "i");
+MODULE_PARM(speed, "i");
+MODULE_PARM(debug, "i");
+EXPORT_NO_SYMBOLS;
+
 #endif
 
 
index ff4f987ff9a62b2c03699033252668bc645e9aa5..514a458fbc3a1df75892a8595eeade26d4082ce4 100644 (file)
@@ -340,6 +340,7 @@ struct pci_dev_info dev_info[] = {
        DEVICE( VIA,            VIA_82C585,     "VT 82C585 Apollo VP1/VPX"),
        DEVICE( VIA,            VIA_82C586_0,   "VT 82C586 Apollo ISA"),
        DEVICE( VIA,            VIA_82C595,     "VT 82C595 Apollo VP2"),
+       DEVICE( VIA,            VIA_82C596_0,   "VT 82C596 Apollo Pro"),
        DEVICE( VIA,            VIA_82C597_0,   "VT 82C597 Apollo VP3"),
        DEVICE( VIA,            VIA_82C598_0,   "VT 82C598 Apollo MVP3"),
        DEVICE( VIA,            VIA_82C926,     "VT 82C926 Amazon"),
index 3fe63303089ca9ce15a5f1ff751d731f4591f308..0e76a8e598b9bbecbc81f564bf2137d78f9b8a87 100644 (file)
@@ -198,10 +198,10 @@ static struct quirk_info quirk_list[] __initdata = {
        { PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82441,      quirk_passive_release,  0x00 },
        /*
         * Its not totally clear which chipsets are the problematic ones
-        * This is the 82C586 variants. At the moment the 596 is an unknown
-        * quantity 
+        * This is the 82C586 variants.
         */
        { PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_82C586_0,     quirk_isa_dma_hangs,    0x00 },
+       { PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_82C596_0,     quirk_isa_dma_hangs,    0x00 },
 };
 
 __initfunc(void pci_quirks_init(void))
index dc46aa27e9b02b5934ef1f31722b59e70be6134e..a31526d2451a9a7a4cf28caa3871ee3c9fff4106 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: advansys.c,v 1.50 1998/05/08 23:39:15 bobf Exp bobf $ */
-#define ASC_VERSION "3.1E"    /* AdvanSys Driver Version */
+/* $Id: advansys.c,v 1.58 1999/09/03 23:02:16 bobf Exp bobf $ */
+#define ASC_VERSION "3.2F"    /* AdvanSys Driver Version */
 
 /*
  * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
  * 
- * Copyright (c) 1995-1998 Advanced System Products, Inc.
+ * Copyright (c) 1995-1999 Advanced System Products, Inc.
  * All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
   G. Driver Compile Time Options and Debugging
   H. Driver LILO Option
   I. Release History
-  J. Known Problems or Issues
+  J. Known Problems/Fix List
   K. Credits
   L. AdvanSys Contact Information
 
   A. Linux Kernel Testing
 
      This driver has been tested in the following Linux kernels: v1.2.13,
-     v1.3.57, v2.0.33, v2.1.77. These kernel versions are major releases
-     of Linux or the latest Linux kernel versions available when this version
-     of the driver was released. The driver should also work in earlier
-     versions of the Linux kernel. Beginning with v1.3.58 the AdvanSys driver
-     is included with all Linux kernels. Please refer to sections C, D, and
-     E for instructions on adding or upgrading the AdvanSys driver.
+     v1.3.57, v2.0.38, v2.2.12, and v2.3.16. These kernel versions are major
+     releases of Linux or the latest Linux kernel versions available when
+     this version of the driver was released. The driver should also work
+     in earlier versions of the Linux kernel. Beginning with v1.3.58 the
+     AdvanSys driver is included with all Linux kernels. Please refer to
+     sections C, D, and E for instructions on adding or upgrading the
+     AdvanSys driver.
 
   B. Adapters Supported by this Driver
  
      lowered in the BIOS by changing the 'Host Queue Size' adapter setting.
 
      Connectivity Products:
-        ABP510/5150 - Bus-Master ISA (240 CDB) (Footnote 1)
-        ABP5140 - Bus-Master ISA PnP (16 CDB) (Footnote 1, 3)
-        ABP5142 - Bus-Master ISA PnP with floppy (16 CDB) (Footnote 4)
+        ABP510/5150 - Bus-Master ISA (240 CDB)
+        ABP5140 - Bus-Master ISA PnP (16 CDB)
+        ABP5142 - Bus-Master ISA PnP with floppy (16 CDB)
+        ABP902/3902 - Bus-Master PCI (16 CDB)
+        ABP3905 - Bus-Master PCI (16 CDB)
+        ABP915 - Bus-Master PCI (16 CDB)
         ABP920 - Bus-Master PCI (16 CDB)
-        ABP930 - Bus-Master PCI (16 CDB) (Footnote 5)
+        ABP3922 - Bus-Master PCI (16 CDB)
+        ABP3925 - Bus-Master PCI (16 CDB)
+        ABP930 - Bus-Master PCI (16 CDB)
         ABP930U - Bus-Master PCI Ultra (16 CDB)
         ABP930UA - Bus-Master PCI Ultra (16 CDB)
-        ABP960 - Bus-Master PCI MAC/PC (16 CDB) (Footnote 2)
-        ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB) (Footnote 2)
+        ABP960 - Bus-Master PCI MAC/PC (16 CDB)
+        ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB)
      
      Single Channel Products:
         ABP542 - Bus-Master ISA with floppy (240 CDB)
         ABP842 - Bus-Master VL (240 CDB)
         ABP940 - Bus-Master PCI (240 CDB)
         ABP940U - Bus-Master PCI Ultra (240 CDB)
+        ABP940UA/3940UA - Bus-Master PCI Ultra (240 CDB)
         ABP970 - Bus-Master PCI MAC/PC (240 CDB)
         ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB)
-        ABP940UW - Bus-Master PCI Ultra-Wide (240 CDB)
+        ABP3960UA - Bus-Master PCI MAC/PC Ultra (240 CDB)
+        ABP940UW/3940UW - Bus-Master PCI Ultra-Wide (253 CDB)
+        ABP970UW - Bus-Master PCI MAC/PC Ultra-Wide (253 CDB)
+        ABP3940U2W - Bus-Master PCI LVD/Ultra2-Wide (253 CDB)
      
-     Multi Channel Products:
+     Multi-Channel Products:
         ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel)
         ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel)
         ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel)
+        ABP950UW - Dual Channel Bus-Master PCI Ultra-Wide (253 CDB Per Channel)
         ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel)
         ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel)
+        ABP980UA/3980UA - Four Channel Bus-Master PCI Ultra (16 CDB Per Chan.)
      
-     Footnotes:
-       1. This board has been shipped by HP with the 4020i CD-R drive.
-          The board has no BIOS so it cannot control a boot device, but
-          it can control any secondary SCSI device.
-       2. This board has been sold by Iomega as a Jaz Jet PCI adapter.
-       3. This board has been sold by SIIG as the i540 SpeedMaster.
-       4. This board has been sold by SIIG as the i542 SpeedMaster.
-       5. This board has been sold by SIIG as the Fast SCSI Pro PCI.
-
   C. Linux v1.2.X - Directions for Adding the AdvanSys Driver
 
      These directions apply to v1.2.13. For versions that follow v1.2.13.
             flag set to allow IRQ sharing with drivers that do not set
             the SA_INTERRUPT flag. Also display a more descriptive error
             message if request_irq() fails.
-         5. Update to latest Asc and Adv Libraries.
-
-  J. Known Problems or Issues
-
-         1. Remove conditional constants (ASC_QUEUE_FLOW_CONTROL) around
-            the queue depth flow control code when mid-level SCSI changes
-            are included in Linux.
+         6. Update to latest Asc and Adv Libraries.
+
+     3.2A (7/22/99):
+         1. Update Adv Library to 4.16 which includes support for
+            the ASC38C0800 (Ultra2/LVD) IC.
+
+     3.2B (8/23/99):
+         1. Correct PCI compile time option for v2.1.93 and greater
+            kernels, advansys_info() string, and debug compile time
+            option.
+         2. Correct DvcSleepMilliSecond() for v2.1.0 and greater
+            kernels. This caused an LVD detection/BIST problem problem
+            among other things.
+         3. Sort PCI cards by PCI Bus, Slot, Function ascending order
+            to be consistent with the BIOS.
+         4. Update to Asc Library S121 and Adv Library 5.2.
+
+     3.2C (8/24/99):
+         1. Correct PCI card detection bug introduced in 3.2B that
+            prevented PCI cards from being detected in kernels older
+            than v2.1.93.
+
+     3.2D (8/26/99):
+         1. Correct /proc device synchronous speed information display.
+            Also when re-negotiation is pending for a target device
+            note this condition with an * and footnote.
+         2. Correct initialization problem with Ultra-Wide cards that
+            have a pre-3.2 BIOS. A microcode variable changed locations
+            in 3.2 and greater BIOSes which caused WDTR to be attempted
+            erroneously with drives that don't support WDTR.
+
+     3.2E (8/30/99):
+         1. Fix compile error caused by v2.3.13 PCI structure change.
+         2. Remove field from ASCEEP_CONFIG that resulted in an EEPROM
+            checksum error for ISA cards.
+         3. Remove ASC_QUEUE_FLOW_CONTROL conditional code. The mid-level
+            SCSI changes that it depended on were never included in Linux.
+
+     3.2F (9/3/99):
+         1. Handle new initial function code added in v2.3.16 for all
+            driver versions.
+            
+  J. Known Problems/Fix List (XXX)
+
+     1. Need to add memory mapping workaround. Test the memory mapping.
+        If it doesn't work revert to I/O port access. Can a test be done
+        safely?
+     2. Handle an interrupt not working. Keep an interrupt counter in
+        the interrupt handler. In the timeout function if the interrupt
+        has not occurred then print a message and run in polled mode.
+     3. Allow bus type scanning order to be changed.
+     4. Need to add support for target mode commands, cf. CAM XPT.
+     5  Need to add support for new Linux SCSI error handling method.
+     6. Need to fix sti/cli code in Asc Library.
+     7. Need to fix abort code in Adv Library.
+     8. Reduce io_request_lock hold time.
+     9. Add big-endian support for Alpha.
 
   K. Credits
 
      Mark Moran <mmoran@mmoran.com> has helped test Ultra-Wide
      support in the 3.1A driver.
 
+     Doug Gilbert <dgilbert@interlog.com> has made changes and
+     suggestions to improve the driver and done testing.
+
   L. AdvanSys Contact Information
  
      Mail:                   Advanced System Products, Inc.
                              1150 Ringwood Court
                              San Jose, CA 95131
-     Operator:               1-408-383-9400
+     Operator/Sales:         1-408-383-9400
      FAX:                    1-408-383-9612
-     Tech Support:           1-800-525-7440/1-408-467-2930
-     BBS:                    1-408-383-9540 (14400,N,8,1)
-     Interactive FAX:        1-408-383-9753
-     Customer Direct Sales:  1-800-525-7443/1-408-383-5777
+     Tech Support:           1-408-467-2930
      Tech Support E-Mail:    support@advansys.com
      FTP Site:               ftp.advansys.com (login: anonymous)
      Web Site:               http://www.advansys.com
 #include <linux/string.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
+#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,0)
+#include <linux/head.h>
+#endif /* verions < v2.1.0 */
 #include <linux/types.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
  */
 
 #define ASC_LIB_VERSION_MAJOR  1
-#define ASC_LIB_VERSION_MINOR  22
-#define ASC_LIB_SERIAL_NUMBER  113
+#define ASC_LIB_VERSION_MINOR  24
+#define ASC_LIB_SERIAL_NUMBER  121
 
 typedef unsigned char uchar;
 
@@ -832,6 +888,15 @@ typedef unsigned char uchar;
 #define  ASC_DVCLIB_CALL_FAILED   (0)
 #define  ASC_DVCLIB_CALL_ERROR    (-1)
 
+/*
+ * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
+ * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
+ * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
+ * SRB structure.
+ */
+#define CC_VERY_LONG_SG_LIST 0
+#define ASC_SRB2SCSIQ(srb_ptr)  (srb_ptr)
+
 #define PortAddr            unsigned short    /* port address size  */
 #define Ptr2Func            ulong
 #define inp(port)           inb(port)
@@ -976,6 +1041,9 @@ typedef unsigned char uchar;
 #define SCSI_TYPE_COMM     0x09
 #define SCSI_TYPE_UNKNOWN  0x1F
 #define SCSI_TYPE_NO_DVC   0xFF
+#define INQ_CLOCKING_ST_ONLY    0x0
+#define INQ_CLOCKING_DT_ONLY    0x1
+#define INQ_CLOCKING_ST_AND_DT  0x3
 #define ASC_SCSIDIR_NOCHK    0x00
 #define ASC_SCSIDIR_T2H      0x08
 #define ASC_SCSIDIR_H2T      0x10
@@ -1194,9 +1262,10 @@ typedef struct asc_req_sense {
 #define ASC_SCSIQ_CDB_BEG             36
 #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
 #define ASC_SCSIQ_DW_REMAIN_XFER_CNT  60
+#define ASC_SCSIQ_B_FIRST_SG_WK_QP    48
 #define ASC_SCSIQ_B_SG_WK_QP          49
 #define ASC_SCSIQ_B_SG_WK_IX          50
-#define ASC_SCSIQ_W_REQ_COUNT         52
+#define ASC_SCSIQ_W_ALT_DC1           52
 #define ASC_SCSIQ_B_LIST_CNT          6
 #define ASC_SCSIQ_B_CUR_LIST_CNT      7
 #define ASC_SGQ_B_SG_CNTL             4
@@ -1307,6 +1376,8 @@ typedef struct asc_scsi_q {
     ASC_SCSIQ_2         q2;
     uchar               *cdbptr;
     ASC_SG_HEAD         *sg_head;
+    ushort              remain_sg_entry_cnt;
+    ushort              next_sg_index;
 } ASC_SCSI_Q;
 
 typedef struct asc_scsi_req_q {
@@ -1781,6 +1852,7 @@ typedef struct asceep_config {
 #define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX  (ushort)0x8300
 #define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX   (ushort)0x8400
 #define ASC_HALT_SDTR_REJECTED (ushort)0x4000
+#define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
 #define ASC_MAX_QNO        0xF8
 #define ASC_DATA_SEC_BEG   (ushort)0x0080
 #define ASC_DATA_SEC_END   (ushort)0x0080
@@ -1876,10 +1948,10 @@ typedef struct asc_mc_saved {
 #define AscGetRiscVarDoneQTail(port)        AscReadLramByte((port), ASCV_DONENEXT_B)
 #define AscPutRiscVarFreeQHead(port, val)   AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
 #define AscPutRiscVarDoneQTail(port, val)   AscWriteLramByte((port), ASCV_DONENEXT_B, val)
-#define AscPutMCodeSDTRDoneAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data)) ;
-#define AscGetMCodeSDTRDoneAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id)) ;
-#define AscPutMCodeInitSDTRAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data) ;
-#define AscGetMCodeInitSDTRAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id)) ;
+#define AscPutMCodeSDTRDoneAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
+#define AscGetMCodeSDTRDoneAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
+#define AscPutMCodeInitSDTRAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
+#define AscGetMCodeInitSDTRAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
 #define AscSynIndexToPeriod(index)        (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
 #define AscGetChipSignatureByte(port)     (uchar)inp((port)+IOP_SIG_BYTE)
 #define AscGetChipSignatureWord(port)     (ushort)inpw((port)+IOP_SIG_WORD)
@@ -2074,8 +2146,8 @@ STATIC ulong     AscGetMaxDmaCount(ushort);
  * --- Adv Library Constants and Macros
  */
 
-#define ADV_LIB_VERSION_MAJOR  3
-#define ADV_LIB_VERSION_MINOR  45
+#define ADV_LIB_VERSION_MAJOR  5
+#define ADV_LIB_VERSION_MINOR  2
 
 /* d_os_dep.h */
 #define ADV_OS_LINUX
@@ -2105,6 +2177,8 @@ STATIC ulong     AscGetMaxDmaCount(ushort);
 #define iounmap vfree
 #endif /* version < v2.1.0 */
 
+#define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
+
 /*
  * Define total number of simultaneous maximum element scatter-gather
  * requests, i.e. ADV_TOT_SG_LIST * ADV_MAX_SG_LIST is the total number
@@ -2117,18 +2191,9 @@ STATIC ulong     AscGetMaxDmaCount(ushort);
  */
 #define ADV_MAX_SG_LIST         64
 
-/*
- * Scatter-Gather Definitions per request.
- *
- * Because SG block memory is allocated in virtual memory but is
- * referenced by the microcode as physical memory, we need to do
- * calculations to insure there will be enough physically contiguous
- * memory to support ADV_MAX_SG_LIST SG entries.
- */
-
 /* Number of SG blocks needed. */
 #define ADV_NUM_SG_BLOCK \
-     ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
+    ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
 
 /* Total contiguous memory needed for SG blocks. */
 #define ADV_SG_TOTAL_MEM_SIZE \
@@ -2136,26 +2201,16 @@ STATIC ulong     AscGetMaxDmaCount(ushort);
 
 #define ASC_PAGE_SIZE PAGE_SIZE
 
-/*
- * Number of page crossings possible for the total contiguous virtual memory
- * needed for SG blocks.
- *
- * We need to allocate this many additional SG blocks in virtual memory to
- * insure there will be space for ADV_NUM_SG_BLOCK physically contiguous
- * scatter-gather blocks.
- */
 #define ADV_NUM_PAGE_CROSSING \
     ((ADV_SG_TOTAL_MEM_SIZE + (ASC_PAGE_SIZE - 1))/ASC_PAGE_SIZE)
 
-/*
- * Define Adv Library Assertion Macro.
- */
-
 #define ADV_ASSERT(a) ASC_ASSERT(a)
 
 /* a_condor.h */
 #define ADV_PCI_VENDOR_ID               0x10CD
 #define ADV_PCI_DEVICE_ID_REV_A         0x2300
+#define ADV_PCI_DEVID_38C0800_REV1      0x2500
+#define ADV_PCI_DEVID_38C1600_REV1      0x2700
 
 #define ASC_EEP_DVC_CFG_BEGIN           (0x00)
 #define ASC_EEP_DVC_CFG_END             (0x15)
@@ -2164,31 +2219,13 @@ STATIC ulong     AscGetMaxDmaCount(ushort);
 
 #define ASC_EEP_DELAY_MS                100
 
-/*
- * EEPROM bits reference by the RISC after initialization.
- */
 #define ADV_EEPROM_BIG_ENDIAN          0x8000   /* EEPROM Bit 15 */
 #define ADV_EEPROM_BIOS_ENABLE         0x4000   /* EEPROM Bit 14 */
 #define ADV_EEPROM_TERM_POL            0x2000   /* EEPROM Bit 13 */
+#define ADV_EEPROM_CIS_LD              0x1000   /* EEPROM Bit 12 */
 
-/*
- * EEPROM configuration format
- *
- * Field naming convention: 
- *
- *  *_enable indicates the field enables or disables the feature. The
- *  value is never reset.
- *
- *  *_able indicates both whether a feature should be enabled or disabled
- *  and whether a device isi capable of the feature. At initialization
- *  this field may be set, but later if a device is found to be incapable
- *  of the feature, the field is cleared.
- *
- * Default values are maintained in a_init.c in the structure
- * Default_EEPROM_Config.
- */
-typedef struct adveep_config
-{                              
+typedef struct adveep_3550_config
+{
                                 /* Word Offset, Description */
 
   ushort cfg_lsw;               /* 00 power up initialization */
@@ -2255,7 +2292,109 @@ typedef struct adveep_config
   ushort  saved_adv_err_code;   /* 34 saved last uc and Adv Lib error code */
   ushort  saved_adv_err_addr;   /* 35 saved last uc error address         */  
   ushort  num_of_err;           /* 36 number of error */
-} ADVEEP_CONFIG; 
+} ADVEEP_3550_CONFIG; 
+
+typedef struct adveep_38C0800_config
+{
+                                /* Word Offset, Description */
+
+  ushort cfg_lsw;               /* 00 power up initialization */
+                                /*  bit 12 set - CIS Load */
+                                /*  bit 13 set - Term Polarity Control */
+                                /*  bit 14 set - BIOS Enable */
+                                /*  bit 15 set - Big Endian Mode */
+  ushort cfg_msw;               /* 01 unused      */
+  ushort disc_enable;           /* 02 disconnect enable */
+  ushort wdtr_able;             /* 03 Wide DTR able */
+  ushort sdtr_speed1;           /* 04 SDTR Speed TID 0-3 */
+  ushort start_motor;           /* 05 send start up motor */
+  ushort tagqng_able;           /* 06 tag queuing able */
+  ushort bios_scan;             /* 07 BIOS device control */
+  ushort scam_tolerant;         /* 08 no scam */
+
+  uchar  adapter_scsi_id;       /* 09 Host Adapter ID */
+  uchar  bios_boot_delay;       /*    power up wait */
+
+  uchar  scsi_reset_delay;      /* 10 reset delay */
+  uchar  bios_id_lun;           /*    first boot device scsi id & lun */
+                                /*    high nibble is lun */
+                                /*    low nibble is scsi id */
+
+  uchar  termination_se;        /* 11 0 - automatic */
+                                /*    1 - low off / high off */
+                                /*    2 - low off / high on */
+                                /*    3 - low on  / high on */
+                                /*    There is no low on  / high off */
+
+  uchar  termination_lvd;       /* 11 0 - automatic */
+                                /*    1 - low off / high off */
+                                /*    2 - low off / high on */
+                                /*    3 - low on  / high on */
+                                /*    There is no low on  / high off */
+
+  ushort bios_ctrl;             /* 12 BIOS control bits */
+                                /*  bit 0  set: BIOS don't act as initiator. */
+                                /*  bit 1  set: BIOS > 1 GB support */
+                                /*  bit 2  set: BIOS > 2 Disk Support */
+                                /*  bit 3  set: BIOS don't support removables */
+                                /*  bit 4  set: BIOS support bootable CD */
+                                /*  bit 5  set: BIOS scan enabled */
+                                /*  bit 6  set: BIOS support multiple LUNs */
+                                /*  bit 7  set: BIOS display of message */
+                                /*  bit 8  set: */
+                                /*  bit 9  set: Reset SCSI bus during init. */
+                                /*  bit 10 set: */
+                                /*  bit 11 set: No verbose initialization. */
+                                /*  bit 12 set: SCSI parity enabled */
+                                /*  bit 13 set: */
+                                /*  bit 14 set: */
+                                /*  bit 15 set: */
+  ushort  sdtr_speed2;          /* 13 SDTR speed TID 4-7 */
+  ushort  sdtr_speed3;          /* 14 SDTR speed TID 8-11 */
+  uchar   max_host_qng;         /* 15 maximum host queueing */
+  uchar   max_dvc_qng;          /*    maximum per device queuing */
+  ushort  dvc_cntl;             /* 16 control bit for driver */
+  ushort  sdtr_speed4;          /* 17 SDTR speed 4 TID 12-15 */
+  ushort  serial_number_word1;  /* 18 Board serial number word 1 */
+  ushort  serial_number_word2;  /* 19 Board serial number word 2 */
+  ushort  serial_number_word3;  /* 20 Board serial number word 3 */
+  ushort  check_sum;            /* 21 EEP check sum */
+  uchar   oem_name[16];         /* 22 OEM name */
+  ushort  dvc_err_code;         /* 30 last device driver error code */
+  ushort  adv_err_code;         /* 31 last uc and Adv Lib error code */
+  ushort  adv_err_addr;         /* 32 last uc error address */
+  ushort  saved_dvc_err_code;   /* 33 saved last dev. driver error code   */
+  ushort  saved_adv_err_code;   /* 34 saved last uc and Adv Lib error code */
+  ushort  saved_adv_err_addr;   /* 35 saved last uc error address         */
+  ushort  reserved36;           /* 36 reserved */
+  ushort  reserved37;           /* 37 reserved */
+  ushort  reserved38;           /* 38 reserved */
+  ushort  reserved39;           /* 39 reserved */
+  ushort  reserved40;           /* 40 reserved */
+  ushort  reserved41;           /* 41 reserved */
+  ushort  reserved42;           /* 42 reserved */
+  ushort  reserved43;           /* 43 reserved */
+  ushort  reserved44;           /* 44 reserved */
+  ushort  reserved45;           /* 45 reserved */
+  ushort  reserved46;           /* 46 reserved */
+  ushort  reserved47;           /* 47 reserved */
+  ushort  reserved48;           /* 48 reserved */
+  ushort  reserved49;           /* 49 reserved */
+  ushort  reserved50;           /* 50 reserved */
+  ushort  reserved51;           /* 51 reserved */
+  ushort  reserved52;           /* 52 reserved */
+  ushort  reserved53;           /* 53 reserved */
+  ushort  reserved54;           /* 54 reserved */
+  ushort  reserved55;           /* 55 reserved */
+  ushort  cisptr_lsw;           /* 56 CIS PTR LSW */
+  ushort  cisprt_msw;           /* 57 CIS PTR MSW */
+  ushort  subsysvid;            /* 58 SubSystem Vendor ID */
+  ushort  subsysid;             /* 59 SubSystem ID */
+  ushort  reserved60;           /* 60 reserved */
+  ushort  reserved61;           /* 61 reserved */
+  ushort  reserved62;           /* 62 reserved */
+  ushort  reserved63;           /* 63 reserved */
+} ADVEEP_38C0800_CONFIG;
 
 /*
  * EEPROM Commands
@@ -2279,15 +2418,15 @@ typedef struct adveep_config
 #define BIOS_CTRL_INIT_VERBOSE       0x0800
 #define BIOS_CTRL_SCSI_PARITY        0x1000
 
-/*
- * ASC 3550 Internal Memory Size - 8KB
- */
-#define ADV_CONDOR_MEMSIZE   0x2000     /* 8 KB Internal Memory */
+#define ADV_3550_MEMSIZE   0x2000       /* 8 KB Internal Memory */
+#define ADV_3550_IOLEN     0x40         /* I/O Port Range in bytes */
 
-/*
- * ASC 3550 I/O Length - 64 bytes
- */
-#define ADV_CONDOR_IOLEN     0x40       /* I/O Port Range in bytes */
+#define ADV_38C0800_MEMSIZE  0x4000     /* 16 KB Internal Memory */
+#define ADV_38C0800_IOLEN    0x100      /* I/O Port Range in bytes */
+
+#define ADV_38C1600_MEMSIZE  0x4000    /* 16 KB Internal Memory */
+#define ADV_38C1600_IOLEN    0x100     /* I/O Port Range 256 bytes */
+#define ADV_38C1600_MEMLEN   0x1000    /* Memory Range 4KB bytes */
 
 /*
  * Byte I/O register address from base of 'iop_base'.
@@ -2306,11 +2445,11 @@ typedef struct adveep_config
 #define IOPB_RES_ADDR_B         0x0B
 #define IOPB_RES_ADDR_C         0x0C
 #define IOPB_RES_ADDR_D         0x0D
-#define IOPB_RES_ADDR_E         0x0E
+#define IOPB_SOFT_OVER_WR       0x0E
 #define IOPB_RES_ADDR_F         0x0F
 #define IOPB_MEM_CFG            0x10
-#define IOPB_RES_ADDR_11        0x11
-#define IOPB_RES_ADDR_12        0x12
+#define IOPB_GPIO_CNTL          0x11
+#define IOPB_GPIO_DATA          0x12
 #define IOPB_RES_ADDR_13        0x13
 #define IOPB_FLASH_PAGE         0x14
 #define IOPB_RES_ADDR_15        0x15
@@ -2348,8 +2487,8 @@ typedef struct adveep_config
 #define IOPB_RES_ADDR_35        0x35
 #define IOPB_RES_ADDR_36        0x36
 #define IOPB_RES_ADDR_37        0x37
-#define IOPB_RES_ADDR_38        0x38
-#define IOPB_RES_ADDR_39        0x39
+#define IOPB_RAM_BIST           0x38
+#define IOPB_PLL_TEST           0x39
 #define IOPB_RES_ADDR_3A        0x3A
 #define IOPB_RES_ADDR_3B        0x3B
 #define IOPB_RFIFO_CNT          0x3C
@@ -2402,8 +2541,8 @@ typedef struct adveep_config
 #define IOPDW_RES_ADDR_8         0x08
 #define IOPDW_RES_ADDR_C         0x0C
 #define IOPDW_RES_ADDR_10        0x10
-#define IOPDW_RES_ADDR_14        0x14
-#define IOPDW_RES_ADDR_18        0x18
+#define IOPDW_COMMA              0x14
+#define IOPDW_COMMB              0x18
 #define IOPDW_RES_ADDR_1C        0x1C
 #define IOPDW_SDMA_ADDR0         0x20
 #define IOPDW_SDMA_ADDR1         0x24
@@ -2453,9 +2592,14 @@ typedef struct adveep_config
 #define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE  0x00C3
 #define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE  0x00C2
 
+#define ADV_TICKLE_NOP                      0x00
+#define ADV_TICKLE_A                        0x01
+#define ADV_TICKLE_B                        0x02
+#define ADV_TICKLE_C                        0x03
+
 #define ADV_SCSI_CTRL_RSTOUT        0x2000
 
-#define AdvIsIntPending(port)  \
+#define AdvIsIntPending(port) \
     (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
 
 /*
@@ -2492,41 +2636,34 @@ typedef struct adveep_config
 #define  TERM_CTL_L      0x0010  /* Enable External SCSI Lower Termination */
 #define CABLE_DETECT    0x000F  /* External SCSI Cable Connection Status */
 
+/*
+ * Addendum for ASC-38C0800 Chip
+ */
+#define DIS_TERM_DRV    0x4000  /* 1: Read c_det[3:0], 0: cannot read */
+#define HVD_LVD_SE      0x1C00  /* Device Detect Bits */
+#define  HVD             0x1000  /* HVD Device Detect */
+#define  LVD             0x0800  /* LVD Device Detect */
+#define  SE              0x0400  /* SE Device Detect */
+#define TERM_LVD        0x00C0  /* LVD Termination Bits */
+#define  TERM_LVD_HI     0x0080  /* Enable LVD Upper Termination */
+#define  TERM_LVD_LO     0x0040  /* Enable LVD Lower Termination */
+#define TERM_SE         0x0030  /* SE Termination Bits */
+#define  TERM_SE_HI      0x0020  /* Enable SE Upper Termination */
+#define  TERM_SE_LO      0x0010  /* Enable SE Lower Termination */
+#define C_DET_LVD       0x000C  /* LVD Cable Detect Bits */
+#define  C_DET3          0x0008  /* Cable Detect for LVD External Wide */
+#define  C_DET2          0x0004  /* Cable Detect for LVD Internal Wide */
+#define C_DET_SE        0x0003  /* SE Cable Detect Bits */
+#define  C_DET1          0x0002  /* Cable Detect for SE Internal Wide */
+#define  C_DET0          0x0001  /* Cable Detect for SE Internal Narrow */
+
+
 #define CABLE_ILLEGAL_A 0x7
     /* x 0 0 0  | on  on | Illegal (all 3 connectors are used) */
 
 #define CABLE_ILLEGAL_B 0xB
     /* 0 x 0 0  | on  on | Illegal (all 3 connectors are used) */
 
-/*
-   The following table details the SCSI_CFG1 Termination Polarity,
-   Termination Control and Cable Detect bits.
-
-   Cable Detect | Termination
-   Bit 3 2 1 0  | 5   4  | Notes
-   _____________|________|____________________
-       1 1 1 0  | on  on | Internal wide only
-       1 1 0 1  | on  on | Internal narrow only
-       1 0 1 1  | on  on | External narrow only
-       0 x 1 1  | on  on | External wide only
-       1 1 0 0  | on  off| Internal wide and internal narrow
-       1 0 1 0  | on  off| Internal wide and external narrow
-       0 x 1 0  | off off| Internal wide and external wide
-       1 0 0 1  | on  off| Internal narrow and external narrow
-       0 x 0 1  | on  off| Internal narrow and external wide
-       1 1 1 1  | on  on | No devices are attached
-       x 0 0 0  | on  on | Illegal (all 3 connectors are used)
-       0 x 0 0  | on  on | Illegal (all 3 connectors are used)
-  
-       x means don't-care (either '0' or '1')
-  
-       If term_pol (bit 13) is '0' (active-low terminator enable), then:
-           'on' is '0' and 'off' is '1'.
-  
-       If term_pol bit is '1' (meaning active-hi terminator enable), then:
-           'on' is '1' and 'off' is '0'.
- */
-
 /*
  * MEM_CFG Register bit definitions
  */
@@ -2564,6 +2701,22 @@ typedef struct adveep_config
 #define  READ_CMD_MRL    0x02    /* Memory Read Long */
 #define  READ_CMD_MRM    0x03    /* Memory Read Multiple (default) */
 
+/*
+ * ASC-38C0800 RAM BIST Register bit definitions
+ */
+#define RAM_TEST_MODE         0x80
+#define PRE_TEST_MODE         0x40
+#define NORMAL_MODE           0x00
+#define RAM_TEST_DONE         0x10
+#define RAM_TEST_STATUS       0x0F
+#define  RAM_TEST_HOST_ERROR   0x08
+#define  RAM_TEST_INTRAM_ERROR 0x04
+#define  RAM_TEST_RISC_ERROR   0x02
+#define  RAM_TEST_SCSI_ERROR   0x01
+#define  RAM_TEST_SUCCESS      0x00
+#define PRE_TEST_VALUE        0x05
+#define NORMAL_VALUE          0x00
+
 /* a_advlib.h */
 
 /*
@@ -2580,6 +2733,7 @@ typedef struct adveep_config
 /*
  * ASC_DVC_VAR 'warn_code' values
  */
+#define ASC_WARN_BUSRESET_ERROR         0x0001 /* SCSI Bus Reset error */
 #define ASC_WARN_EEPROM_CHKSUM          0x0002 /* EEP check sum error */
 #define ASC_WARN_EEPROM_TERMINATION     0x0004 /* EEP termination bad field */
 #define ASC_WARN_SET_PCI_CONFIG_SPACE   0x0080 /* PCI config space set error */
@@ -2596,14 +2750,18 @@ typedef struct adveep_config
  */
 #define ASC_IERR_WRITE_EEPROM       0x0001 /* write EEPROM error */
 #define ASC_IERR_MCODE_CHKSUM       0x0002 /* micro code check sum error */
+#define ASC_IERR_NO_CARRIER         0x0004 /* No more carrier memory. */
 #define ASC_IERR_START_STOP_CHIP    0x0008 /* start/stop chip failed */
 #define ASC_IERR_CHIP_VERSION       0x0040 /* wrong chip version */
 #define ASC_IERR_SET_SCSI_ID        0x0080 /* set SCSI ID failed */
+#define ASC_IERR_HVD_DEVICE         0x0100 /* HVD attached to LVD connector. */
 #define ASC_IERR_BAD_SIGNATURE      0x0200 /* signature not found */
 #define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
 #define ASC_IERR_SINGLE_END_DEVICE  0x0800 /* Single-end used w/differential */
 #define ASC_IERR_REVERSED_CABLE     0x1000 /* Narrow flat cable reversed */
-#define ASC_IERR_RW_LRAM            0x8000 /* read/write local RAM error */
+#define ASC_IERR_BIST_PRE_TEST      0x2000 /* BIST pre-test error */
+#define ASC_IERR_BIST_RAM_TEST      0x4000 /* BIST RAM test error */
+#define ASC_IERR_BAD_CHIPTYPE       0x8000 /* Invalid 'chip_type' setting. */
 
 /*
  * Fixed locations of microcode operating variables.
@@ -2611,37 +2769,38 @@ typedef struct adveep_config
 #define ASC_MC_CODE_BEGIN_ADDR          0x0028 /* microcode start address */
 #define ASC_MC_CODE_END_ADDR            0x002A /* microcode end address */
 #define ASC_MC_CODE_CHK_SUM             0x002C /* microcode code checksum */
-#define ASC_MC_STACK_BEGIN              0x002E /* microcode stack begin */
-#define ASC_MC_STACK_END                0x0030 /* microcode stack end */
 #define ASC_MC_VERSION_DATE             0x0038 /* microcode version */
 #define ASC_MC_VERSION_NUM              0x003A /* microcode number */
-#define ASCV_VER_SERIAL_W               0x003C /* used in dos_init */
 #define ASC_MC_BIOSMEM                  0x0040 /* BIOS RISC Memory Start */
 #define ASC_MC_BIOSLEN                  0x0050 /* BIOS RISC Memory Length */
-#define ASC_MC_HALTCODE                 0x0094 /* microcode halt code */
-#define ASC_MC_CALLERPC                 0x0096 /* microcode halt caller PC */
-#define ASC_MC_ADAPTER_SCSI_ID          0x0098 /* one ID byte + reserved */
-#define ASC_MC_ULTRA_ABLE               0x009C
+#define ASC_MC_BIOS_SIGNATURE           0x0058 /* BIOS Signature 0x55AA */
+#define ASC_MC_BIOS_VERSION             0x005A /* BIOS Version (2 bytes) */
+#define ASC_MC_SDTR_SPEED1              0x0090 /* SDTR Speed for TID 0-3 */
+#define ASC_MC_SDTR_SPEED2              0x0092 /* SDTR Speed for TID 4-7 */
+#define ASC_MC_SDTR_SPEED3              0x0094 /* SDTR Speed for TID 8-11 */
+#define ASC_MC_SDTR_SPEED4              0x0096 /* SDTR Speed for TID 12-15 */
+#define ASC_MC_CHIP_TYPE                0x009A
+#define ASC_MC_INTRB_CODE               0x009B
+#define ASC_MC_WDTR_ABLE                0x009C
 #define ASC_MC_SDTR_ABLE                0x009E
 #define ASC_MC_TAGQNG_ABLE              0x00A0
 #define ASC_MC_DISC_ENABLE              0x00A2
+#define ASC_MC_IDLE_CMD_STATUS          0x00A4
 #define ASC_MC_IDLE_CMD                 0x00A6
-#define ASC_MC_IDLE_PARA_STAT           0x00A8
+#define ASC_MC_IDLE_CMD_PARAMETER       0x00A8
 #define ASC_MC_DEFAULT_SCSI_CFG0        0x00AC
 #define ASC_MC_DEFAULT_SCSI_CFG1        0x00AE
 #define ASC_MC_DEFAULT_MEM_CFG          0x00B0
 #define ASC_MC_DEFAULT_SEL_MASK         0x00B2
-#define ASC_MC_RISC_NEXT_READY          0x00B4
-#define ASC_MC_RISC_NEXT_DONE           0x00B5
 #define ASC_MC_SDTR_DONE                0x00B6
 #define ASC_MC_NUMBER_OF_QUEUED_CMD     0x00C0
 #define ASC_MC_NUMBER_OF_MAX_CMD        0x00D0
 #define ASC_MC_DEVICE_HSHK_CFG_TABLE    0x0100
-#define ASC_MC_WDTR_ABLE                0x0120 /* Wide Transfer TID bitmask. */
 #define ASC_MC_CONTROL_FLAG             0x0122 /* Microcode control flag. */
 #define ASC_MC_WDTR_DONE                0x0124
-#define ASC_MC_HOST_NEXT_READY          0x0128 /* Host Next Ready RQL Entry. */
-#define ASC_MC_HOST_NEXT_DONE           0x0129 /* Host Next Done RQL Entry. */
+#define ASC_MC_CAM_MODE_MASK            0x015E /* CAM mode TID bitmask. */
+#define ASC_MC_ICQ                      0x0160
+#define ASC_MC_IRQ                      0x0164
 
 /*
  * BIOS LRAM variable absolute offsets.
@@ -2650,7 +2809,6 @@ typedef struct adveep_config
 #define BIOS_CODELEN    0x56
 #define BIOS_SIGNATURE  0x58
 #define BIOS_VERSION    0x5A
-#define BIOS_SIGNATURE  0x58
 
 /*
  * Microcode Control Flags
@@ -2667,50 +2825,61 @@ typedef struct adveep_config
 #define HSHK_CFG_RATE           0x0F00
 #define HSHK_CFG_OFFSET         0x001F
 
-/*
- * LRAM RISC Queue Lists (LRAM addresses 0x1200 - 0x19FF)
- *
- * Each of the 255 Adv Library/Microcode RISC queue lists or mailboxes 
- * starting at LRAM address 0x1200 is 8 bytes and has the following
- * structure. Only 253 of these are actually used for command queues.
- */
-
-#define ASC_MC_RISC_Q_LIST_BASE         0x1200
-#define ASC_MC_RISC_Q_LIST_SIZE         0x0008
-#define ASC_MC_RISC_Q_TOTAL_CNT         0x00FF /* Num. queue slots in LRAM. */
-#define ASC_MC_RISC_Q_FIRST             0x0001
-#define ASC_MC_RISC_Q_LAST              0x00FF
-
 #define ASC_DEF_MAX_HOST_QNG    0xFD /* Max. number of host commands (253) */
 #define ASC_DEF_MIN_HOST_QNG    0x10 /* Min. number of host commands (16) */
 #define ASC_DEF_MAX_DVC_QNG     0x3F /* Max. number commands per device (63) */
 #define ASC_DEF_MIN_DVC_QNG     0x04 /* Min. number commands per device (4) */
 
-/* RISC Queue List structure - 8 bytes */
-#define RQL_FWD     0     /* forward pointer (1 byte) */
-#define RQL_BWD     1     /* backward pointer (1 byte) */
-#define RQL_STATE   2     /* state byte - free, ready, done, aborted (1 byte) */
-#define RQL_TID     3     /* request target id (1 byte) */
-#define RQL_PHYADDR 4     /* request physical pointer (4 bytes) */
-     
-/* RISC Queue List state values */
-#define ASC_MC_QS_FREE                  0x00
-#define ASC_MC_QS_READY                 0x01
-#define ASC_MC_QS_DONE                  0x40
-#define ASC_MC_QS_ABORTED               0x80
+#define ASC_QC_DATA_CHECK  0x01 /* Require ASC_QC_DATA_OUT set or clear. */
+#define ASC_QC_DATA_OUT    0x02 /* Data out DMA transfer. */
+#define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
+#define ASC_QC_NO_OVERRUN  0x08 /* Don't report overrun. */
+#define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
+
+#define ASC_QSC_NO_DISC     0x01 /* Don't allow disconnect for request. */
+#define ASC_QSC_NO_TAGMSG   0x02 /* Don't allow tag queuing for request. */
+#define ASC_QSC_NO_SYNC     0x04 /* Don't use Synch. transfer on request. */
+#define ASC_QSC_NO_WIDE     0x08 /* Don't use Wide transfer on request. */
+#define ASC_QSC_REDO_DTR    0x10 /* Renegotiate WDTR/SDTR before request. */
+/*
+ * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
+ * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
+ */
+#define ASC_QSC_HEAD_TAG    0x40 /* Use Head Tag Message (0x21). */
+#define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
+
+typedef struct adv_carr_t
+{
+    ulong       carr_va;       /* Carrier Virtual Address */
+    ulong       carr_pa;       /* Carrier Physical Address */
+    ulong       areq_vpa;      /* ASC_SCSI_REQ_Q Virtual or Physical Address */
+    /*
+     * next_vpa [31:4]            Carrier Virtual or Physical Next Pointer
+     *
+     * next_vpa [3:1]             Reserved Bits
+     * next_vpa [0]               Done Flag set in Response Queue.
+     */
+    ulong       next_vpa;
+} ADV_CARR_T;
+
+/*
+ * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
+ */
+#define ASC_NEXT_VPA_MASK       0xFFFFFFF0
 
-/* RISC Queue List pointer values */
-#define ASC_MC_NULL_Q                   0x00            /* NULL_Q == 0   */
-#define ASC_MC_BIOS_Q                   0xFF            /* BIOS_Q = 255  */
+#define ASC_RQ_DONE             0x00000001
+#define ASC_CQ_STOPPER          0x00000000
 
-/* ASC_SCSI_REQ_Q 'cntl' field values */
-#define ASC_MC_QC_START_MOTOR           0x02     /* Issue start motor. */
-#define ASC_MC_QC_NO_OVERRUN            0x04     /* Don't report overrun. */
-#define ASC_MC_QC_FIRST_DMA             0x08     /* Internal microcode flag. */
-#define ASC_MC_QC_ABORTED               0x10     /* Request aborted by host. */
-#define ASC_MC_QC_REQ_SENSE             0x20     /* Auto-Request Sense. */
-#define ASC_MC_QC_DOS_REQ               0x80     /* Request issued by DOS. */
+#define ASC_GET_CARRP(carrp) ((ADV_CARR_T *) ((carrp) & ASC_NEXT_VPA_MASK))
 
+#define ADV_PAGE_SIZE   4096    /* Assume 4KB page size. */
+
+#define ADV_CARRIER_NUM_PAGE_CROSSING \
+    (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
+        (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
+
+#define ADV_CARRIER_BUFSIZE \
+    ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
 
 /*
  * ASC_SCSI_REQ_Q 'a_flag' definitions
@@ -2720,6 +2889,11 @@ typedef struct adveep_config
  */
 #define ADV_POLL_REQUEST                0x01   /* poll for request completion */
 #define ADV_SCSIQ_DONE                  0x02   /* request done */
+#define ADV_DONT_RETRY                  0x08   /* don't do retry */
+
+#define ADV_CHIP_ASC3550          0x01   /* Ultra-Wide IC */
+#define ADV_CHIP_ASC38C0800       0x02   /* Ultra2-Wide/LVD IC */
+#define ADV_CHIP_ASC38C1600       0x03   /* Ultra3-Wide/LVD2 IC */
 
 /*
  * Adapter temporary configuration structure
@@ -2744,12 +2918,20 @@ typedef struct adv_dvc_cfg {
   ushort pci_slot_info;     /* high byte device/function number */
                             /* bits 7-3 device num., bits 2-0 function num. */
                             /* low byte bus num. */
-  ushort bios_boot_wait;    /* BIOS boot time delay */
   ushort serial1;           /* EEPROM serial number word 1 */
   ushort serial2;           /* EEPROM serial number word 2 */
   ushort serial3;           /* EEPROM serial number word 3 */
 } ADV_DVC_CFG; 
 
+struct adv_dvc_var;
+struct adv_scsi_req_q;
+
+typedef void (* ADV_ISR_CALLBACK)
+    (struct adv_dvc_var *, struct adv_scsi_req_q *);
+
+typedef void (* ADV_ASYNC_CALLBACK)
+    (struct adv_dvc_var *, uchar);
+
 /*
  * Adapter operation variable structure.
  *
@@ -2766,23 +2948,32 @@ typedef struct adv_dvc_var {
   AdvPortAddr iop_base;   /* I/O port address */
   ushort err_code;        /* fatal error code */
   ushort bios_ctrl;       /* BIOS control word, EEPROM word 12 */
-  Ptr2Func isr_callback;  /* pointer to function, called in AdvISR() */
-  Ptr2Func sbreset_callback;  /* pointer to function, called in AdvISR() */
+  ADV_ISR_CALLBACK isr_callback;
+  ADV_ASYNC_CALLBACK async_callback;
   ushort wdtr_able;       /* try WDTR for a device */
   ushort sdtr_able;       /* try SDTR for a device */
   ushort ultra_able;      /* try SDTR Ultra speed for a device */
+  ushort sdtr_speed1;     /* EEPROM SDTR Speed for TID 0-3   */
+  ushort sdtr_speed2;     /* EEPROM SDTR Speed for TID 4-7   */
+  ushort sdtr_speed3;     /* EEPROM SDTR Speed for TID 8-11  */
+  ushort sdtr_speed4;     /* EEPROM SDTR Speed for TID 12-15 */
   ushort tagqng_able;     /* try tagged queuing with a device */
   uchar  max_dvc_qng;     /* maximum number of tagged commands per device */
   ushort start_motor;     /* start motor command allowed */
   uchar  scsi_reset_wait; /* delay in seconds after scsi bus reset */
   uchar  chip_no;         /* should be assigned by caller */
   uchar  max_host_qng;    /* maximum number of Q'ed command allowed */
-  uchar  cur_host_qng;    /* total number of queue command */
   uchar  irq_no;          /* IRQ number */
   ushort no_scam;         /* scam_tolerant of EEPROM */
-  ushort idle_cmd_done;   /* microcode idle command done set by AdvISR() */
   ulong  drv_ptr;         /* driver pointer to private structure */
   uchar  chip_scsi_id;    /* chip SCSI target ID */
+  uchar  chip_type;
+  uchar  bist_err_code;
+  ADV_CARR_T *carrier_buf;
+  ADV_CARR_T *carr_freelist; /* Carrier free list. */
+  ADV_CARR_T *icq_sp;  /* Initiator command queue stopper pointer. */
+  ADV_CARR_T *irq_sp;  /* Initiator response queue stopper pointer. */
+  ushort carr_pending_cnt;    /* Count of pending carriers. */
  /*
   * Note: The following fields will not be used after initialization. The
   * driver may discard the buffer after initialization is done.
@@ -2795,17 +2986,17 @@ typedef struct adv_dvc_var {
 typedef struct asc_sg_block {
     uchar reserved1; 
     uchar reserved2; 
-    uchar first_entry_no;             /* starting entry number */
-    uchar last_entry_no;              /* last entry number */
+    uchar reserved3;
+    uchar sg_cnt;                     /* Valid entries in block. */
     struct asc_sg_block *sg_ptr; /* links to the next sg block */
     struct  {
-        ulong sg_addr;                /* SG element address */
-        ulong sg_count;               /* SG element count */
+        ulong sg_addr;                /* SG element address. */
+        ulong sg_count;               /* SG element count. */
     } sg_list[NO_OF_SG_PER_BLOCK];
 } ADV_SG_BLOCK;
 
 /*
- * ASC_SCSI_REQ_Q - microcode request structure
+ * ADV_SCSI_REQ_Q - microcode request structure
  *
  * All fields in this structure up to byte 60 are used by the microcode.
  * The microcode makes assumptions about the size and ordering of fields
@@ -2814,35 +3005,36 @@ typedef struct asc_sg_block {
  */
 typedef struct adv_scsi_req_q {
     uchar       cntl;           /* Ucode flags and state (ASC_MC_QC_*). */
-    uchar       sg_entry_cnt;   /* SG element count. Zero for no SG. */
+    uchar       reserved;
     uchar       target_id;      /* Device target identifier. */
     uchar       target_lun;     /* Device target logical unit number. */
     ulong       data_addr;      /* Data buffer physical address. */
     ulong       data_cnt;       /* Data count. Ucode sets to residual. */
-    ulong       sense_addr;     /* Sense buffer physical address. */
-    ulong       srb_ptr;        /* Driver request pointer. */
-    uchar       a_flag;         /* Adv Library flag field. */
-    uchar       sense_len;      /* Auto-sense length. Ucode sets to residual. */
+    ulong       sense_addr;
+    ulong       carr_pa;
+    uchar       mflag;
+    uchar       sense_len;
     uchar       cdb_len;        /* SCSI CDB length. */
-    uchar       tag_code;       /* SCSI-2 Tag Queue Code: 00, 20-22. */
+    uchar       scsi_cntl;
     uchar       done_status;    /* Completion status. */
     uchar       scsi_status;    /* SCSI status byte. */
     uchar       host_status;    /* Ucode host status. */
-    uchar       ux_sg_ix;       /* Ucode working SG variable. */
+    uchar       sg_working_ix;
     uchar       cdb[12];        /* SCSI command block. */
     ulong       sg_real_addr;   /* SG list physical address. */
-    struct adv_scsi_req_q *free_scsiq_link;
-    ulong       ux_wk_data_cnt; /* Saved data count at disconnection. */
+    ulong       scsiq_rptr;
+    ulong       sg_working_data_cnt;
     struct adv_scsi_req_q *scsiq_ptr;
-    ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
+    ulong       carr_va;
     /*
      * End of microcode structure - 60 bytes. The rest of the structure
      * is used by the Adv Library and ignored by the microcode.
      */
-    ulong       vsense_addr;    /* Sense buffer virtual address. */
+    ulong       srb_ptr;
+    ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
     ulong       vdata_addr;     /* Data buffer virtual address. */
-    uchar       orig_sense_len; /* Original length of sense buffer. */
-} ADV_SCSI_REQ_Q; /* BIOS - 70 bytes, DOS - 76 bytes, W95, WNT - 69 bytes */
+    uchar       a_flag;
+} ADV_SCSI_REQ_Q;
 
 /*
  * Microcode idle loop commands
@@ -2853,7 +3045,12 @@ typedef struct adv_scsi_req_q {
 #define IDLE_CMD_SEND_INT            0x0004
 #define IDLE_CMD_ABORT               0x0008
 #define IDLE_CMD_DEVICE_RESET        0x0010
-#define IDLE_CMD_SCSI_RESET          0x0020
+#define IDLE_CMD_SCSI_RESET_START    0x0020 /* Assert SCSI Bus Reset */
+#define IDLE_CMD_SCSI_RESET_END      0x0040 /* Deassert SCSI Bus Reset */
+#define IDLE_CMD_SCSIREQ             0x0080
+
+#define IDLE_CMD_STATUS_SUCCESS      0x0001
+#define IDLE_CMD_STATUS_FAILURE      0x0002
 
 /*
  * AdvSendIdleCmd() flag definitions.
@@ -2863,8 +3060,17 @@ typedef struct adv_scsi_req_q {
 /*
  * Wait loop time out values.
  */
-#define SCSI_WAIT_10_SEC             10         /* 10 seconds */
-#define SCSI_MS_PER_SEC              1000       /* milliseconds per second */
+#define SCSI_WAIT_10_SEC             10UL    /* 10 seconds */
+#define SCSI_WAIT_100_MSEC           100UL   /* 100 milliseconds */
+#define SCSI_US_PER_MSEC             1000    /* microseconds per millisecond */
+#define SCSI_MS_PER_SEC              1000UL  /* milliseconds per second */
+#define SCSI_MAX_RETRY               10      /* retry count */
+
+#define ADV_ASYNC_RDMA_FAILURE          0x01 /* Fatal RDMA failure. */
+#define ADV_ASYNC_SCSI_BUS_RESET_DET    0x02 /* Detected SCSI Bus Reset. */
+#define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
+
+#define ADV_HOST_SCSI_BUS_RESET      0x80 /* Host Initiated SCSI Bus Reset. */
 
 /*
  * Device drivers must define the following functions.
@@ -2886,21 +3092,23 @@ STATIC int     AdvExeScsiQueue(ADV_DVC_VAR *,
 STATIC int     AdvISR(ADV_DVC_VAR *);
 STATIC int     AdvInitGetConfig(ADV_DVC_VAR *);
 STATIC int     AdvInitAsc3550Driver(ADV_DVC_VAR *);
-STATIC int     AdvResetSB(ADV_DVC_VAR *);
+STATIC int     AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
+STATIC int     AdvResetChipAndSB(ADV_DVC_VAR *);
+STATIC int     AdvResetSB(ADV_DVC_VAR *asc_dvc);
 
 /*
  * Internal Adv Library functions.
  */
-STATIC int    AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ulong, int);
-STATIC void   AdvResetChip(ADV_DVC_VAR *);
-STATIC int    AdvSendScsiCmd(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
+STATIC int    AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ulong);
 STATIC void   AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
-STATIC int    AdvInitFromEEP(ADV_DVC_VAR *);
-STATIC ushort AdvGetEEPConfig(AdvPortAddr, ADVEEP_CONFIG *);
-STATIC void   AdvSetEEPConfig(AdvPortAddr, ADVEEP_CONFIG *);
+STATIC int    AdvInitFrom3550EEP(ADV_DVC_VAR *);
+STATIC int    AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
+STATIC ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
+STATIC void   AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
+STATIC ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
+STATIC void   AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
 STATIC void   AdvWaitEEPCmd(AdvPortAddr);
 STATIC ushort AdvReadEEPWord(AdvPortAddr, int);
-STATIC void   AdvResetSCSIBus(ADV_DVC_VAR *);
 
 /*
  * PCI Bus Definitions
@@ -2911,20 +3119,16 @@ STATIC void   AdvResetSCSIBus(ADV_DVC_VAR *);
 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
 
 /* Read byte from a register. */
-#define AdvReadByteRegister(iop_base, reg_off) \
-     (inp((iop_base) + (reg_off)))
+#define AdvReadByteRegister(iop_base, reg_off) (inp((iop_base) + (reg_off)))
 
 /* Write byte to a register. */
-#define AdvWriteByteRegister(iop_base, reg_off, byte) \
-     (outp((iop_base) + (reg_off), (byte)))
+#define AdvWriteByteRegister(iop_base, reg_off, byte) (outp((iop_base) + (reg_off), (byte)))
 
 /* Read word (2 bytes) from a register. */
-#define AdvReadWordRegister(iop_base, reg_off) \
-     (inpw((iop_base) + (reg_off)))
+#define AdvReadWordRegister(iop_base, reg_off) (inpw((iop_base) + (reg_off)))
 
 /* Write word (2 bytes) to a register. */
-#define AdvWriteWordRegister(iop_base, reg_off, word) \
-     (outpw((iop_base) + (reg_off), (word)))
+#define AdvWriteWordRegister(iop_base, reg_off, word) (outpw((iop_base) + (reg_off), (word)))
 
 /* Read byte from LRAM. */
 #define AdvReadByteLram(iop_base, addr, byte) \
@@ -3060,9 +3264,9 @@ do { \
  *      ADV_TRUE(1) - Queue was successfully aborted.
  *      ADV_FALSE(0) - Queue was not found on the active queue list.
  */
-#define AdvAbortSRB(asc_dvc, srb_ptr) \
-    AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
-                (ulong) (srb_ptr), 0)
+#define AdvAbortQueue(asc_dvc, scsiq) \
+        AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
+                       (ulong) (scsiq))
 
 /*
  * Send a Bus Device Reset Message to the specified target ID.
@@ -3077,7 +3281,7 @@ do { \
  */
 #define AdvResetDevice(asc_dvc, target_id) \
         AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
-                    (ulong) (target_id), 0)
+                    (ulong) (target_id))
 
 /*
  * SCSI Wide Type definition.
@@ -3120,22 +3324,25 @@ do { \
 #define QHSTA_M_SXFR_XFR_OFLW       0x12 /* SXFR_STATUS Transfer Overflow */
 #define QHSTA_M_SXFR_XFR_PH_ERR     0x24 /* SXFR_STATUS Transfer Phase Error */
 #define QHSTA_M_SXFR_UNKNOWN_ERROR  0x25 /* SXFR_STATUS Unknown Error */
+#define QHSTA_M_SCSI_BUS_RESET      0x30 /* Request aborted from SBR */
+#define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
+#define QHSTA_M_BUS_DEVICE_RESET    0x32 /* Request aborted from BDR */
+#define QHSTA_M_DIRECTION_ERR       0x35 /* Data Phase mismatch */
+#define QHSTA_M_DIRECTION_ERR_HUNG  0x36 /* Data Phase mismatch and bus hang */
 #define QHSTA_M_WTM_TIMEOUT         0x41
 #define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
 #define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
 #define QHSTA_M_INVALID_DEVICE      0x45 /* Bad target ID */
+#define QHSTA_M_FROZEN_TIDQ         0x46 /* TID Queue frozen. */
+#define QHSTA_M_SGBACKUP_ERROR      0x47 /* Scatter-Gather backup error */
 
-typedef int (* ADV_ISR_CALLBACK)
-    (ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
-
-typedef int (* ADV_SBRESET_CALLBACK)
-    (ADV_DVC_VAR *);
 
 /*
  * Default EEPROM Configuration structure defined in a_init.c.
  */
-extern ADVEEP_CONFIG Default_EEPROM_Config;
+extern ADVEEP_3550_CONFIG Default_3550_EEPROM_Config;
+extern ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config;
 
 /*
  * DvcGetPhyAddr() flag arguments
@@ -3145,9 +3352,11 @@ extern ADVEEP_CONFIG Default_EEPROM_Config;
 #define ADV_IS_SENSE_FLAG       0x04 /* 'addr' is sense virtual pointer */
 #define ADV_IS_DATA_FLAG        0x08 /* 'addr' is data virtual pointer */
 #define ADV_IS_SGLIST_FLAG      0x10 /* 'addr' is sglist virtual pointer */
+#define ADV_IS_CARRIER_FLAG     0x20 /* 'addr' is ADV_CARR_T pointer */
 
 /* Return the address that is aligned at the next doubleword >= to 'addr'. */
 #define ADV_DWALIGN(addr)       (((ulong) (addr) + 0x3) & ~0x3)
+#define ADV_16BALIGN(addr)     (((ulong) (addr) + 0xF) & ~0xF)
 
 /*
  * Total contiguous memory needed for driver SG blocks.
@@ -3174,6 +3383,44 @@ Forced Error: Driver must define ADV_MAX_SG_LIST.
 #define ADV_ASSERT(a)
 #endif /* ADV_ASSERT */
 
+typedef struct {
+  uchar peri_dvc_type   : 5;    /* peripheral device type */
+  uchar peri_qualifier  : 3;    /* peripheral qualifier */
+  uchar dvc_type_modifier : 7;  /* device type modifier (for SCSI I) */
+  uchar rmb      : 1;           /* RMB - removable medium bit */
+  uchar ansi_apr_ver : 3;       /* ANSI approved version */
+  uchar ecma_ver : 3;           /* ECMA version */
+  uchar iso_ver  : 2;           /* ISO version */
+  uchar rsp_data_fmt : 4;       /* response data format */
+                                /* 0 SCSI 1 */
+                                /* 1 CCS */
+                                /* 2 SCSI-2 */
+                                /* 3-F reserved */
+  uchar res1     : 2;           /* reserved */
+  uchar TemIOP   : 1;           /* terminate I/O process bit (see 5.6.22) */
+  uchar aenc     : 1;           /* asynch. event notification (processor) */
+  uchar add_len;                /* additional length */
+  uchar res2;                   /* reserved */
+  uchar res3;                   /* reserved */
+  uchar StfRe   : 1;            /* soft reset implemented */
+  uchar CmdQue  : 1;            /* command queuing */
+  uchar res4    : 1;            /* reserved */
+  uchar Linked  : 1;            /* linked command for this logical unit */
+  uchar Sync    : 1;            /* synchronous data transfer */
+  uchar WBus16  : 1;            /* wide bus 16 bit data transfer */
+  uchar WBus32  : 1;            /* wide bus 32 bit data transfer */
+  uchar RelAdr  : 1;            /* relative addressing mode */
+  uchar vendor_id[8];           /* vendor identification */
+  uchar product_id[16];         /* product identification */
+  uchar product_rev_level[4];   /* product revision level */
+  uchar vendor_specific[20];    /* vendor specific */
+  uchar IUS      : 1;           /* information unit supported */
+  uchar QAS      : 1;           /* quick arbitrate supported */
+  uchar Clocking : 2;           /* clocking field */
+  uchar res5     : 4;           /* reserved */
+  uchar res6;                   /* reserved */
+} ADV_SCSI_INQUIRY; /* 58 bytes */
+
 
 /*
  * --- Driver Constants and Macros
@@ -3203,13 +3450,17 @@ Forced Error: Driver must define ADV_MAX_SG_LIST.
  * are not used when the driver is built as a module, cf. linux/init.h.
  */
 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,23)
-#define ASC_INITFUNC(func)      func
+#define ASC_INITFUNC(type, func)        type func
 #define ASC_INITDATA
 #define ASC_INIT
 #else /* version >= v2.1.23 */
-#define ASC_INITFUNC(func)      __initfunc(func)
-#define ASC_INITDATA            __initdata
-#define ASC_INIT                __init
+#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,3,16)
+#define ASC_INITFUNC(type, func)        __initfunc(type func)
+#else /* version >= v2.3.16 */
+#define ASC_INITFUNC(type, func)        type __init func
+#endif /* version >= v2.3.16 */
+#define ASC_INITDATA                    __initdata
+#define ASC_INIT                        __init
 #endif /* version >= v2.1.23 */
 
 #define ASC_INFO_SIZE           128            /* advansys_info() line size */
@@ -3352,11 +3603,12 @@ typedef Scsi_Cmnd            REQ, *REQP;
 #define PCI_MAX_BUS             0xFF
 #define PCI_IOADDRESS_MASK      0xFFFE
 #define ASC_PCI_VENDORID        0x10CD
-#define ASC_PCI_DEVICE_ID_CNT   4       /* PCI Device ID count. */
+#define ASC_PCI_DEVICE_ID_CNT   5       /* PCI Device ID count. */
 #define ASC_PCI_DEVICE_ID_1100  0x1100
 #define ASC_PCI_DEVICE_ID_1200  0x1200
 #define ASC_PCI_DEVICE_ID_1300  0x1300
-#define ASC_PCI_DEVICE_ID_2300  0x2300
+#define ASC_PCI_DEVICE_ID_2300  0x2300  /* ASC-3550 */
+#define ASC_PCI_DEVICE_ID_2500  0x2500  /* ASC-38C0800 */
 
 /* PCI IO Port Addresses to generate special cycle */
 
@@ -3662,14 +3914,12 @@ typedef struct asc_board {
     ADV_SCSI_BIT_ID_TYPE init_tidmask;          /* Target init./valid mask */
     Scsi_Device          *device[ADV_MAX_TID+1]; /* Mid-Level Scsi Device */
     ushort               reqcnt[ADV_MAX_TID+1]; /* Starvation request count */
-#if ASC_QUEUE_FLOW_CONTROL
-    ushort               nerrcnt[ADV_MAX_TID+1]; /* No error request count */
-#endif /* ASC_QUEUE_FLOW_CONTROL */
     ADV_SCSI_BIT_ID_TYPE queue_full;            /* Queue full mask */
     ushort               queue_full_cnt[ADV_MAX_TID+1]; /* Queue full count */
     union {
-        ASCEEP_CONFIG    asc_eep;               /* Narrow EEPROM config. */
-        ADVEEP_CONFIG    adv_eep;               /* Wide EEPROM config. */
+        ASCEEP_CONFIG         asc_eep;          /* Narrow EEPROM config. */
+        ADVEEP_3550_CONFIG    adv_3550_eep;     /* 3550 EEPROM config. */
+        ADVEEP_38C0800_CONFIG adv_38C0800_eep;  /* 38C0800 EEPROM config. */
     } eep_config;
     ulong                last_reset;            /* Saved last reset time */
 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
@@ -3692,6 +3942,7 @@ typedef struct asc_board {
      */
     void                 *ioremap_addr;         /* I/O Memory remap address. */
     ushort               ioport;                /* I/O Port address. */
+    ADV_CARR_T           *orig_carrp;           /* ADV_CARR_T memory block. */
     adv_req_t            *orig_reqp;            /* adv_req_t memory block. */
     adv_req_t            *adv_reqp;             /* Request structures. */
     adv_sgblk_t          *orig_sgblkp;          /* adv_sgblk_t memory block. */
@@ -3810,6 +4061,7 @@ STATIC int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 };
  * 16 elements of each structure. v1.3.0 kernels will probably
  * not need any more than this number.
  */
+uchar adv_carr_buf[20 * sizeof(ADV_CARR_T)] = { 0 };
 uchar adv_req_buf[16 * sizeof(adv_req_t)] = { 0 };
 uchar adv_sgblk_buf[16 * sizeof(adv_sgblk_t)] = { 0 };
 #endif /* version >= v1,3,0 */
@@ -3856,6 +4108,7 @@ STATIC int        adv_build_req(asc_board_t *, Scsi_Cmnd *, ADV_SCSI_REQ_Q **);
 STATIC int        adv_get_sglist(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *, Scsi_Cmnd *);
 STATIC void       asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
 STATIC void       adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
+STATIC void       adv_async_callback(ADV_DVC_VAR *, uchar);
 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
 #ifdef ASC_CONFIG_PCI
 STATIC int        asc_srch_pci_dev(PCI_DEVICE *);
@@ -3885,7 +4138,7 @@ STATIC int        asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
 STATIC int        asc_prt_line(char *, int, char *fmt, ...);
 #endif /* version >= v1.3.0 */
 
-/* Declaration for Asc Library internal functions reference by driver. */
+/* Declaration for Asc Library internal functions referenced by driver. */
 STATIC int          AscFindSignature(PortAddr);
 STATIC ushort       AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
 
@@ -3942,7 +4195,6 @@ advansys_proc_info(char *buffer, char **start, off_t offset, int length,
                    int hostno, int inout)
 {
 #ifdef CONFIG_PROC_FS
-
     struct Scsi_Host    *shp;
     asc_board_t         *boardp;
     int                 i;
@@ -4152,9 +4404,9 @@ advansys_proc_info(char *buffer, char **start, off_t offset, int length,
 #else /* CONFIG_PROC_FS */
     return 0;
 #endif /* CONFIG_PROC_FS */
-
 }
 #endif /* version >= v1.3.0 */
+
 /*
  * advansys_detect()
  *
@@ -4169,21 +4421,26 @@ advansys_proc_info(char *buffer, char **start, off_t offset, int length,
  * and scsi_free().
  */
 ASC_INITFUNC(
-int
+int,
 advansys_detect(Scsi_Host_Template *tpnt)
 )
 {
     static int          detect_called = ASC_FALSE;
     int                 iop;
     int                 bus;
-    struct Scsi_Host    *shp;
-    asc_board_t         *boardp;
+    struct Scsi_Host    *shp = NULL;
+    asc_board_t         *boardp = NULL;
     ASC_DVC_VAR         *asc_dvc_varp = NULL;
     ADV_DVC_VAR         *adv_dvc_varp = NULL;
     int                 ioport = 0;
     int                 share_irq = FALSE;
+    int                 iolen = 0;
 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
 #ifdef ASC_CONFIG_PCI
+    int                 pci_init_search = 0;
+    PCI_DEVICE          pci_device[ASC_NUM_BOARD_SUPPORTED];
+    int                 pci_card_cnt_max = 0;
+    int                 pci_card_cnt = 0;
     PCI_DEVICE          pciDevice;
     PCI_CONFIG_SPACE    pciConfig;
 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
@@ -4192,13 +4449,18 @@ advansys_detect(Scsi_Host_Template *tpnt)
 #endif /* ASC_CONFIG_PCI */
 #else /* version >= v2.1.93 */ 
 #ifdef CONFIG_PCI
+    int                 pci_init_search = 0;
+    struct pci_dev      *pci_devicep[ASC_NUM_BOARD_SUPPORTED];
+    int                 pci_card_cnt_max = 0;
+    int                 pci_card_cnt = 0;
     struct pci_dev      *pci_devp = NULL;
     int                 pci_device_id_cnt = 0;
     unsigned int        pci_device_id[ASC_PCI_DEVICE_ID_CNT] = {
                                     ASC_PCI_DEVICE_ID_1100,
                                     ASC_PCI_DEVICE_ID_1200,
                                     ASC_PCI_DEVICE_ID_1300,
-                                    ASC_PCI_DEVICE_ID_2300
+                                    ASC_PCI_DEVICE_ID_2300,
+                                    ASC_PCI_DEVICE_ID_2500
                         };
     unsigned long       pci_memory_address;
 #endif /* CONFIG_PCI */
@@ -4312,10 +4574,10 @@ advansys_detect(Scsi_Host_Template *tpnt)
                                 (AscGetChipVersion(iop, ASC_IS_ISA) &
                                  ASC_CHIP_VER_ISA_BIT) == 0) {
                                  /*
-                                 * Don't clear 'asc_ioport[ioport]'. Try
-                                 * this board again for VL. Increment
-                                 * 'ioport' past this board.
-                                 */
+                                  * Don't clear 'asc_ioport[ioport]'. Try
+                                  * this board again for VL. Increment
+                                  * 'ioport' past this board.
+                                  */
                                  ioport++;
                                  goto ioport_try_again;
                             }
@@ -4334,12 +4596,54 @@ advansys_detect(Scsi_Host_Template *tpnt)
                 iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
                 break;
 
+            case ASC_IS_PCI:
 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
 #ifdef ASC_CONFIG_PCI
-            case ASC_IS_PCI:
-                if (asc_srch_pci_dev(&pciDevice) != PCI_DEVICE_FOUND) {
+                if (pci_init_search == 0) {
+                    int i, j;
+
+                    pci_init_search = 1;
+
+                    /* Find all PCI cards. */
+                    while (asc_srch_pci_dev(&pciDevice) == PCI_DEVICE_FOUND) {
+                        pci_device[pci_card_cnt_max++] = pciDevice;
+                    }
+
+                    /*
+                     * Sort PCI cards in ascending order by PCI Bus, Slot,
+                     * and Device Number.
+                     */
+                    for (i = 0; i < pci_card_cnt_max - 1; i++)
+                    {
+                        for (j = i + 1; j < pci_card_cnt_max; j++) {
+                            if ((pci_device[j].busNumber <
+                                 pci_device[i].busNumber) ||
+                                ((pci_device[j].busNumber ==
+                                  pci_device[i].busNumber) &&
+                                  (pci_device[j].slotNumber <
+                                   pci_device[i].slotNumber)) ||
+                                ((pci_device[j].busNumber ==
+                                  pci_device[i].busNumber) &&
+                                  (pci_device[j].slotNumber ==
+                                   pci_device[i].slotNumber) &&
+                                  (pci_device[j].devFunc <
+                                   pci_device[i].devFunc))) {
+                                pciDevice = pci_device[i];
+                                pci_device[i] = pci_device[j];
+                                pci_device[j] = pciDevice;
+                            }
+                        }
+                    }
+
+                    pci_card_cnt = 0;
+                } else {
+                    pci_card_cnt++;
+                }
+
+                if (pci_card_cnt == pci_card_cnt_max) {
                     iop = 0;
                 } else {
+                    pciDevice = pci_device[pci_card_cnt];
                     ASC_DBG2(2,
                         "advansys_detect: slotFound %d, busNumber %d\n",
                         pciDevice.slotFound, pciDevice.busNumber);
@@ -4355,31 +4659,69 @@ advansys_detect(Scsi_Host_Template *tpnt)
 #endif /* ASC_CONFIG_PCI */
 #else /* version >= v2.1.93 */ 
 #ifdef CONFIG_PCI
-            case ASC_IS_PCI:
-                while (pci_device_id_cnt < ASC_PCI_DEVICE_ID_CNT) {
-                    if ((pci_devp = pci_find_device(ASC_PCI_VENDORID,
-                         pci_device_id[pci_device_id_cnt], pci_devp)) == NULL) {
-                        pci_device_id_cnt++;
-                    } else {
-                        break;
+                if (pci_init_search == 0) {
+                    int i, j;
+
+                    pci_init_search = 1;
+
+                    /* Find all PCI cards. */
+                    while (pci_device_id_cnt < ASC_PCI_DEVICE_ID_CNT) {
+                        if ((pci_devp = pci_find_device(ASC_PCI_VENDORID,
+                            pci_device_id[pci_device_id_cnt], pci_devp)) ==
+                            NULL) {
+                            pci_device_id_cnt++;
+                        } else {
+                            pci_devicep[pci_card_cnt_max++] = pci_devp;
+                        }
+                    }
+
+                    /*
+                     * Sort PCI cards in ascending order by PCI Bus, Slot,
+                     * and Device Number.
+                     */
+                    for (i = 0; i < pci_card_cnt_max - 1; i++)
+                    {
+                        for (j = i + 1; j < pci_card_cnt_max; j++) {
+                            if ((pci_devicep[j]->bus->number <
+                                 pci_devicep[i]->bus->number) ||
+                                ((pci_devicep[j]->bus->number ==
+                                  pci_devicep[i]->bus->number) &&
+                                  (pci_devicep[j]->devfn <
+                                   pci_devicep[i]->devfn))) {
+                                pci_devp = pci_devicep[i];
+                                pci_devicep[i] = pci_devicep[j];
+                                pci_devicep[j] = pci_devp;
+                            }
+                        }
                     }
+
+                    pci_card_cnt = 0;
+                } else {
+                    pci_card_cnt++;
                 }
-                if (pci_devp == NULL) {
+
+                if (pci_card_cnt == pci_card_cnt_max) {
                     iop = 0;
                 } else {
+                    pci_devp = pci_devicep[pci_card_cnt];
+
                     ASC_DBG2(2,
                         "advansys_detect: devfn %d, bus number %d\n",
                         pci_devp->devfn, pci_devp->bus->number);
+#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,3,13)
                     iop = pci_devp->base_address[0] & PCI_IOADDRESS_MASK;
+#else /* version >= v2.3.13 */ 
+                    iop = pci_devp->resource[1].start & PCI_IOADDRESS_MASK;
+#endif /* version >= v2.3.13 */ 
                     ASC_DBG2(1,
                         "advansys_detect: vendorID %X, deviceID %X\n",
                         pci_devp->vendor, pci_devp->device);
                     ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n",
                         iop, pci_devp->irq);
                 }
-                break;
 #endif /* CONFIG_PCI */
 #endif /* version >= v2.1.93 */ 
+                break;
 
             default:
                 ASC_PRINT1("advansys_detect: unknown bus type: %d\n",
@@ -4422,14 +4764,18 @@ advansys_detect(Scsi_Host_Template *tpnt)
 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
 #ifdef ASC_CONFIG_PCI
             if (asc_bus[bus] == ASC_IS_PCI &&
-                 pciConfig.deviceID == ASC_PCI_DEVICE_ID_2300) {
+                (pciConfig.deviceID == ASC_PCI_DEVICE_ID_2300 ||
+                 pciConfig.deviceID == ASC_PCI_DEVICE_ID_2500))
+            {
                 boardp->flags |= ASC_IS_WIDE_BOARD;
             }
 #endif /* ASC_CONFIG_PCI */
 #else /* version >= v2.1.93 */ 
 #ifdef CONFIG_PCI
             if (asc_bus[bus] == ASC_IS_PCI &&
-                 pci_devp->device == ASC_PCI_DEVICE_ID_2300) {
+                (pci_devp->device == ASC_PCI_DEVICE_ID_2300 ||
+                 pci_devp->device == ASC_PCI_DEVICE_ID_2500))
+            {
                 boardp->flags |= ASC_IS_WIDE_BOARD;
             }
 #endif /* CONFIG_PCI */
@@ -4449,7 +4795,34 @@ advansys_detect(Scsi_Host_Template *tpnt)
                 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
                 adv_dvc_varp->drv_ptr = (ulong) boardp;
                 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
-                adv_dvc_varp->isr_callback = (Ptr2Func) adv_isr_callback;
+                adv_dvc_varp->isr_callback = adv_isr_callback;
+                adv_dvc_varp->async_callback = adv_async_callback;
+
+#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
+#ifdef ASC_CONFIG_PCI
+                if (pciConfig.deviceID == ASC_PCI_DEVICE_ID_2300)
+                {
+                    ASC_DBG(1, "advansys_detect: ASC-3550\n");
+                    adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
+                } else
+                {
+                    ASC_DBG(1, "advansys_detect: ASC-38C0800\n");
+                    adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
+                }
+#endif /* ASC_CONFIG_PCI */
+#else /* version >= v2.1.93 */ 
+#ifdef CONFIG_PCI
+                if (pci_devp->device == ASC_PCI_DEVICE_ID_2300)
+                {
+                    ASC_DBG(1, "advansys_detect: ASC-3550\n");
+                    adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
+                } else
+                {
+                    ASC_DBG(1, "advansys_detect: ASC-38C0800\n");
+                    adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
+                }
+#endif /* CONFIG_PCI */
+#endif /* version >= v2.1.93 */ 
 
 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
                 adv_dvc_varp->iop_base = iop;
@@ -4465,39 +4838,61 @@ advansys_detect(Scsi_Host_Template *tpnt)
                  * PCI register base address will not cross a page
                  * boundary.
                  */
+                if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
+                {
+                    iolen = ADV_3550_IOLEN;
+                } else {
+                    iolen = ADV_38C0800_IOLEN;
+                }
 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
 #ifdef ASC_CONFIG_PCI
                 pci_memory_address = pciConfig.baseAddress[1];
+                ASC_DBG1(1, "advansys_detect: pci_memory_address: %lu\n",
+                    pci_memory_address);
                 if ((boardp->ioremap_addr =
                     ioremap(pci_memory_address & PAGE_MASK,
                          PAGE_SIZE)) == 0) {
                    ASC_PRINT3(
 "advansys_detect: board %d: ioremap(%lx, %d) returned NULL\n",
-                   boardp->id, pci_memory_address, ADV_CONDOR_IOLEN);
+                   boardp->id, pci_memory_address, iolen);
                    scsi_unregister(shp);
                    asc_board_count--;
                    continue;
                 }
+                ASC_DBG1(1, "advansys_detect: ioremap_addr: %lx\n",
+                    (ulong) boardp->ioremap_addr);
                 adv_dvc_varp->iop_base = (AdvPortAddr)
                     (boardp->ioremap_addr +
                      (pci_memory_address - (pci_memory_address & PAGE_MASK)));
+                ASC_DBG1(1, "advansys_detect: iop_base: %lx\n",
+                    adv_dvc_varp->iop_base);
 #endif /* ASC_CONFIG_PCI */
 #else /* version >= v2.1.93 */ 
 #ifdef CONFIG_PCI
+#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,3,13)
                 pci_memory_address = pci_devp->base_address[1];
+#else /* version >= v2.3.13 */ 
+                pci_memory_address = pci_devp->resource[1].start;
+#endif /* version >= v2.3.13 */ 
+                ASC_DBG1(1, "advansys_detect: pci_memory_address: %lu\n",
+                    pci_memory_address);
                 if ((boardp->ioremap_addr =
                     ioremap(pci_memory_address & PAGE_MASK,
                          PAGE_SIZE)) == 0) {
                    ASC_PRINT3(
 "advansys_detect: board %d: ioremap(%lx, %d) returned NULL\n",
-                   boardp->id, pci_memory_address, ADV_CONDOR_IOLEN);
+                   boardp->id, pci_memory_address, iolen);
                    scsi_unregister(shp);
                    asc_board_count--;
                    continue;
                 }
+                ASC_DBG1(1, "advansys_detect: ioremap_addr: %lx\n",
+                    (ulong) boardp->ioremap_addr);
                 adv_dvc_varp->iop_base = (AdvPortAddr)
                     (boardp->ioremap_addr +
                      (pci_memory_address - (pci_memory_address & PAGE_MASK)));
+                ASC_DBG1(1, "advansys_detect: iop_base: %lx\n",
+                    adv_dvc_varp->iop_base);
 #endif /* CONFIG_PCI */
 #endif /* version >= v2.1.93 */ 
 #endif /* version >= v1,3,0 */
@@ -4509,6 +4904,9 @@ advansys_detect(Scsi_Host_Template *tpnt)
                  * displayed.
                  */
                 boardp->ioport = iop;
+
+                ASC_DBG2(1, "iopb_chip_id_1 %x, iopw_chip_id_0 %x\n",
+                    (ushort) inp(iop + 1), (ushort) inpw(iop));
             }
 
 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
@@ -4590,9 +4988,9 @@ advansys_detect(Scsi_Host_Template *tpnt)
                 shp->irq = adv_dvc_varp->irq_no = pciConfig.irqLine;
                 adv_dvc_varp->cfg->pci_device_id = pciConfig.deviceID;
                 adv_dvc_varp->cfg->pci_slot_info =
-                ASC_PCI_MKID(pciDevice.busNumber,
-                    pciDevice.slotFound,
-                    pciDevice.devFunc);
+                    ASC_PCI_MKID(pciDevice.busNumber,
+                        pciDevice.slotFound,
+                        pciDevice.devFunc);
                 shp->unchecked_isa_dma = FALSE;
                 share_irq = TRUE;
 #endif /* ASC_CONFIG_PCI */
@@ -4601,9 +4999,9 @@ advansys_detect(Scsi_Host_Template *tpnt)
                 shp->irq = adv_dvc_varp->irq_no = pci_devp->irq;
                 adv_dvc_varp->cfg->pci_device_id = pci_devp->device;
                 adv_dvc_varp->cfg->pci_slot_info =
-                ASC_PCI_MKID(pci_devp->bus->number,
-                    PCI_SLOT(pci_devp->devfn),
-                    PCI_FUNC(pci_devp->devfn));
+                    ASC_PCI_MKID(pci_devp->bus->number,
+                        PCI_SLOT(pci_devp->devfn),
+                        PCI_FUNC(pci_devp->devfn));
                 shp->unchecked_isa_dma = FALSE;
                 share_irq = TRUE;
 #endif /* CONFIG_PCI */
@@ -4620,7 +5018,7 @@ advansys_detect(Scsi_Host_Template *tpnt)
                   * longer be used. If the bus_type field must be
                   * referenced only use the bit-wise AND operator "&".
                   */
-                 ASC_DBG(2, "advansys_detect: AscInitGetConfig()\n");
+                ASC_DBG(2, "advansys_detect: AscInitGetConfig()\n");
                 switch(ret = AscInitGetConfig(asc_dvc_varp)) {
                 case 0:    /* No error */
                     break;
@@ -4780,30 +5178,62 @@ advansys_detect(Scsi_Host_Template *tpnt)
                     shp->irq = asc_dvc_varp->irq_no;
                 }
             } else {
-
-                ADVEEP_CONFIG *ep;
+                ADVEEP_3550_CONFIG      *ep_3550;
+                ADVEEP_38C0800_CONFIG   *ep_38C0800;
 
                 /*
                  * Save Wide EEP Configuration Information.
                  */
-                ep = &boardp->eep_config.adv_eep;
-
-                ep->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
-                ep->max_host_qng = adv_dvc_varp->max_host_qng;
-                ep->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
-                ep->termination = adv_dvc_varp->cfg->termination;
-                ep->disc_enable = adv_dvc_varp->cfg->disc_enable;
-                ep->bios_ctrl = adv_dvc_varp->bios_ctrl;
-                ep->wdtr_able = adv_dvc_varp->wdtr_able;
-                ep->sdtr_able = adv_dvc_varp->sdtr_able;
-                ep->ultra_able = adv_dvc_varp->ultra_able;
-                ep->tagqng_able = adv_dvc_varp->tagqng_able;
-                ep->start_motor = adv_dvc_varp->start_motor;
-                ep->scsi_reset_delay = adv_dvc_varp->scsi_reset_wait;
-                ep->bios_boot_delay = adv_dvc_varp->cfg->bios_boot_wait;
-                ep->serial_number_word1 = adv_dvc_varp->cfg->serial1;
-                ep->serial_number_word2 = adv_dvc_varp->cfg->serial2;
-                ep->serial_number_word3 = adv_dvc_varp->cfg->serial3;
+                if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
+                {
+                    ep_3550 = &boardp->eep_config.adv_3550_eep;
+
+                    ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
+                    ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
+                    ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
+                    ep_3550->termination = adv_dvc_varp->cfg->termination;
+                    ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
+                    ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
+                    ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
+                    ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
+                    ep_3550->ultra_able = adv_dvc_varp->ultra_able;
+                    ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
+                    ep_3550->start_motor = adv_dvc_varp->start_motor;
+                    ep_3550->scsi_reset_delay = adv_dvc_varp->scsi_reset_wait;
+                    ep_3550->serial_number_word1 =
+                        adv_dvc_varp->cfg->serial1;
+                    ep_3550->serial_number_word2 =
+                        adv_dvc_varp->cfg->serial2;
+                    ep_3550->serial_number_word3 =
+                        adv_dvc_varp->cfg->serial3;
+                } else
+                {
+                    ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
+
+                    ep_38C0800->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
+                    ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
+                    ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
+                    ep_38C0800->termination_lvd =
+                        adv_dvc_varp->cfg->termination;
+                    ep_38C0800->disc_enable = adv_dvc_varp->cfg->disc_enable;
+                    ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
+                    ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
+                    ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
+                    ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
+                    ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
+                    ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
+                    ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
+                    ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
+                    ep_38C0800->start_motor = adv_dvc_varp->start_motor;
+                    ep_38C0800->scsi_reset_delay =
+                        adv_dvc_varp->scsi_reset_wait;
+                    ep_38C0800->serial_number_word1 =
+                        adv_dvc_varp->cfg->serial1;
+                    ep_38C0800->serial_number_word2 =
+                        adv_dvc_varp->cfg->serial2;
+                    ep_38C0800->serial_number_word3 =
+                        adv_dvc_varp->cfg->serial3;
+                }
 
                 /*
                  * Set the adapter's target id bit in the 'init_tidmask' field.
@@ -4846,7 +5276,7 @@ advansys_detect(Scsi_Host_Template *tpnt)
                  * Memory Mapped I/O.
                  */
                 shp->io_port = iop;
-                shp->n_io_port = ADV_CONDOR_IOLEN;
+                shp->n_io_port = iolen;
 
                 shp->this_id = adv_dvc_varp->chip_scsi_id;
 
@@ -5069,17 +5499,30 @@ advansys_detect(Scsi_Host_Template *tpnt)
                         warn_code, err_code);
                 }
             } else {
+                ADV_CARR_T      *carrp;
                 int             req_cnt;
                 adv_req_t       *reqp = NULL;
-                int             sg_cnt;
+                int             sg_cnt = 0;
                 adv_sgblk_t     *sgp = NULL;
 
 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
+                carrp = (ADV_CARR_T *) &adv_carr_buf[0];
                 req_cnt = sizeof(adv_req_buf)/sizeof(adv_req_t);
                 sg_cnt = sizeof(adv_sgblk_buf)/sizeof(adv_sgblk_t);
                 reqp = (adv_req_t *) &adv_req_buf[0];
                 sgp = (adv_sgblk_t *) &adv_sgblk_buf[0];
 #else /* version >= v1.3.0 */
+                /*
+                 * Allocate buffer carrier structures.
+                 */
+                carrp =
+                    (ADV_CARR_T *) kmalloc(ADV_CARRIER_BUFSIZE, GFP_ATOMIC);
+                ASC_DBG1(1, "advansys_detect: carrp %x\n", (unsigned) carrp);
+
+                if (carrp == NULL) {
+                    goto kmalloc_error;
+                }
+
                 /*
                  * Allocate up to 'max_host_qng' request structures for
                  * the Wide board.
@@ -5098,6 +5541,10 @@ advansys_detect(Scsi_Host_Template *tpnt)
                         break;
                     }
                 }
+                if (reqp == NULL)
+                {
+                    goto kmalloc_error;
+                }
 
                 /*
                  * Allocate up to ADV_TOT_SG_LIST request structures for
@@ -5116,19 +5563,27 @@ advansys_detect(Scsi_Host_Template *tpnt)
                         break;
                     }
                 }
-#endif /* version >= v1.3.0 */
 
                 /*
                  * If no request structures or scatter-gather structures could
                  * be allocated, then return an error. Otherwise continue with
                  * initialization.
                  */
-                if (reqp == NULL) {
+    kmalloc_error:
+                if (carrp == NULL)
+                {
+                    ASC_PRINT1(
+"advansys_detect: board %d: error: failed to kmalloc() carrier buffer.\n",
+                        boardp->id);
+                    err_code = ADV_ERROR;
+                } else if (reqp == NULL) {
+                    kfree(carrp);
                     ASC_PRINT1(
 "advansys_detect: board %d: error: failed to kmalloc() adv_req_t buffer.\n",
                         boardp->id);
                     err_code = ADV_ERROR;
                 } else if (sgp == NULL) {
+                    kfree(carrp);
                     kfree(reqp);
                     ASC_PRINT1(
 "advansys_detect: board %d: error: failed to kmalloc() adv_sgblk_t buffer.\n",
@@ -5136,12 +5591,24 @@ advansys_detect(Scsi_Host_Template *tpnt)
                     err_code = ADV_ERROR;
                 } else {
                     
+                    /* Save carrier buffer pointer. */
+                    boardp->orig_carrp = carrp;
+
                     /*
                      * Save original pointer for kfree() in case the
                      * driver is built as a module and can be unloaded.
                      */
                     boardp->orig_reqp = reqp;
 
+                    /*
+                     * Save original pointer for kfree() in case the
+                     * driver is built as a module and can be unloaded.
+                     */
+                    boardp->orig_sgblkp = sgp;
+#endif /* version >= v1.3.0 */
+
+                    adv_dvc_varp->carrier_buf = carrp;
+
                     /*
                      * Point 'adv_reqp' to the request structures and
                      * link them together.
@@ -5153,12 +5620,6 @@ advansys_detect(Scsi_Host_Template *tpnt)
                     }
                     boardp->adv_reqp = &reqp[0];
 
-                    /*
-                     * Save original pointer for kfree() in case the
-                     * driver is built as a module and can be unloaded.
-                     */
-                    boardp->orig_sgblkp = sgp;
-
                     /*
                      * Point 'adv_sgblkp' to the request structures and
                      * link them together.
@@ -5170,24 +5631,37 @@ advansys_detect(Scsi_Host_Template *tpnt)
                     }
                     boardp->adv_sgblkp = &sgp[0];
 
-                    ASC_DBG(2, "advansys_detect: AdvInitAsc3550Driver()\n");
-                    warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
+                    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
+                    {
+                        ASC_DBG(2,
+                            "advansys_detect: AdvInitAsc3550Driver()\n");
+                        warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
+                    } else {
+                        ASC_DBG(2,
+                            "advansys_detect: AdvInitAsc38C0800Driver()\n");
+                        warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
+                    }
                     err_code = adv_dvc_varp->err_code;
 
                     if (warn_code || err_code) {
                         ASC_PRINT3(
-"AdvInitAsc3550Driver: board %d: error: warn %x, error %x\n",
+"AdvInitAsc3550/38C0800Driver: board %d: error: warn %x, error %x\n",
                             boardp->id, warn_code, adv_dvc_varp->err_code);
                     }
+#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
                 }
+#endif /* version >= v1,3,0 */
             }
 
             if (err_code != 0) {
                 release_region(shp->io_port, shp->n_io_port);
-                if (ASC_WIDE_BOARD(boardp)) {
 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
+                if (ASC_WIDE_BOARD(boardp)) {
                     iounmap(boardp->ioremap_addr);
-#endif /* version >= v1,3,0 */
+                    if (boardp->orig_carrp) {
+                        kfree(boardp->orig_carrp);
+                        boardp->orig_carrp = NULL;
+                    }
                     if (boardp->orig_reqp) {
                         kfree(boardp->orig_reqp);
                         boardp->orig_reqp = boardp->adv_reqp = NULL;
@@ -5197,6 +5671,7 @@ advansys_detect(Scsi_Host_Template *tpnt)
                         boardp->orig_sgblkp = boardp->adv_sgblkp = NULL;
                     }
                 }
+#endif /* version >= v1,3,0 */
                 if (shp->dma_channel != NO_ISA_DMA) {
                     free_dma(shp->dma_channel);
                 }
@@ -5241,10 +5716,13 @@ advansys_release(struct Scsi_Host *shp)
         free_dma(shp->dma_channel);
     }
     release_region(shp->io_port, shp->n_io_port);
-    if (ASC_WIDE_BOARD(boardp)) {
 #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
+    if (ASC_WIDE_BOARD(boardp)) {
         iounmap(boardp->ioremap_addr);
-#endif /* version >= v1,3,0 */
+        if (boardp->orig_carrp) {
+            kfree(boardp->orig_carrp);
+            boardp->orig_carrp = NULL;
+        }
         if (boardp->orig_reqp) {
             kfree(boardp->orig_reqp);
             boardp->orig_reqp = boardp->adv_reqp = NULL;
@@ -5254,7 +5732,6 @@ advansys_release(struct Scsi_Host *shp)
             boardp->orig_sgblkp = boardp->adv_sgblkp = NULL;
         }
     }
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
     ASC_ASSERT(boardp->prtbuf != NULL);
     kfree(boardp->prtbuf);
 #endif /* version >= v1.3.0 */
@@ -5280,6 +5757,8 @@ advansys_info(struct Scsi_Host *shp)
     ASC_DVC_VAR     *asc_dvc_varp;
     ADV_DVC_VAR     *adv_dvc_varp;
     char            *busname;
+    int             iolen;
+    char            *widename = NULL;
 
     boardp = ASC_BOARDP(shp);
     if (ASC_NARROW_BOARD(boardp)) {
@@ -5346,21 +5825,31 @@ advansys_info(struct Scsi_Host *shp)
          * I/O address is displayed through the driver /proc file.
          */
         adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
+        if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
+        {
+            iolen = ADV_3550_IOLEN;
+            widename = "Ultra-Wide";
+        } else {
+            iolen = ADV_38C0800_IOLEN;
+            widename = "Ultra2-Wide";
+        }
         if (boardp->bios_signature == 0x55AA) {
             sprintf(info,
-"AdvanSys SCSI %s: PCI Ultra-Wide: BIOS %X/%X, IO %X/%X, IRQ %u",
+"AdvanSys SCSI %s: PCI %s: BIOS %X/%X, IO %X/%X, IRQ %u",
                 ASC_VERSION,
+                widename,
                 boardp->bios_codeseg << 4,
                 boardp->bios_codelen > 0 ?
                 (boardp->bios_codelen << 9) - 1 : 0,
-                (unsigned) boardp->ioport, ADV_CONDOR_IOLEN - 1,
+                (unsigned) boardp->ioport, iolen - 1,
                 shp->irq);
         } else {
             sprintf(info,
-"AdvanSys SCSI %s: PCI Ultra-Wide: IO %X/%X, IRQ %u",
+"AdvanSys SCSI %s: PCI %s: IO %X/%X, IRQ %u",
                 ASC_VERSION,
+                widename,
                 (unsigned) boardp->ioport,
-                (ADV_CONDOR_IOLEN - 1),
+                (iolen - 1),
                 shp->irq);
         }
     }
@@ -5583,7 +6072,7 @@ advansys_abort(Scsi_Cmnd *scp)
                 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
                 scp->result = HOST_BYTE(DID_ABORT);
 
-                /* sti(); - FIXME!!! Enable interrupts for AscAbortSRB() must be careful about io_lock. */
+                /* sti(); XXX */ /* Enable interrupts for AscAbortSRB(). */
                 ASC_DBG1(1, "advansys_abort: before AscAbortSRB(), scp %x\n",
                     (unsigned) scp);
                 switch (AscAbortSRB(asc_dvc_varp, (ulong) scp)) {
@@ -5611,22 +6100,23 @@ advansys_abort(Scsi_Cmnd *scp)
                 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
                 scp->result = HOST_BYTE(DID_ABORT);
 
-                ASC_DBG1(1, "advansys_abort: before AdvAbortSRB(), scp %x\n",
+                ASC_DBG1(1, "advansys_abort: before AdvAbortQueue(), scp %x\n",
                     (unsigned) scp);
-                switch (AdvAbortSRB(adv_dvc_varp, (ulong) scp)) {
+#if 0 /* XXX */
+                switch (AdvAbortQueue(adv_dvc_varp, (ulong) XXX)) {
                 case ASC_TRUE:
                     /* asc_isr_callback() will be called */
-                    ASC_DBG(1, "advansys_abort: AdvAbortSRB() TRUE\n");
+                    ASC_DBG(1, "advansys_abort: AdvAbortQueue() TRUE\n");
                     ret = SCSI_ABORT_PENDING;
                     break;
                 case ASC_FALSE:
                     /* Request has apparently already completed. */
-                    ASC_DBG(1, "advansys_abort: AdvAbortSRB() FALSE\n");
+                    ASC_DBG(1, "advansys_abort: AdvAbortQueue() FALSE\n");
                     ret = SCSI_ABORT_NOT_RUNNING;
                     break;
                 case ASC_ERROR:
                 default:
-                    ASC_DBG(1, "advansys_abort: AdvAbortSRB() ERROR\n");
+                    ASC_DBG(1, "advansys_abort: AdvAbortQueue() ERROR\n");
                     ret = SCSI_ABORT_ERROR;
                     break;
                 }
@@ -5635,6 +6125,10 @@ advansys_abort(Scsi_Cmnd *scp)
                  * been processed by calling AdvISR().
                  */
                 (void) AdvISR(adv_dvc_varp);
+#else /* XXX */
+                (void) AdvResetChipAndSB(adv_dvc_varp);
+                ret = SCSI_ABORT_SUCCESS;
+#endif /* XXX */
             }
 
             /*
@@ -5648,7 +6142,6 @@ advansys_abort(Scsi_Cmnd *scp)
                 scp_found = asc_rmqueue(&boardp->done, scp);
                 ASC_ASSERT(scp_found == ASC_TRUE);
             }
-
         } else {
             /*
              * The command was not found on the active or waiting queues.
@@ -5790,8 +6283,13 @@ advansys_reset(Scsi_Cmnd *scp, unsigned int reset_flags)
         }
         scp->result = HOST_BYTE(DID_ERROR);
         ret = SCSI_RESET_ERROR;
+#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,0)
     } else if (time_after_eq(jiffies, boardp->last_reset) &&
                time_before(jiffies, boardp->last_reset + (10 * HZ))) {
+#else /* version < v2.1.0 */
+    } else if (jiffies >= boardp->last_reset &&
+               jiffies < (boardp->last_reset + (10 * HZ))) {
+#endif /* version < v2.1.0 */
         /*
          * Don't allow a reset to be attempted within 10 seconds
          * of the last reset.
@@ -5853,9 +6351,9 @@ advansys_reset(Scsi_Cmnd *scp, unsigned int reset_flags)
                  * Reset the target's SCSI bus.
                  */
                 ASC_DBG(1, "advansys_reset: before AscResetSB()\n");
-                /* sti();    FIXME!!! Enable interrupts for AscResetSB(). */
+                /* sti(); XXX */ /* Enable interrupts for AscResetSB(). */
                 status = AscResetSB(asc_dvc_varp);
-                /* cli();    FIXME!!! */
+                /* cli(); XXX */
                 switch (status) {
                 case ASC_TRUE:
                     ASC_DBG(1, "advansys_reset: AscResetSB() success\n");
@@ -5878,9 +6376,9 @@ advansys_reset(Scsi_Cmnd *scp, unsigned int reset_flags)
                 ASC_DBG1(1,
                     "advansys_reset: before AscResetDevice(), target %d\n",
                     scp->target);
-                /* sti();    FIXME!!! Enable interrupts for AscResetDevice(). */
+                /* sti(); XXX */ /* Enable interrupts for AscResetDevice(). */
                 status = AscResetDevice(asc_dvc_varp, scp->target);
-                /* cli();    FIXME!!! */
+                /* cli(); XXX */
 
                 switch (status) {
                 case ASC_TRUE:
@@ -5892,9 +6390,9 @@ advansys_reset(Scsi_Cmnd *scp, unsigned int reset_flags)
                 default:
                     ASC_DBG(1,
 "advansys_reset: AscResetDevice() failed; Calling AscResetSB()\n");
-                    /* sti();   FIXME!!! Enable interrupts for AscResetSB(). */
+                    /* sti(); XXX */ /* Enable interrupts for AscResetSB(). */
                     status = AscResetSB(asc_dvc_varp);
-                    /* cli(); */
+                    /* cli(); XXX */
                     switch (status) {
                     case ASC_TRUE:
                         ASC_DBG(1, "advansys_reset: AscResetSB() TRUE\n");
@@ -5927,15 +6425,16 @@ advansys_reset(Scsi_Cmnd *scp, unsigned int reset_flags)
                 /*
                  * Reset the target's SCSI bus.
                  */
-                ASC_DBG(1, "advansys_reset: before AdvResetSB()\n");
-                switch (AdvResetSB(adv_dvc_varp)) {
+                ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
+                switch (AdvResetChipAndSB(adv_dvc_varp)) {
                 case ASC_TRUE:
-                    ASC_DBG(1, "advansys_reset: AdvResetSB() success\n");
+                    ASC_DBG(1,
+                        "advansys_reset: AdvResetChipAndSB() success\n");
                     ret = SCSI_RESET_SUCCESS;
                     break;
                 case ASC_FALSE:
                 default:
-                    ASC_DBG(1, "advansys_reset: AdvResetSB() failed\n");
+                    ASC_DBG(1, "advansys_reset: AdvResetChipAndSB() failed\n");
                     ret = SCSI_RESET_ERROR;
                     break;
                 }
@@ -5964,16 +6463,18 @@ advansys_reset(Scsi_Cmnd *scp, unsigned int reset_flags)
                 case ASC_FALSE:
                 default:
                     ASC_DBG(1,
-"advansys_reset: AdvResetDevice() failed; Calling AdvResetSB()\n");
+"advansys_reset: AdvResetDevice() failed; Calling AdvResetChipAndSB()\n");
                     
-                    switch (AdvResetSB(adv_dvc_varp)) {
+                    switch (AdvResetChipAndSB(adv_dvc_varp)) {
                     case ASC_TRUE:
-                        ASC_DBG(1, "advansys_reset: AdvResetSB() TRUE\n");
+                        ASC_DBG(1,
+                            "advansys_reset: AdvResetChipAndSB() TRUE\n");
                         ret = SCSI_RESET_SUCCESS;
                         break;
                     case ASC_FALSE:
                     default:
-                        ASC_DBG(1, "advansys_reset: AdvResetSB() ERROR\n");
+                        ASC_DBG(1,
+                            "advansys_reset: AdvResetChipAndSB() ERROR\n");
                         ret = SCSI_RESET_ERROR;
                         break;
                     }
@@ -6193,7 +6694,7 @@ advansys_biosparam(Disk *dp, kdev_t dep, int ip[])
  * ...
  */
 ASC_INITFUNC(
-void
+void,
 advansys_setup(char *str, int *ints)
 )
 {
@@ -6547,27 +7048,6 @@ asc_execute_scsi_cmnd(Scsi_Cmnd *scp)
              */
             boardp->reqcnt[scp->target]++;
 
-#if ASC_QUEUE_FLOW_CONTROL
-            /*
-             * Conditionally increment the device queue depth.
-             *
-             * If no error occurred and there have been 100 consecutive
-             * successful requests and the current queue depth is less
-             * than the maximum queue depth, then increment the current
-             * queue depth.
-             */
-            if (boardp->nerrcnt[scp->target]++ > 100) {
-                boardp->nerrcnt[scp->target] = 0;
-                if (device != NULL &&
-                    (device->queue_curr_depth < device->queue_depth) &&
-                    (!(boardp->queue_full &
-                       ADV_TID_TO_TIDMASK(scp->target)) ||
-                     (boardp->queue_full_cnt[scp->target] >
-                      device->queue_curr_depth))) {
-                    device->queue_curr_depth++;
-                }
-            }
-#endif /* ASC_QUEUE_FLOW_CONTROL */
             asc_enqueue(&boardp->active, scp, ASC_BACK);
             ASC_DBG(1,
                 "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
@@ -6575,26 +7055,12 @@ asc_execute_scsi_cmnd(Scsi_Cmnd *scp)
         case ASC_BUSY:
             /* Caller must enqueue request and retry later. */
             ASC_STATS(scp->host, exe_busy);
-#if ASC_QUEUE_FLOW_CONTROL
-            /*
-             * Clear consecutive no error counter and if possible decrement
-             * queue depth.
-             */
-            boardp->nerrcnt[scp->target] = 0;
-            if (device != NULL && device->queue_curr_depth > 1) {
-                device->queue_curr_depth--;
-            }
-#endif /* ASC_QUEUE_FLOW_CONTROL */
             break;
         case ASC_ERROR:
             ASC_PRINT2(
 "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code %x\n",
                 boardp->id, asc_dvc_varp->err_code);
             ASC_STATS(scp->host, exe_error);
-#if ASC_QUEUE_FLOW_CONTROL
-            /* Clear consecutive no error counter. */
-            boardp->nerrcnt[scp->target] = 0;
-#endif /* ASC_QUEUE_FLOW_CONTROL */
             scp->result = HOST_BYTE(DID_ERROR);
             asc_enqueue(&boardp->done, scp, ASC_BACK);
             break;
@@ -6603,10 +7069,6 @@ asc_execute_scsi_cmnd(Scsi_Cmnd *scp)
 "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code %x\n",
                 boardp->id, asc_dvc_varp->err_code);
             ASC_STATS(scp->host, exe_unknown);
-#if ASC_QUEUE_FLOW_CONTROL
-            /* Clear consecutive no error counter. */
-            boardp->nerrcnt[scp->target] = 0;
-#endif /* ASC_QUEUE_FLOW_CONTROL */
             scp->result = HOST_BYTE(DID_ERROR);
             asc_enqueue(&boardp->done, scp, ASC_BACK);
             break;
@@ -6874,7 +7336,6 @@ adv_build_req(asc_board_t *boardp, Scsi_Cmnd *scp,
     scsiqp->target_id = scp->target;
     scsiqp->target_lun = scp->lun;
 
-    scsiqp->vsense_addr = (ulong) &scp->sense_buffer[0];
 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
     scsiqp->sense_addr = (ulong) &scp->sense_buffer[0];
 #else /* version >= v2.0.0 */
@@ -7000,7 +7461,7 @@ adv_get_sglist(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp,
     ADV_SG_BLOCK        *sg_block;              /* virtual address of a SG */
     ulong               sg_block_next_addr;     /* block and its next */
     ulong               sg_block_physical_addr;
-    int                 sg_block_index, i;      /* how many SG entries */
+    int                 i;
     struct scatterlist  *slp;
     int                 sg_elem_cnt;
 
@@ -7019,10 +7480,8 @@ adv_get_sglist(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp,
                    sg_block_physical_addr);
     scsiqp->sg_real_addr = sg_block_physical_addr;
 
-    sg_block_index = 0;
     do
     {
-        sg_block->first_entry_no = sg_block_index;
         for (i = 0; i < NO_OF_SG_PER_BLOCK; i++)
         {
             sg_block->sg_list[i].sg_addr =
@@ -7036,21 +7495,19 @@ adv_get_sglist(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp,
 
             if (--sg_elem_cnt == 0)
             {   /* last entry, get out */
-                scsiqp->sg_entry_cnt = sg_block_index + i + 1;
-                sg_block->last_entry_no = sg_block_index + i;
+                sg_block->sg_cnt = i + 1;
                 sg_block->sg_ptr = 0L;    /* next link = NULL */
                 return ADV_SUCCESS;
             }
             slp++;
         } 
+        sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
         sg_block_next_addr += sizeof(ADV_SG_BLOCK);
         sg_block_physical_addr += sizeof(ADV_SG_BLOCK);
         ADV_ASSERT(ADV_DWALIGN(sg_block_physical_addr) ==
                        sg_block_physical_addr);
 
-        sg_block_index += NO_OF_SG_PER_BLOCK;
         sg_block->sg_ptr = (ADV_SG_BLOCK *) sg_block_physical_addr;
-        sg_block->last_entry_no = sg_block_index - 1;
         sg_block = (ADV_SG_BLOCK *) sg_block_next_addr; /* virtual addr */
     }
     while (1);
@@ -7276,7 +7733,7 @@ adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
      * command that has been completed.
      *
      * Note: The adv_req_t request structure and adv_sgblk_t structure,
-     * if any, * dropped, because a board structure pointer can not be
+     * if any, are dropped, because a board structure pointer can not be
      * determined.
      */
     scp = reqp->cmndp;
@@ -7449,13 +7906,51 @@ adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
     return;
 }
 
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
-#ifdef ASC_CONFIG_PCI
+/*
+ * adv_async_callback() - Adv Library asynchronous event callback function.
+ */
+STATIC void
+adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
+{
+    switch (code)
+    {
+    case ADV_ASYNC_SCSI_BUS_RESET_DET:
+        /*
+         * The firmware detected a SCSI Bus reset.
+         */
+        ASC_DBG(0, "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
+        break;
+
+    case ADV_ASYNC_RDMA_FAILURE:
+        /*
+         * Handle RDMA failure by resetting the SCSI Bus and
+         * possibly the chip if it is unresponsive. Log the error
+         * with a unique code.
+         */
+        ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
+        AdvResetChipAndSB(adv_dvc_varp);
+        break;
+
+    case ADV_HOST_SCSI_BUS_RESET:
+        /*
+         * Host generated SCSI bus reset occurred.
+         */
+        ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
+        break;
+
+    default:
+        ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
+        break;
+    }
+}
+
+#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
+#ifdef ASC_CONFIG_PCI
 /*
  * Search for an AdvanSys PCI device in the PCI configuration space.
  */
 ASC_INITFUNC(
-STATIC int
+STATIC int,
 asc_srch_pci_dev(PCI_DEVICE *pciDevice)
 )
 {
@@ -7495,7 +7990,7 @@ asc_srch_pci_dev(PCI_DEVICE *pciDevice)
  * Determine the access method to be used for 'pciDevice'.
  */
 ASC_INITFUNC(
-STATIC uchar
+STATIC uchar,
 asc_scan_method(void)
 )
 {
@@ -7527,7 +8022,7 @@ asc_scan_method(void)
  * Return PCI_DEVICE_FOUND if found, otherwise return PCI_DEVICE_NOT_FOUND.
  */
 ASC_INITFUNC(
-STATIC int
+STATIC int,
 asc_pci_find_dev(PCI_DEVICE *pciDevice)
 )
 {
@@ -7554,7 +8049,8 @@ asc_pci_find_dev(PCI_DEVICE *pciDevice)
                 ((deviceid == ASC_PCI_DEVICE_ID_1100) ||
                  (deviceid == ASC_PCI_DEVICE_ID_1200) ||
                  (deviceid == ASC_PCI_DEVICE_ID_1300) ||
-                 (deviceid == ASC_PCI_DEVICE_ID_2300))) {
+                 (deviceid == ASC_PCI_DEVICE_ID_2300) ||
+                 (deviceid == ASC_PCI_DEVICE_ID_2500))) {
                 pciDevice->slotFound = lslot;
                 ASC_DBG(3, "asc_pci_find_dev: PCI_DEVICE_FOUND\n");
                 return PCI_DEVICE_FOUND;
@@ -7579,7 +8075,7 @@ asc_pci_find_dev(PCI_DEVICE *pciDevice)
  * Read PCI configuration data into 'pciConfig'.
  */
 ASC_INITFUNC(
-STATIC void
+STATIC void,
 asc_get_pci_cfg(PCI_DEVICE *pciDevice, PCI_CONFIG_SPACE *pciConfig)
 )
 {
@@ -7611,7 +8107,7 @@ asc_get_pci_cfg(PCI_DEVICE *pciDevice, PCI_CONFIG_SPACE *pciConfig)
  * The configuration mechanism is checked for the correct access method.
  */
 ASC_INITFUNC(
-STATIC ushort
+STATIC ushort,
 asc_get_cfg_word(PCI_DATA *pciData)
 )
 {
@@ -7642,7 +8138,7 @@ asc_get_cfg_word(PCI_DATA *pciData)
         /* set for type 1 cycle, if needed */
         outp(0xCFA, pciData->bus);
         /* set the function number */
-        outp(0xCF8, 0x10 | (pciData->func << 1)) ;
+        outp(0xCF8, 0x10 | (pciData->func << 1));
 
         /*
          * Read the configuration space type 2 locations.
@@ -7694,7 +8190,7 @@ asc_get_cfg_word(PCI_DATA *pciData)
  * The configuration mechanism is checked for the correct access method.
  */
 ASC_INITFUNC(
-STATIC uchar
+STATIC uchar,
 asc_get_cfg_byte(PCI_DATA *pciData)
 )
 {
@@ -7774,7 +8270,7 @@ asc_get_cfg_byte(PCI_DATA *pciData)
  * Write a byte to the PCI configuration space.
  */
 ASC_INITFUNC(
-STATIC void
+STATIC void,
 asc_put_cfg_byte(PCI_DATA *pciData, uchar byte_data)
 )
 {
@@ -8518,19 +9014,29 @@ asc_prt_asc_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
 STATIC int
 asc_prt_adv_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
 {
-    asc_board_t        *boardp;
-    ADV_DVC_VAR        *adv_dvc_varp;
-    int                leftlen;
-    int                totlen;
-    int                len;
-    int                i;
-    char               *termstr;
-    uchar              serialstr[13];
-    ADVEEP_CONFIG      *ep;
+    asc_board_t                 *boardp;
+    ADV_DVC_VAR                 *adv_dvc_varp;
+    int                         leftlen;
+    int                         totlen;
+    int                         len;
+    int                         i;
+    char                        *termstr;
+    uchar                       serialstr[13];
+    ADVEEP_3550_CONFIG          *ep_3550 = NULL;
+    ADVEEP_38C0800_CONFIG       *ep_38C0800 = NULL;
+    ushort                      word;
+    ushort                      *wordp;
+    ushort                      sdtr_speed = 0;
 
     boardp = ASC_BOARDP(shp);
     adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
-    ep = &boardp->eep_config.adv_eep;
+    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
+    {
+        ep_3550 = &boardp->eep_config.adv_3550_eep;
+    } else
+    {
+        ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
+    }
 
     leftlen = cplen;
     totlen = len = 0;
@@ -8539,8 +9045,15 @@ asc_prt_adv_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
     ASC_PRT_NEXT();
 
-    if (asc_get_eeprom_string(&ep->serial_number_word1, serialstr) ==
-        ASC_TRUE) {
+    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
+    {
+        wordp = &ep_3550->serial_number_word1;
+    } else
+    {
+        wordp = &ep_38C0800->serial_number_word1;
+    }
+
+    if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
         len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
         ASC_PRT_NEXT();
     } else {
@@ -8549,12 +9062,29 @@ asc_prt_adv_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
         ASC_PRT_NEXT();
     }
 
-    len = asc_prt_line(cp, leftlen,
+    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
+    {
+        len = asc_prt_line(cp, leftlen,
 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
-        ep->adapter_scsi_id, ep->max_host_qng, ep->max_dvc_qng);
-    ASC_PRT_NEXT();
-
-    switch (ep->termination) {
+            ep_3550->adapter_scsi_id, ep_3550->max_host_qng,
+            ep_3550->max_dvc_qng);
+        ASC_PRT_NEXT();
+    } else
+    {
+        len = asc_prt_line(cp, leftlen,
+" Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
+            ep_38C0800->adapter_scsi_id, ep_38C0800->max_host_qng,
+            ep_38C0800->max_dvc_qng);
+        ASC_PRT_NEXT();
+    }
+    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
+    {
+        word = ep_3550->termination;
+    } else
+    {
+        word = ep_38C0800->termination_lvd;
+    }
+    switch (word) {
         case 1:
             termstr = "Low Off/High Off";
             break;
@@ -8570,10 +9100,19 @@ asc_prt_adv_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
             break;
     }
 
-    len = asc_prt_line(cp, leftlen,
+    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
+    {
+        len = asc_prt_line(cp, leftlen,
 " termination: %u (%s), bios_ctrl: %x\n",
-        ep->termination, termstr, ep->bios_ctrl);
-    ASC_PRT_NEXT();
+            ep_3550->termination, termstr, ep_3550->bios_ctrl);
+        ASC_PRT_NEXT();
+    } else
+    {
+        len = asc_prt_line(cp, leftlen,
+" termination: %u (%s), bios_ctrl: %x\n",
+            ep_38C0800->termination_lvd, termstr, ep_38C0800->bios_ctrl);
+        ASC_PRT_NEXT();
+    }
 
     len = asc_prt_line(cp, leftlen,
 " Target ID:           ");
@@ -8585,72 +9124,150 @@ asc_prt_adv_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
     len = asc_prt_line(cp, leftlen, "\n");
     ASC_PRT_NEXT();
 
+    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
+    {
+        word = ep_3550->disc_enable;
+    } else
+    {
+        word = ep_38C0800->disc_enable;
+    }
     len = asc_prt_line(cp, leftlen,
 " Disconnects:         ");
     ASC_PRT_NEXT();
     for (i = 0; i <= ADV_MAX_TID; i++) {
         len = asc_prt_line(cp, leftlen, " %c",
-            (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+            (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
         ASC_PRT_NEXT();
     }
     len = asc_prt_line(cp, leftlen, "\n");
     ASC_PRT_NEXT();
 
+    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
+    {
+        word = ep_3550->tagqng_able;
+    } else
+    {
+        word = ep_38C0800->tagqng_able;
+    }
     len = asc_prt_line(cp, leftlen,
 " Command Queuing:     ");
     ASC_PRT_NEXT();
     for (i = 0; i <= ADV_MAX_TID; i++) {
         len = asc_prt_line(cp, leftlen, " %c",
-            (ep->tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+            (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
         ASC_PRT_NEXT();
     }
     len = asc_prt_line(cp, leftlen, "\n");
     ASC_PRT_NEXT();
 
+    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
+    {
+        word = ep_3550->start_motor;
+    } else
+    {
+        word = ep_38C0800->start_motor;
+    }
     len = asc_prt_line(cp, leftlen,
 " Start Motor:         ");
     ASC_PRT_NEXT();
     for (i = 0; i <= ADV_MAX_TID; i++) {
         len = asc_prt_line(cp, leftlen, " %c",
-            (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+            (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
         ASC_PRT_NEXT();
     }
     len = asc_prt_line(cp, leftlen, "\n");
     ASC_PRT_NEXT();
 
-    len = asc_prt_line(cp, leftlen,
+    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
+    {
+        len = asc_prt_line(cp, leftlen,
 " Synchronous Transfer:");
-    ASC_PRT_NEXT();
-    for (i = 0; i <= ADV_MAX_TID; i++) {
-        len = asc_prt_line(cp, leftlen, " %c",
-            (ep->sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+        ASC_PRT_NEXT();
+        for (i = 0; i <= ADV_MAX_TID; i++) {
+            len = asc_prt_line(cp, leftlen, " %c",
+                (ep_3550->sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+            ASC_PRT_NEXT();
+        }
+        len = asc_prt_line(cp, leftlen, "\n");
         ASC_PRT_NEXT();
     }
-    len = asc_prt_line(cp, leftlen, "\n");
-    ASC_PRT_NEXT();
 
-    len = asc_prt_line(cp, leftlen,
+    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
+    {
+        len = asc_prt_line(cp, leftlen,
 " Ultra Transfer:      ");
     ASC_PRT_NEXT();
-    for (i = 0; i <= ADV_MAX_TID; i++) {
-        len = asc_prt_line(cp, leftlen, " %c",
-            (ep->ultra_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+        for (i = 0; i <= ADV_MAX_TID; i++) {
+            len = asc_prt_line(cp, leftlen, " %c",
+                (ep_3550->ultra_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+            ASC_PRT_NEXT();
+        }
+        len = asc_prt_line(cp, leftlen, "\n");
         ASC_PRT_NEXT();
     }
-    len = asc_prt_line(cp, leftlen, "\n");
-    ASC_PRT_NEXT();
 
+    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
+    {
+        word = ep_3550->wdtr_able;
+    } else
+    {
+        word = ep_38C0800->wdtr_able;
+    }
     len = asc_prt_line(cp, leftlen,
 " Wide Transfer:       ");
     ASC_PRT_NEXT();
     for (i = 0; i <= ADV_MAX_TID; i++) {
         len = asc_prt_line(cp, leftlen, " %c",
-            (ep->wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+            (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
         ASC_PRT_NEXT();
     }
     len = asc_prt_line(cp, leftlen, "\n");
     ASC_PRT_NEXT();
 
+    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
+    {
+        len = asc_prt_line(cp, leftlen,
+" Synchronous Transfer Speed (Mhz):\n  ");
+        ASC_PRT_NEXT();
+        for (i = 0; i <= ADV_MAX_TID; i++) {
+            char *speed_str;
+
+            if (i == 0)
+            {
+                sdtr_speed = adv_dvc_varp->sdtr_speed1;
+            } else if (i == 4)
+            {
+                sdtr_speed = adv_dvc_varp->sdtr_speed2;
+            } else if (i == 8)
+            {
+                sdtr_speed = adv_dvc_varp->sdtr_speed3;
+            } else if (i == 12)
+            {
+                sdtr_speed = adv_dvc_varp->sdtr_speed4;
+            }
+            switch (sdtr_speed & ADV_MAX_TID)
+            {
+                case 0:  speed_str = "Off"; break;
+                case 1:  speed_str = "  5"; break;
+                case 2:  speed_str = " 10"; break;
+                case 3:  speed_str = " 20"; break;
+                case 4:  speed_str = " 40"; break;
+                case 5:  speed_str = " 80"; break;
+                default: speed_str = "Unk"; break;
+            }
+            len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
+            ASC_PRT_NEXT();
+            if (i == 7)
+            {
+                len = asc_prt_line(cp, leftlen, "\n  ");
+                ASC_PRT_NEXT();
+            }
+            sdtr_speed >>= 4;
+        }
+        len = asc_prt_line(cp, leftlen, "\n");
+        ASC_PRT_NEXT();
+    }
+
     return totlen;
 }
 
@@ -8748,46 +9365,6 @@ asc_prt_driver_conf(struct Scsi_Host *shp, char *cp, int cplen)
     }
 #endif /* version >= v1.3.89 */
 
-#if ASC_QUEUE_FLOW_CONTROL
-    if (ASC_NARROW_BOARD(boardp)) {
-        len = asc_prt_line(cp, leftlen, " queue_curr_depth:");
-        ASC_PRT_NEXT();
-        /* Use ASC_MAX_TID for Narrow Board. */
-        for (i = 0; i <= ASC_MAX_TID; i++) {
-            if ((boardp->asc_dvc_cfg.chip_scsi_id == i) ||
-                ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
-                continue;
-            }
-            if (boardp->device[i] == NULL) {
-                continue;
-            }
-            len = asc_prt_line(cp, leftlen, " %d:%d",
-                i, boardp->device[i]->queue_curr_depth);
-            ASC_PRT_NEXT();
-        }
-        len = asc_prt_line(cp, leftlen, "\n");
-        ASC_PRT_NEXT();
-
-        len = asc_prt_line(cp, leftlen, " queue_count:");
-        ASC_PRT_NEXT();
-        /* Use ASC_MAX_TID for Narrow Board. */
-        for (i = 0; i <= ASC_MAX_TID; i++) {
-            if ((boardp->asc_dvc_cfg.chip_scsi_id == i) ||
-                ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
-                continue;
-            }
-            if (boardp->device[i] == NULL) {
-                continue;
-            }
-            len = asc_prt_line(cp, leftlen, " %d:%d",
-                i, boardp->device[i]->queue_count);
-            ASC_PRT_NEXT();
-        }
-        len = asc_prt_line(cp, leftlen, "\n");
-        ASC_PRT_NEXT();
-    }
-#endif /* ASC_QUEUE_FLOW_CONTROL */
-
     return totlen;
 }
 
@@ -8806,16 +9383,19 @@ STATIC int
 asc_prt_asc_board_info(struct Scsi_Host *shp, char *cp, int cplen)
 {
     asc_board_t            *boardp;
+    int                    chip_scsi_id;
     int                    leftlen;
     int                    totlen;
     int                    len;
     ASC_DVC_VAR            *v;
     ASC_DVC_CFG            *c;
     int                    i;
+    int                    renegotiate = 0;
 
     boardp = ASC_BOARDP(shp);
     v = &boardp->dvc_var.asc_dvc_var;
     c = &boardp->dvc_cfg.asc_dvc_cfg;
+    chip_scsi_id = c->chip_scsi_id;
 
     leftlen = cplen;
     totlen = len = 0;
@@ -8844,11 +9424,11 @@ asc_prt_asc_board_info(struct Scsi_Host *shp, char *cp, int cplen)
 " Command Queuing:");
     ASC_PRT_NEXT();
     for (i = 0; i <= ASC_MAX_TID; i++) {
-        if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
+        if ((chip_scsi_id == i) ||
             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
             continue;
         }
-        len = asc_prt_line(cp, leftlen, " %d:%c",
+        len = asc_prt_line(cp, leftlen, " %X:%c",
             i, (v->use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
         ASC_PRT_NEXT();
     }
@@ -8860,11 +9440,11 @@ asc_prt_asc_board_info(struct Scsi_Host *shp, char *cp, int cplen)
 " Command Queue Pending:");
     ASC_PRT_NEXT();
     for (i = 0; i <= ASC_MAX_TID; i++) {
-        if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
+        if ((chip_scsi_id == i) ||
             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
             continue;
         }
-        len = asc_prt_line(cp, leftlen, " %d:%u", i, v->cur_dvc_qng[i]);
+        len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
         ASC_PRT_NEXT();
     }
     len = asc_prt_line(cp, leftlen, "\n");
@@ -8875,11 +9455,11 @@ asc_prt_asc_board_info(struct Scsi_Host *shp, char *cp, int cplen)
 " Command Queue Limit:");
     ASC_PRT_NEXT();
     for (i = 0; i <= ASC_MAX_TID; i++) {
-        if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
+        if ((chip_scsi_id == i) ||
             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
             continue;
         }
-        len = asc_prt_line(cp, leftlen, " %d:%u", i, v->max_dvc_qng[i]);
+        len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
         ASC_PRT_NEXT();
     }
     len = asc_prt_line(cp, leftlen, "\n");
@@ -8890,15 +9470,15 @@ asc_prt_asc_board_info(struct Scsi_Host *shp, char *cp, int cplen)
 " Command Queue Full:");
     ASC_PRT_NEXT();
     for (i = 0; i <= ASC_MAX_TID; i++) {
-        if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
+        if ((chip_scsi_id == i) ||
             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
             continue;
         }
         if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
-            len = asc_prt_line(cp, leftlen, " %d:Y-%d",
+            len = asc_prt_line(cp, leftlen, " %X:Y-%d",
                 i, boardp->queue_full_cnt[i]);
         } else {
-            len = asc_prt_line(cp, leftlen, " %d:N", i);
+            len = asc_prt_line(cp, leftlen, " %X:N", i);
         }
         ASC_PRT_NEXT();
     }
@@ -8909,11 +9489,11 @@ asc_prt_asc_board_info(struct Scsi_Host *shp, char *cp, int cplen)
 " Synchronous Transfer:");
     ASC_PRT_NEXT();
     for (i = 0; i <= ASC_MAX_TID; i++) {
-        if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
+        if ((chip_scsi_id == i) ||
             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
             continue;
         }
-        len = asc_prt_line(cp, leftlen, " %d:%c",
+        len = asc_prt_line(cp, leftlen, " %X:%c",
             i, (v->sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
         ASC_PRT_NEXT();
     }
@@ -8923,26 +9503,50 @@ asc_prt_asc_board_info(struct Scsi_Host *shp, char *cp, int cplen)
     for (i = 0; i <= ASC_MAX_TID; i++) {
         uchar syn_period_ix;
 
-        if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
-            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
+        if ((chip_scsi_id == i) ||
+            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
+            ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
             continue;
         }
+
+        len = asc_prt_line(cp, leftlen, "  %X:", i);
+        ASC_PRT_NEXT();
+
+        if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0)
+        {
+            len = asc_prt_line(cp, leftlen, " Asynchronous");
+            ASC_PRT_NEXT();
+        } else
+        {
+            syn_period_ix =
+                (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index - 1);
+
+            len = asc_prt_line(cp, leftlen,
+                " Transfer Period Factor: %d (%d.%d Mhz),",
+                v->sdtr_period_tbl[syn_period_ix],
+                250 / v->sdtr_period_tbl[syn_period_ix],
+                ASC_TENTHS(250, v->sdtr_period_tbl[syn_period_ix]));
+            ASC_PRT_NEXT();
+
+            len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
+                boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET);
+            ASC_PRT_NEXT();
+        }
+
         if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
-            continue;
+            len = asc_prt_line(cp, leftlen, "*\n");
+            renegotiate = 1;
+        } else
+        {
+            len = asc_prt_line(cp, leftlen, "\n");
         }
-        syn_period_ix = (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index - 1);
-        len = asc_prt_line(cp, leftlen, "  %d:", i);
         ASC_PRT_NEXT();
+    }
 
+    if (renegotiate)
+    {
         len = asc_prt_line(cp, leftlen,
-            " Transfer Period Factor: %d (%d.%d Mhz),",
-            v->sdtr_period_tbl[syn_period_ix],
-            250 / v->sdtr_period_tbl[syn_period_ix],
-            ASC_TENTHS(250, v->sdtr_period_tbl[syn_period_ix]));
-        ASC_PRT_NEXT();
-
-        len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d\n",
-            boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET);
+            " * = Re-negotiation pending before next command.\n");
         ASC_PRT_NEXT();
     }
 
@@ -8974,8 +9578,11 @@ asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen)
     ushort                 chip_scsi_id;
     ushort                 lramword;
     uchar                  lrambyte;
-    ushort                 sdtr_able;
-    ushort                 period;
+    ushort                 tagqng_able;
+    ushort                 sdtr_able, wdtr_able;
+    ushort                 wdtr_done, sdtr_done;
+    ushort                 period = 0;
+    int                    renegotiate = 0;
 
     boardp = ASC_BOARDP(shp);
     v = &boardp->dvc_var.adv_dvc_var;
@@ -8992,10 +9599,10 @@ asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen)
     ASC_PRT_NEXT();
 
     len = asc_prt_line(cp, leftlen,
-" iop_base %lx, cable_detect: %X, err_code %u, idle_cmd_done %u\n",
+" iop_base %lx, cable_detect: %X, err_code %u\n",
          v->iop_base,
          AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1) & CABLE_DETECT,
-         v->err_code, v->idle_cmd_done);
+         v->err_code);
     ASC_PRT_NEXT();
 
     len = asc_prt_line(cp, leftlen,
@@ -9003,7 +9610,7 @@ asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen)
         c->chip_version, c->lib_version, c->mcode_date, c->mcode_version);
     ASC_PRT_NEXT();
 
-    AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, lramword);
+    AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
     len = asc_prt_line(cp, leftlen,
 " Queuing Enabled:");
     ASC_PRT_NEXT();
@@ -9014,7 +9621,7 @@ asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen)
         }
 
         len = asc_prt_line(cp, leftlen, " %X:%c",
-            i, (lramword & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+            i, (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
         ASC_PRT_NEXT();
     }
     len = asc_prt_line(cp, leftlen, "\n");
@@ -9054,7 +9661,7 @@ asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen)
     len = asc_prt_line(cp, leftlen, "\n");
     ASC_PRT_NEXT();
 
-    AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, lramword);
+    AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
     len = asc_prt_line(cp, leftlen,
 " Wide Enabled:");
     ASC_PRT_NEXT();
@@ -9065,12 +9672,13 @@ asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen)
         }
 
         len = asc_prt_line(cp, leftlen, " %X:%c",
-            i, (lramword & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
+            i, (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
         ASC_PRT_NEXT();
     }
     len = asc_prt_line(cp, leftlen, "\n");
     ASC_PRT_NEXT();
 
+    AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
     len = asc_prt_line(cp, leftlen,
 " Transfer Bit Width:");
     ASC_PRT_NEXT();
@@ -9082,9 +9690,17 @@ asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen)
 
         AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
             lramword);
+
         len = asc_prt_line(cp, leftlen, " %X:%d",
             i, (lramword & 0x8000) ? 16 : 8);
         ASC_PRT_NEXT();
+
+        if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
+            (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
+            len = asc_prt_line(cp, leftlen, "*");
+            ASC_PRT_NEXT();
+            renegotiate = 1;
+        }
     }
     len = asc_prt_line(cp, leftlen, "\n");
     ASC_PRT_NEXT();
@@ -9106,6 +9722,7 @@ asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen)
     len = asc_prt_line(cp, leftlen, "\n");
     ASC_PRT_NEXT();
 
+    AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
     for (i = 0; i <= ADV_MAX_TID; i++) {
 
         AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
@@ -9113,23 +9730,67 @@ asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen)
         lramword &= ~0x8000;
 
         if ((chip_scsi_id == i) ||
-            ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0) ||
-            (lramword == 0)) {
+            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
+            ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
             continue;
         }
 
         len = asc_prt_line(cp, leftlen, "  %X:", i);
         ASC_PRT_NEXT();
-        
-        period = (((lramword >> 8) * 25) + 50)/4;
 
-        len = asc_prt_line(cp, leftlen,
-            " Transfer Period Factor: %d (%d.%d Mhz),",
-            period, 250/period, ASC_TENTHS(250, period));
+        if ((lramword & 0x1F) == 0) /* Check for REQ/ACK Offset 0. */
+        {
+            len = asc_prt_line(cp, leftlen, " Asynchronous");
+            ASC_PRT_NEXT();
+        } else
+        {
+            len = asc_prt_line(cp, leftlen, " Transfer Period Factor: ");
+            ASC_PRT_NEXT();
+
+            if ((lramword & 0x1F00) == 0x1100) /* 80 Mhz */
+            {
+                len = asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
+                ASC_PRT_NEXT();
+            } else if ((lramword & 0x1F00) == 0x1000) /* 40 Mhz */
+            {
+                len = asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
+                ASC_PRT_NEXT();
+            } else /* 20 Mhz or below. */
+            {
+                period = (((lramword >> 8) * 25) + 50)/4;
+
+                if (period == 0) /* Should never happen. */
+                {
+                    len = asc_prt_line(cp, leftlen, "%d (? Mhz), ");
+                    ASC_PRT_NEXT();
+                } else
+                {
+                    len = asc_prt_line(cp, leftlen,
+                        "%d (%d.%d Mhz),",
+                        period, 250/period, ASC_TENTHS(250, period));
+                    ASC_PRT_NEXT();
+                }
+            }
+
+            len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
+                lramword & 0x1F);
+            ASC_PRT_NEXT();
+        }
+
+        if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
+            len = asc_prt_line(cp, leftlen, "*\n");
+            renegotiate = 1;
+        } else
+        {
+            len = asc_prt_line(cp, leftlen, "\n");
+        }
         ASC_PRT_NEXT();
+    }
 
-        len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d\n",
-            lramword & 0x1F);
+    if (renegotiate)
+    {
+        len = asc_prt_line(cp, leftlen,
+            " * = Re-negotiation pending before next command.\n");
         ASC_PRT_NEXT();
     }
 
@@ -9184,7 +9845,7 @@ asc_prt_line(char *buf, int buflen, char *fmt, ...)
 {
     va_list        args;
     int            ret;
-    char        s[ASC_PRTLINE_SIZE];
+    char           s[ASC_PRTLINE_SIZE];
 
     va_start(args, fmt);
     ret = vsprintf(s, fmt, args);
@@ -9215,8 +9876,18 @@ asc_prt_line(char *buf, int buflen, char *fmt, ...)
 STATIC void
 DvcSleepMilliSecond(ulong n)
 {
+#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,0)
+    ulong i;
+#endif /* version < v2.1.0 */ 
+
     ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", n);
+#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,0)
     mdelay(n);
+#else /* version < v2.1.0 */ 
+    for (i = 0; i < n; i++) {
+        udelay(1000);
+    }
+#endif /* version < v2.1.0 */ 
 }
 
 STATIC int
@@ -9367,7 +10038,7 @@ DvcOutPortDWords(PortAddr port, ulong *pdw, int dwords)
  * Read a PCI configuration byte.
  */
 ASC_INITFUNC(
-STATIC uchar
+STATIC uchar,
 DvcReadPCIConfigByte(
         ASC_DVC_VAR asc_ptr_type *asc_dvc, 
         ushort offset)
@@ -9404,7 +10075,7 @@ DvcReadPCIConfigByte(
  * Write a PCI configuration byte.
  */
 ASC_INITFUNC(
-STATIC void
+STATIC void,
 DvcWritePCIConfigByte(
         ASC_DVC_VAR asc_ptr_type *asc_dvc, 
         ushort offset, 
@@ -9437,15 +10108,15 @@ DvcWritePCIConfigByte(
  * I/O port and with the specified bus type.
  */
 ASC_INITFUNC(
-STATIC ushort
+STATIC ushort,
 AscGetChipBiosAddress(
         PortAddr iop_base,
         ushort bus_type
 )
 )
 {
-    ushort  cfg_lsw ;
-    ushort  bios_addr ;
+    ushort  cfg_lsw;
+    ushort  bios_addr;
 
     /*
      * The PCI BIOS is re-located by the motherboard BIOS. Because
@@ -9459,14 +10130,14 @@ AscGetChipBiosAddress(
 
     if((bus_type & ASC_IS_EISA) != 0)
     {
-        cfg_lsw = AscGetEisaChipCfg(iop_base) ;
-        cfg_lsw &= 0x000F ;
+        cfg_lsw = AscGetEisaChipCfg(iop_base);
+        cfg_lsw &= 0x000F;
         bios_addr = (ushort)(ASC_BIOS_MIN_ADDR  +
-                                (cfg_lsw * ASC_BIOS_BANK_SIZE)) ;
-        return(bios_addr) ;
+                                (cfg_lsw * ASC_BIOS_BANK_SIZE));
+        return(bios_addr);
     }/* if */
 
-    cfg_lsw = AscGetChipCfgLsw(iop_base) ;
+    cfg_lsw = AscGetChipCfgLsw(iop_base);
 
     /*
     *  ISA PnP uses the top bit as the 32K BIOS flag
@@ -9477,8 +10148,8 @@ AscGetChipBiosAddress(
     }/* if */
 
     bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) +
-            ASC_BIOS_MIN_ADDR) ;
-    return(bios_addr) ;
+            ASC_BIOS_MIN_ADDR);
+    return(bios_addr);
 }
 
 
@@ -9520,7 +10191,7 @@ DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
  * Read a PCI configuration byte.
  */
 ASC_INITFUNC(
-STATIC uchar
+STATIC uchar,
 DvcAdvReadPCIConfigByte(
         ADV_DVC_VAR *asc_dvc, 
         ushort offset)
@@ -9557,7 +10228,7 @@ DvcAdvReadPCIConfigByte(
  * Write a PCI configuration byte.
  */
 ASC_INITFUNC(
-STATIC void
+STATIC void,
 DvcAdvWritePCIConfigByte(
         ADV_DVC_VAR *asc_dvc, 
         ushort offset, 
@@ -9773,12 +10444,13 @@ asc_prt_scsi_host(struct Scsi_Host *s)
         (unsigned) s->hostt, (unsigned) s->block);
 
     printk(
-" wish_block %d, base %x, io_port %d, n_io_port %d, irq %d, dma_channel %d,\n",
-        s->wish_block, (unsigned) s->base, s->io_port, s->n_io_port,
-        s->irq, s->dma_channel);
+" wish_block %d, base %lu, io_port %lu, n_io_port %u, irq %d,\n",
+        s->wish_block, (ulong) s->base, (ulong) s->io_port, s->n_io_port,
+        s->irq);
 
     printk(
-" this_id %d, can_queue %d,\n", s->this_id, s->can_queue);
+" dma_channel %d, this_id %d, can_queue %d,\n",
+        s->dma_channel, s->this_id, s->can_queue);
 
     printk(
 " cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d, loaded_as_module %d\n",
@@ -9996,15 +10668,23 @@ asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
         (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
 
     printk(
-"  max_host_qng 0x%x, cur_host_qng 0x%x, max_dvc_qng 0x%x\n",
-        (unsigned) h->max_host_qng, (unsigned) h->cur_host_qng,
-        (unsigned) h->max_dvc_qng);
+"  max_host_qng %x, max_dvc_qng %x, carr_freelist %lxn\n",
+        (unsigned) h->max_host_qng, (unsigned) h->max_dvc_qng,
+        (ulong) h->carr_freelist);
+
 
     printk(
-"  no_scam 0x%x, tagqng_able 0x%x, chip_scsi_id 0x%x, cfg 0x%lx\n",
-        (unsigned) h->no_scam, (unsigned) h->tagqng_able,
-        (unsigned) h->chip_scsi_id, (ulong) h->cfg);
+"  icq_sp %lx, irq_sp %lx\n",
+        (ulong) h->icq_sp,
+        (ulong) h->irq_sp);
+
+    printk(
+"  no_scam 0x%x, tagqng_able 0x%x\n",
+        (unsigned) h->no_scam, (unsigned) h->tagqng_able);
 
+    printk(
+"  chip_scsi_id 0x%x, cfg %lx\n",
+        (unsigned) h->chip_scsi_id, (ulong) h->cfg);
 }
 
 /*
@@ -10042,7 +10722,7 @@ asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
 STATIC void 
 asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
 {
-    int                 i;
+    int                 sg_blk_cnt;
     struct asc_sg_block *sg_ptr;
 
     printk("ADV_SCSI_REQ_Q at addr %x\n", (unsigned) q);
@@ -10054,6 +10734,10 @@ asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
     printk("  cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
             q->cntl, q->data_addr, q->vdata_addr);
 
+    printk(
+"  cntl 0x%x, data_addr %lx, vdata_addr %lx\n",
+            q->cntl, q->data_addr, q->vdata_addr);
+
     printk(
 "  data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
             q->data_cnt, q->sense_addr, q->sense_len);
@@ -10063,32 +10747,33 @@ asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
             q->cdb_len, q->done_status, q->host_status, q->scsi_status);
 
     printk(
-"  vsense_addr 0x%lx, scsiq_ptr 0x%lx, ux_wk_data_cnt %lu\n",
-            (ulong) q->vsense_addr, (ulong) q->scsiq_ptr,
-            (ulong) q->ux_wk_data_cnt);
-
-    printk(
-"  sg_list_ptr 0x%lx, sg_real_addr 0x%lx, sg_entry_cnt %u\n",
-            (ulong) q->sg_list_ptr, (ulong) q->sg_real_addr, q->sg_entry_cnt);
+"  sg_working_ix %x, sg_working_data_cnt %lx, reserved %u\n",
+            q->sg_working_ix, q->sg_working_data_cnt, q->reserved);
 
     printk(
-"  ux_sg_ix %u, orig_sense_len %u\n",
-            q->ux_sg_ix, q->orig_sense_len);
+"  scsiq_rptr %lx, sg_real_addr %lx, sg_list_ptr %lx\n",
+            q->scsiq_rptr, q->sg_real_addr, (ulong) q->sg_list_ptr);
 
     /* Display the request's ADV_SG_BLOCK structures. */
-    for (sg_ptr = q->sg_list_ptr, i = 0; sg_ptr != NULL;
-        sg_ptr = sg_ptr->sg_ptr, i++) {
-        /*
-         * 'sg_ptr' is a physical address. Convert it to a virtual
-         * address by indexing 'i' into the virtual address array
-         * 'sg_list_ptr'.
-         *
-         * At the end of the each iteration of the loop 'sg_ptr' is
-         * converted back into a physical address by setting 'sg_ptr'
-         *  to the next pointer 'sg_ptr->sg_ptr'.
-         */
-        sg_ptr = &(((ADV_SG_BLOCK *) (q->sg_list_ptr))[i]);
-        asc_prt_adv_sgblock(i, sg_ptr);
+    if (q->sg_list_ptr != NULL)
+    {
+        sg_blk_cnt = 0;
+        while (1) {
+            /*
+             * 'sg_ptr' is a physical address. Convert it to a virtual
+             * address by indexing 'sg_blk_cnt' into the virtual address
+             * array 'sg_list_ptr'.
+             *
+             * XXX - Assumes all SG physical blocks are virtually contiguous.
+             */
+            sg_ptr = &(((ADV_SG_BLOCK *) (q->sg_list_ptr))[sg_blk_cnt]);
+            asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
+            if (sg_ptr->sg_ptr == NULL)
+            {
+                break;
+            }
+            sg_blk_cnt++;
+        }
     }
 }
 
@@ -10100,26 +10785,20 @@ asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
 STATIC void
 asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
 {
-    int i, s;
-
-    /* Calculate starting entry number for the current block. */
-    s = sgblockno * NO_OF_SG_PER_BLOCK;
+    int i;
 
-    printk(" ADV_SG_BLOCK at addr 0x%lx (sgblockno %lu)\n",
-        (ulong) b, (ulong) sgblockno);
-    printk(
-"  first_entry_no %lu, last_entry_no %lu, sg_ptr 0x%lx\n",
-        (ulong) b->first_entry_no, (ulong) b->last_entry_no, (ulong) b->sg_ptr);
-    ASC_ASSERT(b->first_entry_no - s >= 0);
-    ASC_ASSERT(b->last_entry_no - s >= 0);
-    ASC_ASSERT(b->last_entry_no - s <= NO_OF_SG_PER_BLOCK);
-    ASC_ASSERT(b->first_entry_no - s <= NO_OF_SG_PER_BLOCK);
-    ASC_ASSERT(b->first_entry_no - s <= NO_OF_SG_PER_BLOCK);
-    ASC_ASSERT(b->first_entry_no - s <= b->last_entry_no - s);
-    for (i = b->first_entry_no - s; i <= b->last_entry_no - s; i++) {
-        printk("  [%lu]: sg_addr 0x%lx, sg_count 0x%lx\n",
-            (ulong) i, (ulong) b->sg_list[i].sg_addr,
-            (ulong) b->sg_list[i].sg_count);
+    printk(" ASC_SG_BLOCK at addr %lx (sgblockno %d)\n",
+        (ulong) b, sgblockno);
+    printk("  sg_cnt %u, sg_ptr %lx\n",
+        b->sg_cnt, (ulong) b->sg_ptr);
+    ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
+    if (b->sg_ptr != NULL)
+    {
+        ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
+    }
+    for (i = 0; i < b->sg_cnt; i++) {
+        printk("  [%u]: sg_addr %lx, sg_count %lx\n",
+            i, b->sg_list[i].sg_addr, b->sg_list[i].sg_count);
     }
 }
 
@@ -10146,7 +10825,7 @@ asc_prt_hex(char *f, uchar *s, int l)
             k = 8;
             m = 0;
         } else {
-            m = (l - i) % 4 ;
+            m = (l - i) % 4;
         }
 
         for (j = 0; j < k; j++) {
@@ -10207,7 +10886,7 @@ interrupts_enabled(void)
  */
 
 ASC_INITFUNC(
-STATIC ushort
+STATIC ushort,
 AscGetEisaChipCfg(
                      PortAddr iop_base
 )
@@ -10221,7 +10900,7 @@ AscGetEisaChipCfg(
 }
 
 ASC_INITFUNC(
-STATIC uchar
+STATIC uchar,
 AscSetChipScsiID(
                     PortAddr iop_base,
                     uchar new_host_id
@@ -10241,7 +10920,7 @@ AscSetChipScsiID(
 }
 
 ASC_INITFUNC(
-STATIC uchar
+STATIC uchar,
 AscGetChipScsiCtrl(
                       PortAddr iop_base
 )
@@ -10256,7 +10935,7 @@ AscGetChipScsiCtrl(
 }
 
 ASC_INITFUNC(
-STATIC uchar
+STATIC uchar,
 AscGetChipVersion(
                      PortAddr iop_base,
                      ushort bus_type
@@ -10275,7 +10954,7 @@ AscGetChipVersion(
 }
 
 ASC_INITFUNC(
-STATIC ushort
+STATIC ushort,
 AscGetChipBusType(
                      PortAddr iop_base
 )
@@ -10310,7 +10989,7 @@ AscGetChipBusType(
 }
 
 ASC_INITFUNC(
-STATIC ulong
+STATIC ulong,
 AscLoadMicroCode(
                     PortAddr iop_base,
                     ushort s_addr,
@@ -10336,7 +11015,7 @@ AscLoadMicroCode(
 }
 
 ASC_INITFUNC(
-STATIC int
+STATIC int,
 AscFindSignature(
                     PortAddr iop_base
 )
@@ -10362,7 +11041,7 @@ STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] ASC_INITDATA =
 };
 
 ASC_INITFUNC(
-STATIC PortAddr
+STATIC PortAddr,
 AscSearchIOPortAddr(
                        PortAddr iop_beg,
                        ushort bus_type
@@ -10399,7 +11078,7 @@ AscSearchIOPortAddr(
 }
 
 ASC_INITFUNC(
-STATIC PortAddr
+STATIC PortAddr,
 AscSearchIOPortAddr11(
                          PortAddr s_addr
 )
@@ -10430,7 +11109,7 @@ AscSearchIOPortAddr11(
 }
 
 ASC_INITFUNC(
-STATIC void
+STATIC void,
 AscToggleIRQAct(
                    PortAddr iop_base
 )
@@ -10442,7 +11121,7 @@ AscToggleIRQAct(
 }
 
 ASC_INITFUNC(
-STATIC void
+STATIC void,
 AscSetISAPNPWaitForKey(
     void)
 )
@@ -10453,7 +11132,7 @@ AscSetISAPNPWaitForKey(
 }
 
 ASC_INITFUNC(
-STATIC uchar
+STATIC uchar,
 AscGetChipIRQ(
                  PortAddr iop_base,
                  ushort bus_type
@@ -10489,7 +11168,7 @@ AscGetChipIRQ(
 }
 
 ASC_INITFUNC(
-STATIC uchar
+STATIC uchar,
 AscSetChipIRQ(
                  PortAddr iop_base,
                  uchar irq_no,
@@ -10530,7 +11209,7 @@ AscSetChipIRQ(
 }
 
 ASC_INITFUNC(
-STATIC void
+STATIC void,
 AscEnableIsaDma(
                    uchar dma_channel
 )
@@ -10585,7 +11264,6 @@ AscIsrChipHalted(
     tid_no = ASC_TIX_TO_TID(target_ix);
     target_id = (uchar) ASC_TID_TO_TARGET_ID(tid_no);
     if (asc_dvc->pci_fix_asyn_xfer & target_id) {
-
         asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
     } else {
         asyn_sdtr = 0;
@@ -10812,19 +11490,169 @@ AscIsrChipHalted(
                      */
                     boardp->queue_full |= target_id;
                     boardp->queue_full_cnt[tid_no] = cur_dvc_qng;
-#if ASC_QUEUE_FLOW_CONTROL
-                    if (boardp->device[tid_no] != NULL &&
-                        boardp->device[tid_no]->queue_curr_depth >
-                        cur_dvc_qng) {
-                        boardp->device[tid_no]->queue_curr_depth =
-                            cur_dvc_qng;
-                    }
-#endif /* ASC_QUEUE_FLOW_CONTROL */
                 }
             }
         }
         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
         return (0);
+    } else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC)
+    {
+         uchar              q_no;
+         ushort             q_addr;
+         ulong              srb_ptr;
+         uchar              sg_wk_q_no;
+         uchar              first_sg_wk_q_no;
+         ASC_SCSI_Q         *scsiq; /* Ptr to driver request. */
+         ASC_SG_HEAD        *sg_head; /* Ptr to driver SG request. */
+         ASC_SG_LIST_Q      scsi_sg_q; /* Structure written to queue. */
+         ushort             sg_list_dwords;
+         ushort             sg_entry_cnt;
+         uchar              next_qp;
+         int                i;
+
+         q_no = AscReadLramByte(iop_base, (ushort) ASCV_REQ_SG_LIST_QP);
+         if (q_no == ASC_QLINK_END)
+         {
+             return(0);
+         }
+
+         q_addr = ASC_QNO_TO_QADDR(q_no);
+
+         /* Read request's SRB pointer. */
+         srb_ptr = AscReadLramDWord(iop_base,
+                           (ushort) (q_addr + ASC_SCSIQ_D_SRBPTR));
+
+         /*
+          * Get request's first and working SG queue.
+          */
+         sg_wk_q_no = AscReadLramByte(iop_base,
+             (ushort) (q_addr + ASC_SCSIQ_B_SG_WK_QP));
+
+         first_sg_wk_q_no = AscReadLramByte(iop_base,
+             (ushort) (q_addr + ASC_SCSIQ_B_FIRST_SG_WK_QP));
+
+         /*
+          * Reset request's working SG queue back to the
+          * first SG queue.
+          */
+         AscWriteLramByte(iop_base,
+             (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SG_WK_QP),
+             first_sg_wk_q_no);
+
+         /*
+          * Convert the request's SRB pointer to a host ASC_SCSI_REQ
+          * structure pointer using a macro provided by the driver.
+          * The ASC_SCSI_REQ pointer provides a pointer to the
+          * host ASC_SG_HEAD structure.
+          */
+         scsiq = (ASC_SCSI_Q *) ASC_SRB2SCSIQ(srb_ptr);
+
+         sg_head = scsiq->sg_head;
+
+         /*
+          * Set sg_entry_cnt to the number of SG elements
+          * that will be completed on this interrupt.
+          *
+          * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
+          * SG elements. The data_cnt and data_addr fields which
+          * add 1 to the SG element capacity are not used when
+          * restarting SG handling after a halt.
+          */
+         if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1))
+         {
+              sg_entry_cnt = ASC_MAX_SG_LIST - 1;
+
+              /*
+               * Keep track of remaining number of SG elements that will
+               * need to be handled on the next interrupt.
+               */
+              scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
+         } else
+         {
+              sg_entry_cnt = scsiq->remain_sg_entry_cnt;
+              scsiq->remain_sg_entry_cnt = 0;
+         }
+
+         /*
+          * Copy SG elements into the list of allocated SG queues.
+          *
+          * Last index completed is saved in scsiq->next_sg_index.
+          */
+         next_qp = first_sg_wk_q_no;
+         q_addr = ASC_QNO_TO_QADDR(next_qp);
+         scsi_sg_q.sg_head_qp = q_no;
+         scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
+         for( i = 0; i < sg_head->queue_cnt; i++)
+         {
+              scsi_sg_q.seq_no = i + 1;
+              if (sg_entry_cnt > ASC_SG_LIST_PER_Q)
+              {
+                  sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
+                  sg_entry_cnt -= ASC_SG_LIST_PER_Q;
+                  /*
+                   * After very first SG queue RISC FW uses next
+                   * SG queue first element then checks sg_list_cnt
+                   * against zero and then decrements, so set
+                   * sg_list_cnt 1 less than number of SG elements
+                   * in each SG queue.
+                   */
+                  scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
+                  scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
+              } else {
+                  /*
+                   * This is the last SG queue in the list of
+                   * allocated SG queues. If there are more
+                   * SG elements than will fit in the allocated
+                   * queues, then set the QCSG_SG_XFER_MORE flag.
+                   */
+                  if (scsiq->remain_sg_entry_cnt != 0)
+                  {
+                      scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
+                  } else
+                  {
+                      scsi_sg_q.cntl |= QCSG_SG_XFER_END;
+                  }
+                  /* equals sg_entry_cnt * 2 */
+                  sg_list_dwords = sg_entry_cnt << 1;
+                  scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
+                  scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
+                  sg_entry_cnt = 0;
+              }
+
+              scsi_sg_q.q_no = next_qp;
+              AscMemWordCopyToLram(iop_base,
+                           (ushort) (q_addr+ASC_SCSIQ_SGHD_CPY_BEG),
+                           (ushort *) &scsi_sg_q,
+                           (ushort) (sizeof(ASC_SG_LIST_Q) >> 1));
+
+              AscMemDWordCopyToLram( iop_base,
+                           (ushort) (q_addr+ASC_SGQ_LIST_BEG ),
+                           (ulong *) &sg_head->sg_list[scsiq->next_sg_index],
+                           (ushort) sg_list_dwords);
+
+              scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
+
+              /*
+               * If the just completed SG queue contained the
+               * last SG element, then no more SG queues need
+               * to be written.
+               */
+              if (scsi_sg_q.cntl & QCSG_SG_XFER_END)
+              {
+                  break;
+              }
+
+              next_qp = AscReadLramByte( iop_base,
+                           ( ushort )( q_addr+ASC_SCSIQ_B_FWD ) );
+              q_addr = ASC_QNO_TO_QADDR( next_qp );
+         }
+
+         /*
+          * Clear the halt condition so the RISC will be restarted
+          * after the return.
+          */
+         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
+         return(0);
     }
     return (0);
 }
@@ -10856,8 +11684,18 @@ _AscCopyLramScsiDoneQ(
                         (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SENSE_LEN));
     scsiq->sense_len = (uchar) _val;
     scsiq->extra_bytes = (uchar) (_val >> 8);
-    scsiq->remain_bytes = AscReadLramWord(iop_base,
-                 (ushort) (q_addr + (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT));
+
+    /*
+     * Read high word of remain bytes from alternate location.
+     */
+    scsiq->remain_bytes = (((ulong) AscReadLramWord( iop_base,
+                      (ushort) (q_addr+ (ushort) ASC_SCSIQ_W_ALT_DC1))) << 16);
+    /*
+     * Read low word of remain bytes from original location.
+     */
+    scsiq->remain_bytes += AscReadLramWord(iop_base,
+        (ushort) (q_addr+ (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT));
+
     scsiq->remain_bytes &= max_dma_count;
     return (sg_queue_cnt);
 }
@@ -11015,6 +11853,12 @@ AscISR(
 
     iop_base = asc_dvc->iop_base;
     int_pending = FALSE;
+
+    if (AscIsIntPending(iop_base) == 0)
+    {
+        return int_pending;
+    }
+
     if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
         || (asc_dvc->isr_callback == 0)
 ) {
@@ -11035,10 +11879,15 @@ AscISR(
     chipstat = AscGetChipStatus(iop_base);
     if (chipstat & CSW_SCSI_RESET_LATCH) {
         if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
+            int i = 10;
             int_pending = TRUE;
             asc_dvc->sdtr_done = 0;
             saved_ctrl_reg &= (uchar) (~CC_HALT);
-            while (AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) ;
+            while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) &&
+                   (i-- > 0))
+            {
+                  DvcSleepMilliSecond(100);
+            }
             AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
             AscSetChipControl(iop_base, CC_HALT);
             AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
@@ -11092,82 +11941,82 @@ STATIC uchar _asc_mcode_buf[] ASC_INITDATA =
   0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
-  0x00,  0x00,  0x00,  0x00,  0x91,  0x10,  0x0A,  0x05,  0x01,  0x00,  0x00,  0x00,  0x00,  0xFF,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0xC3,  0x12,  0x0D,  0x05,  0x01,  0x00,  0x00,  0x00,  0x00,  0xFF,  0x00,  0x00,
   0x00,  0x00,  0x00,  0x00,  0xFF,  0x80,  0xFF,  0xFF,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
-  0x00,  0x00,  0x00,  0x23,  0x00,  0x24,  0x00,  0x00,  0x00,  0x07,  0x00,  0xFF,  0x00,  0x00,  0x00,  0x00,
-  0xFF,  0xFF,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xE2,  0x88,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x23,  0x00,  0x00,  0x00,  0x00,  0x00,  0x07,  0x00,  0xFF,  0x00,  0x00,  0x00,  0x00,
+  0xFF,  0xFF,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xE4,  0x88,  0x00,  0x00,  0x00,  0x00,
   0x80,  0x73,  0x48,  0x04,  0x36,  0x00,  0x00,  0xA2,  0xC2,  0x00,  0x80,  0x73,  0x03,  0x23,  0x36,  0x40,
   0xB6,  0x00,  0x36,  0x00,  0x05,  0xD6,  0x0C,  0xD2,  0x12,  0xDA,  0x00,  0xA2,  0xC2,  0x00,  0x92,  0x80,
   0x1E,  0x98,  0x50,  0x00,  0xF5,  0x00,  0x48,  0x98,  0xDF,  0x23,  0x36,  0x60,  0xB6,  0x00,  0x92,  0x80,
   0x4F,  0x00,  0xF5,  0x00,  0x48,  0x98,  0xEF,  0x23,  0x36,  0x60,  0xB6,  0x00,  0x92,  0x80,  0x80,  0x62,
-  0x92,  0x80,  0x00,  0x46,  0x17,  0xEE,  0x13,  0xEA,  0x02,  0x01,  0x09,  0xD8,  0xCD,  0x04,  0x4D,  0x00,
+  0x92,  0x80,  0x00,  0x46,  0x15,  0xEE,  0x13,  0xEA,  0x02,  0x01,  0x09,  0xD8,  0xCD,  0x04,  0x4D,  0x00,
   0x00,  0xA3,  0xD6,  0x00,  0xA6,  0x97,  0x7F,  0x23,  0x04,  0x61,  0x84,  0x01,  0xE6,  0x84,  0xD2,  0xC1,
-  0x80,  0x73,  0xCD,  0x04,  0x4D,  0x00,  0x00,  0xA3,  0xE2,  0x01,  0xA6,  0x97,  0xCE,  0x81,  0x00,  0x33,
-  0x02,  0x00,  0xC0,  0x88,  0x80,  0x73,  0x80,  0x77,  0x00,  0x01,  0x01,  0xA1,  0x02,  0x01,  0x4F,  0x00,
-  0x84,  0x97,  0x07,  0xA6,  0x0C,  0x01,  0x00,  0x33,  0x03,  0x00,  0xC0,  0x88,  0x03,  0x03,  0x03,  0xDE,
-  0x00,  0x33,  0x05,  0x00,  0xC0,  0x88,  0xCE,  0x00,  0x69,  0x60,  0xCE,  0x00,  0x02,  0x03,  0x4A,  0x60,
-  0x00,  0xA2,  0x80,  0x01,  0x80,  0x63,  0x07,  0xA6,  0x2C,  0x01,  0x80,  0x81,  0x03,  0x03,  0x80,  0x63,
-  0xE2,  0x00,  0x07,  0xA6,  0x3C,  0x01,  0x00,  0x33,  0x04,  0x00,  0xC0,  0x88,  0x03,  0x07,  0x02,  0x01,
-  0x04,  0xCA,  0x0D,  0x23,  0x68,  0x98,  0x4D,  0x04,  0x04,  0x85,  0x05,  0xD8,  0x0D,  0x23,  0x68,  0x98,
-  0xCD,  0x04,  0x15,  0x23,  0xF6,  0x88,  0xFB,  0x23,  0x02,  0x61,  0x82,  0x01,  0x80,  0x63,  0x02,  0x03,
-  0x06,  0xA3,  0x6A,  0x01,  0x00,  0x33,  0x0A,  0x00,  0xC0,  0x88,  0x4E,  0x00,  0x07,  0xA3,  0x76,  0x01,
-  0x00,  0x33,  0x0B,  0x00,  0xC0,  0x88,  0xCD,  0x04,  0x36,  0x2D,  0x00,  0x33,  0x1A,  0x00,  0xC0,  0x88,
-  0x50,  0x04,  0x90,  0x81,  0x06,  0xAB,  0x8A,  0x01,  0x90,  0x81,  0x4E,  0x00,  0x07,  0xA3,  0x9A,  0x01,
-  0x50,  0x00,  0x00,  0xA3,  0x44,  0x01,  0x00,  0x05,  0x84,  0x81,  0x46,  0x97,  0x02,  0x01,  0x05,  0xC6,
-  0x04,  0x23,  0xA0,  0x01,  0x15,  0x23,  0xA1,  0x01,  0xC6,  0x81,  0xFD,  0x23,  0x02,  0x61,  0x82,  0x01,
-  0x0A,  0xDA,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA0,  0xBC,  0x01,  0x80,  0x63,  0xCD,  0x04,  0x36,  0x2D,
-  0x00,  0x33,  0x1B,  0x00,  0xC0,  0x88,  0x06,  0x23,  0x68,  0x98,  0xCD,  0x04,  0xE6,  0x84,  0x06,  0x01,
-  0x00,  0xA2,  0xDC,  0x01,  0x57,  0x60,  0x00,  0xA0,  0xE2,  0x01,  0xE6,  0x84,  0x80,  0x23,  0xA0,  0x01,
-  0xE6,  0x84,  0x80,  0x73,  0x4B,  0x00,  0x06,  0x61,  0x00,  0xA2,  0x08,  0x02,  0x04,  0x01,  0x0C,  0xDE,
-  0x02,  0x01,  0x03,  0xCC,  0x4F,  0x00,  0x84,  0x97,  0x04,  0x82,  0x08,  0x23,  0x02,  0x41,  0x82,  0x01,
-  0x4F,  0x00,  0x62,  0x97,  0x48,  0x04,  0x84,  0x80,  0xF0,  0x97,  0x00,  0x46,  0x56,  0x00,  0x03,  0xC0,
-  0x01,  0x23,  0xE8,  0x00,  0x81,  0x73,  0x06,  0x29,  0x03,  0x42,  0x06,  0xE2,  0x03,  0xEE,  0x67,  0xEB,
-  0x11,  0x23,  0xF6,  0x88,  0x04,  0x98,  0xF4,  0x80,  0x80,  0x73,  0x80,  0x77,  0x07,  0xA4,  0x32,  0x02,
-  0x7C,  0x95,  0x06,  0xA6,  0x3C,  0x02,  0x03,  0xA6,  0x4C,  0x04,  0xC0,  0x88,  0x04,  0x01,  0x03,  0xD8,
-  0xB2,  0x98,  0x6A,  0x96,  0x4E,  0x82,  0xFE,  0x95,  0x80,  0x67,  0x83,  0x03,  0x80,  0x63,  0xB6,  0x2D,
-  0x02,  0xA6,  0x78,  0x02,  0x07,  0xA6,  0x66,  0x02,  0x06,  0xA6,  0x6A,  0x02,  0x03,  0xA6,  0x6E,  0x02,
-  0x00,  0x33,  0x10,  0x00,  0xC0,  0x88,  0x7C,  0x95,  0x50,  0x82,  0x60,  0x96,  0x50,  0x82,  0x04,  0x23,
-  0xA0,  0x01,  0x14,  0x23,  0xA1,  0x01,  0x3C,  0x84,  0x04,  0x01,  0x0C,  0xDC,  0xE0,  0x23,  0x25,  0x61,
-  0xEF,  0x00,  0x14,  0x01,  0x4F,  0x04,  0xA8,  0x01,  0x6F,  0x00,  0xA5,  0x01,  0x03,  0x23,  0xA4,  0x01,
-  0x06,  0x23,  0x9C,  0x01,  0x24,  0x2B,  0x1C,  0x01,  0x02,  0xA6,  0xB6,  0x02,  0x07,  0xA6,  0x66,  0x02,
-  0x06,  0xA6,  0x6A,  0x02,  0x03,  0xA6,  0x20,  0x04,  0x01,  0xA6,  0xC0,  0x02,  0x00,  0xA6,  0xC0,  0x02,
-  0x00,  0x33,  0x12,  0x00,  0xC0,  0x88,  0x00,  0x0E,  0x80,  0x63,  0x00,  0x43,  0x00,  0xA0,  0x98,  0x02,
-  0x4D,  0x04,  0x04,  0x01,  0x0B,  0xDC,  0xE7,  0x23,  0x04,  0x61,  0x84,  0x01,  0x10,  0x31,  0x12,  0x35,
-  0x14,  0x01,  0xEC,  0x00,  0x6C,  0x38,  0x00,  0x3F,  0x00,  0x00,  0xF6,  0x82,  0x18,  0x23,  0x04,  0x61,
-  0x18,  0xA0,  0xEE,  0x02,  0x04,  0x01,  0x9C,  0xC8,  0x00,  0x33,  0x1F,  0x00,  0xC0,  0x88,  0x08,  0x31,
-  0x0A,  0x35,  0x0C,  0x39,  0x0E,  0x3D,  0x7E,  0x98,  0xB6,  0x2D,  0x01,  0xA6,  0x20,  0x03,  0x00,  0xA6,
-  0x20,  0x03,  0x07,  0xA6,  0x18,  0x03,  0x06,  0xA6,  0x1C,  0x03,  0x03,  0xA6,  0x20,  0x04,  0x02,  0xA6,
-  0x78,  0x02,  0x00,  0x33,  0x33,  0x00,  0xC0,  0x88,  0x7C,  0x95,  0xFA,  0x82,  0x60,  0x96,  0xFA,  0x82,
-  0x82,  0x98,  0x80,  0x42,  0x7E,  0x98,  0x60,  0xE4,  0x04,  0x01,  0x29,  0xC8,  0x31,  0x05,  0x07,  0x01,
-  0x00,  0xA2,  0x60,  0x03,  0x00,  0x43,  0x87,  0x01,  0x05,  0x05,  0x86,  0x98,  0x7E,  0x98,  0x00,  0xA6,
-  0x22,  0x03,  0x07,  0xA6,  0x58,  0x03,  0x03,  0xA6,  0x3C,  0x04,  0x06,  0xA6,  0x5C,  0x03,  0x01,  0xA6,
-  0x22,  0x03,  0x00,  0x33,  0x25,  0x00,  0xC0,  0x88,  0x7C,  0x95,  0x3E,  0x83,  0x60,  0x96,  0x3E,  0x83,
-  0x04,  0x01,  0x0C,  0xCE,  0x03,  0xC8,  0x00,  0x33,  0x42,  0x00,  0xC0,  0x88,  0x00,  0x01,  0x05,  0x05,
-  0xFF,  0xA2,  0x7E,  0x03,  0xB1,  0x01,  0x08,  0x23,  0xB2,  0x01,  0x3A,  0x83,  0x05,  0x05,  0x15,  0x01,
-  0x00,  0xA2,  0x9E,  0x03,  0xEC,  0x00,  0x6E,  0x00,  0x95,  0x01,  0x6C,  0x38,  0x00,  0x3F,  0x00,  0x00,
-  0x01,  0xA6,  0x9A,  0x03,  0x00,  0xA6,  0x9A,  0x03,  0x12,  0x84,  0x80,  0x42,  0x7E,  0x98,  0x01,  0xA6,
-  0xA8,  0x03,  0x00,  0xA6,  0xC0,  0x03,  0x12,  0x84,  0xA6,  0x98,  0x80,  0x42,  0x01,  0xA6,  0xA8,  0x03,
-  0x07,  0xA6,  0xB6,  0x03,  0xD8,  0x83,  0x7C,  0x95,  0xAC,  0x83,  0x00,  0x33,  0x2F,  0x00,  0xC0,  0x88,
-  0xA6,  0x98,  0x80,  0x42,  0x00,  0xA6,  0xC0,  0x03,  0x07,  0xA6,  0xCE,  0x03,  0xD8,  0x83,  0x7C,  0x95,
-  0xC4,  0x83,  0x00,  0x33,  0x26,  0x00,  0xC0,  0x88,  0x38,  0x2B,  0x80,  0x32,  0x80,  0x36,  0x04,  0x23,
-  0xA0,  0x01,  0x12,  0x23,  0xA1,  0x01,  0x12,  0x84,  0x06,  0xF0,  0x06,  0xA4,  0xF6,  0x03,  0x80,  0x6B,
-  0x05,  0x23,  0x83,  0x03,  0x80,  0x63,  0x03,  0xA6,  0x10,  0x04,  0x07,  0xA6,  0x08,  0x04,  0x06,  0xA6,
-  0x0C,  0x04,  0x00,  0x33,  0x17,  0x00,  0xC0,  0x88,  0x7C,  0x95,  0xF6,  0x83,  0x60,  0x96,  0xF6,  0x83,
-  0x20,  0x84,  0x06,  0xF0,  0x06,  0xA4,  0x20,  0x04,  0x80,  0x6B,  0x05,  0x23,  0x83,  0x03,  0x80,  0x63,
+  0x80,  0x73,  0xCD,  0x04,  0x4D,  0x00,  0x00,  0xA3,  0xDA,  0x01,  0xA6,  0x97,  0xC6,  0x81,  0xC2,  0x88,
+  0x80,  0x73,  0x80,  0x77,  0x00,  0x01,  0x01,  0xA1,  0xFE,  0x00,  0x4F,  0x00,  0x84,  0x97,  0x07,  0xA6,
+  0x08,  0x01,  0x00,  0x33,  0x03,  0x00,  0xC2,  0x88,  0x03,  0x03,  0x01,  0xDE,  0xC2,  0x88,  0xCE,  0x00,
+  0x69,  0x60,  0xCE,  0x00,  0x02,  0x03,  0x4A,  0x60,  0x00,  0xA2,  0x78,  0x01,  0x80,  0x63,  0x07,  0xA6,
+  0x24,  0x01,  0x78,  0x81,  0x03,  0x03,  0x80,  0x63,  0xE2,  0x00,  0x07,  0xA6,  0x34,  0x01,  0x00,  0x33,
+  0x04,  0x00,  0xC2,  0x88,  0x03,  0x07,  0x02,  0x01,  0x04,  0xCA,  0x0D,  0x23,  0x68,  0x98,  0x4D,  0x04,
+  0x04,  0x85,  0x05,  0xD8,  0x0D,  0x23,  0x68,  0x98,  0xCD,  0x04,  0x15,  0x23,  0xF8,  0x88,  0xFB,  0x23,
+  0x02,  0x61,  0x82,  0x01,  0x80,  0x63,  0x02,  0x03,  0x06,  0xA3,  0x62,  0x01,  0x00,  0x33,  0x0A,  0x00,
+  0xC2,  0x88,  0x4E,  0x00,  0x07,  0xA3,  0x6E,  0x01,  0x00,  0x33,  0x0B,  0x00,  0xC2,  0x88,  0xCD,  0x04,
+  0x36,  0x2D,  0x00,  0x33,  0x1A,  0x00,  0xC2,  0x88,  0x50,  0x04,  0x88,  0x81,  0x06,  0xAB,  0x82,  0x01,
+  0x88,  0x81,  0x4E,  0x00,  0x07,  0xA3,  0x92,  0x01,  0x50,  0x00,  0x00,  0xA3,  0x3C,  0x01,  0x00,  0x05,
+  0x7C,  0x81,  0x46,  0x97,  0x02,  0x01,  0x05,  0xC6,  0x04,  0x23,  0xA0,  0x01,  0x15,  0x23,  0xA1,  0x01,
+  0xBE,  0x81,  0xFD,  0x23,  0x02,  0x61,  0x82,  0x01,  0x0A,  0xDA,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA0,
+  0xB4,  0x01,  0x80,  0x63,  0xCD,  0x04,  0x36,  0x2D,  0x00,  0x33,  0x1B,  0x00,  0xC2,  0x88,  0x06,  0x23,
+  0x68,  0x98,  0xCD,  0x04,  0xE6,  0x84,  0x06,  0x01,  0x00,  0xA2,  0xD4,  0x01,  0x57,  0x60,  0x00,  0xA0,
+  0xDA,  0x01,  0xE6,  0x84,  0x80,  0x23,  0xA0,  0x01,  0xE6,  0x84,  0x80,  0x73,  0x4B,  0x00,  0x06,  0x61,
+  0x00,  0xA2,  0x00,  0x02,  0x04,  0x01,  0x0C,  0xDE,  0x02,  0x01,  0x03,  0xCC,  0x4F,  0x00,  0x84,  0x97,
+  0xFC,  0x81,  0x08,  0x23,  0x02,  0x41,  0x82,  0x01,  0x4F,  0x00,  0x62,  0x97,  0x48,  0x04,  0x84,  0x80,
+  0xF0,  0x97,  0x00,  0x46,  0x56,  0x00,  0x03,  0xC0,  0x01,  0x23,  0xE8,  0x00,  0x81,  0x73,  0x06,  0x29,
+  0x03,  0x42,  0x06,  0xE2,  0x03,  0xEE,  0x6B,  0xEB,  0x11,  0x23,  0xF8,  0x88,  0x04,  0x98,  0xF0,  0x80,
+  0x80,  0x73,  0x80,  0x77,  0x07,  0xA4,  0x2A,  0x02,  0x7C,  0x95,  0x06,  0xA6,  0x34,  0x02,  0x03,  0xA6,
+  0x4C,  0x04,  0x46,  0x82,  0x04,  0x01,  0x03,  0xD8,  0xB4,  0x98,  0x6A,  0x96,  0x46,  0x82,  0xFE,  0x95,
+  0x80,  0x67,  0x83,  0x03,  0x80,  0x63,  0xB6,  0x2D,  0x02,  0xA6,  0x6C,  0x02,  0x07,  0xA6,  0x5A,  0x02,
+  0x06,  0xA6,  0x5E,  0x02,  0x03,  0xA6,  0x62,  0x02,  0xC2,  0x88,  0x7C,  0x95,  0x48,  0x82,  0x60,  0x96,
+  0x48,  0x82,  0x04,  0x23,  0xA0,  0x01,  0x14,  0x23,  0xA1,  0x01,  0x3C,  0x84,  0x04,  0x01,  0x0C,  0xDC,
+  0xE0,  0x23,  0x25,  0x61,  0xEF,  0x00,  0x14,  0x01,  0x4F,  0x04,  0xA8,  0x01,  0x6F,  0x00,  0xA5,  0x01,
+  0x03,  0x23,  0xA4,  0x01,  0x06,  0x23,  0x9C,  0x01,  0x24,  0x2B,  0x1C,  0x01,  0x02,  0xA6,  0xAA,  0x02,
+  0x07,  0xA6,  0x5A,  0x02,  0x06,  0xA6,  0x5E,  0x02,  0x03,  0xA6,  0x20,  0x04,  0x01,  0xA6,  0xB4,  0x02,
+  0x00,  0xA6,  0xB4,  0x02,  0x00,  0x33,  0x12,  0x00,  0xC2,  0x88,  0x00,  0x0E,  0x80,  0x63,  0x00,  0x43,
+  0x00,  0xA0,  0x8C,  0x02,  0x4D,  0x04,  0x04,  0x01,  0x0B,  0xDC,  0xE7,  0x23,  0x04,  0x61,  0x84,  0x01,
+  0x10,  0x31,  0x12,  0x35,  0x14,  0x01,  0xEC,  0x00,  0x6C,  0x38,  0x00,  0x3F,  0x00,  0x00,  0xEA,  0x82,
+  0x18,  0x23,  0x04,  0x61,  0x18,  0xA0,  0xE2,  0x02,  0x04,  0x01,  0xA2,  0xC8,  0x00,  0x33,  0x1F,  0x00,
+  0xC2,  0x88,  0x08,  0x31,  0x0A,  0x35,  0x0C,  0x39,  0x0E,  0x3D,  0x7E,  0x98,  0xB6,  0x2D,  0x01,  0xA6,
+  0x14,  0x03,  0x00,  0xA6,  0x14,  0x03,  0x07,  0xA6,  0x0C,  0x03,  0x06,  0xA6,  0x10,  0x03,  0x03,  0xA6,
+  0x20,  0x04,  0x02,  0xA6,  0x6C,  0x02,  0x00,  0x33,  0x33,  0x00,  0xC2,  0x88,  0x7C,  0x95,  0xEE,  0x82,
+  0x60,  0x96,  0xEE,  0x82,  0x82,  0x98,  0x80,  0x42,  0x7E,  0x98,  0x64,  0xE4,  0x04,  0x01,  0x2D,  0xC8,
+  0x31,  0x05,  0x07,  0x01,  0x00,  0xA2,  0x54,  0x03,  0x00,  0x43,  0x87,  0x01,  0x05,  0x05,  0x86,  0x98,
+  0x7E,  0x98,  0x00,  0xA6,  0x16,  0x03,  0x07,  0xA6,  0x4C,  0x03,  0x03,  0xA6,  0x3C,  0x04,  0x06,  0xA6,
+  0x50,  0x03,  0x01,  0xA6,  0x16,  0x03,  0x00,  0x33,  0x25,  0x00,  0xC2,  0x88,  0x7C,  0x95,  0x32,  0x83,
+  0x60,  0x96,  0x32,  0x83,  0x04,  0x01,  0x10,  0xCE,  0x07,  0xC8,  0x05,  0x05,  0xEB,  0x04,  0x00,  0x33,
+  0x00,  0x20,  0xC0,  0x20,  0x81,  0x62,  0x72,  0x83,  0x00,  0x01,  0x05,  0x05,  0xFF,  0xA2,  0x7A,  0x03,
+  0xB1,  0x01,  0x08,  0x23,  0xB2,  0x01,  0x2E,  0x83,  0x05,  0x05,  0x15,  0x01,  0x00,  0xA2,  0x9A,  0x03,
+  0xEC,  0x00,  0x6E,  0x00,  0x95,  0x01,  0x6C,  0x38,  0x00,  0x3F,  0x00,  0x00,  0x01,  0xA6,  0x96,  0x03,
+  0x00,  0xA6,  0x96,  0x03,  0x10,  0x84,  0x80,  0x42,  0x7E,  0x98,  0x01,  0xA6,  0xA4,  0x03,  0x00,  0xA6,
+  0xBC,  0x03,  0x10,  0x84,  0xA8,  0x98,  0x80,  0x42,  0x01,  0xA6,  0xA4,  0x03,  0x07,  0xA6,  0xB2,  0x03,
+  0xD4,  0x83,  0x7C,  0x95,  0xA8,  0x83,  0x00,  0x33,  0x2F,  0x00,  0xC2,  0x88,  0xA8,  0x98,  0x80,  0x42,
+  0x00,  0xA6,  0xBC,  0x03,  0x07,  0xA6,  0xCA,  0x03,  0xD4,  0x83,  0x7C,  0x95,  0xC0,  0x83,  0x00,  0x33,
+  0x26,  0x00,  0xC2,  0x88,  0x38,  0x2B,  0x80,  0x32,  0x80,  0x36,  0x04,  0x23,  0xA0,  0x01,  0x12,  0x23,
+  0xA1,  0x01,  0x10,  0x84,  0x07,  0xF0,  0x06,  0xA4,  0xF4,  0x03,  0x80,  0x6B,  0x80,  0x67,  0x05,  0x23,
+  0x83,  0x03,  0x80,  0x63,  0x03,  0xA6,  0x0E,  0x04,  0x07,  0xA6,  0x06,  0x04,  0x06,  0xA6,  0x0A,  0x04,
+  0x00,  0x33,  0x17,  0x00,  0xC2,  0x88,  0x7C,  0x95,  0xF4,  0x83,  0x60,  0x96,  0xF4,  0x83,  0x20,  0x84,
+  0x07,  0xF0,  0x06,  0xA4,  0x20,  0x04,  0x80,  0x6B,  0x80,  0x67,  0x05,  0x23,  0x83,  0x03,  0x80,  0x63,
   0xB6,  0x2D,  0x03,  0xA6,  0x3C,  0x04,  0x07,  0xA6,  0x34,  0x04,  0x06,  0xA6,  0x38,  0x04,  0x00,  0x33,
-  0x30,  0x00,  0xC0,  0x88,  0x7C,  0x95,  0x20,  0x84,  0x60,  0x96,  0x20,  0x84,  0x1D,  0x01,  0x06,  0xCC,
+  0x30,  0x00,  0xC2,  0x88,  0x7C,  0x95,  0x20,  0x84,  0x60,  0x96,  0x20,  0x84,  0x1D,  0x01,  0x06,  0xCC,
   0x00,  0x33,  0x00,  0x84,  0xC0,  0x20,  0x00,  0x23,  0xEA,  0x00,  0x81,  0x62,  0xA2,  0x0D,  0x80,  0x63,
-  0x07,  0xA6,  0x5A,  0x04,  0x00,  0x33,  0x18,  0x00,  0xC0,  0x88,  0x03,  0x03,  0x80,  0x63,  0xA3,  0x01,
+  0x07,  0xA6,  0x5A,  0x04,  0x00,  0x33,  0x18,  0x00,  0xC2,  0x88,  0x03,  0x03,  0x80,  0x63,  0xA3,  0x01,
   0x07,  0xA4,  0x64,  0x04,  0x23,  0x01,  0x00,  0xA2,  0x86,  0x04,  0x0A,  0xA0,  0x76,  0x04,  0xE0,  0x00,
-  0x00,  0x33,  0x1D,  0x00,  0xC0,  0x88,  0x0B,  0xA0,  0x82,  0x04,  0xE0,  0x00,  0x00,  0x33,  0x1E,  0x00,
-  0xC0,  0x88,  0x42,  0x23,  0xF6,  0x88,  0x00,  0x23,  0x22,  0xA3,  0xE6,  0x04,  0x08,  0x23,  0x22,  0xA3,
+  0x00,  0x33,  0x1D,  0x00,  0xC2,  0x88,  0x0B,  0xA0,  0x82,  0x04,  0xE0,  0x00,  0x00,  0x33,  0x1E,  0x00,
+  0xC2,  0x88,  0x42,  0x23,  0xF8,  0x88,  0x00,  0x23,  0x22,  0xA3,  0xE6,  0x04,  0x08,  0x23,  0x22,  0xA3,
   0xA2,  0x04,  0x28,  0x23,  0x22,  0xA3,  0xAE,  0x04,  0x02,  0x23,  0x22,  0xA3,  0xC4,  0x04,  0x42,  0x23,
-  0xF6,  0x88,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA0,  0xAE,  0x04,  0x45,  0x23,  0xF6,  0x88,  0x04,  0x98,
-  0x00,  0xA2,  0xC0,  0x04,  0xB2,  0x98,  0x00,  0x33,  0x00,  0x82,  0xC0,  0x20,  0x81,  0x62,  0xF0,  0x81,
-  0x47,  0x23,  0xF6,  0x88,  0x04,  0x01,  0x0B,  0xDE,  0x04,  0x98,  0xB2,  0x98,  0x00,  0x33,  0x00,  0x81,
-  0xC0,  0x20,  0x81,  0x62,  0x14,  0x01,  0x00,  0xA0,  0x08,  0x02,  0x43,  0x23,  0xF6,  0x88,  0x04,  0x23,
+  0xF8,  0x88,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA0,  0xAE,  0x04,  0x45,  0x23,  0xF8,  0x88,  0x04,  0x98,
+  0x00,  0xA2,  0xC0,  0x04,  0xB4,  0x98,  0x00,  0x33,  0x00,  0x82,  0xC0,  0x20,  0x81,  0x62,  0xE8,  0x81,
+  0x47,  0x23,  0xF8,  0x88,  0x04,  0x01,  0x0B,  0xDE,  0x04,  0x98,  0xB4,  0x98,  0x00,  0x33,  0x00,  0x81,
+  0xC0,  0x20,  0x81,  0x62,  0x14,  0x01,  0x00,  0xA0,  0x00,  0x02,  0x43,  0x23,  0xF8,  0x88,  0x04,  0x23,
   0xA0,  0x01,  0x44,  0x23,  0xA1,  0x01,  0x80,  0x73,  0x4D,  0x00,  0x03,  0xA3,  0xF4,  0x04,  0x00,  0x33,
-  0x27,  0x00,  0xC0,  0x88,  0x04,  0x01,  0x04,  0xDC,  0x02,  0x23,  0xA2,  0x01,  0x04,  0x23,  0xA0,  0x01,
+  0x27,  0x00,  0xC2,  0x88,  0x04,  0x01,  0x04,  0xDC,  0x02,  0x23,  0xA2,  0x01,  0x04,  0x23,  0xA0,  0x01,
   0x04,  0x98,  0x26,  0x95,  0x4B,  0x00,  0xF6,  0x00,  0x4F,  0x04,  0x4F,  0x00,  0x00,  0xA3,  0x22,  0x05,
   0x00,  0x05,  0x76,  0x00,  0x06,  0x61,  0x00,  0xA2,  0x1C,  0x05,  0x0A,  0x85,  0x46,  0x97,  0xCD,  0x04,
   0x24,  0x85,  0x48,  0x04,  0x84,  0x80,  0x02,  0x01,  0x03,  0xDA,  0x80,  0x23,  0x82,  0x01,  0x34,  0x85,
@@ -11176,16 +12025,16 @@ STATIC uchar _asc_mcode_buf[] ASC_INITDATA =
   0x04,  0x01,  0x02,  0xC8,  0x30,  0x01,  0x80,  0x01,  0xF7,  0x04,  0x03,  0x01,  0x49,  0x04,  0x80,  0x01,
   0xC9,  0x00,  0x00,  0x05,  0x00,  0x01,  0xFF,  0xA0,  0x60,  0x05,  0x77,  0x04,  0x01,  0x23,  0xEA,  0x00,
   0x5D,  0x00,  0xFE,  0xC7,  0x00,  0x62,  0x00,  0x23,  0xEA,  0x00,  0x00,  0x63,  0x07,  0xA4,  0xF8,  0x05,
-  0x03,  0x03,  0x02,  0xA0,  0x8E,  0x05,  0xF4,  0x85,  0x00,  0x33,  0x2D,  0x00,  0xC0,  0x88,  0x04,  0xA0,
+  0x03,  0x03,  0x02,  0xA0,  0x8E,  0x05,  0xF4,  0x85,  0x00,  0x33,  0x2D,  0x00,  0xC2,  0x88,  0x04,  0xA0,
   0xB8,  0x05,  0x80,  0x63,  0x00,  0x23,  0xDF,  0x00,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA2,  0xA4,  0x05,
   0x1D,  0x01,  0x06,  0xD6,  0x02,  0x23,  0x02,  0x41,  0x82,  0x01,  0x50,  0x00,  0x62,  0x97,  0x04,  0x85,
   0x04,  0x23,  0x02,  0x41,  0x82,  0x01,  0x04,  0x85,  0x08,  0xA0,  0xBE,  0x05,  0xF4,  0x85,  0x03,  0xA0,
   0xC4,  0x05,  0xF4,  0x85,  0x01,  0xA0,  0xCE,  0x05,  0x88,  0x00,  0x80,  0x63,  0xCC,  0x86,  0x07,  0xA0,
   0xEE,  0x05,  0x5F,  0x00,  0x00,  0x2B,  0xDF,  0x08,  0x00,  0xA2,  0xE6,  0x05,  0x80,  0x67,  0x80,  0x63,
-  0x01,  0xA2,  0x7A,  0x06,  0x7C,  0x85,  0x06,  0x23,  0x68,  0x98,  0x48,  0x23,  0xF6,  0x88,  0x07,  0x23,
+  0x01,  0xA2,  0x7A,  0x06,  0x7C,  0x85,  0x06,  0x23,  0x68,  0x98,  0x48,  0x23,  0xF8,  0x88,  0x07,  0x23,
   0x80,  0x00,  0x06,  0x87,  0x80,  0x63,  0x7C,  0x85,  0x00,  0x23,  0xDF,  0x00,  0x00,  0x63,  0x4A,  0x00,
   0x06,  0x61,  0x00,  0xA2,  0x36,  0x06,  0x1D,  0x01,  0x16,  0xD4,  0xC0,  0x23,  0x07,  0x41,  0x83,  0x03,
-  0x80,  0x63,  0x06,  0xA6,  0x1C,  0x06,  0x00,  0x33,  0x37,  0x00,  0xC0,  0x88,  0x1D,  0x01,  0x01,  0xD6,
+  0x80,  0x63,  0x06,  0xA6,  0x1C,  0x06,  0x00,  0x33,  0x37,  0x00,  0xC2,  0x88,  0x1D,  0x01,  0x01,  0xD6,
   0x20,  0x23,  0x63,  0x60,  0x83,  0x03,  0x80,  0x63,  0x02,  0x23,  0xDF,  0x00,  0x07,  0xA6,  0x7C,  0x05,
   0xEF,  0x04,  0x6F,  0x00,  0x00,  0x63,  0x4B,  0x00,  0x06,  0x41,  0xCB,  0x00,  0x52,  0x00,  0x06,  0x61,
   0x00,  0xA2,  0x4E,  0x06,  0x1D,  0x01,  0x03,  0xCA,  0xC0,  0x23,  0x07,  0x41,  0x00,  0x63,  0x1D,  0x01,
@@ -11197,12 +12046,12 @@ STATIC uchar _asc_mcode_buf[] ASC_INITDATA =
   0x01,  0x00,  0x06,  0xA6,  0xAA,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x40,  0x0E,  0x80,  0x63,  0x00,  0x43,
   0x00,  0xA0,  0xA2,  0x06,  0x06,  0xA6,  0xBC,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x80,  0x67,  0x40,  0x0E,
   0x80,  0x63,  0x07,  0xA6,  0x7C,  0x05,  0x00,  0x23,  0xDF,  0x00,  0x00,  0x63,  0x07,  0xA6,  0xD6,  0x06,
-  0x00,  0x33,  0x2A,  0x00,  0xC0,  0x88,  0x03,  0x03,  0x80,  0x63,  0x89,  0x00,  0x0A,  0x2B,  0x07,  0xA6,
-  0xE8,  0x06,  0x00,  0x33,  0x29,  0x00,  0xC0,  0x88,  0x00,  0x43,  0x00,  0xA2,  0xF4,  0x06,  0xC0,  0x0E,
+  0x00,  0x33,  0x2A,  0x00,  0xC2,  0x88,  0x03,  0x03,  0x80,  0x63,  0x89,  0x00,  0x0A,  0x2B,  0x07,  0xA6,
+  0xE8,  0x06,  0x00,  0x33,  0x29,  0x00,  0xC2,  0x88,  0x00,  0x43,  0x00,  0xA2,  0xF4,  0x06,  0xC0,  0x0E,
   0x80,  0x63,  0xDE,  0x86,  0xC0,  0x0E,  0x00,  0x33,  0x00,  0x80,  0xC0,  0x20,  0x81,  0x62,  0x04,  0x01,
   0x02,  0xDA,  0x80,  0x63,  0x7C,  0x85,  0x80,  0x7B,  0x80,  0x63,  0x06,  0xA6,  0x8C,  0x06,  0x00,  0x33,
-  0x2C,  0x00,  0xC0,  0x88,  0x0C,  0xA2,  0x2E,  0x07,  0xFE,  0x95,  0x83,  0x03,  0x80,  0x63,  0x06,  0xA6,
-  0x2C,  0x07,  0x07,  0xA6,  0x7C,  0x05,  0x00,  0x33,  0x3D,  0x00,  0xC0,  0x88,  0x00,  0x00,  0x80,  0x67,
+  0x2C,  0x00,  0xC2,  0x88,  0x0C,  0xA2,  0x2E,  0x07,  0xFE,  0x95,  0x83,  0x03,  0x80,  0x63,  0x06,  0xA6,
+  0x2C,  0x07,  0x07,  0xA6,  0x7C,  0x05,  0x00,  0x33,  0x3D,  0x00,  0xC2,  0x88,  0x00,  0x00,  0x80,  0x67,
   0x83,  0x03,  0x80,  0x63,  0x0C,  0xA0,  0x44,  0x07,  0x07,  0xA6,  0x7C,  0x05,  0xBF,  0x23,  0x04,  0x61,
   0x84,  0x01,  0xE6,  0x84,  0x00,  0x63,  0xF0,  0x04,  0x01,  0x01,  0xF1,  0x00,  0x00,  0x01,  0xF2,  0x00,
   0x01,  0x05,  0x80,  0x01,  0x72,  0x04,  0x71,  0x00,  0x81,  0x01,  0x70,  0x04,  0x80,  0x05,  0x81,  0x05,
@@ -11212,7 +12061,7 @@ STATIC uchar _asc_mcode_buf[] ASC_INITDATA =
   0x80,  0x01,  0x70,  0x04,  0x71,  0x00,  0x80,  0x01,  0x72,  0x00,  0x81,  0x01,  0x71,  0x04,  0x70,  0x00,
   0x81,  0x01,  0x70,  0x04,  0x00,  0x63,  0x00,  0x23,  0xB3,  0x01,  0x83,  0x05,  0xA3,  0x01,  0xA2,  0x01,
   0xA1,  0x01,  0x01,  0x23,  0xA0,  0x01,  0x00,  0x01,  0xC8,  0x00,  0x03,  0xA1,  0xC4,  0x07,  0x00,  0x33,
-  0x07,  0x00,  0xC0,  0x88,  0x80,  0x05,  0x81,  0x05,  0x04,  0x01,  0x11,  0xC8,  0x48,  0x00,  0xB0,  0x01,
+  0x07,  0x00,  0xC2,  0x88,  0x80,  0x05,  0x81,  0x05,  0x04,  0x01,  0x11,  0xC8,  0x48,  0x00,  0xB0,  0x01,
   0xB1,  0x01,  0x08,  0x23,  0xB2,  0x01,  0x05,  0x01,  0x48,  0x04,  0x00,  0x43,  0x00,  0xA2,  0xE4,  0x07,
   0x00,  0x05,  0xDA,  0x87,  0x00,  0x01,  0xC8,  0x00,  0xFF,  0x23,  0x80,  0x01,  0x05,  0x05,  0x00,  0x63,
   0xF7,  0x04,  0x1A,  0x09,  0xF6,  0x08,  0x6E,  0x04,  0x00,  0x02,  0x80,  0x43,  0x76,  0x08,  0x80,  0x02,
@@ -11223,19 +12072,19 @@ STATIC uchar _asc_mcode_buf[] ASC_INITDATA =
   0x26,  0x95,  0x24,  0x88,  0x73,  0x04,  0x00,  0x63,  0xF3,  0x04,  0x75,  0x04,  0x5A,  0x88,  0x02,  0x01,
   0x04,  0xD8,  0x46,  0x97,  0x04,  0x98,  0x26,  0x95,  0x4A,  0x88,  0x75,  0x00,  0x00,  0xA3,  0x64,  0x08,
   0x00,  0x05,  0x4E,  0x88,  0x73,  0x04,  0x00,  0x63,  0x80,  0x7B,  0x80,  0x63,  0x06,  0xA6,  0x76,  0x08,
-  0x00,  0x33,  0x3E,  0x00,  0xC0,  0x88,  0x80,  0x67,  0x83,  0x03,  0x80,  0x63,  0x00,  0x63,  0x38,  0x2B,
+  0x00,  0x33,  0x3E,  0x00,  0xC2,  0x88,  0x80,  0x67,  0x83,  0x03,  0x80,  0x63,  0x00,  0x63,  0x38,  0x2B,
   0x9C,  0x88,  0x38,  0x2B,  0x92,  0x88,  0x32,  0x09,  0x31,  0x05,  0x92,  0x98,  0x05,  0x05,  0xB2,  0x09,
   0x00,  0x63,  0x00,  0x32,  0x00,  0x36,  0x00,  0x3A,  0x00,  0x3E,  0x00,  0x63,  0x80,  0x32,  0x80,  0x36,
-  0x80,  0x3A,  0x80,  0x3E,  0x00,  0x63,  0x38,  0x2B,  0x40,  0x32,  0x40,  0x36,  0x40,  0x3A,  0x40,  0x3E,
-  0x00,  0x63,  0x5A,  0x20,  0xC9,  0x40,  0x00,  0xA0,  0xB2,  0x08,  0x5D,  0x00,  0xFE,  0xC3,  0x00,  0x63,
-  0x80,  0x73,  0xE6,  0x20,  0x02,  0x23,  0xE8,  0x00,  0x82,  0x73,  0xFF,  0xFD,  0x80,  0x73,  0x13,  0x23,
-  0xF6,  0x88,  0x66,  0x20,  0xC0,  0x20,  0x04,  0x23,  0xA0,  0x01,  0xA1,  0x23,  0xA1,  0x01,  0x81,  0x62,
-  0xE0,  0x88,  0x80,  0x73,  0x80,  0x77,  0x68,  0x00,  0x00,  0xA2,  0x80,  0x00,  0x03,  0xC2,  0xF1,  0xC7,
-  0x41,  0x23,  0xF6,  0x88,  0x11,  0x23,  0xA1,  0x01,  0x04,  0x23,  0xA0,  0x01,  0xE6,  0x84,
+  0x80,  0x3A,  0x80,  0x3E,  0xB4,  0x3D,  0x00,  0x63,  0x38,  0x2B,  0x40,  0x32,  0x40,  0x36,  0x40,  0x3A,
+  0x40,  0x3E,  0x00,  0x63,  0x5A,  0x20,  0xC9,  0x40,  0x00,  0xA0,  0xB4,  0x08,  0x5D,  0x00,  0xFE,  0xC3,
+  0x00,  0x63,  0x80,  0x73,  0xE6,  0x20,  0x02,  0x23,  0xE8,  0x00,  0x82,  0x73,  0xFF,  0xFD,  0x80,  0x73,
+  0x13,  0x23,  0xF8,  0x88,  0x66,  0x20,  0xC0,  0x20,  0x04,  0x23,  0xA0,  0x01,  0xA1,  0x23,  0xA1,  0x01,
+  0x81,  0x62,  0xE2,  0x88,  0x80,  0x73,  0x80,  0x77,  0x68,  0x00,  0x00,  0xA2,  0x80,  0x00,  0x03,  0xC2,
+  0xF1,  0xC7,  0x41,  0x23,  0xF8,  0x88,  0x11,  0x23,  0xA1,  0x01,  0x04,  0x23,  0xA0,  0x01,  0xE6,  0x84,
 };
 
 STATIC ushort _asc_mcode_size ASC_INITDATA = sizeof(_asc_mcode_buf);
-STATIC ulong _asc_mcode_chksum ASC_INITDATA = 0x012B5442UL;
+STATIC ulong  _asc_mcode_chksum ASC_INITDATA = 0x012C453FUL;
 
 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST  16
 STATIC uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] =
@@ -11302,7 +12151,7 @@ AscExeScsiQueue(
     n_q_required = 1;
     if (scsiq->cdbptr[0] == SCSICMD_RequestSense) {
         if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
-            asc_dvc->sdtr_done &= ~scsiq->q1.target_id ;
+            asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
             sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
             AscMsgOutSDTR(asc_dvc,
                           asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
@@ -11324,12 +12173,15 @@ AscExeScsiQueue(
             DvcLeaveCritical(last_int_level);
             return (ERR);
         }
-        if (sg_entry_cnt > ASC_MAX_SG_LIST) {
-            return (ERR);
+#if !CC_VERY_LONG_SG_LIST
+        if (sg_entry_cnt > ASC_MAX_SG_LIST)
+        {
+            return(ERR);
         }
+#endif /* !CC_VERY_LONG_SG_LIST */
         if (sg_entry_cnt == 1) {
-            scsiq->q1.data_addr = sg_head->sg_list[0].addr;
-            scsiq->q1.data_cnt = sg_head->sg_list[0].bytes;
+            scsiq->q1.data_addr = (ulong) sg_head->sg_list[0].addr;
+            scsiq->q1.data_cnt = (ulong) sg_head->sg_list[0].bytes;
             scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
         }
         sg_entry_cnt_minus_one = sg_entry_cnt - 1;
@@ -11341,7 +12193,7 @@ AscExeScsiQueue(
         if (scsiq->q1.cntl & QC_SG_HEAD) {
             data_cnt = 0;
             for (i = 0; i < sg_entry_cnt; i++) {
-                data_cnt += sg_head->sg_list[i].bytes;
+                data_cnt += (ulong) sg_head->sg_list[i].bytes;
             }
         } else {
             data_cnt = scsiq->q1.data_cnt;
@@ -11375,8 +12227,9 @@ AscExeScsiQueue(
             if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
                 if ((scsi_cmd == SCSICMD_Read6) ||
                     (scsi_cmd == SCSICMD_Read10)) {
-                    addr = sg_head->sg_list[sg_entry_cnt_minus_one].addr +
-                      sg_head->sg_list[sg_entry_cnt_minus_one].bytes;
+                    addr =
+                        (ulong) sg_head->sg_list[sg_entry_cnt_minus_one].addr +
+                        (ulong) sg_head->sg_list[sg_entry_cnt_minus_one].bytes;
                     extra_bytes = (uchar) ((ushort) addr & 0x0003);
                     if ((extra_bytes != 0) &&
                         ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
@@ -11390,6 +12243,15 @@ AscExeScsiQueue(
             }
         }
         sg_head->entry_to_copy = sg_head->entry_cnt;
+        /*
+         * Set the sg_entry_cnt to the maximum possible. The rest of
+         * the SG elements will be copied when the RISC completes the
+         * SG elements that fit and halts.
+         */
+        if (sg_entry_cnt > ASC_MAX_SG_LIST)
+        {
+             sg_entry_cnt = ASC_MAX_SG_LIST;
+        }
         n_q_required = AscSgListToQueue(sg_entry_cnt);
         if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
             (uint) n_q_required) || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
@@ -11616,9 +12478,39 @@ AscPutReadySgListQueue(
     sg_head = scsiq->sg_head;
     saved_data_addr = scsiq->q1.data_addr;
     saved_data_cnt = scsiq->q1.data_cnt;
-    scsiq->q1.data_addr = sg_head->sg_list[0].addr;
-    scsiq->q1.data_cnt = sg_head->sg_list[0].bytes;
-    sg_entry_cnt = sg_head->entry_cnt - 1;
+    scsiq->q1.data_addr = (ulong) sg_head->sg_list[0].addr;
+    scsiq->q1.data_cnt = (ulong) sg_head->sg_list[0].bytes;
+    /*
+     * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
+     * then not all SG elements will fit in the allocated queues.
+     * The rest of the SG elements will be copied when the RISC
+     * completes the SG elements that fit and halts.
+     */
+    if (sg_head->entry_cnt > ASC_MAX_SG_LIST)
+    {
+         /*
+          * Set sg_entry_cnt to be the number of SG elements that
+          * will fit in the allocated SG queues. It is minus 1 because
+          * first SG element handled above. ASC_MAX_SG_LIST is already
+          * inflated by 1 to account for this. For example it may
+          * be 50 which is 1 + 7 queues * 7 SG elements.
+          */
+         sg_entry_cnt = ASC_MAX_SG_LIST - 1;
+
+         /*
+          * Keep track of remaining number of SG elements that will
+          * need to be handled from a_isr.c.
+          */
+         scsiq->remain_sg_entry_cnt = sg_head->entry_cnt - ASC_MAX_SG_LIST;
+    } else
+    {
+         /*
+          * Set sg_entry_cnt to be the number of SG elements that
+          * will fit in the allocated SG queues. Refer to comment
+          * above regarding why it is - 1.
+          */
+         sg_entry_cnt = sg_head->entry_cnt - 1;
+    }
     if (sg_entry_cnt != 0) {
         scsiq->q1.cntl |= QC_SG_HEAD;
         q_addr = ASC_QNO_TO_QADDR(q_no);
@@ -11639,7 +12531,19 @@ AscPutReadySgListQueue(
                     scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
                 }
             } else {
-                scsi_sg_q.cntl |= QCSG_SG_XFER_END;
+                /*
+                 * This is the last SG queue in the list of
+                 * allocated SG queues. If there are more
+                 * SG elements than will fit in the allocated
+                 * queues, then set the QCSG_SG_XFER_MORE flag.
+                 */
+                if (sg_head->entry_cnt > ASC_MAX_SG_LIST)
+                {
+                    scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
+                } else
+                {
+                    scsi_sg_q.cntl |= QCSG_SG_XFER_END;
+                }
                 sg_list_dwords = sg_entry_cnt << 1;
                 if (i == 0) {
                     scsi_sg_q.sg_list_cnt = sg_entry_cnt;
@@ -11663,6 +12567,7 @@ AscPutReadySgListQueue(
                               (ulong *) & sg_head->sg_list[sg_index],
                                   (ushort) sg_list_dwords);
             sg_index += ASC_SG_LIST_PER_Q;
+            scsiq->next_sg_index = sg_index;
         }
     } else {
         scsiq->q1.cntl &= ~QC_SG_HEAD;
@@ -11848,7 +12753,7 @@ AscSetChipSynRegAtID(
         if (org_id == (0x01 << i))
             break;
     }
-    org_id = i;
+    org_id = (ASC_SCSI_BIT_ID_TYPE) i;
     AscWriteChipDvcID(iop_base, id);
     if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
         AscSetBank(iop_base, 0);
@@ -11987,7 +12892,7 @@ _AscWaitQDone(
     uchar               q_status;
     int                 count = 0;
 
-    while (scsiq->q1.q_no == 0) ;
+    while (scsiq->q1.q_no == 0);
     q_addr = ASC_QNO_TO_QADDR(scsiq->q1.q_no);
     do {
         q_status = AscReadLramByte(iop_base, q_addr + ASC_SCSIQ_B_STATUS);
@@ -12082,7 +12987,7 @@ AscGetSynPeriodIndex(
 
     period_table = asc_dvc->sdtr_period_tbl;
     max_index = (int) asc_dvc->max_sdtr_index;
-    min_index = (int)asc_dvc->host_init_sdtr_index ;
+    min_index = (int)asc_dvc->host_init_sdtr_index;
     if ((syn_time <= period_table[max_index])) {
         for (i = min_index; i < (max_index - 1); i++) {
             if (syn_time <= period_table[i]) {
@@ -12381,7 +13286,7 @@ AscGetOnePhyAddr(
     if (sg_head.entry_cnt > 1) {
         return (0L);
     }
-    return (sg_head.sg_list[0].addr);
+    return ((ulong) sg_head.sg_list[0].addr);
 }
 
 STATIC void
@@ -12397,7 +13302,7 @@ DvcDelayNanoSecond(ASC_DVC_VAR asc_ptr_type * asc_dvc, ulong nano_sec)
 }
 
 ASC_INITFUNC(
-STATIC ulong
+STATIC ulong,
 AscGetEisaProductID(
                        PortAddr iop_base
 )
@@ -12415,7 +13320,7 @@ AscGetEisaProductID(
 }
 
 ASC_INITFUNC(
-STATIC PortAddr
+STATIC PortAddr,
 AscSearchIOPortAddrEISA(
                            PortAddr iop_base
 )
@@ -12592,9 +13497,13 @@ AscResetChipAndScsiBus(
 )
 {
     PortAddr    iop_base;
+    int         i = 10;
 
     iop_base = asc_dvc->iop_base;
-    while (AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) ;
+    while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) && (i-- > 0))
+    {
+          DvcSleepMilliSecond(100);
+    }
     AscStopChip(iop_base);
     AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
     DvcDelayNanoSecond(asc_dvc, 60000);
@@ -12609,7 +13518,7 @@ AscResetChipAndScsiBus(
 }
 
 ASC_INITFUNC(
-STATIC ulong
+STATIC ulong,
 AscGetMaxDmaCount(
                      ushort bus_type
 )
@@ -12623,7 +13532,7 @@ AscGetMaxDmaCount(
 }
 
 ASC_INITFUNC(
-STATIC ushort
+STATIC ushort,
 AscGetIsaDmaChannel(
                        PortAddr iop_base
 )
@@ -12640,7 +13549,7 @@ AscGetIsaDmaChannel(
 }
 
 ASC_INITFUNC(
-STATIC ushort
+STATIC ushort,
 AscSetIsaDmaChannel(
                        PortAddr iop_base,
                        ushort dma_channel
@@ -12664,7 +13573,7 @@ AscSetIsaDmaChannel(
 }
 
 ASC_INITFUNC(
-STATIC uchar
+STATIC uchar,
 AscSetIsaDmaSpeed(
                      PortAddr iop_base,
                      uchar speed_value
@@ -12679,7 +13588,7 @@ AscSetIsaDmaSpeed(
 }
 
 ASC_INITFUNC(
-STATIC uchar
+STATIC uchar,
 AscGetIsaDmaSpeed(
                      PortAddr iop_base
 )
@@ -12695,7 +13604,7 @@ AscGetIsaDmaSpeed(
 }
 
 ASC_INITFUNC(
-STATIC ushort
+STATIC ushort,
 AscReadPCIConfigWord(
     ASC_DVC_VAR asc_ptr_type *asc_dvc,
     ushort pci_config_offset)
@@ -12709,7 +13618,7 @@ AscReadPCIConfigWord(
 }
 
 ASC_INITFUNC(
-STATIC ushort 
+STATIC ushort,
 AscInitGetConfig(
         ASC_DVC_VAR asc_ptr_type * asc_dvc
 )
@@ -12794,7 +13703,7 @@ AscInitGetConfig(
 }
 
 ASC_INITFUNC(
-STATIC ushort
+STATIC ushort,
 AscInitSetConfig(
                     ASC_DVC_VAR asc_ptr_type * asc_dvc
 )
@@ -12815,7 +13724,7 @@ AscInitSetConfig(
 }
 
 ASC_INITFUNC(
-STATIC ushort
+STATIC ushort,
 AscInitFromAscDvcVar(
                         ASC_DVC_VAR asc_ptr_type * asc_dvc
 )
@@ -12878,7 +13787,7 @@ AscInitFromAscDvcVar(
 }
 
 ASC_INITFUNC(
-STATIC ushort
+STATIC ushort,
 AscInitAsc1000Driver(
                         ASC_DVC_VAR asc_ptr_type * asc_dvc
 )
@@ -12886,9 +13795,6 @@ AscInitAsc1000Driver(
 {
     ushort              warn_code;
     PortAddr            iop_base;
-    extern ushort       _asc_mcode_size;
-    extern ulong        _asc_mcode_chksum;
-    extern uchar        _asc_mcode_buf[];
 
     iop_base = asc_dvc->iop_base;
     warn_code = 0;
@@ -12920,7 +13826,7 @@ AscInitAsc1000Driver(
 }
 
 ASC_INITFUNC(
-STATIC ushort
+STATIC ushort,
 AscInitAscDvcVar(
                     ASC_DVC_VAR asc_ptr_type * asc_dvc
 )
@@ -12953,12 +13859,12 @@ AscInitAscDvcVar(
     asc_dvc->no_scam = 0;
     asc_dvc->unit_not_ready = 0;
     asc_dvc->queue_full_or_busy = 0;
-    asc_dvc->redo_scam = 0 ;
-    asc_dvc->res2 = 0 ;
-    asc_dvc->host_init_sdtr_index = 0 ;
-    asc_dvc->res7 = 0 ;
-    asc_dvc->res8 = 0 ;
-    asc_dvc->cfg->can_tagged_qng = 0 ;
+    asc_dvc->redo_scam = 0;
+    asc_dvc->res2 = 0;
+    asc_dvc->host_init_sdtr_index = 0;
+    asc_dvc->res7 = 0;
+    asc_dvc->res8 = 0;
+    asc_dvc->cfg->can_tagged_qng = 0;
     asc_dvc->cfg->cmd_qng_enabled = 0;
     asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
     asc_dvc->init_sdtr = 0;
@@ -13035,7 +13941,7 @@ AscInitAscDvcVar(
 }
 
 ASC_INITFUNC(
-STATIC ushort
+STATIC ushort,
 AscInitFromEEP(
                   ASC_DVC_VAR asc_ptr_type * asc_dvc
 )
@@ -13117,11 +14023,11 @@ AscInitFromEEP(
                 /* Indicate EEPROM-less board. */
                 eep_config->adapter_info[5] = 0xBB;
             } else {
-                write_eep = 1 ;
-                warn_code |= ASC_WARN_EEPROM_CHKSUM ;
+                write_eep = 1;
+                warn_code |= ASC_WARN_EEPROM_CHKSUM;
             }
     }
-    asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr ;
+    asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
     asc_dvc->cfg->disc_enable = eep_config->disc_enable;
     asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
     asc_dvc->cfg->isa_dma_speed = eep_config->isa_dma_speed;
@@ -13190,7 +14096,7 @@ AscInitFromEEP(
 }
 
 ASC_INITFUNC(
-STATIC ushort
+STATIC ushort,
 AscInitMicroCodeVar(
                        ASC_DVC_VAR asc_ptr_type * asc_dvc
 )
@@ -13240,7 +14146,7 @@ AscInitMicroCodeVar(
 }
 
 ASC_INITFUNC(
-STATIC int
+STATIC int,
 AscTestExternalLram(
                        ASC_DVC_VAR asc_ptr_type * asc_dvc
 )
@@ -13267,7 +14173,7 @@ AscTestExternalLram(
 }
 
 ASC_INITFUNC(
-STATIC int
+STATIC int,
 AscWriteEEPCmdReg(
                      PortAddr iop_base,
                      uchar cmd_reg
@@ -13292,7 +14198,7 @@ AscWriteEEPCmdReg(
 }
 
 ASC_INITFUNC(
-STATIC int
+STATIC int,
 AscWriteEEPDataReg(
                       PortAddr iop_base,
                       ushort data_reg
@@ -13317,7 +14223,7 @@ AscWriteEEPDataReg(
 }
 
 ASC_INITFUNC(
-STATIC void
+STATIC void,
 AscWaitEEPRead(
                   void
 )
@@ -13328,7 +14234,7 @@ AscWaitEEPRead(
 }
 
 ASC_INITFUNC(
-STATIC void
+STATIC void,
 AscWaitEEPWrite(
                    void
 )
@@ -13339,7 +14245,7 @@ AscWaitEEPWrite(
 }
 
 ASC_INITFUNC(
-STATIC ushort
+STATIC ushort,
 AscReadEEPWord(
                   PortAddr iop_base,
                   uchar addr
@@ -13360,7 +14266,7 @@ AscReadEEPWord(
 }
 
 ASC_INITFUNC(
-STATIC ushort
+STATIC ushort,
 AscWriteEEPWord(
                    PortAddr iop_base,
                    uchar addr,
@@ -13387,7 +14293,7 @@ AscWriteEEPWord(
 }
 
 ASC_INITFUNC(
-STATIC ushort
+STATIC ushort,
 AscGetEEPConfig(
                    PortAddr iop_base,
                    ASCEEP_CONFIG * cfg_buf, ushort bus_type
@@ -13428,7 +14334,7 @@ AscGetEEPConfig(
 }
 
 ASC_INITFUNC(
-STATIC int
+STATIC int,
 AscSetEEPConfigOnce(
                        PortAddr iop_base,
                        ASCEEP_CONFIG * cfg_buf, ushort bus_type
@@ -13485,7 +14391,7 @@ AscSetEEPConfigOnce(
 }
 
 ASC_INITFUNC(
-STATIC int
+STATIC int,
 AscSetEEPConfig(
                    PortAddr iop_base,
                    ASCEEP_CONFIG * cfg_buf, ushort bus_type
@@ -13514,55 +14420,35 @@ AscAsyncFix(
                uchar tid_no,
                ASC_SCSI_INQUIRY *inq)
 {
-    uchar                dvc_type;
-    ASC_SCSI_BIT_ID_TYPE tid_bits;
+    uchar                       dvc_type;
+    ASC_SCSI_BIT_ID_TYPE        tid_bits;
 
     dvc_type = inq->byte0.peri_dvc_type;
     tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
 
-    if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) {
-        if (!(asc_dvc->init_sdtr & tid_bits)) {
+    if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN)
+    {
+        if (!(asc_dvc->init_sdtr & tid_bits))
+        {
             if ((dvc_type == SCSI_TYPE_CDROM) &&
                 (AscCompareString((uchar *) inq->vendor_id,
-                    (uchar *) "HP ", 3) == 0)) {
+                    (uchar *) "HP ", 3) == 0))
+            {
                 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
             }
             asc_dvc->pci_fix_asyn_xfer |= tid_bits;
             if ((dvc_type == SCSI_TYPE_PROC) ||
-                (dvc_type == SCSI_TYPE_SCANNER)) {
-                asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
-            }
-            if ((dvc_type == SCSI_TYPE_SASD) &&
-                (AscCompareString((uchar *) inq->vendor_id,
-                 (uchar *) "TANDBERG", 8) == 0) &&
-                (AscCompareString((uchar *) inq->product_id,
-                 (uchar *) " TDC 36", 7) == 0)) {
-                asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
-            }
-            if ((dvc_type == SCSI_TYPE_SASD) &&
-                (AscCompareString((uchar *) inq->vendor_id,
-                 (uchar *) "WANGTEK ", 8) == 0)) {
-                asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
-            }
-
-            if ((dvc_type == SCSI_TYPE_CDROM) &&
-                (AscCompareString((uchar *) inq->vendor_id,
-                 (uchar *) "NEC     ", 8) == 0) &&
-                (AscCompareString((uchar *) inq->product_id,
-                 (uchar *) "CD-ROM DRIVE    ", 16) == 0)) {
+                (dvc_type == SCSI_TYPE_SCANNER) ||
+                (dvc_type == SCSI_TYPE_CDROM) ||
+                (dvc_type == SCSI_TYPE_SASD))
+            {
                 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
             }
 
-            if ((dvc_type == SCSI_TYPE_CDROM) &&
-                (AscCompareString((uchar *) inq->vendor_id,
-                 (uchar *) "YAMAHA", 6) == 0) &&
-                (AscCompareString((uchar *) inq->product_id,
-                 (uchar *) "CDR400", 6) == 0)) {
-                asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
-            }
-            if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
+            if (asc_dvc->pci_fix_asyn_xfer & tid_bits)
+            {
                 AscSetRunChipSynRegAtID(asc_dvc->iop_base, tid_no,
-                                        ASYN_SDTR_DATA_FIX_PCI_REV_AB);
+                    ASYN_SDTR_DATA_FIX_PCI_REV_AB);
             }
         }
     }
@@ -13826,299 +14712,666 @@ AscMemWordSetLram(
  * --- Adv Library Functions
  */
 
-/* a_qswap.h */
-STATIC unsigned char _adv_mcode_buf[] ASC_INITDATA = {
-  0x9C,  0xF0,  0x80,  0x01,  0x00,  0xF0,  0x44,  0x0A,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
-  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
-  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x72,  0x01,  0xD6,  0x11,  0x00,  0x00,  0x70,  0x01,
-  0x30,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x90,  0x10,  0x2D,  0x03,  0x00,  0x00,  0x00,  0x00,
-  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
-  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
-  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
-  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
-  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
-  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
-  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
-  0x48,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
-  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
-  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,
-  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
-  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
-  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
-  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
-  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x78,  0x56,  0x34,  0x12,
-  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
-  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
-  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
-  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
-  0x00,  0x00,  0x04,  0xF7,  0x70,  0x01,  0x0C,  0x1C,  0x06,  0xF7,  0x02,  0x00,  0x00,  0xF2,  0xD6,  0x0A,
-  0x04,  0xF7,  0x70,  0x01,  0x06,  0xF7,  0x02,  0x00,  0x3E,  0x57,  0x3C,  0x56,  0x0C,  0x1C,  0x00,  0xFC,
-  0xA6,  0x00,  0x01,  0x58,  0xAA,  0x13,  0x20,  0xF0,  0xA6,  0x03,  0x06,  0xEC,  0xB9,  0x00,  0x0E,  0x47,
-  0x03,  0xE6,  0x10,  0x00,  0xCE,  0x45,  0x02,  0x13,  0x3E,  0x57,  0x06,  0xEA,  0xB9,  0x00,  0x47,  0x4B,
-  0x03,  0xF6,  0xE0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x01,  0x48,  0x4E,  0x12,  0x03,  0xF6,  0xC0,  0x00,
-  0x00,  0xF2,  0x68,  0x0A,  0x41,  0x58,  0x03,  0xF6,  0xD0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x49,  0x44,
-  0x59,  0xF0,  0x0A,  0x02,  0x03,  0xF6,  0xE0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x44,  0x58,  0x00,  0xF2,
-  0xE2,  0x0D,  0x02,  0xCC,  0x4A,  0xE4,  0x01,  0x00,  0x55,  0xF0,  0x08,  0x03,  0x45,  0xF4,  0x02,  0x00,
-  0x83,  0x5A,  0x04,  0xCC,  0x01,  0x4A,  0x12,  0x12,  0x00,  0xF2,  0xE2,  0x0D,  0x00,  0xCD,  0x48,  0xE4,
-  0x01,  0x00,  0xE9,  0x13,  0x00,  0xF2,  0xC6,  0x0F,  0xFA,  0x10,  0x0E,  0x47,  0x03,  0xE6,  0x10,  0x00,
-  0xCE,  0x45,  0x02,  0x13,  0x3E,  0x57,  0xCE,  0x47,  0x97,  0x13,  0x04,  0xEC,  0xB4,  0x00,  0x00,  0xF2,
-  0xE2,  0x0D,  0x00,  0xCD,  0x48,  0xE4,  0x00,  0x00,  0x12,  0x12,  0x3E,  0x57,  0x06,  0xCC,  0x45,  0xF4,
-  0x02,  0x00,  0x83,  0x5A,  0x00,  0xCC,  0x00,  0xEA,  0xB4,  0x00,  0x92,  0x10,  0x00,  0xF0,  0x8C,  0x01,
-  0x43,  0xF0,  0x5C,  0x02,  0x44,  0xF0,  0x60,  0x02,  0x45,  0xF0,  0x64,  0x02,  0x46,  0xF0,  0x68,  0x02,
-  0x47,  0xF0,  0x6E,  0x02,  0x48,  0xF0,  0x9E,  0x02,  0xB9,  0x54,  0x62,  0x10,  0x00,  0x1C,  0x5A,  0x10,
-  0x02,  0x1C,  0x56,  0x10,  0x1E,  0x1C,  0x52,  0x10,  0x00,  0xF2,  0x1E,  0x11,  0x50,  0x10,  0x06,  0xFC,
-  0xA8,  0x00,  0x03,  0xF6,  0xBE,  0x00,  0x00,  0xF2,  0x4E,  0x0A,  0x8C,  0x10,  0x01,  0xF6,  0x01,  0x00,
-  0x01,  0xFA,  0xA8,  0x00,  0x00,  0xF2,  0x2C,  0x0B,  0x06,  0x10,  0xB9,  0x54,  0x01,  0xFA,  0xA8,  0x00,
-  0x03,  0xF6,  0xBE,  0x00,  0x00,  0xF2,  0x58,  0x0A,  0x01,  0xFC,  0xA8,  0x00,  0x20,  0x10,  0x58,  0x1C,
-  0x00,  0xF2,  0x1C,  0x0B,  0x5A,  0x1C,  0x01,  0xF6,  0x01,  0x00,  0x38,  0x54,  0x00,  0xFA,  0xA6,  0x00,
-  0x01,  0xFA,  0xA8,  0x00,  0x20,  0x1C,  0x00,  0xF0,  0x72,  0x01,  0x01,  0xF6,  0x01,  0x00,  0x38,  0x54,
-  0x00,  0xFA,  0xA6,  0x00,  0x01,  0xFA,  0xA8,  0x00,  0x20,  0x1C,  0x00,  0xF0,  0x80,  0x01,  0x03,  0xF6,
-  0xE0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x01,  0x48,  0x0A,  0x13,  0x00,  0xF2,  0x38,  0x10,  0x00,  0xF2,
-  0x54,  0x0F,  0x24,  0x10,  0x03,  0xF6,  0xC0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x02,  0xF6,  0xD0,  0x00,
-  0x02,  0x57,  0x03,  0x59,  0x01,  0xCC,  0x49,  0x44,  0x5B,  0xF0,  0x04,  0x03,  0x00,  0xF2,  0x9C,  0x0F,
-  0x00,  0xF0,  0x80,  0x01,  0x00,  0xF2,  0x14,  0x10,  0x0C,  0x1C,  0x02,  0x4B,  0xBF,  0x57,  0x9E,  0x43,
-  0x77,  0x57,  0x07,  0x4B,  0x20,  0xF0,  0xA6,  0x03,  0x40,  0x1C,  0x1E,  0xF0,  0x30,  0x03,  0x26,  0xF0,
-  0x2C,  0x03,  0xA0,  0xF0,  0x1A,  0x03,  0x11,  0xF0,  0xA6,  0x03,  0x12,  0x10,  0x9F,  0xF0,  0x3E,  0x03,
-  0x46,  0x1C,  0x82,  0xE7,  0x05,  0x00,  0x9E,  0xE7,  0x11,  0x00,  0x00,  0xF0,  0x06,  0x0A,  0x0C,  0x1C,
-  0x48,  0x1C,  0x46,  0x1C,  0x38,  0x54,  0x00,  0xEC,  0xBA,  0x00,  0x08,  0x44,  0x00,  0xEA,  0xBA,  0x00,
-  0x03,  0xF6,  0xC0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x08,  0x44,  0x00,  0x4C,  0x82,  0xE7,  0x02,  0x00,
-  0x00,  0xF2,  0x12,  0x11,  0x00,  0xF2,  0x12,  0x11,  0x85,  0xF0,  0x70,  0x03,  0x00,  0xF2,  0x60,  0x0B,
-  0x06,  0xF0,  0x80,  0x03,  0x09,  0xF0,  0x24,  0x09,  0x1E,  0xF0,  0xFC,  0x09,  0x00,  0xF0,  0x02,  0x0A,
-  0x00,  0xFC,  0xBE,  0x00,  0x98,  0x57,  0x55,  0xF0,  0xAC,  0x04,  0x01,  0xE6,  0x0C,  0x00,  0x00,  0xF2,
-  0x4E,  0x0D,  0x00,  0xF2,  0x12,  0x11,  0x00,  0xF2,  0xBC,  0x11,  0x00,  0xF2,  0xC8,  0x11,  0x01,  0xF0,
-  0x7C,  0x02,  0x00,  0xF0,  0x8A,  0x02,  0x46,  0x1C,  0x0C,  0x1C,  0x67,  0x1B,  0xBF,  0x57,  0x77,  0x57,
-  0x02,  0x4B,  0x48,  0x1C,  0x32,  0x1C,  0x00,  0xF2,  0x92,  0x0D,  0x30,  0x1C,  0x96,  0xF0,  0xBC,  0x03,
-  0xB1,  0xF0,  0xC0,  0x03,  0x1E,  0xF0,  0xFC,  0x09,  0x85,  0xF0,  0x02,  0x0A,  0x00,  0xFC,  0xBE,  0x00,
-  0x98,  0x57,  0x14,  0x12,  0x01,  0xE6,  0x0C,  0x00,  0x00,  0xF2,  0x4E,  0x0D,  0x00,  0xF2,  0x12,  0x11,
-  0x01,  0xF0,  0x7C,  0x02,  0x00,  0xF0,  0x8A,  0x02,  0x03,  0xF6,  0xE0,  0x00,  0x00,  0xF2,  0x68,  0x0A,
-  0x01,  0x48,  0x55,  0xF0,  0x98,  0x04,  0x03,  0x82,  0x03,  0xFC,  0xA0,  0x00,  0x9B,  0x57,  0x40,  0x12,
-  0x69,  0x18,  0x00,  0xF2,  0x12,  0x11,  0x85,  0xF0,  0x42,  0x04,  0x69,  0x08,  0x00,  0xF2,  0x12,  0x11,
-  0x85,  0xF0,  0x02,  0x0A,  0x68,  0x08,  0x4C,  0x44,  0x28,  0x12,  0x44,  0x48,  0x03,  0xF6,  0xE0,  0x00,
-  0x00,  0xF2,  0x68,  0x0A,  0x45,  0x58,  0x00,  0xF2,  0xF6,  0x0D,  0x00,  0xCC,  0x01,  0x48,  0x55,  0xF0,
-  0x98,  0x04,  0x4C,  0x44,  0xEF,  0x13,  0x00,  0xF2,  0xC6,  0x0F,  0x00,  0xF2,  0x14,  0x10,  0x08,  0x10,
-  0x68,  0x18,  0x45,  0x5A,  0x00,  0xF2,  0xF6,  0x0D,  0x04,  0x80,  0x18,  0xE4,  0x10,  0x00,  0x28,  0x12,
-  0x01,  0xE6,  0x06,  0x00,  0x04,  0x80,  0x18,  0xE4,  0x01,  0x00,  0x04,  0x12,  0x01,  0xE6,  0x0D,  0x00,
-  0x00,  0xF2,  0x4E,  0x0D,  0x00,  0xF2,  0x12,  0x11,  0x04,  0xE6,  0x02,  0x00,  0x9E,  0xE7,  0x15,  0x00,
-  0x01,  0xF0,  0x1C,  0x0A,  0x00,  0xF0,  0x02,  0x0A,  0x69,  0x08,  0x05,  0x80,  0x48,  0xE4,  0x00,  0x00,
-  0x0C,  0x12,  0x00,  0xE6,  0x11,  0x00,  0x00,  0xEA,  0xB8,  0x00,  0x00,  0xF2,  0xB6,  0x10,  0x82,  0xE7,
-  0x02,  0x00,  0x1C,  0x90,  0x40,  0x5C,  0x00,  0x16,  0x01,  0xE6,  0x06,  0x00,  0x00,  0xF2,  0x4E,  0x0D,
-  0x01,  0xF0,  0x80,  0x01,  0x1E,  0xF0,  0x80,  0x01,  0x00,  0xF0,  0xA0,  0x04,  0x42,  0x5B,  0x06,  0xF7,
-  0x03,  0x00,  0x46,  0x59,  0xBF,  0x57,  0x77,  0x57,  0x01,  0xE6,  0x80,  0x00,  0x07,  0x80,  0x31,  0x44,
-  0x04,  0x80,  0x18,  0xE4,  0x20,  0x00,  0x56,  0x13,  0x20,  0x80,  0x48,  0xE4,  0x03,  0x00,  0x4E,  0x12,
-  0x00,  0xFC,  0xA2,  0x00,  0x98,  0x57,  0x55,  0xF0,  0x1C,  0x05,  0x31,  0xE4,  0x40,  0x00,  0x00,  0xFC,
-  0xA0,  0x00,  0x98,  0x57,  0x36,  0x12,  0x4C,  0x1C,  0x00,  0xF2,  0x12,  0x11,  0x89,  0x48,  0x00,  0xF2,
-  0x12,  0x11,  0x86,  0xF0,  0x2E,  0x05,  0x82,  0xE7,  0x06,  0x00,  0x1B,  0x80,  0x48,  0xE4,  0x22,  0x00,
-  0x5B,  0xF0,  0x0C,  0x05,  0x48,  0xE4,  0x20,  0x00,  0x59,  0xF0,  0x10,  0x05,  0x00,  0xE6,  0x20,  0x00,
-  0x09,  0x48,  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0x2E,  0x05,  0x83,  0x80,  0x04,  0x10,  0x00,  0xF2,
-  0xA2,  0x0D,  0x00,  0xE6,  0x01,  0x00,  0x00,  0xEA,  0x26,  0x01,  0x01,  0xEA,  0x27,  0x01,  0x04,  0x80,
-  0x18,  0xE4,  0x10,  0x00,  0x36,  0x12,  0xB9,  0x54,  0x00,  0xF2,  0xF6,  0x0E,  0x01,  0xE6,  0x06,  0x00,
-  0x04,  0x80,  0x18,  0xE4,  0x01,  0x00,  0x04,  0x12,  0x01,  0xE6,  0x0D,  0x00,  0x00,  0xF2,  0x4E,  0x0D,
-  0x00,  0xF2,  0x12,  0x11,  0x00,  0xF2,  0xBC,  0x11,  0x00,  0xF2,  0xC8,  0x11,  0x04,  0xE6,  0x02,  0x00,
-  0x9E,  0xE7,  0x15,  0x00,  0x01,  0xF0,  0x1C,  0x0A,  0x00,  0xF0,  0x02,  0x0A,  0x00,  0xFC,  0x20,  0x01,
-  0x98,  0x57,  0x34,  0x12,  0x00,  0xFC,  0x24,  0x01,  0x98,  0x57,  0x2C,  0x13,  0xB9,  0x54,  0x00,  0xF2,
-  0xF6,  0x0E,  0x86,  0xF0,  0xA8,  0x05,  0x03,  0xF6,  0x01,  0x00,  0x00,  0xF2,  0x8C,  0x0E,  0x85,  0xF0,
-  0x9E,  0x05,  0x82,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x60,  0x0B,  0x82,  0xE7,  0x02,  0x00,  0x00,  0xFC,
-  0x24,  0x01,  0xB0,  0x57,  0x00,  0xFA,  0x24,  0x01,  0x00,  0xFC,  0x9E,  0x00,  0x98,  0x57,  0x5A,  0x12,
-  0x00,  0xFC,  0xB6,  0x00,  0x98,  0x57,  0x52,  0x13,  0x03,  0xE6,  0x0C,  0x00,  0x00,  0xFC,  0x9C,  0x00,
-  0x98,  0x57,  0x04,  0x13,  0x03,  0xE6,  0x19,  0x00,  0x05,  0xE6,  0x08,  0x00,  0x00,  0xF6,  0x00,  0x01,
-  0x00,  0x57,  0x00,  0x57,  0x03,  0x58,  0x00,  0xDC,  0x18,  0xF4,  0x00,  0x80,  0x04,  0x13,  0x05,  0xE6,
-  0x0F,  0x00,  0xB9,  0x54,  0x00,  0xF2,  0xF6,  0x0E,  0x86,  0xF0,  0x0A,  0x06,  0x00,  0xF2,  0xBA,  0x0E,
-  0x85,  0xF0,  0x00,  0x06,  0x82,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x60,  0x0B,  0x82,  0xE7,  0x02,  0x00,
-  0x00,  0xFC,  0xB6,  0x00,  0xB0,  0x57,  0x00,  0xFA,  0xB6,  0x00,  0x01,  0xF6,  0x01,  0x00,  0x00,  0xF2,
-  0xF6,  0x0E,  0x9C,  0x32,  0x4E,  0x1C,  0x32,  0x1C,  0x00,  0xF2,  0x92,  0x0D,  0x30,  0x1C,  0x82,  0xE7,
-  0x04,  0x00,  0xB1,  0xF0,  0x22,  0x06,  0x0A,  0xF0,  0x3E,  0x06,  0x05,  0xF0,  0xD6,  0x06,  0x06,  0xF0,
-  0xDC,  0x06,  0x09,  0xF0,  0x24,  0x09,  0x1E,  0xF0,  0xFC,  0x09,  0x00,  0xF0,  0x02,  0x0A,  0x04,  0x80,
-  0x18,  0xE4,  0x20,  0x00,  0x30,  0x12,  0x09,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x21,  0x80,
-  0x18,  0xE4,  0xE0,  0x00,  0x09,  0x48,  0x00,  0xF2,  0x12,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF2,
-  0x12,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x99,  0xA4,  0x00,  0xF2,  0x12,  0x11,
-  0x09,  0xE7,  0x00,  0x00,  0x9A,  0x10,  0x04,  0x80,  0x18,  0xE4,  0x02,  0x00,  0x34,  0x12,  0x09,  0xE7,
-  0x1B,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x21,  0x80,  0x18,  0xE4,  0xE0,  0x00,  0x09,  0x48,  0x00,  0xF2,
-  0x12,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF2,
-  0x12,  0x11,  0x09,  0xE7,  0x01,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF0,
-  0x0C,  0x09,  0xBB,  0x55,  0x9A,  0x81,  0x03,  0xF7,  0x20,  0x00,  0x09,  0x6F,  0x93,  0x45,  0x55,  0xF0,
-  0xE2,  0x06,  0xB1,  0xF0,  0xC2,  0x06,  0x0A,  0xF0,  0xBA,  0x06,  0x09,  0xF0,  0x24,  0x09,  0x1E,  0xF0,
-  0xFC,  0x09,  0x00,  0xF0,  0x02,  0x0A,  0x00,  0xF2,  0x60,  0x0B,  0x47,  0x10,  0x09,  0xE7,  0x08,  0x00,
-  0x41,  0x10,  0x05,  0x80,  0x48,  0xE4,  0x00,  0x00,  0x1E,  0x12,  0x00,  0xE6,  0x11,  0x00,  0x00,  0xEA,
-  0xB8,  0x00,  0x00,  0xF2,  0xB6,  0x10,  0x2C,  0x90,  0xAE,  0x90,  0x08,  0x50,  0x8A,  0x50,  0x38,  0x54,
-  0x1F,  0x40,  0x00,  0xF2,  0xB4,  0x0D,  0x08,  0x10,  0x08,  0x90,  0x8A,  0x90,  0x30,  0x50,  0xB2,  0x50,
-  0x9C,  0x32,  0x0C,  0x92,  0x8E,  0x92,  0x38,  0x54,  0x04,  0x80,  0x30,  0xE4,  0x08,  0x00,  0x04,  0x40,
-  0x0C,  0x1C,  0x00,  0xF6,  0x03,  0x00,  0xB1,  0xF0,  0x26,  0x07,  0x9E,  0xF0,  0x3A,  0x07,  0x01,  0x48,
-  0x55,  0xF0,  0xFC,  0x09,  0x0C,  0x1C,  0x10,  0x44,  0xED,  0x10,  0x0B,  0xF0,  0x5E,  0x07,  0x0C,  0xF0,
-  0x62,  0x07,  0x05,  0xF0,  0x52,  0x07,  0x06,  0xF0,  0x58,  0x07,  0x09,  0xF0,  0x24,  0x09,  0x00,  0xF0,
-  0x02,  0x0A,  0x00,  0xF2,  0x60,  0x0B,  0xCF,  0x10,  0x09,  0xE7,  0x08,  0x00,  0xC9,  0x10,  0x2E,  0x1C,
-  0x02,  0x10,  0x2C,  0x1C,  0xAA,  0xF0,  0x64,  0x07,  0xAC,  0xF0,  0x72,  0x07,  0x40,  0x10,  0x34,  0x1C,
-  0xF3,  0x10,  0xAD,  0xF0,  0x7C,  0x07,  0xC8,  0x10,  0x36,  0x1C,  0xE9,  0x10,  0x2B,  0xF0,  0x82,  0x08,
-  0x6B,  0x18,  0x18,  0xF4,  0x00,  0xFE,  0x20,  0x12,  0x01,  0x58,  0xD2,  0xF0,  0x82,  0x08,  0x76,  0x18,
-  0x18,  0xF4,  0x03,  0x00,  0xEC,  0x12,  0x00,  0xFC,  0x22,  0x01,  0x18,  0xF4,  0x01,  0x00,  0xE2,  0x12,
-  0x0B,  0xF0,  0x64,  0x07,  0x0C,  0xF0,  0x64,  0x07,  0x36,  0x1C,  0x34,  0x1C,  0xB7,  0x10,  0x38,  0x54,
-  0xB9,  0x54,  0x84,  0x80,  0x19,  0xE4,  0x20,  0x00,  0xB2,  0x13,  0x85,  0x80,  0x81,  0x48,  0x66,  0x12,
-  0x04,  0x80,  0x18,  0xE4,  0x08,  0x00,  0x58,  0x13,  0x1F,  0x80,  0x08,  0x44,  0xC8,  0x44,  0x9F,  0x12,
-  0x1F,  0x40,  0x34,  0x91,  0xB6,  0x91,  0x44,  0x55,  0xE5,  0x55,  0x02,  0xEC,  0xB8,  0x00,  0x02,  0x49,
-  0xBB,  0x55,  0x82,  0x81,  0xC0,  0x55,  0x48,  0xF4,  0x0F,  0x00,  0x5A,  0xF0,  0x1A,  0x08,  0x4A,  0xE4,
-  0x17,  0x00,  0xD5,  0xF0,  0xFA,  0x07,  0x02,  0xF6,  0x0F,  0x00,  0x02,  0xF4,  0x02,  0x00,  0x02,  0xEA,
-  0xB8,  0x00,  0x04,  0x91,  0x86,  0x91,  0x02,  0x4B,  0x2C,  0x90,  0x08,  0x50,  0x2E,  0x90,  0x0A,  0x50,
-  0x2C,  0x51,  0xAE,  0x51,  0x00,  0xF2,  0xB6,  0x10,  0x38,  0x54,  0x00,  0xF2,  0xB4,  0x0D,  0x56,  0x10,
-  0x34,  0x91,  0xB6,  0x91,  0x0C,  0x10,  0x04,  0x80,  0x18,  0xE4,  0x08,  0x00,  0x41,  0x12,  0x0C,  0x91,
-  0x8E,  0x91,  0x04,  0x80,  0x18,  0xE4,  0xF7,  0x00,  0x04,  0x40,  0x30,  0x90,  0xB2,  0x90,  0x36,  0x10,
-  0x02,  0x80,  0x48,  0xE4,  0x10,  0x00,  0x31,  0x12,  0x82,  0xE7,  0x10,  0x00,  0x84,  0x80,  0x19,  0xE4,
-  0x20,  0x00,  0x10,  0x13,  0x0C,  0x90,  0x8E,  0x90,  0x5D,  0xF0,  0x78,  0x07,  0x0C,  0x58,  0x8D,  0x58,
-  0x00,  0xF0,  0x64,  0x07,  0x38,  0x54,  0xB9,  0x54,  0x19,  0x80,  0xF1,  0x10,  0x3A,  0x55,  0x19,  0x81,
-  0xBB,  0x55,  0x10,  0x90,  0x92,  0x90,  0x10,  0x58,  0x91,  0x58,  0x14,  0x59,  0x95,  0x59,  0x00,  0xF0,
-  0x64,  0x07,  0x04,  0x80,  0x18,  0xE4,  0x20,  0x00,  0x06,  0x12,  0x6C,  0x19,  0x19,  0x41,  0x7C,  0x10,
-  0x6C,  0x19,  0x0C,  0x51,  0xED,  0x19,  0x8E,  0x51,  0x6B,  0x18,  0x18,  0xF4,  0x00,  0xFF,  0x02,  0x13,
-  0x6A,  0x10,  0x01,  0x58,  0xD2,  0xF0,  0xC0,  0x08,  0x76,  0x18,  0x18,  0xF4,  0x03,  0x00,  0x0A,  0x12,
-  0x00,  0xFC,  0x22,  0x01,  0x18,  0xF4,  0x01,  0x00,  0x06,  0x13,  0x9E,  0xE7,  0x16,  0x00,  0x4C,  0x10,
-  0xD1,  0xF0,  0xCA,  0x08,  0x9E,  0xE7,  0x17,  0x00,  0x42,  0x10,  0xD0,  0xF0,  0xD4,  0x08,  0x9E,  0xE7,
-  0x19,  0x00,  0x38,  0x10,  0xCF,  0xF0,  0xDE,  0x08,  0x9E,  0xE7,  0x20,  0x00,  0x2E,  0x10,  0xCE,  0xF0,
-  0xE8,  0x08,  0x9E,  0xE7,  0x21,  0x00,  0x24,  0x10,  0xCD,  0xF0,  0xF2,  0x08,  0x9E,  0xE7,  0x22,  0x00,
-  0x1A,  0x10,  0xCC,  0xF0,  0x04,  0x09,  0x84,  0x80,  0x19,  0xE4,  0x04,  0x00,  0x06,  0x12,  0x9E,  0xE7,
-  0x12,  0x00,  0x08,  0x10,  0xCB,  0xF0,  0x0C,  0x09,  0x9E,  0xE7,  0x24,  0x00,  0xB1,  0xF0,  0x0C,  0x09,
-  0x05,  0xF0,  0x1E,  0x09,  0x09,  0xF0,  0x24,  0x09,  0x1E,  0xF0,  0xFC,  0x09,  0xE4,  0x10,  0x00,  0xF2,
-  0x60,  0x0B,  0xE9,  0x10,  0x9C,  0x32,  0x82,  0xE7,  0x20,  0x00,  0x32,  0x1C,  0xE9,  0x09,  0x00,  0xF2,
-  0x12,  0x11,  0x85,  0xF0,  0x02,  0x0A,  0x69,  0x08,  0x01,  0xF0,  0x44,  0x09,  0x1E,  0xF0,  0xFC,  0x09,
-  0x00,  0xF0,  0x38,  0x09,  0x30,  0x44,  0x06,  0x12,  0x9E,  0xE7,  0x42,  0x00,  0xB8,  0x10,  0x04,  0xF6,
-  0x01,  0x00,  0xB3,  0x45,  0x74,  0x12,  0x04,  0x80,  0x18,  0xE4,  0x20,  0x00,  0x22,  0x13,  0x4B,  0xE4,
-  0x02,  0x00,  0x36,  0x12,  0x4B,  0xE4,  0x28,  0x00,  0xAC,  0x13,  0x00,  0xF2,  0xBC,  0x11,  0x00,  0xF2,
-  0xC8,  0x11,  0x03,  0xF6,  0xD0,  0x00,  0xFA,  0x14,  0x82,  0xE7,  0x01,  0x00,  0x00,  0xF0,  0x80,  0x01,
-  0x9E,  0xE7,  0x44,  0x00,  0x4B,  0xE4,  0x02,  0x00,  0x06,  0x12,  0x03,  0xE6,  0x02,  0x00,  0x76,  0x10,
-  0x00,  0xF2,  0xA2,  0x0D,  0x03,  0xE6,  0x02,  0x00,  0x6C,  0x10,  0x00,  0xF2,  0xA2,  0x0D,  0x19,  0x82,
-  0x34,  0x46,  0x0A,  0x13,  0x03,  0xE6,  0x02,  0x00,  0x9E,  0xE7,  0x43,  0x00,  0x68,  0x10,  0x04,  0x80,
-  0x30,  0xE4,  0x20,  0x00,  0x04,  0x40,  0x00,  0xF2,  0xBC,  0x11,  0x00,  0xF2,  0xC8,  0x11,  0x82,  0xE7,
-  0x01,  0x00,  0x06,  0xF7,  0x02,  0x00,  0x00,  0xF0,  0x08,  0x03,  0x04,  0x80,  0x18,  0xE4,  0x20,  0x00,
-  0x06,  0x12,  0x03,  0xE6,  0x02,  0x00,  0x3E,  0x10,  0x04,  0x80,  0x18,  0xE4,  0x02,  0x00,  0x3A,  0x12,
-  0x04,  0x80,  0x18,  0xE4,  0xFD,  0x00,  0x04,  0x40,  0x1C,  0x1C,  0x9D,  0xF0,  0xEA,  0x09,  0x1C,  0x1C,
-  0x9D,  0xF0,  0xF0,  0x09,  0xC1,  0x10,  0x9E,  0xE7,  0x13,  0x00,  0x0A,  0x10,  0x9E,  0xE7,  0x41,  0x00,
-  0x04,  0x10,  0x9E,  0xE7,  0x24,  0x00,  0x00,  0xFC,  0xBE,  0x00,  0x98,  0x57,  0xD5,  0xF0,  0x8A,  0x02,
-  0x04,  0xE6,  0x04,  0x00,  0x06,  0x10,  0x04,  0xE6,  0x04,  0x00,  0x9D,  0x41,  0x1C,  0x42,  0x9F,  0xE7,
-  0x00,  0x00,  0x06,  0xF7,  0x02,  0x00,  0x03,  0xF6,  0xE0,  0x00,  0x3C,  0x14,  0x44,  0x58,  0x45,  0x58,
-  0x00,  0xF2,  0xF6,  0x0D,  0x00,  0xF2,  0x7E,  0x10,  0x00,  0xF2,  0xC6,  0x0F,  0x3C,  0x14,  0x1E,  0x1C,
-  0x00,  0xF0,  0x80,  0x01,  0x12,  0x1C,  0x22,  0x1C,  0xD2,  0x14,  0x00,  0xF0,  0x72,  0x01,  0x83,  0x59,
-  0x03,  0xDC,  0x73,  0x57,  0x80,  0x5D,  0x00,  0x16,  0x83,  0x59,  0x03,  0xDC,  0x38,  0x54,  0x70,  0x57,
-  0x33,  0x54,  0x3B,  0x54,  0x80,  0x5D,  0x00,  0x16,  0x03,  0x57,  0x83,  0x59,  0x38,  0x54,  0x00,  0xCC,
-  0x00,  0x16,  0x03,  0x57,  0x83,  0x59,  0x00,  0x4C,  0x00,  0x16,  0x02,  0x80,  0x48,  0xE4,  0x01,  0x00,
-  0x0E,  0x12,  0x48,  0xE4,  0x05,  0x00,  0x08,  0x12,  0x00,  0xF2,  0xBC,  0x11,  0x00,  0xF2,  0xC8,  0x11,
-  0xC1,  0x5A,  0x3A,  0x55,  0x02,  0xEC,  0xB5,  0x00,  0x45,  0x59,  0x00,  0xF2,  0xF6,  0x0D,  0x83,  0x58,
-  0x30,  0xE7,  0x00,  0x00,  0x10,  0x4D,  0x30,  0xE7,  0x40,  0x00,  0x10,  0x4F,  0x38,  0x90,  0xBA,  0x90,
-  0x10,  0x5C,  0x80,  0x5C,  0x83,  0x5A,  0x10,  0x4E,  0x04,  0xEA,  0xB5,  0x00,  0x43,  0x5B,  0x03,  0xF4,
-  0xE0,  0x00,  0x83,  0x59,  0x04,  0xCC,  0x01,  0x4A,  0x0A,  0x12,  0x45,  0x5A,  0x00,  0xF2,  0xF6,  0x0D,
-  0x00,  0xF2,  0x38,  0x10,  0x00,  0x16,  0x08,  0x1C,  0x00,  0xFC,  0xAC,  0x00,  0x06,  0x58,  0x67,  0x18,
-  0x18,  0xF4,  0x8F,  0xE1,  0x01,  0xFC,  0xAE,  0x00,  0x19,  0xF4,  0x70,  0x1E,  0xB0,  0x54,  0x07,  0x58,
-  0x00,  0xFC,  0xB0,  0x00,  0x08,  0x58,  0x00,  0xFC,  0xB2,  0x00,  0x09,  0x58,  0x0A,  0x1C,  0x00,  0xE6,
-  0x0F,  0x00,  0x00,  0xEA,  0xB9,  0x00,  0x38,  0x54,  0x00,  0xFA,  0x24,  0x01,  0x00,  0xFA,  0xB6,  0x00,
-  0x18,  0x1C,  0x14,  0x1C,  0x10,  0x1C,  0x32,  0x1C,  0x12,  0x1C,  0x00,  0x16,  0x3E,  0x57,  0x0C,  0x14,
-  0x0E,  0x47,  0x07,  0xE6,  0x10,  0x00,  0xCE,  0x47,  0xF5,  0x13,  0x00,  0x16,  0x00,  0xF2,  0xA2,  0x0D,
-  0x02,  0x4B,  0x03,  0xF6,  0xE0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x01,  0x48,  0x20,  0x12,  0x44,  0x58,
-  0x45,  0x58,  0x9E,  0xE7,  0x15,  0x00,  0x9C,  0xE7,  0x04,  0x00,  0x00,  0xF2,  0xF6,  0x0D,  0x00,  0xF2,
-  0x7E,  0x10,  0x00,  0xF2,  0xC6,  0x0F,  0x00,  0xF2,  0x7A,  0x0A,  0x1E,  0x1C,  0xD5,  0x10,  0x00,  0x16,
-  0x69,  0x08,  0x48,  0xE4,  0x04,  0x00,  0x64,  0x12,  0x48,  0xE4,  0x02,  0x00,  0x20,  0x12,  0x48,  0xE4,
-  0x03,  0x00,  0x1A,  0x12,  0x48,  0xE4,  0x08,  0x00,  0x14,  0x12,  0x48,  0xE4,  0x01,  0x00,  0xF0,  0x12,
-  0x48,  0xE4,  0x07,  0x00,  0x12,  0x12,  0x01,  0xE6,  0x07,  0x00,  0x00,  0xF2,  0x4E,  0x0D,  0x00,  0xF2,
-  0x12,  0x11,  0x05,  0xF0,  0x60,  0x0B,  0x00,  0x16,  0x00,  0xE6,  0x01,  0x00,  0x00,  0xEA,  0x99,  0x00,
-  0x02,  0x80,  0x48,  0xE4,  0x03,  0x00,  0xE7,  0x12,  0x48,  0xE4,  0x06,  0x00,  0xE1,  0x12,  0x01,  0xE6,
-  0x06,  0x00,  0x00,  0xF2,  0x4E,  0x0D,  0x00,  0xF2,  0x12,  0x11,  0x04,  0xE6,  0x02,  0x00,  0x9E,  0xE7,
-  0x15,  0x00,  0x01,  0xF0,  0x1C,  0x0A,  0x00,  0xF0,  0x02,  0x0A,  0x00,  0x16,  0x02,  0x80,  0x48,  0xE4,
-  0x10,  0x00,  0x1C,  0x12,  0x82,  0xE7,  0x08,  0x00,  0x3C,  0x56,  0x03,  0x82,  0x00,  0xF2,  0xE2,  0x0D,
-  0x30,  0xE7,  0x08,  0x00,  0x04,  0xF7,  0x70,  0x01,  0x06,  0xF7,  0x02,  0x00,  0x00,  0xF0,  0x80,  0x01,
-  0x6C,  0x19,  0xED,  0x19,  0x5D,  0xF0,  0xD4,  0x0B,  0x44,  0x55,  0xE5,  0x55,  0x59,  0xF0,  0x52,  0x0C,
-  0x04,  0x55,  0xA5,  0x55,  0x1F,  0x80,  0x01,  0xEC,  0xB8,  0x00,  0x82,  0x48,  0x82,  0x80,  0x49,  0x44,
-  0x2E,  0x13,  0x01,  0xEC,  0xB8,  0x00,  0x41,  0xE4,  0x02,  0x00,  0x01,  0xEA,  0xB8,  0x00,  0x49,  0xE4,
-  0x11,  0x00,  0x59,  0xF0,  0x2E,  0x0C,  0x01,  0xE6,  0x17,  0x00,  0x01,  0xEA,  0xB8,  0x00,  0x02,  0x4B,
-  0x88,  0x90,  0xAC,  0x50,  0x8A,  0x90,  0xAE,  0x50,  0x01,  0xEC,  0xB8,  0x00,  0x82,  0x48,  0x82,  0x80,
-  0x10,  0x44,  0x02,  0x4B,  0x1F,  0x40,  0xC0,  0x44,  0x00,  0xF2,  0xB4,  0x0D,  0x04,  0x55,  0xA5,  0x55,
-  0x9F,  0x10,  0x0C,  0x51,  0x8E,  0x51,  0x30,  0x90,  0xB2,  0x90,  0x00,  0x56,  0xA1,  0x56,  0x30,  0x50,
-  0xB2,  0x50,  0x34,  0x90,  0xB6,  0x90,  0x40,  0x56,  0xE1,  0x56,  0x34,  0x50,  0xB6,  0x50,  0x65,  0x10,
-  0xB1,  0xF0,  0x70,  0x0C,  0x85,  0xF0,  0xCA,  0x0B,  0xE9,  0x09,  0x4B,  0xE4,  0x03,  0x00,  0x78,  0x12,
-  0x4B,  0xE4,  0x02,  0x00,  0x01,  0x13,  0xB1,  0xF0,  0x86,  0x0C,  0x85,  0xF0,  0xCA,  0x0B,  0x69,  0x08,
-  0x48,  0xE4,  0x03,  0x00,  0xD5,  0xF0,  0x86,  0x0B,  0x00,  0xF2,  0x12,  0x11,  0x85,  0xF0,  0xCA,  0x0B,
-  0xE8,  0x09,  0x3C,  0x56,  0x00,  0xFC,  0x20,  0x01,  0x98,  0x57,  0x02,  0x13,  0xBB,  0x45,  0x4B,  0xE4,
-  0x00,  0x00,  0x08,  0x12,  0x03,  0xE6,  0x01,  0x00,  0x04,  0xF6,  0x00,  0x80,  0xA8,  0x14,  0xD2,  0x14,
-  0x30,  0x1C,  0x02,  0x80,  0x48,  0xE4,  0x03,  0x00,  0x10,  0x13,  0x00,  0xFC,  0xB6,  0x00,  0x98,  0x57,
-  0x02,  0x13,  0x4C,  0x1C,  0x3E,  0x1C,  0x00,  0xF0,  0x8E,  0x0B,  0x00,  0xFC,  0x24,  0x01,  0xB0,  0x57,
-  0x00,  0xFA,  0x24,  0x01,  0x4C,  0x1C,  0x3E,  0x1C,  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0x8E,  0x0B,
-  0x00,  0xF2,  0x8C,  0x0E,  0x00,  0xF0,  0x8E,  0x0B,  0xB1,  0xF0,  0xF8,  0x0C,  0x85,  0xF0,  0x86,  0x0B,
-  0x69,  0x08,  0x48,  0xE4,  0x01,  0x00,  0xD5,  0xF0,  0x86,  0x0B,  0xFC,  0x14,  0x42,  0x58,  0x6C,  0x14,
-  0x80,  0x14,  0x30,  0x1C,  0x4A,  0xF4,  0x02,  0x00,  0x55,  0xF0,  0x86,  0x0B,  0x4A,  0xF4,  0x01,  0x00,
-  0x0E,  0x12,  0x02,  0x80,  0x48,  0xE4,  0x03,  0x00,  0x06,  0x13,  0x3E,  0x1C,  0x00,  0xF0,  0x8E,  0x0B,
-  0x00,  0xFC,  0xB6,  0x00,  0xB0,  0x57,  0x00,  0xFA,  0xB6,  0x00,  0x4C,  0x1C,  0x3E,  0x1C,  0x00,  0xF2,
-  0x12,  0x11,  0x86,  0xF0,  0x8E,  0x0B,  0x00,  0xF2,  0xBA,  0x0E,  0x00,  0xF0,  0x8E,  0x0B,  0x4C,  0x1C,
-  0xB1,  0xF0,  0x50,  0x0D,  0x85,  0xF0,  0x5C,  0x0D,  0x69,  0x08,  0xF3,  0x10,  0x86,  0xF0,  0x64,  0x0D,
-  0x4E,  0x1C,  0x89,  0x48,  0x00,  0x16,  0x00,  0xF6,  0x00,  0x01,  0x00,  0x57,  0x00,  0x57,  0x03,  0x58,
-  0x00,  0xDC,  0x18,  0xF4,  0xFF,  0x7F,  0x30,  0x56,  0x00,  0x5C,  0x00,  0x16,  0x00,  0xF6,  0x00,  0x01,
-  0x00,  0x57,  0x00,  0x57,  0x03,  0x58,  0x00,  0xDC,  0x18,  0xF4,  0x00,  0x80,  0x30,  0x56,  0x00,  0x5C,
-  0x00,  0x16,  0x00,  0xF6,  0x00,  0x01,  0x00,  0x57,  0x00,  0x57,  0x03,  0x58,  0x00,  0xDC,  0x0B,  0x58,
-  0x00,  0x16,  0x03,  0xF6,  0x24,  0x01,  0x00,  0xF2,  0x58,  0x0A,  0x03,  0xF6,  0xB6,  0x00,  0x00,  0xF2,
-  0x58,  0x0A,  0x00,  0x16,  0x02,  0xEC,  0xB8,  0x00,  0x02,  0x49,  0x18,  0xF4,  0xFF,  0x00,  0x00,  0x54,
-  0x00,  0x54,  0x00,  0x54,  0x00,  0xF4,  0x08,  0x00,  0xE1,  0x18,  0x80,  0x54,  0x03,  0x58,  0x00,  0xDD,
-  0x01,  0xDD,  0x02,  0xDD,  0x03,  0xDC,  0x02,  0x4B,  0x30,  0x50,  0xB2,  0x50,  0x34,  0x51,  0xB6,  0x51,
-  0x00,  0x16,  0x45,  0x5A,  0x1D,  0xF4,  0xFF,  0x00,  0x85,  0x56,  0x85,  0x56,  0x85,  0x56,  0x05,  0xF4,
-  0x02,  0x12,  0x83,  0x5A,  0x00,  0x16,  0x1D,  0xF4,  0xFF,  0x00,  0x85,  0x56,  0x85,  0x56,  0x85,  0x56,
-  0x05,  0xF4,  0x00,  0x12,  0x83,  0x5A,  0x00,  0x16,  0x38,  0x54,  0xBB,  0x55,  0x3C,  0x56,  0xBD,  0x56,
-  0x00,  0xF2,  0x12,  0x11,  0x85,  0xF0,  0x82,  0x0E,  0xE9,  0x09,  0xC1,  0x59,  0x00,  0xF2,  0x12,  0x11,
-  0x85,  0xF0,  0x82,  0x0E,  0xE8,  0x0A,  0x83,  0x55,  0x83,  0x55,  0x4B,  0xF4,  0x90,  0x01,  0x5C,  0xF0,
-  0x36,  0x0E,  0xBD,  0x56,  0x40,  0x10,  0x4B,  0xF4,  0x30,  0x00,  0x59,  0xF0,  0x48,  0x0E,  0x01,  0xF6,
-  0x0C,  0x00,  0x00,  0xF6,  0x01,  0x00,  0x2E,  0x10,  0x02,  0xFC,  0x9C,  0x00,  0x9A,  0x57,  0x14,  0x13,
-  0x4B,  0xF4,  0x64,  0x00,  0x59,  0xF0,  0x64,  0x0E,  0x03,  0xF6,  0x64,  0x00,  0x01,  0xF6,  0x19,  0x00,
-  0x00,  0xF6,  0x01,  0x00,  0x43,  0xF4,  0x33,  0x00,  0x56,  0xF0,  0x76,  0x0E,  0x04,  0xF4,  0x00,  0x01,
-  0x43,  0xF4,  0x19,  0x00,  0xF3,  0x10,  0xB4,  0x56,  0xC3,  0x58,  0x02,  0xFC,  0x9E,  0x00,  0x9A,  0x57,
-  0x08,  0x13,  0x3C,  0x56,  0x00,  0xF6,  0x02,  0x00,  0x00,  0x16,  0x00,  0x16,  0x09,  0xE7,  0x01,  0x00,
-  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0xB8,  0x0E,  0x09,  0xE7,  0x02,  0x00,  0x00,  0xF2,  0x12,  0x11,
-  0x86,  0xF0,  0xB8,  0x0E,  0x09,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0xB8,  0x0E,
-  0x4E,  0x1C,  0x89,  0x49,  0x00,  0xF2,  0x12,  0x11,  0x00,  0x16,  0x09,  0xE7,  0x01,  0x00,  0x00,  0xF2,
-  0x12,  0x11,  0x86,  0xF0,  0xF2,  0x0E,  0x09,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,
-  0xF2,  0x0E,  0x09,  0xE7,  0x01,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0xF2,  0x0E,  0x89,  0x49,
-  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0xF2,  0x0E,  0x4E,  0x1C,  0x89,  0x4A,  0x00,  0xF2,  0x12,  0x11,
-  0x00,  0x16,  0x3C,  0x56,  0x00,  0x16,  0x00,  0xEC,  0x26,  0x01,  0x48,  0xE4,  0x01,  0x00,  0x1E,  0x13,
-  0x38,  0x44,  0x00,  0xEA,  0x26,  0x01,  0x49,  0xF4,  0x00,  0x00,  0x04,  0x12,  0x4E,  0x1C,  0x02,  0x10,
-  0x4C,  0x1C,  0x01,  0xEC,  0x27,  0x01,  0x89,  0x48,  0x00,  0xF2,  0x12,  0x11,  0x02,  0x14,  0x00,  0x16,
-  0x85,  0xF0,  0x52,  0x0F,  0x38,  0x54,  0x00,  0xEA,  0x99,  0x00,  0x00,  0xF2,  0x60,  0x0B,  0x02,  0x80,
-  0x48,  0xE4,  0x06,  0x00,  0x1C,  0x13,  0x00,  0xEC,  0x99,  0x00,  0x48,  0xE4,  0x01,  0x00,  0x0A,  0x12,
-  0x04,  0x80,  0x30,  0xE4,  0x01,  0x00,  0x04,  0x40,  0x08,  0x10,  0x04,  0x80,  0x18,  0xE4,  0xFE,  0x00,
-  0x04,  0x40,  0x00,  0x16,  0x02,  0xF6,  0xE0,  0x00,  0x02,  0x57,  0x03,  0x59,  0x01,  0xCC,  0x81,  0x48,
-  0x22,  0x12,  0x00,  0x4E,  0x83,  0x5A,  0x90,  0x4C,  0x20,  0xE7,  0x00,  0x00,  0xC3,  0x58,  0x1B,  0xF4,
-  0xFF,  0x00,  0x83,  0x55,  0x83,  0x55,  0x83,  0x55,  0x03,  0xF4,  0x00,  0x12,  0x8B,  0x55,  0x83,  0x59,
-  0x00,  0x4E,  0x00,  0x16,  0x00,  0x4E,  0x02,  0xF6,  0xF0,  0x00,  0x02,  0x57,  0x03,  0x59,  0x00,  0x4E,
-  0x83,  0x5A,  0x30,  0xE7,  0x00,  0x00,  0x20,  0xE7,  0x00,  0x00,  0x00,  0x16,  0x02,  0xF6,  0xF0,  0x00,
-  0x02,  0x57,  0x03,  0x59,  0x01,  0xCC,  0x00,  0x4E,  0x83,  0x5A,  0x30,  0xE7,  0x00,  0x00,  0x80,  0x4C,
-  0xC3,  0x58,  0x1B,  0xF4,  0xFF,  0x00,  0x83,  0x55,  0x83,  0x55,  0x83,  0x55,  0x03,  0xF4,  0x00,  0x12,
-  0x83,  0x59,  0x00,  0x4E,  0x00,  0x16,  0x03,  0xF6,  0xE0,  0x00,  0x03,  0x57,  0x83,  0x59,  0x3A,  0x55,
-  0x02,  0xCC,  0x45,  0x5A,  0x00,  0xF2,  0xF6,  0x0D,  0xC0,  0x5A,  0x40,  0x5C,  0x38,  0x54,  0x00,  0xCD,
-  0x01,  0xCC,  0x4A,  0x46,  0x0A,  0x13,  0x83,  0x59,  0x00,  0x4C,  0x01,  0x48,  0x16,  0x13,  0x0C,  0x10,
-  0xC5,  0x58,  0x00,  0xF2,  0xF6,  0x0D,  0x00,  0x4C,  0x01,  0x48,  0x08,  0x13,  0x05,  0xF6,  0xF0,  0x00,
-  0x05,  0x57,  0x08,  0x10,  0x45,  0x58,  0x00,  0xF2,  0xF6,  0x0D,  0x8D,  0x56,  0x83,  0x5A,  0x80,  0x4C,
-  0x05,  0x17,  0x00,  0x16,  0x02,  0x4B,  0x06,  0xF7,  0x04,  0x00,  0x62,  0x0B,  0x03,  0x82,  0x00,  0xF2,
-  0xE2,  0x0D,  0x02,  0x80,  0x00,  0x4C,  0x45,  0xF4,  0x02,  0x00,  0x52,  0x14,  0x06,  0xF7,  0x02,  0x00,
-  0x06,  0x14,  0x00,  0xF2,  0x54,  0x0F,  0x00,  0x16,  0x02,  0x4B,  0x01,  0xF6,  0xFF,  0x00,  0x38,  0x1C,
-  0x05,  0xF4,  0x04,  0x00,  0x83,  0x5A,  0x18,  0xDF,  0x19,  0xDF,  0x1D,  0xF7,  0x3C,  0x00,  0xB8,  0xF0,
-  0x4E,  0x10,  0x9C,  0x14,  0x01,  0x48,  0x1C,  0x13,  0x0E,  0xF7,  0x3C,  0x00,  0x03,  0xF7,  0x04,  0x00,
-  0xAF,  0x19,  0x03,  0x42,  0x45,  0xF4,  0x02,  0x00,  0x83,  0x5A,  0x02,  0xCC,  0x02,  0x41,  0x45,  0xF4,
-  0x02,  0x00,  0x00,  0x16,  0x91,  0x44,  0xD5,  0xF0,  0x3E,  0x10,  0x00,  0xF0,  0x9E,  0x02,  0x01,  0xF6,
-  0xFF,  0x00,  0x38,  0x1C,  0x05,  0xF4,  0x04,  0x00,  0x83,  0x5A,  0x18,  0xDF,  0x19,  0xDF,  0x0E,  0xF7,
-  0x3C,  0x00,  0x03,  0xF7,  0x04,  0x00,  0x0F,  0x79,  0x1C,  0xF7,  0x3C,  0x00,  0xB8,  0xF0,  0x9C,  0x10,
-  0x4E,  0x14,  0x01,  0x48,  0x06,  0x13,  0x45,  0xF4,  0x04,  0x00,  0x00,  0x16,  0x91,  0x44,  0xD5,  0xF0,
-  0x82,  0x10,  0x00,  0xF0,  0x9E,  0x02,  0x02,  0xF6,  0xFF,  0x00,  0x38,  0x1C,  0x2C,  0xBC,  0xAE,  0xBC,
-  0xE2,  0x08,  0x00,  0xEC,  0xB8,  0x00,  0x02,  0x48,  0x1D,  0xF7,  0x80,  0x00,  0xB8,  0xF0,  0xCC,  0x10,
-  0x1E,  0x14,  0x01,  0x48,  0x0E,  0x13,  0x0E,  0xF7,  0x80,  0x00,  0x38,  0x54,  0x03,  0x58,  0xAF,  0x19,
-  0x82,  0x48,  0x00,  0x16,  0x82,  0x48,  0x12,  0x45,  0xD5,  0xF0,  0xBA,  0x10,  0x00,  0xF0,  0x9E,  0x02,
-  0x39,  0xF0,  0xF8,  0x10,  0x38,  0x44,  0x00,  0x16,  0x7E,  0x18,  0x18,  0xF4,  0x03,  0x00,  0x04,  0x13,
-  0x61,  0x18,  0x00,  0x16,  0x38,  0x1C,  0x00,  0xFC,  0x22,  0x01,  0x18,  0xF4,  0x01,  0x00,  0xF1,  0x12,
-  0xE3,  0x10,  0x30,  0x44,  0x30,  0x44,  0x30,  0x44,  0xB1,  0xF0,  0x18,  0x11,  0x00,  0x16,  0x3E,  0x57,
-  0x03,  0xF6,  0xE0,  0x00,  0x03,  0x57,  0x83,  0x59,  0x04,  0xCC,  0x01,  0x4A,  0x6A,  0x12,  0x45,  0x5A,
-  0x00,  0xF2,  0xF6,  0x0D,  0x02,  0x4B,  0x70,  0x14,  0x34,  0x13,  0x02,  0x80,  0x48,  0xE4,  0x08,  0x00,
-  0x18,  0x12,  0x9C,  0xE7,  0x02,  0x00,  0x9E,  0xE7,  0x15,  0x00,  0x00,  0xF2,  0xC6,  0x0F,  0x00,  0xF2,
-  0x7A,  0x0A,  0x1E,  0x1C,  0x01,  0xF6,  0x01,  0x00,  0x00,  0x16,  0x30,  0xE4,  0x10,  0x00,  0x04,  0x40,
-  0x00,  0xF2,  0xE2,  0x0D,  0x20,  0xE7,  0x01,  0x00,  0x01,  0xF6,  0x01,  0x00,  0x00,  0x16,  0x04,  0xDC,
-  0x01,  0x4A,  0x24,  0x12,  0x45,  0x5A,  0x00,  0xF2,  0xF6,  0x0D,  0x43,  0x5B,  0x06,  0xEC,  0x98,  0x00,
-  0x00,  0xF2,  0x38,  0x10,  0xC6,  0x59,  0x20,  0x14,  0x0A,  0x13,  0x00,  0xF2,  0xC6,  0x0F,  0x00,  0xF2,
-  0x14,  0x10,  0xA7,  0x10,  0x83,  0x5A,  0xD7,  0x10,  0x0E,  0x47,  0x07,  0xE6,  0x10,  0x00,  0xCE,  0x47,
-  0x5A,  0xF0,  0x20,  0x11,  0xB9,  0x54,  0x00,  0x16,  0x14,  0x90,  0x96,  0x90,  0x02,  0xFC,  0xA8,  0x00,
-  0x03,  0xFC,  0xAA,  0x00,  0x48,  0x55,  0x02,  0x13,  0xC9,  0x55,  0x00,  0x16,  0x00,  0xEC,  0xBA,  0x00,
-  0x10,  0x44,  0x00,  0xEA,  0xBA,  0x00,  0x00,  0x16,  0x03,  0xF6,  0xC0,  0x00,  0x00,  0xF2,  0x68,  0x0A,
-  0x10,  0x44,  0x00,  0x4C,  0x00,  0x16
-};
-
-unsigned short _adv_mcode_size ASC_INITDATA =
-    sizeof(_adv_mcode_buf); /* 0x11D6 */
-unsigned long  _adv_mcode_chksum ASC_INITDATA = 0x03494981UL;
+/* a_mcode.h */
+STATIC unsigned char _adv_asc3550_buf[] = {
+  0x00,  0x00,  0x00,  0xf2,  0x00,  0xf0,  0x00,  0x16,  0x00,  0xfc,  0x48,  0xe4,  0x01,  0x00,  0x01,  0xf6,
+  0x00,  0xf6,  0x18,  0xe4,  0x0a,  0x19,  0x18,  0x80,  0x02,  0x00,  0xff,  0xff,  0x03,  0xf6,  0x00,  0xfa,
+  0xff,  0x00,  0x82,  0xe7,  0x9e,  0xe7,  0x01,  0xfa,  0x06,  0x0e,  0x09,  0xe7,  0x00,  0xea,  0x01,  0xe6,
+  0x03,  0x00,  0x08,  0x00,  0x18,  0xf4,  0x55,  0xf0,  0x3e,  0x01,  0x3e,  0x57,  0x04,  0x00,  0x1e,  0xf0,
+  0x85,  0xf0,  0x00,  0xe6,  0x00,  0xec,  0x32,  0xf0,  0x86,  0xf0,  0xa4,  0x0c,  0xd0,  0x01,  0xd5,  0xf0,
+  0xf6,  0x18,  0x38,  0x54,  0x98,  0x57,  0xbc,  0x00,  0xb1,  0xf0,  0xb4,  0x00,  0x01,  0xfc,  0x02,  0x13,
+  0x03,  0xfc,  0x9e,  0x0c,  0x00,  0x57,  0x01,  0xf0,  0x03,  0xe6,  0x0c,  0x1c,  0x10,  0x00,  0x18,  0x40,
+  0x30,  0x12,  0x3e,  0x1c,  0xbd,  0x00,  0xe0,  0x00,  0x02,  0x48,  0x02,  0x80,  0x3c,  0x00,  0x4e,  0x01,
+  0x66,  0x15,  0x6c,  0x01,  0x6e,  0x01,  0xbb,  0x00,  0xda,  0x12,  0x00,  0x4e,  0x01,  0x01,  0x01,  0xea,
+  0x08,  0x12,  0x30,  0xe4,  0x6a,  0x0f,  0xa8,  0x0c,  0xae,  0x0f,  0xb6,  0x00,  0xb9,  0x54,  0x00,  0x80,
+  0x04,  0x12,  0x06,  0xf7,  0x24,  0x01,  0x28,  0x01,  0x32,  0x00,  0x3c,  0x01,  0x3c,  0x56,  0x3e,  0x00,
+  0x4b,  0xe4,  0x4c,  0x1c,  0x68,  0x01,  0x6a,  0x01,  0x70,  0x01,  0x72,  0x01,  0x74,  0x01,  0x76,  0x01,
+  0x78,  0x01,  0x00,  0x01,  0x02,  0xee,  0x02,  0xfc,  0x03,  0x58,  0x03,  0xf7,  0x04,  0x80,  0x05,  0xfc,
+  0x08,  0x44,  0x09,  0xf0,  0x0a,  0x15,  0x10,  0x44,  0x1b,  0x80,  0x20,  0x01,  0x38,  0x1c,  0x40,  0x00,
+  0x4b,  0xf4,  0x4e,  0x1c,  0x5b,  0xf0,  0x5d,  0xf0,  0x80,  0x00,  0xaa,  0x00,  0xaa,  0x14,  0xb6,  0x08,
+  0xb8,  0x0f,  0xbb,  0x55,  0xbd,  0x56,  0xbe,  0x00,  0xc0,  0x00,  0x00,  0x4c,  0x00,  0xdc,  0x02,  0x4a,
+  0x05,  0xf0,  0x05,  0xf8,  0x06,  0x13,  0x08,  0x13,  0x0c,  0x00,  0x0e,  0x47,  0x0e,  0xf7,  0x0f,  0x00,
+  0x19,  0x00,  0x20,  0x00,  0x2a,  0x01,  0x32,  0x1c,  0x36,  0x00,  0x38,  0x12,  0x3c,  0x0b,  0x45,  0x5a,
+  0x56,  0x14,  0x59,  0xf0,  0x62,  0x0a,  0x69,  0x08,  0x83,  0x59,  0xae,  0x17,  0xb8,  0xf0,  0xba,  0x0f,
+  0xba,  0x17,  0xf0,  0x00,  0xf6,  0x0d,  0x02,  0xfa,  0x03,  0xfa,  0x04,  0x10,  0x04,  0xea,  0x04,  0xf6,
+  0x04,  0xfc,  0x05,  0x00,  0x06,  0x00,  0x06,  0x12,  0x0a,  0x10,  0x0b,  0xf0,  0x0c,  0xf0,  0x12,  0x10,
+  0x30,  0x1c,  0x33,  0x00,  0x34,  0x00,  0x38,  0x44,  0x40,  0x5c,  0x4a,  0xe4,  0x5a,  0x14,  0x62,  0x1a,
+  0x64,  0x0a,  0x68,  0x08,  0x68,  0x54,  0x83,  0x55,  0x83,  0x5a,  0x91,  0x44,  0x98,  0x12,  0x9a,  0x16,
+  0xa4,  0x00,  0xb0,  0x57,  0xb5,  0x00,  0xba,  0x00,  0xce,  0x45,  0xd0,  0x00,  0xe1,  0x00,  0xe7,  0x00,
+  0xec,  0x0d,  0x00,  0x54,  0x01,  0x48,  0x01,  0x58,  0x02,  0x10,  0x02,  0xe6,  0x03,  0xa1,  0x04,  0x13,
+  0x05,  0xe6,  0x06,  0x0b,  0x06,  0x83,  0x06,  0xf0,  0x07,  0x00,  0x0a,  0x00,  0x0a,  0x12,  0x0a,  0xf0,
+  0x0c,  0x04,  0x0c,  0x10,  0x0c,  0x12,  0x0e,  0x13,  0x10,  0x10,  0x12,  0x1c,  0x17,  0x00,  0x18,  0x0e,
+  0x19,  0xe4,  0x1a,  0x10,  0x1c,  0x00,  0x1c,  0x12,  0x1c,  0x14,  0x1d,  0xf7,  0x1e,  0x13,  0x20,  0x1c,
+  0x20,  0xe7,  0x22,  0x01,  0x26,  0x01,  0x2a,  0x12,  0x30,  0xe7,  0x41,  0x58,  0x43,  0x48,  0x44,  0x55,
+  0x46,  0x1c,  0x4e,  0xe4,  0x5c,  0xf0,  0x72,  0x02,  0x74,  0x03,  0x77,  0x57,  0x88,  0x12,  0x89,  0x48,
+  0x92,  0x13,  0x99,  0x00,  0x9b,  0x00,  0x9c,  0x32,  0x9e,  0x00,  0xa8,  0x00,  0xaa,  0x12,  0xb9,  0x00,
+  0xba,  0x06,  0xbf,  0x57,  0xc0,  0x01,  0xc0,  0x08,  0xc2,  0x01,  0xfe,  0x9c,  0xf0,  0x26,  0x02,  0xfe,
+  0xc6,  0x0c,  0xff,  0x10,  0x00,  0x00,  0xfc,  0xfe,  0x18,  0x19,  0x00,  0xfa,  0xfe,  0x80,  0x01,  0xff,
+  0x03,  0x00,  0x00,  0x2f,  0xfe,  0x01,  0x05,  0xff,  0x40,  0x00,  0x00,  0x0d,  0xff,  0x09,  0x00,  0x00,
+  0xff,  0x08,  0x01,  0x01,  0xff,  0x10,  0xff,  0xff,  0xff,  0x1f,  0x00,  0x00,  0xff,  0x10,  0xff,  0xff,
+  0xff,  0x0f,  0x00,  0x00,  0xfe,  0x78,  0x56,  0xfe,  0x34,  0x12,  0xff,  0x21,  0x00,  0x00,  0xfe,  0x04,
+  0xf7,  0xfa,  0x35,  0x51,  0x0c,  0x01,  0xfe,  0xb6,  0x0e,  0xfe,  0x04,  0xf7,  0xfa,  0x51,  0x0c,  0x1d,
+  0x35,  0xfe,  0x3d,  0xf0,  0xfe,  0xf8,  0x01,  0xfe,  0x20,  0xf0,  0xd0,  0x04,  0x55,  0x50,  0x02,  0xfe,
+  0xe2,  0x0c,  0x01,  0xfe,  0x42,  0x0d,  0xfe,  0xe9,  0x12,  0x02,  0xfe,  0x04,  0x03,  0xfe,  0x28,  0x1c,
+  0x04,  0xfe,  0xa6,  0x00,  0xfe,  0xdd,  0x12,  0x4e,  0x13,  0xfe,  0xa6,  0x00,  0xc3,  0xfe,  0x48,  0xf0,
+  0xfe,  0x7c,  0x02,  0xfe,  0x49,  0xf0,  0xfe,  0x96,  0x02,  0xfe,  0x4a,  0xf0,  0xfe,  0xb4,  0x02,  0xfe,
+  0x46,  0xf0,  0xfe,  0x46,  0x02,  0xfe,  0x47,  0xf0,  0xfe,  0x4c,  0x02,  0xfe,  0x43,  0xf0,  0xfe,  0x3a,
+  0x02,  0xfe,  0x44,  0xf0,  0xfe,  0x3e,  0x02,  0xfe,  0x45,  0xf0,  0xfe,  0x42,  0x02,  0x07,  0x0c,  0x9d,
+  0x07,  0x06,  0x13,  0xb8,  0x02,  0x26,  0xfe,  0x00,  0x1c,  0xfe,  0xf1,  0x10,  0xfe,  0x02,  0x1c,  0xfe,
+  0xed,  0x10,  0xfe,  0x1e,  0x1c,  0xfe,  0xe9,  0x10,  0x01,  0xfe,  0x0e,  0x17,  0xfe,  0xe7,  0x10,  0xfe,
+  0x06,  0xfc,  0xf5,  0x0e,  0x7b,  0x01,  0xc0,  0x02,  0x26,  0x17,  0x54,  0x47,  0xba,  0x01,  0xfe,  0x2c,
+  0x0f,  0x0e,  0x7b,  0x01,  0x9a,  0xfe,  0xbd,  0x10,  0x0e,  0x7b,  0x01,  0x9a,  0xfe,  0xad,  0x10,  0xfe,
+  0x16,  0x1c,  0xfe,  0x58,  0x1c,  0x07,  0x06,  0x13,  0xb8,  0x35,  0x1f,  0x26,  0xfe,  0x3d,  0xf0,  0xfe,
+  0xf8,  0x01,  0x27,  0xfe,  0x8a,  0x02,  0xfe,  0x5a,  0x1c,  0xd5,  0xfe,  0x14,  0x1c,  0x17,  0xfe,  0x30,
+  0x00,  0x47,  0xba,  0x01,  0xfe,  0x1c,  0x0f,  0x07,  0x06,  0x13,  0xb8,  0x02,  0xfc,  0x22,  0x2b,  0x05,
+  0x10,  0x2f,  0xfe,  0x69,  0x10,  0x07,  0x06,  0x13,  0xb8,  0xfe,  0x04,  0xec,  0x2b,  0x08,  0x2b,  0x07,
+  0x3a,  0x1d,  0x01,  0x40,  0x7f,  0xfe,  0x05,  0xf6,  0xf5,  0x01,  0xfe,  0x40,  0x16,  0x0b,  0x49,  0x89,
+  0x37,  0x11,  0x43,  0x1d,  0xca,  0x08,  0x1c,  0x07,  0x3f,  0x01,  0x6a,  0x02,  0x26,  0x0e,  0x3b,  0x01,
+  0x14,  0x05,  0x10,  0xd3,  0x08,  0x1c,  0x07,  0x3f,  0x01,  0x76,  0xfe,  0x28,  0x10,  0x0e,  0xbd,  0x01,
+  0x14,  0xe5,  0x0e,  0x7c,  0x01,  0x14,  0xfe,  0x49,  0x54,  0x72,  0xfe,  0x12,  0x03,  0x08,  0x1c,  0x07,
+  0x3f,  0x01,  0x6a,  0x02,  0x26,  0x35,  0x7f,  0xfe,  0x02,  0xe8,  0x2d,  0xf9,  0xfe,  0x9e,  0x43,  0xed,
+  0xfe,  0x07,  0x4b,  0xfe,  0x20,  0xf0,  0xd0,  0xfe,  0x40,  0x1c,  0x1f,  0xec,  0xfe,  0x26,  0xf0,  0xfe,
+  0x70,  0x03,  0xfe,  0xa0,  0xf0,  0xfe,  0x5e,  0x03,  0xfe,  0x11,  0xf0,  0xd0,  0xfe,  0x0e,  0x10,  0xfe,
+  0x9f,  0xf0,  0xfe,  0x7e,  0x03,  0xe8,  0x12,  0xfe,  0x11,  0x00,  0x02,  0x4b,  0x35,  0xfe,  0x48,  0x1c,
+  0xe8,  0x1f,  0xec,  0x33,  0xec,  0xfe,  0x82,  0xf0,  0xfe,  0x84,  0x03,  0x29,  0x22,  0xbb,  0x68,  0x16,
+  0xbb,  0x0e,  0x7c,  0x01,  0x14,  0x68,  0x7d,  0x08,  0x1c,  0x07,  0x3f,  0x01,  0x40,  0x11,  0x3b,  0x08,
+  0x3b,  0x07,  0x99,  0x01,  0x6a,  0xf3,  0x11,  0xfe,  0xe4,  0x00,  0x2c,  0xfe,  0xca,  0x03,  0x1f,  0x31,
+  0x20,  0xfe,  0xda,  0x03,  0x01,  0x4a,  0xcb,  0xfe,  0xea,  0x03,  0x69,  0x8e,  0xcf,  0xfe,  0xaa,  0x06,
+  0x02,  0x25,  0x04,  0x7b,  0x2a,  0x1b,  0xfe,  0x1c,  0x05,  0x17,  0x84,  0x01,  0x38,  0x01,  0x95,  0x01,
+  0x98,  0x33,  0xfe,  0x5c,  0x02,  0x02,  0xeb,  0xe8,  0x35,  0x51,  0x18,  0xfe,  0x67,  0x1b,  0xf9,  0xed,
+  0xfe,  0x48,  0x1c,  0x8b,  0x01,  0xee,  0xa8,  0xfe,  0x96,  0xf0,  0xfe,  0x24,  0x04,  0x2c,  0xfe,  0x28,
+  0x04,  0x33,  0x26,  0x0e,  0x3b,  0x01,  0x14,  0x05,  0x10,  0x1b,  0xfe,  0x08,  0x05,  0x3c,  0x92,  0x9e,
+  0x2d,  0x81,  0x6d,  0x1f,  0x31,  0x20,  0x25,  0x04,  0x7b,  0x2a,  0xfe,  0x10,  0x12,  0x17,  0x84,  0x01,
+  0x38,  0x33,  0xfe,  0x5c,  0x02,  0x02,  0xeb,  0x30,  0xfe,  0xa0,  0x00,  0xfe,  0x9b,  0x57,  0xfe,  0x5e,
+  0x12,  0x0b,  0x09,  0x06,  0xfe,  0x56,  0x12,  0x23,  0x28,  0x93,  0x01,  0x0a,  0x81,  0x6d,  0x20,  0xfe,
+  0xd8,  0x04,  0x23,  0x28,  0x93,  0x01,  0x0a,  0x20,  0x25,  0x23,  0x28,  0xb1,  0xfe,  0x4c,  0x44,  0xfe,
+  0x32,  0x12,  0x56,  0xfe,  0x44,  0x48,  0x08,  0xd6,  0xfe,  0x4c,  0x54,  0x72,  0xfe,  0x08,  0x05,  0x7f,
+  0x9e,  0x2d,  0xfe,  0x06,  0x80,  0xfe,  0x48,  0x47,  0xfe,  0x48,  0x13,  0x3d,  0x05,  0xfe,  0xcc,  0x00,
+  0xfe,  0x40,  0x13,  0x0b,  0x09,  0x06,  0x8d,  0xfe,  0x06,  0x10,  0x23,  0x28,  0xb1,  0x0b,  0x09,  0x36,
+  0xdb,  0x17,  0xa2,  0x0b,  0x09,  0x06,  0x50,  0x17,  0xfe,  0x0d,  0x00,  0x01,  0x38,  0x33,  0xfe,  0x86,
+  0x0c,  0x02,  0x25,  0x39,  0x11,  0xfe,  0xe6,  0x00,  0xfe,  0x1c,  0x90,  0xac,  0x03,  0x17,  0xa2,  0x01,
+  0x38,  0x33,  0x26,  0x1f,  0x26,  0x02,  0xfe,  0x10,  0x05,  0xfe,  0x42,  0x5b,  0x51,  0x18,  0xfe,  0x46,
+  0x59,  0xf9,  0xed,  0x17,  0x74,  0xfe,  0x07,  0x80,  0xfe,  0x31,  0x44,  0x0b,  0x09,  0x0c,  0xfe,  0x78,
+  0x13,  0xfe,  0x20,  0x80,  0x05,  0x18,  0xfe,  0x70,  0x12,  0x6c,  0x09,  0x06,  0xfe,  0x60,  0x13,  0x04,
+  0xfe,  0xa2,  0x00,  0x2a,  0x1b,  0xfe,  0xa8,  0x05,  0xfe,  0x31,  0xe4,  0x6f,  0x6c,  0x09,  0x0c,  0xfe,
+  0x4a,  0x13,  0x04,  0xfe,  0xa0,  0x00,  0x2a,  0xfe,  0x42,  0x12,  0x59,  0x2c,  0xfe,  0x68,  0x05,  0x1f,
+  0x31,  0xef,  0x01,  0x0a,  0x24,  0xfe,  0xc0,  0x05,  0x11,  0xfe,  0xe3,  0x00,  0x29,  0x6c,  0xfe,  0x4a,
+  0xf0,  0xfe,  0x92,  0x05,  0xfe,  0x49,  0xf0,  0xfe,  0x8c,  0x05,  0xd1,  0x21,  0xfe,  0x21,  0x00,  0xa4,
+  0x21,  0xfe,  0x22,  0x00,  0x9d,  0x21,  0x89,  0xfe,  0x09,  0x48,  0x01,  0x0a,  0x24,  0xfe,  0xc0,  0x05,
+  0xfe,  0xe2,  0x08,  0x6c,  0x09,  0xda,  0x50,  0x01,  0xb6,  0x21,  0x06,  0x16,  0xe2,  0x47,  0xfe,  0x27,
+  0x01,  0x0b,  0x09,  0x36,  0xe3,  0x4e,  0x01,  0xae,  0x17,  0xa2,  0x0b,  0x09,  0x06,  0x50,  0x17,  0xfe,
+  0x0d,  0x00,  0x01,  0x38,  0x01,  0x95,  0x01,  0x98,  0x33,  0xfe,  0x86,  0x0c,  0x02,  0x25,  0x04,  0xfe,
+  0x9c,  0x00,  0x2a,  0xfe,  0x3e,  0x12,  0x04,  0x52,  0x2a,  0xfe,  0x36,  0x13,  0x4e,  0x01,  0xae,  0x24,
+  0xfe,  0x38,  0x06,  0x0e,  0x06,  0x6c,  0x09,  0x19,  0xfe,  0x02,  0x12,  0x79,  0x01,  0xfe,  0xf0,  0x13,
+  0x20,  0xfe,  0x2e,  0x06,  0x11,  0xbe,  0x01,  0x4a,  0x11,  0xfe,  0xe5,  0x00,  0x04,  0x52,  0xb9,  0x0f,
+  0x52,  0x04,  0xf4,  0x2a,  0xfe,  0x62,  0x12,  0x04,  0x4d,  0x2a,  0xfe,  0x5a,  0x13,  0x01,  0xfe,  0x60,
+  0x18,  0x01,  0xfe,  0xb2,  0x18,  0xe6,  0xc8,  0x19,  0x08,  0x61,  0xff,  0x02,  0x00,  0x57,  0x64,  0x7e,
+  0x1a,  0x4f,  0xc7,  0xc8,  0x87,  0x4e,  0x01,  0xae,  0x24,  0xfe,  0xa2,  0x06,  0x6c,  0x09,  0x1e,  0xa3,
+  0x7a,  0x0e,  0x54,  0x01,  0xfe,  0x1e,  0x14,  0x20,  0xfe,  0x98,  0x06,  0x11,  0xbe,  0x01,  0x4a,  0x11,
+  0xfe,  0xe5,  0x00,  0x04,  0x4d,  0xb9,  0x0f,  0x4d,  0x07,  0x06,  0x01,  0xae,  0xf3,  0x71,  0x8b,  0x01,
+  0xee,  0xa8,  0x11,  0xfe,  0xe2,  0x00,  0x2c,  0xf8,  0x1f,  0x31,  0xcf,  0xfe,  0xd6,  0x06,  0x80,  0xfe,
+  0x74,  0x07,  0xcb,  0xfe,  0x7c,  0x07,  0x69,  0x8e,  0x02,  0x25,  0x0b,  0x09,  0x0c,  0xfe,  0x2e,  0x12,
+  0x15,  0x18,  0x01,  0x0a,  0x15,  0x00,  0x01,  0x0a,  0x15,  0x00,  0x01,  0x0a,  0x15,  0x00,  0x01,  0x0a,
+  0xfe,  0x99,  0xa4,  0x01,  0x0a,  0x15,  0x00,  0x02,  0xfe,  0x3a,  0x08,  0x66,  0x09,  0x1e,  0x8d,  0x0b,
+  0x09,  0x1e,  0xfe,  0x30,  0x13,  0x15,  0xfe,  0x1b,  0x00,  0x01,  0x0a,  0x15,  0x00,  0x01,  0x0a,  0x15,
+  0x00,  0x01,  0x0a,  0x15,  0x00,  0x01,  0x0a,  0x15,  0x06,  0x01,  0x0a,  0x15,  0x00,  0x02,  0xc9,  0x79,
+  0xfe,  0x9a,  0x81,  0x65,  0x89,  0xfe,  0x09,  0x6f,  0xfe,  0x93,  0x45,  0x1b,  0xfe,  0x84,  0x07,  0x2c,
+  0xfe,  0x5c,  0x07,  0x1f,  0x31,  0xcf,  0xfe,  0x54,  0x07,  0x69,  0x8e,  0x80,  0xfe,  0x74,  0x07,  0x02,
+  0x25,  0x01,  0x4a,  0x02,  0xf8,  0x15,  0x19,  0x02,  0xf8,  0xfe,  0x9c,  0xf7,  0xfe,  0xf0,  0x07,  0xfe,
+  0x2c,  0x90,  0xfe,  0xae,  0x90,  0x73,  0xfe,  0xd2,  0x07,  0x0f,  0x5c,  0x13,  0x5d,  0x0b,  0x49,  0x6f,
+  0x37,  0x01,  0xfe,  0xf6,  0x17,  0x05,  0x10,  0x82,  0xfe,  0x83,  0xe7,  0x88,  0xa4,  0xfe,  0x03,  0x40,
+  0x0b,  0x49,  0x74,  0x37,  0x01,  0xb7,  0xab,  0xfe,  0x1f,  0x40,  0x16,  0x60,  0x01,  0xf6,  0xfe,  0x08,
+  0x50,  0xfe,  0x8a,  0x50,  0xfe,  0x34,  0x51,  0xfe,  0xb6,  0x51,  0xfe,  0x08,  0x90,  0xfe,  0x8a,  0x90,
+  0x0f,  0x5a,  0x13,  0x5b,  0xfe,  0x0c,  0x90,  0xfe,  0x8e,  0x90,  0xfe,  0x28,  0x50,  0xfe,  0xaa,  0x50,
+  0x0f,  0x41,  0x13,  0x42,  0xfe,  0x4a,  0x10,  0x0b,  0x09,  0x6f,  0xe3,  0xfe,  0x2c,  0x90,  0xfe,  0xae,
+  0x90,  0x0f,  0x5c,  0x13,  0x5d,  0x0b,  0x09,  0x74,  0xc7,  0x01,  0xb7,  0xfe,  0x1f,  0x80,  0x16,  0x60,
+  0xfe,  0x34,  0x90,  0xfe,  0xb6,  0x90,  0x0f,  0x5e,  0x13,  0x5f,  0xfe,  0x08,  0x90,  0xfe,  0x8a,  0x90,
+  0x0f,  0x5a,  0x13,  0x5b,  0xfe,  0x28,  0x90,  0xfe,  0xaa,  0x90,  0x0f,  0x41,  0x13,  0x42,  0x0f,  0x3e,
+  0x13,  0x57,  0x0b,  0x49,  0x19,  0x37,  0x35,  0x08,  0xa1,  0x2c,  0xfe,  0x50,  0x08,  0xfe,  0x9e,  0xf0,
+  0xfe,  0x64,  0x08,  0xc2,  0x1b,  0x31,  0x35,  0x6b,  0xfe,  0xed,  0x10,  0xa5,  0xfe,  0x88,  0x08,  0xa6,
+  0xfe,  0xa4,  0x08,  0x80,  0xfe,  0x7c,  0x08,  0xcb,  0xfe,  0x82,  0x08,  0x69,  0x8e,  0x02,  0x25,  0x01,
+  0x4a,  0xfe,  0xc9,  0x10,  0x15,  0x19,  0xfe,  0xc9,  0x10,  0x66,  0x09,  0x06,  0xfe,  0x10,  0x12,  0x66,
+  0x09,  0x0c,  0x48,  0x0b,  0x09,  0x0c,  0xfe,  0x66,  0x12,  0xfe,  0x2e,  0x1c,  0xa7,  0x66,  0x09,  0x06,
+  0x48,  0x66,  0x09,  0x0c,  0xfe,  0x52,  0x12,  0xfe,  0x2c,  0x1c,  0xfe,  0xaa,  0xf0,  0xfe,  0x24,  0x09,
+  0xfe,  0xac,  0xf0,  0xfe,  0xc4,  0x08,  0xfe,  0x92,  0x10,  0xfe,  0x34,  0x1c,  0xfe,  0xf3,  0x10,  0xfe,
+  0xad,  0xf0,  0xfe,  0xd0,  0x08,  0x02,  0xfe,  0x32,  0x0a,  0xfe,  0x36,  0x1c,  0xfe,  0xe7,  0x10,  0xfe,
+  0x2b,  0xf0,  0xb0,  0xfe,  0x6b,  0x18,  0x1a,  0xfe,  0x00,  0xfe,  0xdb,  0xc3,  0xfe,  0xd2,  0xf0,  0xb0,
+  0xfe,  0x76,  0x18,  0x1a,  0x18,  0x1b,  0xb0,  0x04,  0xe1,  0x1a,  0x06,  0x1b,  0xb0,  0xa5,  0x77,  0xa6,
+  0x77,  0xfe,  0x34,  0x1c,  0xfe,  0x36,  0x1c,  0xfe,  0xb1,  0x10,  0x8b,  0x59,  0x39,  0x17,  0xa2,  0x01,
+  0x38,  0x12,  0xfe,  0x35,  0x00,  0x33,  0x4b,  0x12,  0x8c,  0x02,  0x4b,  0xfe,  0x74,  0x18,  0x1a,  0xfe,
+  0x00,  0xf8,  0x1b,  0x77,  0x51,  0x1e,  0x01,  0xfe,  0x42,  0x0d,  0xd2,  0x08,  0x1c,  0x07,  0x3f,  0x01,
+  0x6a,  0x22,  0x2d,  0x3c,  0x51,  0x18,  0x02,  0x77,  0xfe,  0x98,  0x80,  0xd8,  0x0c,  0x27,  0xfe,  0x14,
+  0x0a,  0x0b,  0x09,  0x6f,  0xfe,  0x82,  0x12,  0x0b,  0x09,  0x19,  0xfe,  0x66,  0x13,  0x22,  0x60,  0x68,
+  0xc6,  0xfe,  0x83,  0x80,  0xfe,  0xc8,  0x44,  0xfe,  0x2e,  0x13,  0xfe,  0x04,  0x91,  0xfe,  0x86,  0x91,
+  0x62,  0x2d,  0xfe,  0x40,  0x59,  0xfe,  0xc1,  0x59,  0x73,  0xfb,  0x04,  0x5c,  0x2e,  0x5d,  0x0f,  0xaa,
+  0x13,  0x8c,  0x9b,  0x5c,  0x9c,  0x5d,  0x01,  0xb7,  0xab,  0x62,  0x2d,  0x16,  0x60,  0xa0,  0x3e,  0x67,
+  0x57,  0x63,  0x5e,  0x30,  0x5f,  0xe7,  0xfe,  0xe5,  0x55,  0xfe,  0x04,  0xfa,  0x3e,  0xfe,  0x05,  0xfa,
+  0x57,  0x01,  0xf6,  0xfe,  0x36,  0x10,  0x29,  0x0f,  0xaa,  0x0f,  0x8c,  0x63,  0x5e,  0x30,  0x5f,  0xa7,
+  0x0b,  0x09,  0x19,  0x1b,  0xfb,  0x63,  0x41,  0x30,  0x42,  0x0b,  0x09,  0xfe,  0xf7,  0x00,  0x37,  0x04,
+  0x5a,  0x2e,  0x5b,  0xfe,  0x10,  0x58,  0xfe,  0x91,  0x58,  0xfe,  0x14,  0x59,  0xfe,  0x95,  0x59,  0x02,
+  0x77,  0x0b,  0x09,  0x19,  0x1b,  0xfb,  0x0b,  0x09,  0xfe,  0xf7,  0x00,  0x37,  0xfe,  0x3a,  0x55,  0xfe,
+  0x19,  0x81,  0x79,  0xfe,  0x10,  0x90,  0xfe,  0x92,  0x90,  0xfe,  0xd7,  0x10,  0x3d,  0x05,  0xbf,  0x1b,
+  0xfe,  0xcc,  0x08,  0x11,  0xbf,  0xfe,  0x98,  0x80,  0xd8,  0x0c,  0xfe,  0x14,  0x13,  0x04,  0x41,  0x2e,
+  0x42,  0x73,  0xfe,  0xcc,  0x08,  0xfe,  0x0c,  0x58,  0xfe,  0x8d,  0x58,  0x02,  0x77,  0x29,  0x4e,  0xfe,
+  0x19,  0x80,  0xfe,  0xf1,  0x10,  0x0b,  0x09,  0x0c,  0xa3,  0xfe,  0x6c,  0x19,  0xfe,  0x19,  0x41,  0xfe,
+  0x94,  0x10,  0xfe,  0x6c,  0x19,  0x9b,  0x41,  0xfe,  0xed,  0x19,  0x9c,  0x42,  0xfe,  0x0c,  0x51,  0xfe,
+  0x8e,  0x51,  0xfe,  0x6b,  0x18,  0x1a,  0xfe,  0x00,  0xff,  0x2f,  0xfe,  0x7a,  0x10,  0xc3,  0xfe,  0xd2,
+  0xf0,  0xfe,  0xac,  0x0a,  0xfe,  0x76,  0x18,  0x1a,  0x18,  0xce,  0x04,  0xe1,  0x1a,  0x06,  0x83,  0x12,
+  0xfe,  0x16,  0x00,  0x02,  0x4b,  0xfe,  0xd1,  0xf0,  0xfe,  0xe2,  0x0a,  0x17,  0xa1,  0x01,  0x38,  0x12,
+  0xd6,  0xfe,  0x48,  0x10,  0xfe,  0xce,  0xf0,  0xfe,  0xca,  0x0a,  0x12,  0xfe,  0x21,  0x00,  0x02,  0x4b,
+  0xfe,  0xcd,  0xf0,  0xfe,  0xd6,  0x0a,  0x12,  0xfe,  0x22,  0x00,  0x02,  0x4b,  0xfe,  0xcb,  0xf0,  0xfe,
+  0xe2,  0x0a,  0x12,  0xfe,  0x24,  0x00,  0x02,  0x4b,  0xfe,  0xd0,  0xf0,  0xfe,  0xec,  0x0a,  0x12,  0x88,
+  0xd9,  0xfe,  0xcf,  0xf0,  0xfe,  0xf6,  0x0a,  0x12,  0x89,  0xd4,  0xfe,  0xcc,  0xf0,  0xc9,  0xfe,  0x84,
+  0x80,  0xd8,  0x19,  0xfe,  0xd5,  0x12,  0x12,  0xfe,  0x12,  0x00,  0x2c,  0xc9,  0x1f,  0x31,  0xa5,  0x25,
+  0xa6,  0x25,  0x35,  0xf3,  0x2c,  0xfe,  0x1a,  0x0b,  0x1f,  0x31,  0x80,  0xfe,  0x36,  0x0b,  0x69,  0x8e,
+  0xa5,  0xfe,  0xf0,  0x07,  0xa6,  0xfe,  0xf0,  0x07,  0x02,  0x25,  0x01,  0x4a,  0xfe,  0xdb,  0x10,  0x11,
+  0xfe,  0xe8,  0x00,  0x8b,  0x81,  0x6d,  0xfe,  0x89,  0xf0,  0x25,  0x23,  0x28,  0xfe,  0xe9,  0x09,  0x01,
+  0x0a,  0x81,  0x6d,  0x20,  0x25,  0x23,  0x28,  0x93,  0x33,  0xfe,  0x6e,  0x0b,  0x1f,  0x31,  0x02,  0xfe,
+  0x62,  0x0b,  0xc2,  0x48,  0x12,  0xfe,  0x42,  0x00,  0x02,  0x4b,  0x9f,  0x06,  0xfe,  0x81,  0x49,  0xfe,
+  0xcc,  0x12,  0x0b,  0x09,  0x0c,  0xfe,  0x5a,  0x13,  0x12,  0x00,  0x58,  0x0c,  0xfe,  0x6a,  0x12,  0x58,
+  0xfe,  0x28,  0x00,  0x27,  0xfe,  0xb4,  0x0c,  0x0e,  0x7c,  0x01,  0x14,  0x05,  0x00,  0x83,  0x34,  0xfe,
+  0x28,  0x00,  0x02,  0xfe,  0xb4,  0x0c,  0x01,  0x95,  0x01,  0x98,  0x0e,  0xbd,  0x01,  0xfe,  0x10,  0x0e,
+  0xaf,  0x08,  0x3b,  0x07,  0x99,  0x01,  0x40,  0x11,  0x43,  0x08,  0x1c,  0x07,  0x3f,  0x01,  0x76,  0x02,
+  0x26,  0x12,  0xfe,  0x44,  0x00,  0x58,  0x0c,  0xa3,  0x34,  0x0c,  0xfe,  0xc0,  0x10,  0x01,  0xb6,  0x34,
+  0x0c,  0xfe,  0xb6,  0x10,  0x01,  0xb6,  0xfe,  0x19,  0x82,  0xfe,  0x34,  0x46,  0xfe,  0x0a,  0x13,  0x34,
+  0x0c,  0x12,  0xfe,  0x43,  0x00,  0xfe,  0xa2,  0x10,  0x0b,  0x49,  0x0c,  0x37,  0x01,  0x95,  0x01,  0x98,
+  0xaf,  0x08,  0x3b,  0x07,  0x99,  0x01,  0x40,  0x11,  0x43,  0x08,  0x1c,  0x07,  0x3f,  0x01,  0x76,  0x51,
+  0x0c,  0xaf,  0x1d,  0xca,  0x02,  0xfe,  0x48,  0x03,  0x0b,  0x09,  0x0c,  0xce,  0x34,  0x0c,  0x12,  0x00,
+  0xfe,  0x54,  0x10,  0x66,  0x09,  0x1e,  0xfe,  0x50,  0x12,  0x0b,  0x09,  0x1e,  0xfe,  0x48,  0x13,  0xfe,
+  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,  0x72,  0x0c,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,  0x78,
+  0x0c,  0x0b,  0x49,  0x1e,  0x37,  0xfe,  0x95,  0x10,  0x12,  0xfe,  0x15,  0x00,  0xfe,  0x04,  0xe6,  0x0c,
+  0x79,  0xfe,  0x26,  0x10,  0x12,  0xfe,  0x13,  0x00,  0xd4,  0x12,  0xfe,  0x47,  0x00,  0xa4,  0x12,  0xfe,
+  0x41,  0x00,  0x9d,  0x12,  0xfe,  0x24,  0x00,  0x04,  0x7b,  0x2a,  0x27,  0xeb,  0x79,  0xfe,  0x04,  0xe6,
+  0x1e,  0xfe,  0x9d,  0x41,  0xfe,  0x1c,  0x42,  0xaf,  0x01,  0xd7,  0x02,  0x26,  0xd5,  0x17,  0x0c,  0x47,
+  0xf2,  0xdf,  0x17,  0xfe,  0x31,  0x00,  0x47,  0xba,  0x01,  0xfe,  0x1c,  0x0f,  0x02,  0xfc,  0x1d,  0xfe,
+  0x06,  0xec,  0xf7,  0x85,  0x34,  0x36,  0xbc,  0x2f,  0x1d,  0xfe,  0x06,  0xea,  0xf7,  0xfe,  0x47,  0x4b,
+  0x7a,  0xfe,  0x75,  0x57,  0x04,  0x55,  0xfe,  0x98,  0x56,  0xfe,  0x28,  0x12,  0x0e,  0x7c,  0xfe,  0xfa,
+  0x14,  0x4e,  0xe5,  0x0e,  0xbd,  0xfe,  0xf0,  0x14,  0xfe,  0x49,  0x54,  0x91,  0xfe,  0x28,  0x0d,  0x0e,
+  0x1c,  0xfe,  0xe4,  0x14,  0xfe,  0x44,  0x48,  0x02,  0xfe,  0x48,  0x03,  0x0e,  0x55,  0xfe,  0xc8,  0x14,
+  0x85,  0x34,  0x36,  0xbc,  0x2f,  0x1d,  0xfe,  0xce,  0x47,  0xfe,  0xbd,  0x13,  0x02,  0x26,  0x22,  0x2b,
+  0x05,  0x10,  0xfe,  0x78,  0x12,  0x29,  0x16,  0x54,  0x16,  0xa9,  0x22,  0x43,  0x4e,  0x47,  0x43,  0xc2,
+  0xfe,  0x0c,  0x13,  0xfe,  0xbc,  0xf0,  0xfe,  0xc4,  0x0d,  0x08,  0x06,  0x16,  0x54,  0x01,  0xfe,  0xd0,
+  0x15,  0x04,  0xfe,  0x38,  0x01,  0x2e,  0xfe,  0x3a,  0x01,  0x73,  0xfe,  0xc8,  0x0d,  0x04,  0xfe,  0x38,
+  0x01,  0x1a,  0xfe,  0xf0,  0xff,  0x0f,  0xfe,  0x60,  0x01,  0x04,  0xfe,  0x3a,  0x01,  0x0f,  0xfe,  0x62,
+  0x01,  0x21,  0x06,  0x16,  0x43,  0xfe,  0x04,  0xec,  0x2b,  0x08,  0x2b,  0x07,  0x3a,  0x1d,  0x01,  0x40,
+  0x7f,  0xfe,  0x05,  0xf6,  0xfe,  0x34,  0x01,  0x01,  0xfe,  0x40,  0x16,  0x11,  0x43,  0xca,  0x08,  0x06,
+  0x03,  0x29,  0x03,  0x22,  0x54,  0xfe,  0xf7,  0x12,  0x22,  0xa9,  0x68,  0x16,  0xa9,  0x05,  0xa1,  0xfe,
+  0x93,  0x13,  0xfe,  0x24,  0x1c,  0x17,  0x18,  0x47,  0xf2,  0xdf,  0xfe,  0xd9,  0x10,  0x94,  0xfe,  0x03,
+  0xdc,  0xfe,  0x73,  0x57,  0xfe,  0x80,  0x5d,  0x03,  0x94,  0xfe,  0x03,  0xdc,  0x29,  0xfe,  0x70,  0x57,
+  0xfe,  0x33,  0x54,  0xfe,  0x3b,  0x54,  0xfe,  0x80,  0x5d,  0x03,  0xfe,  0x03,  0x57,  0x94,  0x29,  0xfe,
+  0x00,  0xcc,  0x03,  0xfe,  0x03,  0x57,  0x94,  0x7d,  0x03,  0x01,  0xfe,  0x70,  0x16,  0x3d,  0x05,  0x43,
+  0xfe,  0x0a,  0x13,  0x08,  0x1c,  0x07,  0x3f,  0xd4,  0x01,  0x95,  0x01,  0x98,  0x08,  0x3b,  0x07,  0x99,
+  0x01,  0x40,  0x11,  0xfe,  0xe9,  0x00,  0x0b,  0x09,  0x89,  0xfe,  0x52,  0x13,  0x01,  0xfe,  0x02,  0x16,
+  0xfe,  0x1e,  0x1c,  0xfe,  0x14,  0x90,  0x0f,  0xfe,  0x64,  0x01,  0xfe,  0x16,  0x90,  0x0f,  0xfe,  0x66,
+  0x01,  0x0b,  0x09,  0x74,  0x8d,  0xfe,  0x03,  0x80,  0x6b,  0x3c,  0x11,  0x75,  0x08,  0x2b,  0x07,  0x3a,
+  0x1d,  0x92,  0x01,  0x6a,  0xfe,  0x62,  0x08,  0x68,  0x3c,  0x11,  0x75,  0x08,  0x2b,  0x07,  0x3a,  0x1d,
+  0x92,  0x01,  0x6a,  0x62,  0x2d,  0x11,  0x75,  0x08,  0x2b,  0x07,  0x3a,  0x1d,  0x92,  0x01,  0x76,  0x03,
+  0xfe,  0x08,  0x1c,  0x04,  0xfe,  0xac,  0x00,  0xfe,  0x06,  0x58,  0x04,  0xfe,  0xae,  0x00,  0xfe,  0x07,
+  0x58,  0x04,  0xfe,  0xb0,  0x00,  0xfe,  0x08,  0x58,  0x04,  0xfe,  0xb2,  0x00,  0xfe,  0x09,  0x58,  0xfe,
+  0x0a,  0x1c,  0x21,  0x87,  0x16,  0xf7,  0x29,  0x0f,  0x52,  0x0f,  0x4d,  0x21,  0x10,  0x16,  0x2b,  0x16,
+  0x3a,  0x56,  0x9f,  0xd6,  0x08,  0x2b,  0x07,  0x3a,  0x1d,  0x01,  0x76,  0x7f,  0x11,  0x75,  0xfe,  0x14,
+  0x56,  0xfe,  0xd6,  0xf0,  0xfe,  0xf6,  0x0e,  0xd5,  0x8b,  0xfe,  0x14,  0x1c,  0xfe,  0x10,  0x1c,  0xfe,
+  0x18,  0x1c,  0x03,  0x1d,  0xfe,  0x0c,  0x14,  0x85,  0xfe,  0x07,  0xe6,  0x36,  0xfe,  0xce,  0x47,  0xfe,
+  0xf5,  0x13,  0x03,  0x01,  0xb6,  0x0e,  0x3b,  0x01,  0x14,  0x05,  0x10,  0xd3,  0x0e,  0x1c,  0x01,  0x14,
+  0x05,  0x10,  0xdb,  0xfe,  0x44,  0x58,  0x3c,  0xfe,  0x01,  0xec,  0xba,  0xfe,  0x9e,  0x40,  0xfe,  0x9d,
+  0xe7,  0x00,  0xfe,  0x9c,  0xe7,  0x1e,  0x9e,  0x2d,  0x01,  0xd7,  0xfe,  0xc9,  0x10,  0x03,  0x35,  0x81,
+  0x6d,  0x23,  0x28,  0xb1,  0x05,  0x1e,  0xfe,  0x48,  0x12,  0x05,  0x0c,  0xfe,  0x4c,  0x12,  0x05,  0x18,
+  0x38,  0x05,  0xcc,  0x1b,  0xfe,  0xc0,  0x10,  0x05,  0xfe,  0x23,  0x00,  0x1b,  0xfe,  0xcc,  0x10,  0x05,
+  0x06,  0x1b,  0xfe,  0x2a,  0x11,  0x05,  0x19,  0xfe,  0x12,  0x12,  0x05,  0x00,  0x1b,  0x25,  0x17,  0xcc,
+  0x01,  0x38,  0xc4,  0x39,  0x01,  0x0a,  0x80,  0x4a,  0x03,  0x39,  0x11,  0xfe,  0xcc,  0x00,  0x02,  0x26,
+  0x39,  0x3d,  0x05,  0xbf,  0xfe,  0xe3,  0x13,  0x63,  0x41,  0x30,  0x42,  0x73,  0xfe,  0x7e,  0x10,  0x0b,
+  0x09,  0x6f,  0xfe,  0x72,  0x12,  0xa0,  0x3e,  0x67,  0x57,  0xe7,  0xfe,  0xe5,  0x55,  0x91,  0xfe,  0x48,
+  0x10,  0x22,  0x60,  0xfe,  0x26,  0x13,  0x04,  0xaa,  0x2e,  0x8c,  0x73,  0xfe,  0x98,  0x0c,  0x0f,  0x5c,
+  0x13,  0x5d,  0x29,  0x0f,  0xaa,  0x0f,  0x8c,  0x01,  0xb7,  0x21,  0x87,  0x6b,  0x16,  0x60,  0x01,  0xf6,
+  0xa0,  0x3e,  0x67,  0x57,  0xfe,  0x04,  0x55,  0xfe,  0xa5,  0x55,  0xfe,  0x04,  0xfa,  0x3e,  0xfe,  0x05,
+  0xfa,  0x57,  0xfe,  0x91,  0x10,  0x04,  0x5e,  0x2e,  0x5f,  0xfe,  0x40,  0x56,  0xfe,  0xe1,  0x56,  0x0f,
+  0x5e,  0x13,  0x5f,  0xd1,  0xa0,  0x3e,  0x67,  0x57,  0xe7,  0xfe,  0xe5,  0x55,  0x04,  0x5a,  0x2e,  0x5b,
+  0xfe,  0x00,  0x56,  0xfe,  0xa1,  0x56,  0x0f,  0x5a,  0x13,  0x5b,  0x0b,  0x09,  0x6f,  0xfe,  0x1e,  0x12,
+  0x22,  0x60,  0xfe,  0x1f,  0x40,  0x04,  0x5c,  0x2e,  0x5d,  0xfe,  0x2c,  0x50,  0xfe,  0xae,  0x50,  0x04,
+  0x5e,  0x2e,  0x5f,  0xfe,  0x34,  0x50,  0xfe,  0xb6,  0x50,  0x04,  0x5a,  0x2e,  0x5b,  0xfe,  0x08,  0x50,
+  0xfe,  0x8a,  0x50,  0x04,  0x41,  0x2e,  0x42,  0xfe,  0x28,  0x50,  0xfe,  0xaa,  0x50,  0x02,  0x97,  0x21,
+  0x06,  0x16,  0xf1,  0x02,  0x78,  0x39,  0x01,  0x0a,  0x20,  0x4c,  0x23,  0x28,  0xb1,  0x05,  0x06,  0x27,
+  0x4c,  0x3d,  0x05,  0xbf,  0x27,  0x78,  0x01,  0xee,  0x1a,  0x4f,  0x1b,  0x4c,  0x0b,  0x09,  0x0c,  0xde,
+  0x63,  0x41,  0x30,  0x42,  0xfe,  0x0a,  0x55,  0x2f,  0xfe,  0x8b,  0x55,  0x9b,  0x41,  0x9c,  0x42,  0xfe,
+  0x0c,  0x51,  0xfe,  0x8e,  0x51,  0x02,  0x78,  0xfe,  0x19,  0x81,  0xfe,  0x0a,  0x45,  0xfe,  0x19,  0x41,
+  0x02,  0x78,  0x39,  0x01,  0x0a,  0x20,  0xfe,  0xc2,  0x0f,  0x23,  0x28,  0xfe,  0xe9,  0x09,  0x58,  0x18,
+  0xfe,  0x94,  0x12,  0x58,  0x0c,  0x50,  0x02,  0x4c,  0x2c,  0xfe,  0x4a,  0x11,  0x1f,  0x31,  0x20,  0xfe,
+  0xc2,  0x0f,  0x23,  0x28,  0x93,  0x05,  0x18,  0x27,  0x4c,  0x01,  0x0a,  0x20,  0xfe,  0xc2,  0x0f,  0x23,
+  0x28,  0xfe,  0xe8,  0x09,  0x56,  0x04,  0xfe,  0x9c,  0x00,  0x2a,  0x2f,  0xfe,  0xbb,  0x45,  0x58,  0x00,
+  0x48,  0x34,  0x06,  0x9f,  0x4f,  0xfe,  0xc0,  0x14,  0xfe,  0xf8,  0x14,  0xa8,  0x3d,  0x05,  0xbe,  0xfe,
+  0x16,  0x13,  0x04,  0xf4,  0x2a,  0xce,  0x04,  0x4d,  0x2a,  0x2f,  0x59,  0x02,  0x78,  0xfe,  0xc0,  0x5d,
+  0xfe,  0xe4,  0x14,  0xfe,  0x03,  0x17,  0x04,  0x52,  0xb9,  0x0f,  0x52,  0x59,  0x39,  0x01,  0x0a,  0x24,
+  0x97,  0x01,  0xfe,  0xf0,  0x13,  0x02,  0x97,  0x2c,  0xfe,  0xd4,  0x11,  0x1f,  0x31,  0x20,  0x4c,  0x23,
+  0x28,  0x93,  0x05,  0x06,  0x27,  0x4c,  0xfe,  0xf6,  0x14,  0xfe,  0x42,  0x58,  0xfe,  0x70,  0x14,  0xfe,
+  0x92,  0x14,  0xa8,  0xfe,  0x4a,  0xf4,  0x0c,  0x1b,  0x4c,  0xfe,  0x4a,  0xf4,  0x06,  0xd2,  0x3d,  0x05,
+  0xbe,  0xc7,  0x02,  0x78,  0x04,  0x4d,  0xb9,  0x0f,  0x4d,  0x59,  0x39,  0x01,  0x0a,  0x24,  0x97,  0x01,
+  0xfe,  0x1e,  0x14,  0x02,  0x97,  0x24,  0xfe,  0x3c,  0x12,  0x71,  0xef,  0x71,  0x03,  0x33,  0x8d,  0x69,
+  0x8d,  0x59,  0x39,  0x01,  0x0a,  0xfe,  0xe3,  0x10,  0x08,  0x61,  0xff,  0x02,  0x00,  0x57,  0x64,  0x7e,
+  0x1a,  0xfe,  0xff,  0x7f,  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x03,  0x08,  0x61,  0xff,  0x02,  0x00,
+  0x57,  0x64,  0x7e,  0x1a,  0x4f,  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x03,  0x08,  0x61,  0xff,  0x02,
+  0x00,  0x57,  0x64,  0x7e,  0x03,  0x08,  0x61,  0xff,  0x02,  0x00,  0x57,  0x64,  0x7e,  0xfe,  0x0b,  0x58,
+  0x03,  0x0e,  0x52,  0x01,  0x9a,  0x0e,  0x4d,  0x01,  0x9a,  0x03,  0xc6,  0x1a,  0x10,  0xff,  0x03,  0x00,
+  0x54,  0xfe,  0x00,  0xf4,  0x19,  0x64,  0xfe,  0x00,  0x7d,  0xfe,  0x01,  0x7d,  0xfe,  0x02,  0x7d,  0xfe,
+  0x03,  0x7c,  0x62,  0x2d,  0x0f,  0x5a,  0x13,  0x5b,  0x9b,  0x5e,  0x9c,  0x5f,  0x03,  0xfe,  0x62,  0x18,
+  0xfe,  0x82,  0x5a,  0xfe,  0xe1,  0x1a,  0xb4,  0xfe,  0x02,  0x58,  0x03,  0x01,  0xfe,  0x60,  0x18,  0xfe,
+  0x42,  0x48,  0x79,  0x56,  0x7a,  0x01,  0x0a,  0x20,  0xfe,  0xe8,  0x13,  0x23,  0x28,  0xfe,  0xe9,  0x09,
+  0xfe,  0xc1,  0x59,  0x01,  0x0a,  0x20,  0xfe,  0xe8,  0x13,  0x23,  0x28,  0xfe,  0xe8,  0x0a,  0x04,  0xf4,
+  0x2a,  0xfe,  0xc2,  0x12,  0x29,  0xad,  0x1e,  0xde,  0x58,  0xcd,  0x72,  0xfe,  0x38,  0x13,  0x50,  0x08,
+  0x06,  0x07,  0xcd,  0x9f,  0xfe,  0x00,  0x10,  0xfe,  0x78,  0x10,  0xff,  0x02,  0x83,  0x55,  0xa4,  0xff,
+  0x02,  0x83,  0x55,  0xad,  0x18,  0xfe,  0x12,  0x13,  0x70,  0xfe,  0x30,  0x00,  0x91,  0xf0,  0x07,  0x84,
+  0x08,  0x06,  0xfe,  0x56,  0x10,  0xad,  0x0c,  0xfe,  0x16,  0x13,  0x70,  0xfe,  0x64,  0x00,  0x91,  0xf0,
+  0x0e,  0xfe,  0x64,  0x00,  0x07,  0x88,  0x08,  0x06,  0xfe,  0x28,  0x10,  0xad,  0x06,  0xfe,  0x5e,  0x13,
+  0x70,  0xfe,  0xc8,  0x00,  0x91,  0xf0,  0x0e,  0xfe,  0xc8,  0x00,  0x07,  0x54,  0x08,  0x06,  0xd1,  0x70,
+  0xfe,  0x90,  0x01,  0xea,  0xfe,  0x9e,  0x13,  0x7a,  0xa7,  0xfe,  0x43,  0xf4,  0xa9,  0xfe,  0x56,  0xf0,
+  0xfe,  0xb0,  0x13,  0xfe,  0x04,  0xf4,  0x61,  0xfe,  0x43,  0xf4,  0x88,  0xfe,  0xf3,  0x10,  0xac,  0x01,
+  0xfe,  0x7a,  0x12,  0x1a,  0x4f,  0xd3,  0xfe,  0x00,  0x17,  0xfe,  0x4d,  0xe4,  0x87,  0xea,  0xfe,  0xe2,
+  0x13,  0x7a,  0xfe,  0x14,  0x10,  0xfe,  0x00,  0x17,  0xfe,  0x4d,  0xe4,  0x19,  0xea,  0xfe,  0xe2,  0x13,
+  0xc8,  0x19,  0x9d,  0x56,  0x7a,  0x08,  0x06,  0xfe,  0xb4,  0x56,  0xfe,  0xc3,  0x58,  0x03,  0x56,  0x08,
+  0x0c,  0x03,  0x15,  0x06,  0x01,  0x0a,  0x24,  0xdc,  0x15,  0x0c,  0x01,  0x0a,  0x24,  0xdc,  0x15,  0x18,
+  0x01,  0x0a,  0x24,  0xdc,  0x71,  0xfe,  0x89,  0x49,  0x01,  0x0a,  0x03,  0x15,  0x06,  0x01,  0x0a,  0x24,
+  0x90,  0x15,  0x18,  0x01,  0x0a,  0x24,  0x90,  0x15,  0x06,  0x01,  0x0a,  0x24,  0x90,  0xfe,  0x89,  0x49,
+  0x01,  0x0a,  0x24,  0x90,  0x71,  0xfe,  0x89,  0x4a,  0x01,  0x0a,  0x03,  0x56,  0x03,  0x22,  0xe2,  0x05,
+  0x06,  0xfe,  0x44,  0x13,  0xab,  0x16,  0xe2,  0xfe,  0x49,  0xf4,  0x00,  0x50,  0x71,  0xc4,  0x59,  0xfe,
+  0x01,  0xec,  0xfe,  0x27,  0x01,  0xef,  0x01,  0x0a,  0x3d,  0x05,  0xfe,  0xe3,  0x00,  0xfe,  0x20,  0x13,
+  0x20,  0xfe,  0xa0,  0x14,  0x29,  0x16,  0xf1,  0x01,  0x4a,  0x22,  0xf1,  0x05,  0x06,  0x48,  0x0b,  0x49,
+  0x06,  0x37,  0x03,  0x0f,  0x53,  0x13,  0x8a,  0xfe,  0x43,  0x58,  0x01,  0x14,  0x05,  0x10,  0xfe,  0x1e,
+  0x12,  0x45,  0xe6,  0x8f,  0x01,  0x44,  0xfe,  0x90,  0x4d,  0xe0,  0x10,  0xfe,  0xc5,  0x59,  0x01,  0x44,
+  0xfe,  0x8d,  0x56,  0xb4,  0x45,  0x03,  0x45,  0x30,  0x8a,  0x01,  0x14,  0x45,  0x8f,  0x01,  0x44,  0xe4,
+  0x10,  0xe0,  0x10,  0x30,  0x53,  0x70,  0x1c,  0x83,  0x0e,  0x55,  0x01,  0xc0,  0x03,  0x0f,  0x53,  0x13,
+  0x8a,  0xfe,  0xc3,  0x58,  0x01,  0x14,  0x05,  0x10,  0xfe,  0x1a,  0x12,  0x45,  0xe6,  0x8f,  0x01,  0x44,
+  0xe4,  0x10,  0xfe,  0x80,  0x4d,  0xfe,  0xc5,  0x59,  0x01,  0x44,  0x45,  0x03,  0x45,  0x30,  0x53,  0x01,
+  0x14,  0x45,  0x8f,  0x01,  0x44,  0xe4,  0x10,  0xe0,  0x10,  0x30,  0x53,  0x70,  0x1c,  0x83,  0x0e,  0x55,
+  0x01,  0xc0,  0x03,  0x0f,  0x53,  0x13,  0x8a,  0xfe,  0x43,  0x58,  0x01,  0x14,  0xfe,  0x42,  0x48,  0x8f,
+  0x01,  0x44,  0xfe,  0xc0,  0x5a,  0xac,  0xfe,  0x00,  0xcd,  0xfe,  0x01,  0xcc,  0xfe,  0x4a,  0x46,  0xde,
+  0x94,  0x7d,  0x05,  0x10,  0xfe,  0x2e,  0x13,  0x67,  0x53,  0xfe,  0x4d,  0xf4,  0x1c,  0xfe,  0x1c,  0x13,
+  0x0e,  0x55,  0x01,  0x9a,  0xa7,  0xfe,  0x40,  0x4c,  0xfe,  0xc5,  0x58,  0x01,  0x44,  0xfe,  0x00,  0x07,
+  0x7d,  0x05,  0x10,  0x83,  0x67,  0x8a,  0xfe,  0x05,  0x57,  0xfe,  0x08,  0x10,  0xfe,  0x45,  0x58,  0x01,
+  0x44,  0xfe,  0x8d,  0x56,  0xb4,  0xfe,  0x80,  0x4c,  0xfe,  0x05,  0x17,  0x03,  0x07,  0x10,  0x6e,  0x65,
+  0xfe,  0x60,  0x01,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,  0x24,  0x1c,  0xdd,  0x36,  0x96,  0xfe,
+  0xe4,  0x15,  0x01,  0xfe,  0xea,  0x16,  0xfe,  0x0c,  0x13,  0x86,  0x36,  0x65,  0xfe,  0x2c,  0x01,  0xfe,
+  0x2f,  0x19,  0x03,  0xb5,  0x27,  0xfe,  0xd4,  0x15,  0xfe,  0xda,  0x10,  0x07,  0x10,  0x6e,  0x04,  0xfe,
+  0x64,  0x01,  0xfe,  0x00,  0xf4,  0x19,  0xfe,  0x18,  0x58,  0x04,  0xfe,  0x66,  0x01,  0xfe,  0x19,  0x58,
+  0x86,  0x19,  0xfe,  0x3c,  0x90,  0xfe,  0x30,  0xf4,  0x06,  0xfe,  0x3c,  0x50,  0x65,  0xfe,  0x38,  0x00,
+  0xfe,  0x0f,  0x79,  0xfe,  0x1c,  0xf7,  0x19,  0x96,  0xfe,  0x2e,  0x16,  0xfe,  0xb6,  0x14,  0x2f,  0x03,
+  0xb5,  0x27,  0xfe,  0x06,  0x16,  0xfe,  0x9c,  0x10,  0x07,  0x10,  0x6e,  0xb4,  0xfe,  0x18,  0xdf,  0xfe,
+  0x19,  0xdf,  0xdd,  0x3e,  0x96,  0xfe,  0x50,  0x16,  0xfe,  0x94,  0x14,  0xfe,  0x10,  0x13,  0x86,  0x3e,
+  0x65,  0x1e,  0xfe,  0xaf,  0x19,  0xfe,  0x98,  0xe7,  0x00,  0x03,  0xb5,  0x27,  0xfe,  0x44,  0x16,  0xfe,
+  0x6c,  0x10,  0x07,  0x10,  0x6e,  0xfe,  0x30,  0xbc,  0xfe,  0xb2,  0xbc,  0x86,  0xda,  0x65,  0x1e,  0xfe,
+  0x0f,  0x79,  0xfe,  0x1c,  0xf7,  0xda,  0x96,  0xfe,  0x88,  0x16,  0xfe,  0x5c,  0x14,  0x2f,  0x03,  0xb5,
+  0x27,  0xfe,  0x74,  0x16,  0xfe,  0x42,  0x10,  0xfe,  0x02,  0xf6,  0x10,  0x6e,  0xfe,  0x18,  0xfe,  0x5c,
+  0xfe,  0x19,  0xfe,  0x5d,  0xc6,  0xdd,  0x74,  0x96,  0xfe,  0xae,  0x16,  0xfe,  0x36,  0x14,  0xfe,  0x1c,
+  0x13,  0x86,  0x74,  0x4e,  0xfe,  0x83,  0x58,  0xfe,  0xaf,  0x19,  0xfe,  0x80,  0xe7,  0x10,  0xfe,  0x81,
+  0xe7,  0x10,  0x11,  0xfe,  0xdd,  0x00,  0x62,  0x2d,  0x03,  0x62,  0x2d,  0xfe,  0x12,  0x45,  0x27,  0xfe,
+  0x9e,  0x16,  0x17,  0x06,  0x47,  0xf2,  0xdf,  0x02,  0x26,  0xfe,  0x39,  0xf0,  0xfe,  0xf2,  0x16,  0x29,
+  0x03,  0xfe,  0x7e,  0x18,  0x1a,  0x18,  0x82,  0x08,  0x0d,  0x03,  0x6e,  0x04,  0xe1,  0x1a,  0x06,  0xfe,
+  0xef,  0x12,  0xfe,  0xe1,  0x10,  0x1d,  0x0e,  0x1c,  0x01,  0x14,  0x05,  0x10,  0x48,  0x3c,  0xfe,  0x78,
+  0x14,  0xfe,  0x34,  0x12,  0x4f,  0x85,  0x34,  0x36,  0xbc,  0xfe,  0xe9,  0x13,  0x1d,  0x0e,  0x3b,  0x01,
+  0x14,  0x05,  0x10,  0x48,  0x3c,  0x90,  0xe3,  0x4f,  0x85,  0x34,  0x36,  0xbc,  0xfe,  0xe9,  0x13,  0x07,
+  0x0c,  0x03,  0xfe,  0x9c,  0xe7,  0x0c,  0x12,  0xfe,  0x15,  0x00,  0x92,  0x9e,  0x2d,  0x01,  0xd7,  0x07,
+  0x06,  0x03,  0x0b,  0x49,  0x36,  0x37,  0x08,  0x3b,  0x07,  0x99,  0x01,  0x40,  0x11,  0x43,  0x08,  0x1c,
+  0x07,  0x3f,  0x01,  0x76,  0x07,  0x06,  0x03,  0xfe,  0x38,  0x90,  0xfe,  0xba,  0x90,  0x63,  0xf5,  0x30,
+  0x75,  0xfe,  0x48,  0x55,  0x2f,  0xfe,  0xc9,  0x55,  0x03,  0x22,  0xbb,  0x6b,  0x16,  0xbb,  0x03,  0x0e,
+  0xbd,  0x01,  0x14,  0xe5,  0x0e,  0x7c,  0x01,  0x14,  0xfe,  0x49,  0x44,  0x27,  0xfe,  0xe8,  0x17,  0x0e,
+  0x1c,  0x01,  0x14,  0x05,  0x10,  0x48,  0x0e,  0x55,  0x01,  0xc0,  0x0e,  0x7c,  0x01,  0x14,  0x6b,  0x7d,
+  0x03,  0xfe,  0x40,  0x5e,  0xfe,  0xe2,  0x08,  0xfe,  0xc0,  0x4c,  0x22,  0x3a,  0x05,  0x10,  0xfe,  0x52,
+  0x12,  0x3c,  0x05,  0x00,  0xfe,  0x18,  0x12,  0xfe,  0xe1,  0x18,  0xfe,  0x19,  0xf4,  0xfe,  0x7f,  0x00,
+  0xfe,  0x10,  0x13,  0xfe,  0xe2,  0x08,  0x6b,  0x3c,  0x3d,  0x05,  0x75,  0xa3,  0xfe,  0x82,  0x48,  0xfe,
+  0x01,  0x80,  0xfe,  0xd7,  0x10,  0xfe,  0xc4,  0x48,  0x08,  0x2b,  0x07,  0x3a,  0xfe,  0x40,  0x5f,  0x1d,
+  0x01,  0x40,  0x11,  0xfe,  0xdd,  0x00,  0xfe,  0x14,  0x46,  0x08,  0x2b,  0x07,  0x3a,  0x01,  0x40,  0x11,
+  0xfe,  0xdd,  0x00,  0xfe,  0x40,  0x4a,  0x68,  0xfe,  0x06,  0x17,  0xfe,  0x01,  0x07,  0xfe,  0x82,  0x48,
+  0xfe,  0x04,  0x17,  0x03,  0xe9,  0x18,  0x72,  0xfe,  0x70,  0x18,  0x04,  0xfe,  0x90,  0x00,  0xfe,  0x3a,
+  0x45,  0xfe,  0x2c,  0x10,  0xe9,  0xcc,  0x72,  0xfe,  0x82,  0x18,  0x04,  0xfe,  0x92,  0x00,  0xc5,  0x1e,
+  0xd9,  0xe9,  0xfe,  0x0b,  0x00,  0x72,  0xfe,  0x94,  0x18,  0x04,  0xfe,  0x94,  0x00,  0xc5,  0x19,  0xfe,
+  0x08,  0x10,  0x04,  0xfe,  0x96,  0x00,  0xc5,  0x84,  0xfe,  0x4e,  0x45,  0xd2,  0xfe,  0x0a,  0x45,  0xff,
+  0x04,  0x68,  0x54,  0xfe,  0xf1,  0x10,  0x1a,  0x87,  0x03,  0x05,  0xa1,  0xfe,  0x5a,  0xf0,  0xfe,  0xc0,
+  0x18,  0x21,  0xfe,  0x09,  0x00,  0xfe,  0x34,  0x10,  0x05,  0x1e,  0xfe,  0x5a,  0xf0,  0xfe,  0xce,  0x18,
+  0x21,  0xcd,  0xfe,  0x26,  0x10,  0x05,  0x18,  0x82,  0x21,  0x84,  0xd9,  0x05,  0x0c,  0x82,  0x21,  0x88,
+  0xfe,  0x0e,  0x10,  0x05,  0x06,  0x82,  0x21,  0x54,  0xc4,  0xab,  0x03,  0x17,  0xfe,  0x09,  0x00,  0x01,
+  0x38,  0x2c,  0xfe,  0xfe,  0x18,  0x04,  0x6d,  0xac,  0x03,  0x1f,  0xfe,  0x16,  0x19,  0xfe,  0x14,  0xf0,
+  0x0a,  0x2c,  0xfe,  0x12,  0x19,  0x03,  0xff,  0x34,  0x00,  0x00,};
+
+STATIC unsigned short _adv_asc3550_size =
+    sizeof(_adv_asc3550_buf); /* 0x13AA */
+STATIC unsigned long _adv_asc3550_chksum =
+    0x04F4788EUL; /* Expanded checksum. */
+
+STATIC unsigned char _adv_asc38C0800_buf[] = {
+  0x00,  0x00,  0x00,  0xf2,  0x00,  0xf0,  0x00,  0x16,  0x00,  0xfc,  0x48,  0xe4,  0x01,  0x00,  0x00,  0xf6,
+  0x18,  0xe4,  0x01,  0xf6,  0x18,  0x80,  0x02,  0x00,  0x02,  0x1a,  0xff,  0xff,  0x00,  0xfa,  0x03,  0xf6,
+  0xff,  0x00,  0x82,  0xe7,  0x01,  0xfa,  0x9e,  0xe7,  0x09,  0xe7,  0xe6,  0x0e,  0x00,  0xea,  0x01,  0xe6,
+  0x03,  0x00,  0x1e,  0xf0,  0x55,  0xf0,  0x18,  0xf4,  0x3e,  0x57,  0x04,  0x00,  0x3e,  0x01,  0x85,  0xf0,
+  0x00,  0xe6,  0x03,  0xfc,  0x08,  0x00,  0x32,  0xf0,  0x38,  0x54,  0x84,  0x0d,  0x86,  0xf0,  0xd4,  0x01,
+  0xd5,  0xf0,  0xee,  0x19,  0x00,  0xec,  0x01,  0xfc,  0x98,  0x57,  0xbc,  0x00,  0x10,  0x13,  0xb1,  0xf0,
+  0x02,  0x13,  0x3c,  0x00,  0x7e,  0x0d,  0xb4,  0x00,  0x00,  0x57,  0x01,  0xf0,  0x02,  0xfc,  0x03,  0xe6,
+  0x0c,  0x1c,  0x10,  0x00,  0x18,  0x40,  0x3e,  0x1c,  0xbd,  0x00,  0xe0,  0x00,  0x02,  0x80,  0x3e,  0x00,
+  0x46,  0x16,  0x4a,  0x10,  0x6c,  0x01,  0x6e,  0x01,  0x74,  0x01,  0x76,  0x01,  0xb9,  0x54,  0xba,  0x13,
+  0xbb,  0x00,  0x00,  0x4e,  0x01,  0x01,  0x01,  0xea,  0x02,  0x48,  0x02,  0xfa,  0x08,  0x12,  0x30,  0xe4,
+  0x3c,  0x56,  0x4e,  0x01,  0x5d,  0xf0,  0x7a,  0x01,  0x88,  0x0d,  0x8e,  0x10,  0xb6,  0x00,  0xc4,  0x08,
+  0x00,  0x80,  0x04,  0x12,  0x05,  0xfc,  0x24,  0x01,  0x28,  0x01,  0x32,  0x00,  0x3c,  0x01,  0x40,  0x00,
+  0x4b,  0xe4,  0x4b,  0xf4,  0x4c,  0x1c,  0x68,  0x01,  0x6a,  0x01,  0x70,  0x01,  0x72,  0x01,  0x78,  0x01,
+  0x7c,  0x01,  0xbb,  0x55,  0x00,  0x01,  0x02,  0xee,  0x03,  0x58,  0x03,  0xf7,  0x03,  0xfa,  0x04,  0x80,
+  0x08,  0x44,  0x09,  0xf0,  0x10,  0x44,  0x1b,  0x80,  0x20,  0x01,  0x38,  0x1c,  0x4e,  0x1c,  0x5b,  0xf0,
+  0x80,  0x00,  0x8a,  0x15,  0x98,  0x10,  0xaa,  0x00,  0xbd,  0x56,  0xbe,  0x00,  0xc0,  0x00,  0x00,  0x4c,
+  0x00,  0xdc,  0x02,  0x4a,  0x04,  0xfc,  0x05,  0xf0,  0x05,  0xf8,  0x06,  0x13,  0x06,  0xf7,  0x08,  0x13,
+  0x0c,  0x00,  0x0e,  0x47,  0x0e,  0xf7,  0x0f,  0x00,  0x1c,  0x0c,  0x20,  0x00,  0x2a,  0x01,  0x32,  0x1c,
+  0x36,  0x00,  0x42,  0x54,  0x44,  0x0b,  0x44,  0x55,  0x45,  0x5a,  0x59,  0xf0,  0x5c,  0xf0,  0x62,  0x0a,
+  0x69,  0x08,  0x78,  0x13,  0x83,  0x59,  0x8e,  0x18,  0x9a,  0x10,  0x9a,  0x18,  0xb8,  0xf0,  0xd6,  0x0e,
+  0xea,  0x15,  0xf0,  0x00,  0x04,  0x10,  0x04,  0xea,  0x04,  0xf6,  0x05,  0x00,  0x06,  0x00,  0x06,  0x12,
+  0x0a,  0x10,  0x0a,  0x12,  0x0b,  0xf0,  0x0c,  0x10,  0x0c,  0xf0,  0x12,  0x10,  0x19,  0x00,  0x19,  0xe4,
+  0x2a,  0x12,  0x30,  0x1c,  0x33,  0x00,  0x34,  0x00,  0x36,  0x15,  0x38,  0x44,  0x3a,  0x15,  0x40,  0x5c,
+  0x4a,  0xe4,  0x62,  0x1a,  0x68,  0x08,  0x68,  0x54,  0x7a,  0x17,  0x83,  0x55,  0x83,  0x5a,  0x91,  0x44,
+  0xa2,  0x10,  0xa4,  0x00,  0xb0,  0x57,  0xb5,  0x00,  0xba,  0x00,  0xcc,  0x0e,  0xce,  0x45,  0xd0,  0x00,
+  0xe1,  0x00,  0xe5,  0x55,  0xe7,  0x00,  0x00,  0x54,  0x01,  0x48,  0x01,  0x58,  0x02,  0x10,  0x02,  0xe6,
+  0x03,  0xa1,  0x04,  0x13,  0x05,  0xe6,  0x06,  0x83,  0x06,  0xf0,  0x07,  0x00,  0x0a,  0x00,  0x0a,  0xf0,
+  0x0c,  0x12,  0x0c,  0x13,  0x0e,  0x13,  0x10,  0x04,  0x10,  0x10,  0x12,  0x1c,  0x19,  0x81,  0x1a,  0x10,
+  0x1c,  0x00,  0x1c,  0x12,  0x1c,  0x13,  0x1d,  0xf7,  0x1e,  0x13,  0x20,  0x1c,  0x20,  0xe7,  0x22,  0x01,
+  0x26,  0x01,  0x30,  0xe7,  0x38,  0x12,  0x3a,  0x55,  0x3f,  0x00,  0x41,  0x58,  0x43,  0x48,  0x46,  0x1c,
+  0x4e,  0xe4,  0x5a,  0x13,  0x68,  0x13,  0x72,  0x14,  0x76,  0x02,  0x77,  0x57,  0x78,  0x03,  0x89,  0x48,
+  0x8a,  0x13,  0x98,  0x80,  0x99,  0x00,  0x9b,  0x00,  0x9c,  0x32,  0xfe,  0x9c,  0xf0,  0x27,  0x02,  0xfe,
+  0xa6,  0x0d,  0xff,  0x10,  0x00,  0x00,  0xfe,  0xc6,  0x01,  0xfe,  0x18,  0x1a,  0x00,  0xfe,  0xc4,  0x01,
+  0xfe,  0x84,  0x01,  0xff,  0x03,  0x00,  0x00,  0x30,  0xfe,  0x01,  0x05,  0xff,  0x40,  0x00,  0x00,  0x0d,
+  0xff,  0x09,  0x00,  0x00,  0xff,  0x08,  0x01,  0x01,  0xff,  0x10,  0xff,  0xff,  0xff,  0x1f,  0x00,  0x00,
+  0xff,  0x10,  0xff,  0xff,  0xff,  0x11,  0x00,  0x00,  0xfe,  0x78,  0x56,  0xfe,  0x34,  0x12,  0xff,  0x21,
+  0x00,  0x00,  0xfe,  0x04,  0xf7,  0xfe,  0xc4,  0x01,  0x38,  0x86,  0x0b,  0x01,  0xfe,  0x96,  0x0f,  0xfe,
+  0x04,  0xf7,  0xfe,  0xc4,  0x01,  0x86,  0x0b,  0x1c,  0x38,  0xfe,  0x3d,  0xf0,  0xfe,  0xfc,  0x01,  0xfe,
+  0x20,  0xf0,  0xdb,  0x04,  0x5e,  0x59,  0x02,  0xfe,  0xc2,  0x0d,  0x01,  0xfe,  0x22,  0x0e,  0xfe,  0xe9,
+  0x12,  0x02,  0xfe,  0x08,  0x03,  0xfe,  0x28,  0x1c,  0x04,  0xfe,  0xa6,  0x00,  0xfe,  0xdd,  0x12,  0x46,
+  0x12,  0xfe,  0xa6,  0x00,  0xcd,  0xfe,  0x48,  0xf0,  0xfe,  0x80,  0x02,  0xfe,  0x49,  0xf0,  0xfe,  0x9a,
+  0x02,  0xfe,  0x4a,  0xf0,  0xfe,  0xb8,  0x02,  0xfe,  0x46,  0xf0,  0xfe,  0x4a,  0x02,  0xfe,  0x47,  0xf0,
+  0xfe,  0x50,  0x02,  0xfe,  0x43,  0xf0,  0xfe,  0x3e,  0x02,  0xfe,  0x44,  0xf0,  0xfe,  0x42,  0x02,  0xfe,
+  0x45,  0xf0,  0xfe,  0x46,  0x02,  0x09,  0x0b,  0xa2,  0x09,  0x06,  0x12,  0xc1,  0x02,  0x27,  0xfe,  0x00,
+  0x1c,  0xfe,  0xf1,  0x10,  0xfe,  0x02,  0x1c,  0xfe,  0xed,  0x10,  0xfe,  0x1e,  0x1c,  0xfe,  0xe9,  0x10,
+  0x01,  0xfe,  0xee,  0x17,  0xfe,  0xe7,  0x10,  0xfe,  0x06,  0xfc,  0xfe,  0xa8,  0x00,  0x0f,  0x7d,  0x01,
+  0xc5,  0x02,  0x27,  0x17,  0x5d,  0x4b,  0xc3,  0x01,  0xab,  0x0f,  0x7d,  0x01,  0x9f,  0xfe,  0xbd,  0x10,
+  0x0f,  0x7d,  0x01,  0x9f,  0xfe,  0xad,  0x10,  0xfe,  0x16,  0x1c,  0xfe,  0x58,  0x1c,  0x09,  0x06,  0x12,
+  0xc1,  0x38,  0x19,  0x27,  0xfe,  0x3d,  0xf0,  0xfe,  0xfc,  0x01,  0x28,  0xfe,  0x8e,  0x02,  0xfe,  0x5a,
+  0x1c,  0xdd,  0xfe,  0x14,  0x1c,  0x17,  0xfe,  0x30,  0x00,  0x4b,  0xc3,  0x01,  0xfe,  0xfc,  0x0f,  0x09,
+  0x06,  0x12,  0xc1,  0x02,  0xfe,  0xc6,  0x01,  0x2a,  0x2d,  0x05,  0x10,  0x30,  0xfe,  0x69,  0x10,  0x09,
+  0x06,  0x12,  0xc1,  0xfe,  0x04,  0xec,  0x2d,  0x07,  0x2d,  0x09,  0x3c,  0x1c,  0x01,  0x40,  0x81,  0xfe,
+  0x05,  0xf6,  0xfe,  0xa8,  0x00,  0x01,  0xfe,  0x20,  0x17,  0x0a,  0x4f,  0x8d,  0x3a,  0x11,  0x48,  0x1c,
+  0xd3,  0x07,  0x1e,  0x09,  0x51,  0x01,  0xa0,  0x02,  0x27,  0x0f,  0x3d,  0x01,  0x15,  0x05,  0x10,  0xda,
+  0x07,  0x1e,  0x09,  0x51,  0x01,  0x79,  0xfe,  0x28,  0x10,  0x0f,  0xc7,  0x01,  0x15,  0xed,  0x0f,  0x7e,
+  0x01,  0x15,  0xfe,  0x49,  0x54,  0x77,  0xfe,  0x16,  0x03,  0x07,  0x1e,  0x09,  0x51,  0x01,  0xa0,  0x02,
+  0x27,  0x38,  0x81,  0xfe,  0x02,  0xe8,  0x33,  0xfe,  0xbf,  0x57,  0xfe,  0x9e,  0x43,  0xf5,  0xfe,  0x07,
+  0x4b,  0xfe,  0x20,  0xf0,  0xdb,  0xfe,  0x40,  0x1c,  0x19,  0xf6,  0xfe,  0x26,  0xf0,  0xfe,  0x74,  0x03,
+  0xfe,  0xa0,  0xf0,  0xfe,  0x62,  0x03,  0xfe,  0x11,  0xf0,  0xdb,  0xfe,  0x0e,  0x10,  0xfe,  0x9f,  0xf0,
+  0xfe,  0x82,  0x03,  0xef,  0x13,  0xfe,  0x11,  0x00,  0x02,  0x54,  0x38,  0xfe,  0x48,  0x1c,  0xef,  0x19,
+  0xf6,  0x35,  0xf6,  0xfe,  0x82,  0xf0,  0xfe,  0x88,  0x03,  0x24,  0x2a,  0xc4,  0x70,  0x16,  0xc4,  0x0f,
+  0x7e,  0x01,  0x15,  0x70,  0x7f,  0x07,  0x1e,  0x09,  0x51,  0x01,  0x40,  0x11,  0x3d,  0x07,  0x3d,  0x09,
+  0xa1,  0x01,  0xa0,  0xfc,  0x11,  0xfe,  0xe4,  0x00,  0x2f,  0xfe,  0xce,  0x03,  0x19,  0x32,  0x1f,  0xfe,
+  0xde,  0x03,  0x01,  0x41,  0xd4,  0xfe,  0xee,  0x03,  0x71,  0x8c,  0xd7,  0xfe,  0xae,  0x06,  0x02,  0x25,
+  0x04,  0x7d,  0x2c,  0x1a,  0xfe,  0x20,  0x05,  0x17,  0x88,  0x01,  0x2e,  0x01,  0x9b,  0x01,  0x9d,  0x35,
+  0xfe,  0x60,  0x02,  0x02,  0xf4,  0xef,  0x38,  0x86,  0x18,  0xfe,  0x67,  0x1b,  0xfe,  0xbf,  0x57,  0xf5,
+  0xfe,  0x48,  0x1c,  0x8f,  0x01,  0xf2,  0xb1,  0xfe,  0x96,  0xf0,  0xfe,  0x28,  0x04,  0x2f,  0xfe,  0x2c,
+  0x04,  0x35,  0x27,  0x0f,  0x3d,  0x01,  0x15,  0x05,  0x10,  0x1a,  0xfe,  0x0c,  0x05,  0x4c,  0x97,  0xa3,
+  0x33,  0x84,  0x74,  0x19,  0x32,  0x1f,  0x25,  0x04,  0x7d,  0x2c,  0xfe,  0x10,  0x12,  0x17,  0x88,  0x01,
+  0x2e,  0x35,  0xfe,  0x60,  0x02,  0x02,  0xf4,  0x21,  0xfe,  0xa0,  0x00,  0xfe,  0x9b,  0x57,  0xfe,  0x5e,
+  0x12,  0x0a,  0x08,  0x06,  0xfe,  0x56,  0x12,  0x23,  0x29,  0x98,  0x01,  0x0c,  0x84,  0x74,  0x1f,  0xfe,
+  0xdc,  0x04,  0x23,  0x29,  0x98,  0x01,  0x0c,  0x1f,  0x25,  0x23,  0x29,  0xba,  0xfe,  0x4c,  0x44,  0xfe,
+  0x32,  0x12,  0x50,  0xfe,  0x44,  0x48,  0x07,  0xfe,  0x93,  0x00,  0xfe,  0x4c,  0x54,  0x77,  0xfe,  0x0c,
+  0x05,  0x81,  0xa3,  0x33,  0xfe,  0x06,  0x80,  0xfe,  0x48,  0x47,  0xfe,  0x48,  0x13,  0x3e,  0x05,  0xfe,
+  0xcc,  0x00,  0xfe,  0x40,  0x13,  0x0a,  0x08,  0x06,  0xea,  0xfe,  0x06,  0x10,  0x23,  0x29,  0xba,  0x0a,
+  0x08,  0x39,  0xe1,  0x17,  0xa6,  0x0a,  0x08,  0x06,  0x59,  0x17,  0xfe,  0x0d,  0x00,  0x01,  0x2e,  0x35,
+  0xfe,  0x66,  0x0d,  0x02,  0x25,  0x3b,  0x11,  0xfe,  0xe6,  0x00,  0xfe,  0x1c,  0x90,  0xb7,  0x03,  0x17,
+  0xa6,  0x01,  0x2e,  0x35,  0x27,  0x19,  0x27,  0x02,  0xfe,  0x14,  0x05,  0xfe,  0x42,  0x5b,  0x86,  0x18,
+  0xfe,  0x46,  0x59,  0xfe,  0xbf,  0x57,  0xf5,  0x17,  0x78,  0xfe,  0x07,  0x80,  0xfe,  0x31,  0x44,  0x0a,
+  0x08,  0x0b,  0x99,  0xfe,  0x20,  0x80,  0x05,  0x18,  0xfe,  0x70,  0x12,  0x73,  0x08,  0x06,  0xfe,  0x60,
+  0x13,  0x04,  0xfe,  0xa2,  0x00,  0x2c,  0x1a,  0xfe,  0xac,  0x05,  0xfe,  0x31,  0xe4,  0x5f,  0x73,  0x08,
+  0x0b,  0xfe,  0x4a,  0x13,  0x04,  0xfe,  0xa0,  0x00,  0x2c,  0xfe,  0x42,  0x12,  0x62,  0x2f,  0xfe,  0x6c,
+  0x05,  0x19,  0x32,  0xf7,  0x01,  0x0c,  0x26,  0xfe,  0xc4,  0x05,  0x11,  0xfe,  0xe3,  0x00,  0x24,  0x73,
+  0xfe,  0x4a,  0xf0,  0xfe,  0x96,  0x05,  0xfe,  0x49,  0xf0,  0xfe,  0x90,  0x05,  0xab,  0x20,  0xfe,  0x21,
+  0x00,  0xa8,  0x20,  0xfe,  0x22,  0x00,  0xa2,  0x20,  0x8d,  0xfe,  0x09,  0x48,  0x01,  0x0c,  0x26,  0xfe,
+  0xc4,  0x05,  0xfe,  0xe2,  0x08,  0x73,  0x08,  0xe0,  0x59,  0x01,  0x99,  0x20,  0x06,  0x16,  0xe8,  0x4b,
+  0xfe,  0x27,  0x01,  0x0a,  0x08,  0x39,  0xb0,  0x46,  0x01,  0xb6,  0x17,  0xa6,  0x0a,  0x08,  0x06,  0x59,
+  0x17,  0xfe,  0x0d,  0x00,  0x01,  0x2e,  0x01,  0x9b,  0x01,  0x9d,  0x35,  0xfe,  0x66,  0x0d,  0x02,  0x25,
+  0x04,  0xfe,  0x9c,  0x00,  0x2c,  0xfe,  0x3e,  0x12,  0x04,  0x5b,  0x2c,  0xfe,  0x36,  0x13,  0x46,  0x01,
+  0xb6,  0x26,  0xfe,  0x3c,  0x06,  0x0f,  0x06,  0x73,  0x08,  0x22,  0xfe,  0x02,  0x12,  0x69,  0x01,  0xfe,
+  0xd0,  0x14,  0x1f,  0xfe,  0x32,  0x06,  0x11,  0xc8,  0x01,  0x41,  0x11,  0xfe,  0xe5,  0x00,  0x04,  0x5b,
+  0xc2,  0x0e,  0x5b,  0x04,  0xfe,  0x9e,  0x00,  0x2c,  0xfe,  0x62,  0x12,  0x04,  0x56,  0x2c,  0xf1,  0x01,
+  0xfe,  0x40,  0x19,  0x01,  0xfe,  0xaa,  0x19,  0xee,  0xd2,  0xec,  0x07,  0x6a,  0xff,  0x02,  0x00,  0x57,
+  0x6c,  0x80,  0x1b,  0x58,  0xd1,  0xd2,  0x8b,  0x46,  0x01,  0xb6,  0x26,  0xfe,  0xa6,  0x06,  0x73,  0x08,
+  0x1d,  0xa7,  0x7c,  0x0f,  0x5d,  0x01,  0xfe,  0xfe,  0x14,  0x1f,  0xfe,  0x9c,  0x06,  0x11,  0xc8,  0x01,
+  0x41,  0x11,  0xfe,  0xe5,  0x00,  0x04,  0x56,  0xc2,  0x0e,  0x56,  0x09,  0x06,  0x01,  0xb6,  0xfc,  0x76,
+  0x8f,  0x01,  0xf2,  0xb1,  0x11,  0xfe,  0xe2,  0x00,  0x2f,  0xfe,  0xbe,  0x06,  0x19,  0x32,  0xd7,  0xfe,
+  0xda,  0x06,  0x83,  0xfe,  0x78,  0x07,  0xd4,  0xfe,  0x80,  0x07,  0x71,  0x8c,  0x02,  0x25,  0x0a,  0x08,
+  0x0b,  0xfe,  0x2e,  0x12,  0x14,  0x18,  0x01,  0x0c,  0x14,  0x00,  0x01,  0x0c,  0x14,  0x00,  0x01,  0x0c,
+  0x14,  0x00,  0x01,  0x0c,  0xfe,  0x99,  0xa4,  0x01,  0x0c,  0x14,  0x00,  0x02,  0xfe,  0x3e,  0x08,  0x6f,
+  0x08,  0x1d,  0xea,  0x0a,  0x08,  0x1d,  0xfe,  0x30,  0x13,  0x14,  0xfe,  0x1b,  0x00,  0x01,  0x0c,  0x14,
+  0x00,  0x01,  0x0c,  0x14,  0x00,  0x01,  0x0c,  0x14,  0x00,  0x01,  0x0c,  0x14,  0x06,  0x01,  0x0c,  0x14,
+  0x00,  0x02,  0xfe,  0xe6,  0x0b,  0x69,  0xfe,  0x9a,  0x81,  0x6d,  0x8d,  0xfe,  0x09,  0x6f,  0xfe,  0x93,
+  0x45,  0x1a,  0xfe,  0x88,  0x07,  0x2f,  0xfe,  0x60,  0x07,  0x19,  0x32,  0xd7,  0xfe,  0x58,  0x07,  0x71,
+  0x8c,  0x83,  0xfe,  0x78,  0x07,  0x02,  0x25,  0x01,  0x41,  0x02,  0xfe,  0xbe,  0x06,  0x14,  0x22,  0x02,
+  0xfe,  0xbe,  0x06,  0xfe,  0x9c,  0xf7,  0xfe,  0xf4,  0x07,  0xfe,  0x2c,  0x90,  0xfe,  0xae,  0x90,  0x52,
+  0xfe,  0xd6,  0x07,  0x0e,  0x65,  0x12,  0x66,  0x0a,  0x4f,  0x5f,  0x3a,  0x01,  0xfe,  0xd6,  0x18,  0x05,
+  0x10,  0x85,  0xfe,  0x83,  0xe7,  0xfe,  0x95,  0x00,  0xa8,  0xfe,  0x03,  0x40,  0x0a,  0x4f,  0x78,  0x3a,
+  0x01,  0xbc,  0xb5,  0xfe,  0x1f,  0x40,  0x16,  0x67,  0x01,  0xf8,  0xfe,  0x08,  0x50,  0xfe,  0x8a,  0x50,
+  0xfe,  0x34,  0x51,  0xfe,  0xb6,  0x51,  0xfe,  0x08,  0x90,  0xfe,  0x8a,  0x90,  0x0e,  0x63,  0x12,  0x64,
+  0xfe,  0x0c,  0x90,  0xfe,  0x8e,  0x90,  0xfe,  0x28,  0x50,  0xfe,  0xaa,  0x50,  0x0e,  0x42,  0x12,  0x43,
+  0x41,  0x0a,  0x08,  0x5f,  0xb0,  0xfe,  0x2c,  0x90,  0xfe,  0xae,  0x90,  0x0e,  0x65,  0x12,  0x66,  0x0a,
+  0x08,  0x78,  0xd1,  0x01,  0xbc,  0xfe,  0x1f,  0x80,  0x16,  0x67,  0xfe,  0x34,  0x90,  0xfe,  0xb6,  0x90,
+  0x0e,  0x44,  0x12,  0x45,  0xfe,  0x08,  0x90,  0xfe,  0x8a,  0x90,  0x0e,  0x63,  0x12,  0x64,  0xfe,  0x28,
+  0x90,  0xfe,  0xaa,  0x90,  0x0e,  0x42,  0x12,  0x43,  0x0e,  0x31,  0x12,  0x3f,  0x24,  0x0e,  0x53,  0x0e,
+  0x68,  0x0a,  0x4f,  0x22,  0x3a,  0x38,  0x07,  0xa5,  0x2f,  0xfe,  0x5e,  0x08,  0xfe,  0x9e,  0xf0,  0xfe,
+  0x72,  0x08,  0xcc,  0x1a,  0x32,  0x38,  0x72,  0xfe,  0xed,  0x10,  0xaa,  0xfe,  0x96,  0x08,  0xac,  0xfe,
+  0xb2,  0x08,  0x83,  0xfe,  0x8a,  0x08,  0xd4,  0xfe,  0x90,  0x08,  0x71,  0x8c,  0x02,  0x25,  0x01,  0x41,
+  0xfe,  0xc9,  0x10,  0x14,  0x22,  0xfe,  0xc9,  0x10,  0x6f,  0x08,  0x06,  0xfe,  0x10,  0x12,  0x6f,  0x08,
+  0x0b,  0x4e,  0x0a,  0x08,  0x0b,  0xfe,  0x8e,  0x12,  0xfe,  0x2e,  0x1c,  0xad,  0x6f,  0x08,  0x06,  0x4e,
+  0x6f,  0x08,  0x0b,  0xfe,  0x7a,  0x12,  0xfe,  0x2c,  0x1c,  0xfe,  0xaa,  0xf0,  0xfe,  0xcc,  0x09,  0xfe,
+  0xac,  0xf0,  0xfe,  0xfa,  0x08,  0x02,  0xfe,  0xd8,  0x09,  0xfe,  0xb7,  0xf0,  0xfe,  0xf6,  0x08,  0xfe,
+  0x02,  0xf6,  0x1d,  0x69,  0xfe,  0x70,  0x18,  0xfe,  0xf1,  0x18,  0xfe,  0x40,  0x55,  0xfe,  0xe1,  0x55,
+  0xfe,  0x10,  0x58,  0xfe,  0x91,  0x58,  0xfe,  0x14,  0x59,  0xfe,  0x95,  0x59,  0x19,  0x92,  0xfe,  0x8c,
+  0xf0,  0xfe,  0xf6,  0x08,  0xfe,  0xac,  0xf0,  0xfe,  0xea,  0x08,  0xfe,  0x34,  0x1c,  0xfe,  0xcb,  0x10,
+  0xfe,  0xad,  0xf0,  0xfe,  0x06,  0x09,  0x02,  0xfe,  0x12,  0x0b,  0xfe,  0x36,  0x1c,  0xfe,  0xbf,  0x10,
+  0xfe,  0x2b,  0xf0,  0x92,  0xfe,  0x6b,  0x18,  0x1b,  0xfe,  0x00,  0xfe,  0xe1,  0xcd,  0xfe,  0xd2,  0xf0,
+  0x92,  0xfe,  0x76,  0x18,  0x1b,  0x18,  0x1a,  0x92,  0x04,  0xe7,  0x1b,  0x06,  0x1a,  0x92,  0xaa,  0x57,
+  0xac,  0x57,  0xfe,  0x34,  0x1c,  0xfe,  0x36,  0x1c,  0xfe,  0x89,  0x10,  0x8f,  0x62,  0x3b,  0x17,  0xa6,
+  0x01,  0x2e,  0x13,  0xfe,  0x35,  0x00,  0x35,  0x54,  0x13,  0x90,  0x02,  0x54,  0xf9,  0xaf,  0x0b,  0xfe,
+  0x1a,  0x12,  0x50,  0xfe,  0x19,  0x82,  0xfe,  0x6c,  0x18,  0xfe,  0x44,  0x54,  0xeb,  0xde,  0xfe,  0x74,
+  0x18,  0x91,  0x93,  0x1a,  0xfe,  0xc8,  0x08,  0x02,  0x57,  0x0a,  0x08,  0x5f,  0x2e,  0x04,  0x31,  0x2b,
+  0x3f,  0x0e,  0x44,  0x12,  0x45,  0x82,  0x31,  0x5a,  0x3f,  0xfe,  0x6c,  0x18,  0xfe,  0xed,  0x18,  0xfe,
+  0x44,  0x54,  0xfe,  0xe5,  0x54,  0x36,  0x44,  0x21,  0x45,  0x04,  0x53,  0x2b,  0x68,  0x91,  0xfe,  0xe3,
+  0x54,  0xfe,  0x74,  0x18,  0xfe,  0xf5,  0x18,  0x91,  0xfe,  0xe3,  0x54,  0x93,  0xc9,  0x52,  0xfe,  0xc8,
+  0x08,  0x02,  0x57,  0xfe,  0x37,  0xf0,  0xfe,  0xd4,  0x09,  0xfe,  0x8b,  0xf0,  0xfe,  0x5a,  0x09,  0x02,
+  0x57,  0xf9,  0xaf,  0x0b,  0x28,  0xfe,  0xf4,  0x0a,  0x36,  0x53,  0x21,  0x68,  0x52,  0xfe,  0x38,  0x0a,
+  0x07,  0xfe,  0xc0,  0x07,  0x46,  0x61,  0x00,  0xd9,  0xfe,  0x01,  0x59,  0xfe,  0x52,  0xf0,  0xfe,  0x06,
+  0x0a,  0x91,  0x96,  0xfe,  0x1e,  0x0a,  0x36,  0x53,  0x91,  0xfe,  0xe3,  0x54,  0x4d,  0x53,  0x6e,  0x68,
+  0xfe,  0x14,  0x58,  0xfe,  0x95,  0x58,  0x02,  0x57,  0x36,  0x53,  0x21,  0x68,  0xfe,  0x14,  0x59,  0xfe,
+  0x95,  0x59,  0xeb,  0x4d,  0x53,  0x4d,  0x68,  0x02,  0x57,  0x0a,  0x08,  0x5f,  0xfe,  0x82,  0x12,  0x0a,
+  0x08,  0x22,  0xfe,  0x66,  0x13,  0x2a,  0x67,  0x70,  0xd0,  0xfe,  0x83,  0x80,  0xfe,  0xc8,  0x44,  0xfe,
+  0x2e,  0x13,  0xfe,  0x04,  0x91,  0xfe,  0x86,  0x91,  0x6b,  0x33,  0xfe,  0x40,  0x59,  0xfe,  0xc1,  0x59,
+  0x52,  0xfe,  0xd0,  0x08,  0x04,  0x65,  0x2b,  0x66,  0x0e,  0xb3,  0x12,  0x90,  0x4d,  0x65,  0x6e,  0x66,
+  0x01,  0xbc,  0xb5,  0x6b,  0x33,  0x16,  0x67,  0x82,  0x31,  0x5a,  0x3f,  0x36,  0x44,  0x21,  0x45,  0x93,
+  0xc9,  0xfe,  0x04,  0xfa,  0x31,  0xfe,  0x05,  0xfa,  0x3f,  0x01,  0xf8,  0xfe,  0x36,  0x10,  0x24,  0x0e,
+  0xb3,  0x0e,  0x90,  0x36,  0x44,  0x21,  0x45,  0xad,  0x0a,  0x08,  0x22,  0x1a,  0xfe,  0xd0,  0x08,  0x36,
+  0x42,  0x21,  0x43,  0x0a,  0x08,  0xfe,  0xf7,  0x00,  0x3a,  0x04,  0x63,  0x2b,  0x64,  0xfe,  0x10,  0x58,
+  0xfe,  0x91,  0x58,  0x4d,  0x53,  0x6e,  0x68,  0x02,  0xfe,  0xee,  0x09,  0x0a,  0x08,  0x22,  0x1a,  0xfe,
+  0xd0,  0x08,  0x0a,  0x08,  0xfe,  0xf7,  0x00,  0x3a,  0xeb,  0xde,  0x69,  0xfe,  0x10,  0x90,  0xfe,  0x92,
+  0x90,  0xfe,  0xd3,  0x10,  0x3e,  0x05,  0xca,  0x1a,  0xfe,  0x02,  0x09,  0x11,  0xca,  0xf9,  0xaf,  0x0b,
+  0xfe,  0x14,  0x13,  0x04,  0x42,  0x2b,  0x43,  0x52,  0xfe,  0x02,  0x09,  0xfe,  0x0c,  0x58,  0xfe,  0x8d,
+  0x58,  0x02,  0x57,  0x24,  0x46,  0xfe,  0x19,  0x80,  0xfe,  0xf1,  0x10,  0x0a,  0x08,  0x0b,  0xa7,  0xfe,
+  0x6c,  0x19,  0xfe,  0x19,  0x41,  0xfe,  0x94,  0x10,  0xfe,  0x6c,  0x19,  0x4d,  0x42,  0xfe,  0xed,  0x19,
+  0x6e,  0x43,  0xfe,  0x0c,  0x51,  0xfe,  0x8e,  0x51,  0xfe,  0x6b,  0x18,  0x1b,  0xfe,  0x00,  0xff,  0x30,
+  0xfe,  0x7a,  0x10,  0xcd,  0xfe,  0xd2,  0xf0,  0xfe,  0x8c,  0x0b,  0xfe,  0x76,  0x18,  0x1b,  0x18,  0xa9,
+  0x04,  0xe7,  0x1b,  0x06,  0x87,  0x13,  0xfe,  0x16,  0x00,  0x02,  0x54,  0xfe,  0xd1,  0xf0,  0xfe,  0xc2,
+  0x0b,  0x17,  0xa5,  0x01,  0x2e,  0x13,  0xfe,  0x17,  0x00,  0xfe,  0x48,  0x10,  0xfe,  0xce,  0xf0,  0xfe,
+  0xaa,  0x0b,  0x13,  0xfe,  0x21,  0x00,  0x02,  0x54,  0xfe,  0xcd,  0xf0,  0xfe,  0xb6,  0x0b,  0x13,  0xfe,
+  0x22,  0x00,  0x02,  0x54,  0xfe,  0xcb,  0xf0,  0xfe,  0xc2,  0x0b,  0x13,  0xfe,  0x24,  0x00,  0x02,  0x54,
+  0xfe,  0xd0,  0xf0,  0xfe,  0xcc,  0x0b,  0x13,  0xae,  0xdf,  0xfe,  0xcf,  0xf0,  0xfe,  0xd6,  0x0b,  0x13,
+  0x8d,  0xdc,  0xfe,  0xcc,  0xf0,  0xfe,  0xe6,  0x0b,  0xfe,  0x84,  0x80,  0xaf,  0x22,  0xfe,  0xd5,  0x12,
+  0x13,  0xfe,  0x12,  0x00,  0x2f,  0xfe,  0xe6,  0x0b,  0x19,  0x32,  0xaa,  0x25,  0xac,  0x25,  0x38,  0xfc,
+  0x2f,  0xfe,  0xfa,  0x0b,  0x19,  0x32,  0x83,  0xfe,  0x16,  0x0c,  0x71,  0x8c,  0xaa,  0xfe,  0xf4,  0x07,
+  0xac,  0xfe,  0xf4,  0x07,  0x02,  0x25,  0x01,  0x41,  0xfe,  0xdb,  0x10,  0x11,  0xfe,  0xe8,  0x00,  0x8f,
+  0x84,  0x74,  0xfe,  0x89,  0xf0,  0x25,  0x23,  0x29,  0xfe,  0xe9,  0x09,  0x01,  0x0c,  0x84,  0x74,  0x1f,
+  0x25,  0x23,  0x29,  0x98,  0x35,  0xfe,  0x4e,  0x0c,  0x19,  0x32,  0x02,  0xfe,  0x42,  0x0c,  0xcc,  0x4e,
+  0x13,  0xfe,  0x42,  0x00,  0x02,  0x54,  0xa4,  0x06,  0xfe,  0x81,  0x49,  0xfe,  0xcc,  0x12,  0x0a,  0x08,
+  0x0b,  0xf1,  0x13,  0x00,  0x60,  0x0b,  0xfe,  0x6a,  0x12,  0x60,  0xfe,  0x28,  0x00,  0x28,  0xfe,  0x94,
+  0x0d,  0x0f,  0x7e,  0x01,  0x15,  0x05,  0x00,  0x87,  0x37,  0xfe,  0x28,  0x00,  0x02,  0xfe,  0x94,  0x0d,
+  0x01,  0x9b,  0x01,  0x9d,  0x0f,  0xc7,  0x01,  0xfe,  0xf0,  0x0e,  0xb9,  0x07,  0x3d,  0x09,  0xa1,  0x01,
+  0x40,  0x11,  0x48,  0x07,  0x1e,  0x09,  0x51,  0x01,  0x79,  0x02,  0x27,  0x13,  0xfe,  0x44,  0x00,  0x60,
+  0x0b,  0xa7,  0x37,  0x0b,  0xfe,  0xc0,  0x10,  0x01,  0x99,  0x37,  0x0b,  0xfe,  0xb6,  0x10,  0x01,  0x99,
+  0xfe,  0x19,  0x82,  0xfe,  0x34,  0x46,  0xfe,  0x0a,  0x13,  0x37,  0x0b,  0x13,  0xfe,  0x43,  0x00,  0xc0,
+  0x0a,  0x4f,  0x0b,  0x3a,  0x01,  0x9b,  0x01,  0x9d,  0xb9,  0x07,  0x3d,  0x09,  0xa1,  0x01,  0x40,  0x11,
+  0x48,  0x07,  0x1e,  0x09,  0x51,  0x01,  0x79,  0x86,  0x0b,  0xb9,  0x1c,  0xd3,  0x02,  0xfe,  0x4c,  0x03,
+  0x0a,  0x08,  0x0b,  0xa9,  0x37,  0x0b,  0x13,  0x00,  0xfe,  0x54,  0x10,  0x6f,  0x08,  0x1d,  0xfe,  0x50,
+  0x12,  0x0a,  0x08,  0x1d,  0xfe,  0x48,  0x13,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,  0x52,  0x0d,
+  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,  0x58,  0x0d,  0x0a,  0x4f,  0x1d,  0x3a,  0xfe,  0x95,  0x10,
+  0x13,  0xfe,  0x15,  0x00,  0xfe,  0x04,  0xe6,  0x0b,  0x69,  0xfe,  0x26,  0x10,  0x13,  0xfe,  0x13,  0x00,
+  0xdc,  0x13,  0xfe,  0x47,  0x00,  0xa8,  0x13,  0xfe,  0x41,  0x00,  0xa2,  0x13,  0xfe,  0x24,  0x00,  0x04,
+  0x7d,  0x2c,  0x28,  0xf4,  0x69,  0xfe,  0x04,  0xe6,  0x1d,  0xfe,  0x9d,  0x41,  0xfe,  0x1c,  0x42,  0xb9,
+  0x01,  0xfe,  0xf8,  0x0e,  0x02,  0x27,  0xdd,  0x17,  0x0b,  0x4b,  0xfb,  0xe5,  0x17,  0xfe,  0x31,  0x00,
+  0x4b,  0xc3,  0x01,  0xfe,  0xfc,  0x0f,  0x02,  0xfe,  0xc6,  0x01,  0x1c,  0xfe,  0x06,  0xec,  0xfe,  0xb9,
+  0x00,  0x89,  0x37,  0x39,  0xc6,  0x30,  0x1c,  0xfe,  0x06,  0xea,  0xfe,  0xb9,  0x00,  0xfe,  0x47,  0x4b,
+  0x7c,  0xfe,  0x75,  0x57,  0x04,  0x5e,  0xfe,  0x98,  0x56,  0xfe,  0x28,  0x12,  0x0f,  0x7e,  0xfe,  0xfa,
+  0x14,  0x46,  0xed,  0x0f,  0xc7,  0xfe,  0xf0,  0x14,  0xfe,  0x49,  0x54,  0x95,  0xfe,  0x08,  0x0e,  0x0f,
+  0x1e,  0xfe,  0xe4,  0x14,  0xfe,  0x44,  0x48,  0x02,  0xfe,  0x4c,  0x03,  0x0f,  0x5e,  0xfe,  0xc8,  0x14,
+  0x89,  0x37,  0x39,  0xc6,  0x30,  0x1c,  0xfe,  0xce,  0x47,  0xfe,  0xbd,  0x13,  0x02,  0x27,  0x2a,  0x2d,
+  0x05,  0x10,  0xfe,  0x78,  0x12,  0x24,  0x16,  0x5d,  0x16,  0xb2,  0x2a,  0x48,  0x46,  0x4b,  0x48,  0xcc,
+  0xd9,  0xfe,  0xbc,  0xf0,  0xfe,  0xa4,  0x0e,  0x07,  0x06,  0x16,  0x5d,  0x01,  0xfe,  0xb0,  0x16,  0x04,
+  0xfe,  0x38,  0x01,  0x2b,  0xfe,  0x3a,  0x01,  0x52,  0xfe,  0xa8,  0x0e,  0x04,  0xfe,  0x38,  0x01,  0x1b,
+  0xfe,  0xf0,  0xff,  0x0e,  0xfe,  0x60,  0x01,  0x04,  0xfe,  0x3a,  0x01,  0x0e,  0xfe,  0x62,  0x01,  0x20,
+  0x06,  0x16,  0x48,  0xfe,  0x04,  0xec,  0x2d,  0x07,  0x2d,  0x09,  0x3c,  0x1c,  0x01,  0x40,  0x81,  0xfe,
+  0x05,  0xf6,  0xfe,  0x34,  0x01,  0x01,  0xfe,  0x20,  0x17,  0x11,  0x48,  0xd3,  0x07,  0x06,  0x03,  0x24,
+  0x03,  0x2a,  0x5d,  0xfe,  0xf7,  0x12,  0x2a,  0xb2,  0x70,  0x16,  0xb2,  0x05,  0xa5,  0xfe,  0x93,  0x13,
+  0xfe,  0x24,  0x1c,  0x17,  0x18,  0x4b,  0xfb,  0xe5,  0xfe,  0xd9,  0x10,  0x9a,  0xfe,  0x03,  0xdc,  0xfe,
+  0x73,  0x57,  0xfe,  0x80,  0x5d,  0x03,  0x9a,  0xfe,  0x03,  0xdc,  0x24,  0xfe,  0x70,  0x57,  0xfe,  0x33,
+  0x54,  0xfe,  0x3b,  0x54,  0xfe,  0x80,  0x5d,  0x03,  0xfe,  0x03,  0x57,  0x9a,  0x24,  0xfe,  0x00,  0xcc,
+  0x03,  0xfe,  0x03,  0x57,  0x9a,  0x7f,  0x03,  0x01,  0xfe,  0x50,  0x17,  0x3e,  0x05,  0x48,  0xfe,  0x0a,
+  0x13,  0x07,  0x1e,  0x09,  0x51,  0xdc,  0x01,  0x9b,  0x01,  0x9d,  0x07,  0x3d,  0x09,  0xa1,  0x01,  0x40,
+  0x11,  0xfe,  0xe9,  0x00,  0x0a,  0x08,  0x8d,  0xfe,  0x52,  0x13,  0x01,  0xfe,  0xe2,  0x16,  0xfe,  0x1e,
+  0x1c,  0xfe,  0x14,  0x90,  0x0e,  0xfe,  0x64,  0x01,  0xfe,  0x16,  0x90,  0x0e,  0xfe,  0x66,  0x01,  0x0a,
+  0x08,  0x78,  0xea,  0xfe,  0x03,  0x80,  0x72,  0x4c,  0x11,  0x7b,  0x07,  0x2d,  0x09,  0x3c,  0x1c,  0x97,
+  0x01,  0xa0,  0xfe,  0x62,  0x08,  0x70,  0x4c,  0x11,  0x7b,  0x07,  0x2d,  0x09,  0x3c,  0x1c,  0x97,  0x01,
+  0xa0,  0x6b,  0x33,  0x11,  0x7b,  0x07,  0x2d,  0x09,  0x3c,  0x1c,  0x97,  0x01,  0x79,  0x03,  0xfe,  0x08,
+  0x1c,  0x04,  0xfe,  0xac,  0x00,  0xfe,  0x06,  0x58,  0x04,  0xfe,  0xae,  0x00,  0xfe,  0x07,  0x58,  0x04,
+  0xfe,  0xb0,  0x00,  0xfe,  0x08,  0x58,  0x04,  0xfe,  0xb2,  0x00,  0xfe,  0x09,  0x58,  0xfe,  0x0a,  0x1c,
+  0x20,  0x8b,  0x16,  0xfe,  0xb9,  0x00,  0x24,  0x0e,  0x5b,  0x0e,  0x56,  0x20,  0x10,  0x16,  0x2d,  0x16,
+  0x3c,  0x50,  0xa4,  0xfe,  0x93,  0x00,  0x07,  0x2d,  0x09,  0x3c,  0x1c,  0x01,  0x79,  0x81,  0x11,  0x7b,
+  0xfe,  0x14,  0x56,  0xfe,  0xd6,  0xf0,  0xfe,  0xd6,  0x0f,  0xdd,  0x8f,  0xfe,  0x14,  0x1c,  0xfe,  0x10,
+  0x1c,  0xfe,  0x18,  0x1c,  0x03,  0x1c,  0xfe,  0x0c,  0x14,  0x89,  0xfe,  0x07,  0xe6,  0x39,  0xfe,  0xce,
+  0x47,  0xfe,  0xf5,  0x13,  0x03,  0x01,  0x99,  0x0f,  0x3d,  0x01,  0x15,  0x05,  0x10,  0xda,  0x0f,  0x1e,
+  0x01,  0x15,  0x05,  0x10,  0xe1,  0xfe,  0x44,  0x58,  0x4c,  0xfe,  0x01,  0xec,  0xc3,  0xfe,  0x9e,  0x40,
+  0xfe,  0x9d,  0xe7,  0x00,  0xfe,  0x9c,  0xe7,  0x1d,  0xa3,  0x33,  0x01,  0xfe,  0xf8,  0x0e,  0xfe,  0xc9,
+  0x10,  0x03,  0x38,  0x84,  0x74,  0x23,  0x29,  0xba,  0x05,  0x1d,  0xfe,  0x48,  0x12,  0x05,  0x0b,  0xfe,
+  0x4c,  0x12,  0x05,  0x18,  0xfe,  0x30,  0x12,  0x05,  0xd5,  0x1a,  0xfe,  0xa0,  0x11,  0x05,  0xfe,  0x23,
+  0x00,  0x1a,  0xfe,  0xac,  0x11,  0x05,  0x06,  0x1a,  0xa9,  0x05,  0x22,  0xfe,  0x12,  0x12,  0x05,  0x00,
+  0x1a,  0x25,  0x17,  0xd5,  0x01,  0x2e,  0xce,  0x3b,  0x01,  0x0c,  0x83,  0x41,  0x03,  0x3b,  0x11,  0xfe,
+  0xcc,  0x00,  0x02,  0x27,  0x3b,  0x3e,  0x05,  0xca,  0xfe,  0xe3,  0x13,  0x36,  0x42,  0x21,  0x43,  0x52,
+  0xfe,  0x5e,  0x11,  0x0a,  0x08,  0x5f,  0xfe,  0x72,  0x12,  0x82,  0x31,  0x5a,  0x3f,  0x93,  0xc9,  0x95,
+  0xfe,  0x28,  0x11,  0x2a,  0x67,  0xfe,  0x26,  0x13,  0x04,  0xb3,  0x2b,  0x90,  0x52,  0xfe,  0x78,  0x0d,
+  0x0e,  0x65,  0x12,  0x66,  0x24,  0x0e,  0xb3,  0x0e,  0x90,  0x01,  0xbc,  0x20,  0x8b,  0x72,  0x16,  0x67,
+  0x01,  0xf8,  0x82,  0x31,  0x5a,  0x3f,  0xfe,  0x04,  0x55,  0xfe,  0xa5,  0x55,  0xfe,  0x04,  0xfa,  0x31,
+  0xfe,  0x05,  0xfa,  0x3f,  0xfe,  0x91,  0x10,  0x04,  0x44,  0x2b,  0x45,  0xfe,  0x40,  0x56,  0xfe,  0xe1,
+  0x56,  0x0e,  0x44,  0x12,  0x45,  0xab,  0x82,  0x31,  0x5a,  0x3f,  0x93,  0xc9,  0x04,  0x63,  0x2b,  0x64,
+  0xfe,  0x00,  0x56,  0xfe,  0xa1,  0x56,  0x0e,  0x63,  0x12,  0x64,  0x0a,  0x08,  0x5f,  0xfe,  0x1e,  0x12,
+  0x2a,  0x67,  0xfe,  0x1f,  0x40,  0x04,  0x65,  0x2b,  0x66,  0xfe,  0x2c,  0x50,  0xfe,  0xae,  0x50,  0x04,
+  0x44,  0x2b,  0x45,  0xfe,  0x34,  0x50,  0xfe,  0xb6,  0x50,  0x04,  0x63,  0x2b,  0x64,  0xfe,  0x08,  0x50,
+  0xfe,  0x8a,  0x50,  0x04,  0x42,  0x2b,  0x43,  0xfe,  0x28,  0x50,  0xfe,  0xaa,  0x50,  0x02,  0x9c,  0x20,
+  0x06,  0x16,  0xfa,  0x02,  0x7a,  0x3b,  0x01,  0x0c,  0x1f,  0x55,  0x23,  0x29,  0xba,  0x05,  0x06,  0x28,
+  0x55,  0x3e,  0x05,  0xca,  0x28,  0x7a,  0x01,  0xf2,  0x1b,  0x58,  0x1a,  0x55,  0x0a,  0x08,  0x0b,  0xe4,
+  0x36,  0x42,  0x21,  0x43,  0xfe,  0x0a,  0x55,  0x30,  0xfe,  0x8b,  0x55,  0x4d,  0x42,  0x6e,  0x43,  0xfe,
+  0x0c,  0x51,  0xfe,  0x8e,  0x51,  0x02,  0x7a,  0xde,  0xfe,  0x0a,  0x45,  0xfe,  0x19,  0x41,  0x02,  0x7a,
+  0x3b,  0x01,  0x0c,  0x1f,  0xc0,  0x23,  0x29,  0xfe,  0xe9,  0x09,  0x60,  0x18,  0xfe,  0x94,  0x12,  0x60,
+  0x0b,  0x59,  0x02,  0x55,  0x2f,  0xb0,  0x19,  0x32,  0x1f,  0xc0,  0x23,  0x29,  0x98,  0x05,  0x18,  0x28,
+  0x55,  0x01,  0x0c,  0x1f,  0xc0,  0x23,  0x29,  0xfe,  0xe8,  0x09,  0x50,  0x04,  0xfe,  0x9c,  0x00,  0x2c,
+  0x30,  0xfe,  0xbb,  0x45,  0x60,  0x00,  0x4e,  0x37,  0x06,  0xa4,  0x58,  0xfe,  0xc0,  0x14,  0xfe,  0xf8,
+  0x14,  0xb1,  0x3e,  0x05,  0xc8,  0xfe,  0x16,  0x13,  0x04,  0xfe,  0x9e,  0x00,  0x2c,  0xa9,  0x04,  0x56,
+  0x2c,  0x30,  0x62,  0x02,  0x7a,  0xfe,  0xc0,  0x5d,  0xfe,  0xe4,  0x14,  0xfe,  0x03,  0x17,  0x04,  0x5b,
+  0xc2,  0x0e,  0x5b,  0x62,  0x3b,  0x01,  0x0c,  0x26,  0x9c,  0x01,  0xfe,  0xd0,  0x14,  0x02,  0x9c,  0x2f,
+  0xfe,  0xb4,  0x12,  0x19,  0x32,  0x1f,  0x55,  0x23,  0x29,  0x98,  0x05,  0x06,  0x28,  0x55,  0xfe,  0xf6,
+  0x14,  0xfe,  0x42,  0x58,  0xfe,  0x70,  0x14,  0xfe,  0x92,  0x14,  0xb1,  0xfe,  0x4a,  0xf4,  0x0b,  0x1a,
+  0x55,  0xfe,  0x4a,  0xf4,  0x06,  0xd8,  0x3e,  0x05,  0xc8,  0xd1,  0x02,  0x7a,  0x04,  0x56,  0xc2,  0x0e,
+  0x56,  0x62,  0x3b,  0x01,  0x0c,  0x26,  0x9c,  0x01,  0xfe,  0xfe,  0x14,  0x02,  0x9c,  0x26,  0xe2,  0x76,
+  0xf7,  0x76,  0x03,  0x35,  0xfe,  0x18,  0x13,  0x71,  0xfe,  0x18,  0x13,  0x62,  0x3b,  0x01,  0x0c,  0xfe,
+  0xe3,  0x10,  0x07,  0x6a,  0xff,  0x02,  0x00,  0x57,  0x6c,  0x80,  0x1b,  0xfe,  0xff,  0x7f,  0xfe,  0x30,
+  0x56,  0xfe,  0x00,  0x5c,  0x03,  0x07,  0x6a,  0xff,  0x02,  0x00,  0x57,  0x6c,  0x80,  0x1b,  0x58,  0xfe,
+  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x03,  0x07,  0x6a,  0xff,  0x02,  0x00,  0x57,  0x6c,  0x80,  0x03,  0x07,
+  0x6a,  0xff,  0x02,  0x00,  0x57,  0x6c,  0x80,  0xfe,  0x0b,  0x58,  0x03,  0x0f,  0x5b,  0x01,  0x9f,  0x0f,
+  0x56,  0x01,  0x9f,  0x03,  0xd0,  0x1b,  0x10,  0xff,  0x03,  0x00,  0x54,  0xfe,  0x00,  0xf4,  0x22,  0x6c,
+  0xfe,  0x00,  0x7d,  0xfe,  0x01,  0x7d,  0xfe,  0x02,  0x7d,  0xfe,  0x03,  0x7c,  0x6b,  0x33,  0x0e,  0x63,
+  0x12,  0x64,  0x4d,  0x44,  0x6e,  0x45,  0x03,  0xfe,  0x62,  0x18,  0xfe,  0x82,  0x5a,  0xfe,  0xe1,  0x1a,
+  0xbe,  0xfe,  0x02,  0x58,  0x03,  0x01,  0xfe,  0x40,  0x19,  0xfe,  0x42,  0x48,  0x69,  0x50,  0x7c,  0x01,
+  0x0c,  0x1f,  0xfe,  0xc8,  0x14,  0x23,  0x29,  0xfe,  0xe9,  0x09,  0xfe,  0xc1,  0x59,  0x01,  0x0c,  0x1f,
+  0xfe,  0xc8,  0x14,  0x23,  0x29,  0xfe,  0xe8,  0x0a,  0x04,  0xfe,  0x9e,  0x00,  0x2c,  0xfe,  0xc2,  0x12,
+  0x24,  0xb8,  0x1d,  0xe4,  0x60,  0xd6,  0x77,  0xfe,  0x18,  0x14,  0x59,  0x07,  0x06,  0x09,  0xd6,  0xa4,
+  0xfe,  0x00,  0x10,  0xfe,  0x78,  0x10,  0xff,  0x02,  0x83,  0x55,  0xa8,  0xff,  0x02,  0x83,  0x55,  0xb8,
+  0x18,  0xfe,  0x12,  0x13,  0x61,  0xfe,  0x30,  0x00,  0x95,  0xf3,  0x09,  0x88,  0x07,  0x06,  0xfe,  0x56,
+  0x10,  0xb8,  0x0b,  0xfe,  0x16,  0x13,  0x61,  0xfe,  0x64,  0x00,  0x95,  0xf3,  0x0f,  0xfe,  0x64,  0x00,
+  0x09,  0xae,  0x07,  0x06,  0xfe,  0x28,  0x10,  0xb8,  0x06,  0xfe,  0x5e,  0x13,  0x61,  0xfe,  0xc8,  0x00,
+  0x95,  0xf3,  0x0f,  0xfe,  0xc8,  0x00,  0x09,  0x5d,  0x07,  0x06,  0xab,  0x61,  0xfe,  0x90,  0x01,  0x96,
+  0xfe,  0x7e,  0x14,  0x7c,  0xad,  0xfe,  0x43,  0xf4,  0xb2,  0xfe,  0x56,  0xf0,  0xfe,  0x90,  0x14,  0xfe,
+  0x04,  0xf4,  0x6a,  0xfe,  0x43,  0xf4,  0xae,  0xfe,  0xf3,  0x10,  0xb7,  0x01,  0xf1,  0x1b,  0x58,  0xda,
+  0xfe,  0x00,  0x17,  0xfe,  0x4d,  0xe4,  0x8b,  0x96,  0xfe,  0xc2,  0x14,  0x7c,  0xfe,  0x14,  0x10,  0xfe,
+  0x00,  0x17,  0xfe,  0x4d,  0xe4,  0xec,  0x96,  0xfe,  0xc2,  0x14,  0xd2,  0xec,  0xa2,  0x50,  0x7c,  0x07,
+  0x06,  0xfe,  0xb4,  0x56,  0xfe,  0xc3,  0x58,  0x03,  0x50,  0x07,  0x0b,  0x03,  0x14,  0x06,  0x01,  0x0c,
+  0x26,  0xfe,  0xfc,  0x14,  0x14,  0x0b,  0x01,  0x0c,  0x26,  0xfe,  0xfc,  0x14,  0x14,  0x18,  0x01,  0x0c,
+  0x26,  0xfe,  0xfc,  0x14,  0x76,  0xfe,  0x89,  0x49,  0x01,  0x0c,  0x03,  0x14,  0x06,  0x01,  0x0c,  0x26,
+  0xb4,  0x14,  0x18,  0x01,  0x0c,  0x26,  0xb4,  0x14,  0x06,  0x01,  0x0c,  0x26,  0xb4,  0xfe,  0x89,  0x49,
+  0x01,  0x0c,  0x26,  0xb4,  0x76,  0xfe,  0x89,  0x4a,  0x01,  0x0c,  0x03,  0x50,  0x03,  0x2a,  0xe8,  0x05,
+  0x06,  0xfe,  0x44,  0x13,  0xb5,  0x16,  0xe8,  0xfe,  0x49,  0xf4,  0x00,  0x59,  0x76,  0xce,  0x62,  0xfe,
+  0x01,  0xec,  0xfe,  0x27,  0x01,  0xf7,  0x01,  0x0c,  0x3e,  0x05,  0xfe,  0xe3,  0x00,  0xfe,  0x20,  0x13,
+  0x1f,  0xfe,  0x80,  0x15,  0x24,  0x16,  0xfa,  0x01,  0x41,  0x2a,  0xfa,  0x05,  0x06,  0x4e,  0x0a,  0x4f,
+  0x06,  0x3a,  0x03,  0x0e,  0x5c,  0x12,  0x8e,  0xfe,  0x43,  0x58,  0x01,  0x15,  0x05,  0x10,  0xfe,  0x1e,
+  0x12,  0x49,  0xee,  0x94,  0x01,  0x47,  0xfe,  0x90,  0x4d,  0xe6,  0x10,  0xfe,  0xc5,  0x59,  0x01,  0x47,
+  0xfe,  0x8d,  0x56,  0xbe,  0x49,  0x03,  0x49,  0x21,  0x8e,  0x01,  0x15,  0x49,  0x94,  0x01,  0x47,  0xe9,
+  0x10,  0xe6,  0x10,  0x21,  0x5c,  0x61,  0x1e,  0x87,  0x0f,  0x5e,  0x01,  0xc5,  0x03,  0x0e,  0x5c,  0x12,
+  0x8e,  0xfe,  0xc3,  0x58,  0x01,  0x15,  0x05,  0x10,  0xfe,  0x1a,  0x12,  0x49,  0xee,  0x94,  0x01,  0x47,
+  0xe9,  0x10,  0xfe,  0x80,  0x4d,  0xfe,  0xc5,  0x59,  0x01,  0x47,  0x49,  0x03,  0x49,  0x21,  0x5c,  0x01,
+  0x15,  0x49,  0x94,  0x01,  0x47,  0xe9,  0x10,  0xe6,  0x10,  0x21,  0x5c,  0x61,  0x1e,  0x87,  0x0f,  0x5e,
+  0x01,  0xc5,  0x03,  0x0e,  0x5c,  0x12,  0x8e,  0xfe,  0x43,  0x58,  0x01,  0x15,  0xfe,  0x42,  0x48,  0x94,
+  0x01,  0x47,  0xfe,  0xc0,  0x5a,  0xb7,  0xfe,  0x00,  0xcd,  0xfe,  0x01,  0xcc,  0xfe,  0x4a,  0x46,  0xe4,
+  0x9a,  0x7f,  0x05,  0x10,  0xfe,  0x2e,  0x13,  0x5a,  0x5c,  0xfe,  0x4d,  0xf4,  0x1e,  0xe2,  0x0f,  0x5e,
+  0x01,  0x9f,  0xad,  0xfe,  0x40,  0x4c,  0xfe,  0xc5,  0x58,  0x01,  0x47,  0xfe,  0x00,  0x07,  0x7f,  0x05,
+  0x10,  0x87,  0x5a,  0x8e,  0xfe,  0x05,  0x57,  0xfe,  0x08,  0x10,  0xfe,  0x45,  0x58,  0x01,  0x47,  0xfe,
+  0x8d,  0x56,  0xbe,  0xfe,  0x80,  0x4c,  0xfe,  0x05,  0x17,  0x03,  0x09,  0x10,  0x75,  0x6d,  0xfe,  0x60,
+  0x01,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,  0x24,  0x1c,  0xe3,  0x39,  0x9e,  0xfe,  0xc4,  0x16,
+  0x01,  0xfe,  0xca,  0x17,  0xd9,  0x8a,  0x39,  0x6d,  0xfe,  0x2c,  0x01,  0xfe,  0x2f,  0x19,  0x03,  0xbf,
+  0x28,  0xfe,  0xb4,  0x16,  0xfe,  0xda,  0x10,  0x09,  0x10,  0x75,  0x04,  0xfe,  0x64,  0x01,  0xfe,  0x00,
+  0xf4,  0x22,  0xfe,  0x18,  0x58,  0x04,  0xfe,  0x66,  0x01,  0xfe,  0x19,  0x58,  0x8a,  0x22,  0xfe,  0x3c,
+  0x90,  0xfe,  0x30,  0xf4,  0x06,  0xfe,  0x3c,  0x50,  0x6d,  0xfe,  0x38,  0x00,  0xfe,  0x0f,  0x79,  0xfe,
+  0x1c,  0xf7,  0x22,  0x9e,  0xfe,  0x0e,  0x17,  0xfe,  0xb6,  0x14,  0x30,  0x03,  0xbf,  0x28,  0xfe,  0xe6,
+  0x16,  0xfe,  0x9c,  0x10,  0x09,  0x10,  0x75,  0xbe,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xdf,  0xe3,  0x31,
+  0x9e,  0xfe,  0x30,  0x17,  0xfe,  0x94,  0x14,  0x2e,  0x8a,  0x31,  0x6d,  0x1d,  0xfe,  0xaf,  0x19,  0xfe,
+  0x98,  0xe7,  0x00,  0x03,  0xbf,  0x28,  0xfe,  0x24,  0x17,  0xfe,  0x6c,  0x10,  0x09,  0x10,  0x75,  0xfe,
+  0x30,  0xbc,  0xfe,  0xb2,  0xbc,  0x8a,  0xe0,  0x6d,  0x1d,  0xfe,  0x0f,  0x79,  0xfe,  0x1c,  0xf7,  0xe0,
+  0x9e,  0xfe,  0x68,  0x17,  0xfe,  0x5c,  0x14,  0x30,  0x03,  0xbf,  0x28,  0xfe,  0x54,  0x17,  0xfe,  0x42,
+  0x10,  0xfe,  0x02,  0xf6,  0x10,  0x75,  0xfe,  0x18,  0xfe,  0x65,  0xfe,  0x19,  0xfe,  0x66,  0xd0,  0xe3,
+  0x78,  0x9e,  0xfe,  0x8e,  0x17,  0xfe,  0x36,  0x14,  0xe2,  0x8a,  0x78,  0x46,  0xfe,  0x83,  0x58,  0xfe,
+  0xaf,  0x19,  0xfe,  0x80,  0xe7,  0x10,  0xfe,  0x81,  0xe7,  0x10,  0x11,  0xfe,  0xdd,  0x00,  0x6b,  0x33,
+  0x03,  0x6b,  0x33,  0xfe,  0x12,  0x45,  0x28,  0xfe,  0x7e,  0x17,  0x17,  0x06,  0x4b,  0xfb,  0xe5,  0x02,
+  0x27,  0xfe,  0x39,  0xf0,  0xfe,  0xd2,  0x17,  0x24,  0x03,  0xfe,  0x7e,  0x18,  0x1b,  0x18,  0x85,  0x07,
+  0x0d,  0x03,  0x75,  0x04,  0xe7,  0x1b,  0x06,  0xfe,  0xef,  0x12,  0xfe,  0xe1,  0x10,  0x1c,  0x0f,  0x1e,
+  0x01,  0x15,  0x05,  0x10,  0x4e,  0x4c,  0xfe,  0x78,  0x14,  0xfe,  0x34,  0x12,  0x58,  0x89,  0x37,  0x39,
+  0xc6,  0xfe,  0xe9,  0x13,  0x1c,  0x0f,  0x3d,  0x01,  0x15,  0x05,  0x10,  0x4e,  0x4c,  0xfe,  0x56,  0x14,
+  0xb0,  0x58,  0x89,  0x37,  0x39,  0xc6,  0xfe,  0xe9,  0x13,  0x09,  0x0b,  0x03,  0xfe,  0x9c,  0xe7,  0x0b,
+  0x13,  0xfe,  0x15,  0x00,  0x97,  0xa3,  0x33,  0x01,  0xfe,  0xf8,  0x0e,  0x09,  0x06,  0x03,  0x0a,  0x4f,
+  0x39,  0x3a,  0x07,  0x3d,  0x09,  0xa1,  0x01,  0x40,  0x11,  0x48,  0x07,  0x1e,  0x09,  0x51,  0x01,  0x79,
+  0x09,  0x06,  0x03,  0xfe,  0x38,  0x90,  0xfe,  0xba,  0x90,  0x36,  0xfe,  0xa8,  0x00,  0x21,  0x7b,  0xfe,
+  0x48,  0x55,  0x30,  0xfe,  0xc9,  0x55,  0x03,  0x2a,  0xc4,  0x72,  0x16,  0xc4,  0x03,  0x0f,  0xc7,  0x01,
+  0x15,  0xed,  0x0f,  0x7e,  0x01,  0x15,  0xfe,  0x49,  0x44,  0x28,  0xfe,  0xc8,  0x18,  0x0f,  0x1e,  0x01,
+  0x15,  0x05,  0x10,  0x4e,  0x0f,  0x5e,  0x01,  0xc5,  0x0f,  0x7e,  0x01,  0x15,  0x72,  0x7f,  0x03,  0xfe,
+  0x40,  0x5e,  0xfe,  0xe2,  0x08,  0xfe,  0xc0,  0x4c,  0x2a,  0x3c,  0x05,  0x10,  0xfe,  0x52,  0x12,  0x4c,
+  0x05,  0x00,  0xfe,  0x18,  0x12,  0xfe,  0xe1,  0x18,  0xfe,  0x19,  0xf4,  0xfe,  0x7f,  0x00,  0x2e,  0xfe,
+  0xe2,  0x08,  0x72,  0x4c,  0x3e,  0x05,  0x7b,  0xa7,  0xfe,  0x82,  0x48,  0xfe,  0x01,  0x80,  0xfe,  0xd7,
+  0x10,  0xfe,  0xc4,  0x48,  0x07,  0x2d,  0x09,  0x3c,  0xfe,  0x40,  0x5f,  0x1c,  0x01,  0x40,  0x11,  0xfe,
+  0xdd,  0x00,  0xfe,  0x14,  0x46,  0x07,  0x2d,  0x09,  0x3c,  0x01,  0x40,  0x11,  0xfe,  0xdd,  0x00,  0xfe,
+  0x40,  0x4a,  0x70,  0xfe,  0x06,  0x17,  0xfe,  0x01,  0x07,  0xfe,  0x82,  0x48,  0xfe,  0x04,  0x17,  0x03,
+  0xf0,  0x18,  0x77,  0xfe,  0x50,  0x19,  0x04,  0xfe,  0x90,  0x00,  0xfe,  0x3a,  0x45,  0xfe,  0x2c,  0x10,
+  0xf0,  0xd5,  0x77,  0xfe,  0x62,  0x19,  0x04,  0xfe,  0x92,  0x00,  0xcf,  0x1d,  0xdf,  0xf0,  0xfe,  0x0b,
+  0x00,  0x77,  0xfe,  0x74,  0x19,  0x04,  0xfe,  0x94,  0x00,  0xcf,  0x22,  0xfe,  0x08,  0x10,  0x04,  0xfe,
+  0x96,  0x00,  0xcf,  0x88,  0xfe,  0x4e,  0x45,  0xd8,  0xfe,  0x0a,  0x45,  0xff,  0x04,  0x68,  0x54,  0xfe,
+  0xf1,  0x10,  0x1b,  0x8b,  0xfe,  0x08,  0x1c,  0xfe,  0x67,  0x19,  0xfe,  0x0a,  0x1c,  0xfe,  0x1a,  0xf4,
+  0xfe,  0x00,  0x04,  0xd8,  0xfe,  0x48,  0xf4,  0x18,  0x96,  0xfe,  0xa8,  0x19,  0x07,  0x18,  0x03,  0x05,
+  0xa5,  0xfe,  0x5a,  0xf0,  0xfe,  0xb8,  0x19,  0x20,  0xfe,  0x09,  0x00,  0xfe,  0x34,  0x10,  0x05,  0x1d,
+  0xfe,  0x5a,  0xf0,  0xfe,  0xc6,  0x19,  0x20,  0xd6,  0xfe,  0x26,  0x10,  0x05,  0x18,  0x85,  0x20,  0x88,
+  0xdf,  0x05,  0x0b,  0x85,  0x20,  0xae,  0xfe,  0x0e,  0x10,  0x05,  0x06,  0x85,  0x20,  0x5d,  0xce,  0xb5,
+  0x03,  0x17,  0xfe,  0x09,  0x00,  0x01,  0x2e,  0x2f,  0xfe,  0xf6,  0x19,  0x04,  0x74,  0xb7,  0x03,  0x19,
+  0xfe,  0x16,  0x1a,  0xfe,  0x14,  0xf0,  0x0c,  0x2f,  0xfe,  0x0a,  0x1a,  0x19,  0xfe,  0x16,  0x1a,  0xfe,
+  0x82,  0xf0,  0xfe,  0x0e,  0x1a,  0x03,  0xff,  0x34,  0x00,  0x00,};
+
+STATIC unsigned short _adv_asc38C0800_size =
+    sizeof(_adv_asc38C0800_buf); /* 0x14AA */
+STATIC unsigned long _adv_asc38C0800_chksum =
+    0x05297A65UL; /* Expanded checksum. */
 
 /* a_init.c */
 /*
@@ -14129,8 +15382,8 @@ unsigned long  _adv_mcode_chksum ASC_INITDATA = 0x03494981UL;
  * Additional structure information can be found in a_condor.h where
  * the structure is defined.
  */
-STATIC ADVEEP_CONFIG
-Default_EEPROM_Config ASC_INITDATA = {
+STATIC ADVEEP_3550_CONFIG
+Default_3550_EEPROM_Config ASC_INITDATA = {
     ADV_EEPROM_BIOS_ENABLE,     /* cfg_msw */
     0x0000,                     /* cfg_lsw */
     0xFFFF,                     /* disc_enable */
@@ -14146,7 +15399,7 @@ Default_EEPROM_Config ASC_INITDATA = {
     0,                          /* bios_id_lun */
     0,                          /* termination */
     0,                          /* reserved1 */
-    0xFFEF,                     /* bios_ctrl */
+    0xFFE7,                     /* bios_ctrl */
     0xFFFF,                     /* ultra_able */
     0,                          /* reserved2 */
     ASC_DEF_MAX_HOST_QNG,       /* max_host_qng */
@@ -14167,6 +15420,71 @@ Default_EEPROM_Config ASC_INITDATA = {
     0                           /* num_of_err */
 };
 
+STATIC ADVEEP_38C0800_CONFIG
+Default_38C0800_EEPROM_Config ASC_INITDATA = {
+    ADV_EEPROM_BIOS_ENABLE,     /* 00 cfg_msw */
+    0x0000,                     /* 01 cfg_lsw */
+    0xFFFF,                     /* 02 disc_enable */
+    0xFFFF,                     /* 03 wdtr_able */
+    0x4444,                     /* 04 sdtr_speed1 */
+    0xFFFF,                     /* 05 start_motor */
+    0xFFFF,                     /* 06 tagqng_able */
+    0xFFFF,                     /* 07 bios_scan */
+    0,                          /* 08 scam_tolerant */
+    7,                          /* 09 adapter_scsi_id */
+    0,                          /*    bios_boot_delay */
+    3,                          /* 10 scsi_reset_delay */
+    0,                          /*    bios_id_lun */
+    0,                          /* 11 termination_se */
+    0,                          /*    termination_lvd */
+    0xFFE7,                     /* 12 bios_ctrl */
+    0x4444,                     /* 13 sdtr_speed2 */
+    0x4444,                     /* 14 sdtr_speed3 */
+    ASC_DEF_MAX_HOST_QNG,       /* 15 max_host_qng */
+    ASC_DEF_MAX_DVC_QNG,        /*    max_dvc_qng */
+    0,                          /* 16 dvc_cntl */
+    0x4444,                     /* 17 sdtr_speed4 */
+    0,                          /* 18 serial_number_word1 */
+    0,                          /* 19 serial_number_word2 */
+    0,                          /* 20 serial_number_word3 */
+    0,                          /* 21 check_sum */
+    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* 22-29 oem_name[16] */
+    0,                          /* 30 dvc_err_code */
+    0,                          /* 31 adv_err_code */
+    0,                          /* 32 adv_err_addr */
+    0,                          /* 33 saved_dvc_err_code */
+    0,                          /* 34 saved_adv_err_code */
+    0,                          /* 35 saved_adv_err_addr */
+    0,                          /* 36 reserved */
+    0,                          /* 37 reserved */
+    0,                          /* 38 reserved */
+    0,                          /* 39 reserved */
+    0,                          /* 40 reserved */
+    0,                          /* 41 reserved */
+    0,                          /* 42 reserved */
+    0,                          /* 43 reserved */
+    0,                          /* 44 reserved */
+    0,                          /* 45 reserved */
+    0,                          /* 46 reserved */
+    0,                          /* 47 reserved */
+    0,                          /* 48 reserved */
+    0,                          /* 49 reserved */
+    0,                          /* 50 reserved */
+    0,                          /* 51 reserved */
+    0,                          /* 52 reserved */
+    0,                          /* 53 reserved */
+    0,                          /* 54 reserved */
+    0,                          /* 55 reserved */
+    0,                          /* 56 cisptr_lsw */
+    0,                          /* 57 cisprt_msw */
+    ADV_PCI_VENDOR_ID,          /* 58 subsysvid */
+    ADV_PCI_DEVID_38C0800_REV1, /* 59 subsysid */
+    0,                          /* 60 reserved */
+    0,                          /* 61 reserved */
+    0,                          /* 62 reserved */
+    0                           /* 63 reserved */
+};
+
 /*
  * Initialize the ADV_DVC_VAR structure.
  *
@@ -14176,7 +15494,7 @@ Default_EEPROM_Config ASC_INITDATA = {
  * then 0 is returned.
  */
 ASC_INITFUNC(
-int
+STATIC int,
 AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
 )
 {
@@ -14229,8 +15547,8 @@ AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
     /*
      * Save the state of the PCI Configuration Command Register
      * "Parity Error Response Control" Bit. If the bit is clear (0),
-     * in AdvInitAsc3550Driver() tell the microcode to ignore DMA
-     * parity errors.
+     * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
+     * DMA parity errors.
      */
     asc_dvc->cfg->control_flag = 0;
     if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister)
@@ -14239,13 +15557,19 @@ AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
         asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
     }
 
-    asc_dvc->cur_host_qng = 0;
-
     asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
       ADV_LIB_VERSION_MINOR;
     asc_dvc->cfg->chip_version =
       AdvGetChipVersion(iop_base, asc_dvc->bus_type);
 
+    ASC_DBG2(1, "iopb_chip_id_1: %x %x\n",
+        (ushort) AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
+        (ushort) ADV_CHIP_ID_BYTE);
+
+    ASC_DBG2(1, "iopw_chip_id_0: %x %x\n",
+        (ushort) AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
+        (ushort) ADV_CHIP_ID_WORD);
+
     /*
      * Reset the chip to start and allow register writes.
      */
@@ -14255,52 +15579,75 @@ AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
         return ADV_ERROR;
     }
     else {
-
-        AdvResetChip(asc_dvc);
-
-        if ((status = AdvInitFromEEP(asc_dvc)) == ADV_ERROR)
+        /*
+         * The caller must set 'chip_type' to a valid setting.
+         */
+        if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
+            asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
+            asc_dvc->chip_type != ADV_CHIP_ASC38C1600)
         {
+            asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
             return ADV_ERROR;
         }
-        warn_code |= status;
 
         /*
-         * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
-         * Resets should be performed.
+         * Reset Chip.
          */
-        if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
+        AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
+            ADV_CTRL_REG_CMD_RESET);
+        DvcSleepMilliSecond(100);
+        AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
+            ADV_CTRL_REG_CMD_WR_IO_REG);
+
+        if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
+        {
+            if ((status = AdvInitFrom38C0800EEP(asc_dvc)) == ADV_ERROR)
+            {
+                return ADV_ERROR;
+            }
+        } else
         {
-            AdvResetSCSIBus(asc_dvc);
+            if ((status = AdvInitFrom3550EEP(asc_dvc)) == ADV_ERROR)
+            {
+                return ADV_ERROR;
+            }
         }
+        warn_code |= status;
     }
 
     return warn_code;
 }
 
 /*
- * Initialize the ASC3550.
+ * Initialize the ASC-3550.
  *
  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
  *
  * For a non-fatal error return a warning code. If there are no warnings
  * then 0 is returned.
  */
-ASC_INITFUNC(
-int
+STATIC int
 AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
-)
 {
     AdvPortAddr iop_base;
     ushort      warn_code;
     ulong       sum;
     int         begin_addr;
     int         end_addr;
-    int         code_sum;
+    ushort      code_sum;
     int         word;
-    int         rql_addr;                   /* RISC Queue List address */
+    int         j;
+    int         adv_asc3550_expanded_size;
+    ADV_CARR_T  *carrp;
+    ulong       contig_len;
+    long        buf_size;
+    ulong       carr_paddr;
     int         i;
     ushort      scsi_cfg1;
-    uchar       biosmem[ASC_MC_BIOSLEN];    /* BIOS RISC Memory 0x40-0x8F. */
+    uchar       tid;
+    ushort      bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
+    ushort      wdtr_able = 0, sdtr_able, tagqng_able;
+    uchar       max_cmd[ADV_MAX_TID + 1];
 
     /* If there is already an error, don't continue. */
     if (asc_dvc->err_code != 0)
@@ -14308,6 +15655,15 @@ AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
         return ADV_ERROR;
     }
 
+    /*
+     * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
+     */
+    if (asc_dvc->chip_type != ADV_CHIP_ASC3550)
+    {
+        asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
+        return ADV_ERROR;
+    }
+
     warn_code = 0;
     iop_base = asc_dvc->iop_base;
 
@@ -14319,9 +15675,36 @@ AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
      * Note: This code makes the assumption, which is currently true,
      * that a chip reset does not clear RISC LRAM.
      */
-    for (i = 0; i < ASC_MC_BIOSLEN; i++)
+    for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
+    {
+        AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
+    }
+
+    /*
+     * Save current per TID negotiated values.
+     */
+    if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
+    {
+        ushort  bios_version, major, minor;
+
+        bios_version = bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM)/2];
+        major = (bios_version  >> 12) & 0xF;
+        minor = (bios_version  >> 8) & 0xF;
+        if (major <= 3 || (major == 3 && minor == 1))
+        {
+            /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
+            AdvReadWordLram(iop_base, 0x120, wdtr_able);
+        } else
+        {
+            AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
+        }
+    }
+    AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
+    AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
+    for (tid = 0; tid <= ADV_MAX_TID; tid++)
     {
-        AdvReadByteLram(iop_base, ASC_MC_BIOSMEM + i, biosmem[i]);
+        AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
+            max_cmd[tid]);
     }
 
     /*
@@ -14330,16 +15713,58 @@ AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
      * Write the microcode image to RISC memory starting at address 0.
      */
     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
-    for (word = 0; word < _adv_mcode_size; word += 2)
+    /* Assume the following compressed format of the microcode buffer:
+     *
+     *  254 word (508 byte) table indexed by byte code followed
+     *  by the following byte codes:
+     *
+     *    1-Byte Code:
+     *      00: Emit word 0 in table.
+     *      01: Emit word 1 in table.
+     *      .
+     *      FD: Emit word 253 in table.
+     *
+     *    Multi-Byte Code:
+     *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
+     *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
+     */
+    word = 0;
+    for (i = 253 * 2; i < _adv_asc3550_size; i++)
     {
-        AdvWriteWordAutoIncLram(iop_base,
-            *((ushort *) (&_adv_mcode_buf[word])));
+        if (_adv_asc3550_buf[i] == 0xff)
+        {
+            for (j = 0; j < _adv_asc3550_buf[i + 1]; j++)
+            {
+                AdvWriteWordAutoIncLram(iop_base,
+                    *((ushort *) (&_adv_asc3550_buf[i + 2])));
+                word++;
+            }
+           i += 3;
+        } else if (_adv_asc3550_buf[i] == 0xfe)
+        {
+            AdvWriteWordAutoIncLram(iop_base,
+                *((ushort *) (&_adv_asc3550_buf[i + 1])));
+            i += 2;
+            word++;
+        } else
+        {
+            AdvWriteWordAutoIncLram(iop_base,
+                *((ushort *) &_adv_asc3550_buf[_adv_asc3550_buf[i] * 2]));
+            word++;
+        }
     }
 
     /*
-     * Clear the rest of Condor's Internal RAM (8KB).
+     * Set 'word' for later use to clear the rest of memory and save
+     * the expanded mcode size.
+     */
+    word *= 2;
+    adv_asc3550_expanded_size = word;
+
+    /*
+     * Clear the rest of ASC-3550 Internal RAM (8KB).
      */
-    for (; word < ADV_CONDOR_MEMSIZE; word += 2)
+    for (; word < ADV_3550_MEMSIZE; word += 2)
     {
         AdvWriteWordAutoIncLram(iop_base, 0);
     }
@@ -14349,12 +15774,13 @@ AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
      */
     sum = 0;
     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
-    for (word = 0; word < _adv_mcode_size; word += 2)
+
+    for (word = 0; word < adv_asc3550_expanded_size; word += 2)
     {
         sum += AdvReadWordAutoIncLram(iop_base);
     }
 
-    if (sum != _adv_mcode_chksum)
+    if (sum != _adv_asc3550_chksum)
     {
         asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
         return ADV_ERROR;
@@ -14363,35 +15789,35 @@ AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
     /*
      * Restore the RISC memory BIOS region.
      */
-    for (i = 0; i < ASC_MC_BIOSLEN; i++)
+    for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
     {
-        AdvWriteByteLram(iop_base, ASC_MC_BIOSMEM + i, biosmem[i]);
+        AdvWriteByteLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
     }
 
     /*
      * Calculate and write the microcode code checksum to the microcode
-     * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).  
+     * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
      */
     AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
     AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
     code_sum = 0;
+    AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
     for (word = begin_addr; word < end_addr; word += 2)
     {
-        code_sum += *((ushort *) (&_adv_mcode_buf[word]));
+        code_sum += AdvReadWordAutoIncLram(iop_base);
     }
     AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
 
     /*
-     * Read microcode version and date.
+     * Read and save microcode version and date.
      */
     AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
     AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
 
     /*
-     * Initialize microcode operating variables
+     * Set the chip type to indicate the ASC3550.
      */
-    AdvWriteWordLram(iop_base, ASC_MC_ADAPTER_SCSI_ID,
-                       asc_dvc->chip_scsi_id);
+    AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
 
     /*
      * If the PCI Configuration Command Register "Parity Error Response
@@ -14401,7 +15827,7 @@ AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
      */
     if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
     {
-        /* 
+        /*
          * Note: Don't remove the use of a temporary variable in
          * the following code, otherwise the Microsoft C compiler
          * will turn the following lines into a no-op.
@@ -14412,27 +15838,86 @@ AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
     }
 
     /*
-     * Set default microcode operating variables for WDTR, SDTR, and
-     * command tag queuing based on the EEPROM configuration values.
+     * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
+     * threshold of 128 bytes. This register is only accessible to the host.
+     */
+    AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
+        START_CTL_EMFU | READ_CMD_MRM);
+
+    /*
+     * Microcode operating variables for WDTR, SDTR, and command tag
+     * queuing will be set in AdvInquiryHandling() based on what a
+     * device reports it is capable of in Inquiry byte 7.
      *
-     * These ADV_DVC_VAR fields and the microcode variables will be
-     * changed in AdvInquiryHandling() if it is found a device is
-     * incapable of a particular feature.
+     * If SCSI Bus Resets haev been disabled, then directly set
+     * SDTR and WDTR from the EEPROM configuration. This will allow
+     * the BIOS and warm boot to work without a SCSI bus hang on
+     * the Inquiry caused by host and target mismatched DTR values.
+     * Without the SCSI Bus Reset, before an Inquiry a device can't
+     * be assumed to be in Asynchronous, Narrow mode.
      */
+    if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
+    {
+        AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
+        AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
+    }
 
     /*
-     * Set the microcode ULTRA target mask from EEPROM value. The
-     * SDTR target mask overrides the ULTRA target mask in the
-     * microcode so it is safe to set this value without determining
-     * whether the device supports SDTR.
-     * 
-     * Note: There is no way to know whether a device supports ULTRA
-     * speed without attempting a SDTR ULTRA speed negotiation with
-     * the device. The device will reject the speed if it does not
-     * support it by responding with an SDTR message containing a
-     * slower speed.
+     * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
+     * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
+     * bitmask. These values determine the maximum SDTR speed negotiated
+     * with a device.
+     *
+     * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
+     * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
+     * without determining here whether the device supports SDTR.
+     *
+     * 4-bit speed  SDTR speed name
+     * ===========  ===============
+     * 0000b (0x0)  SDTR disabled
+     * 0001b (0x1)  5 Mhz
+     * 0010b (0x2)  10 Mhz
+     * 0011b (0x3)  20 Mhz (Ultra)
+     * 0100b (0x4)  40 Mhz (LVD/Ultra2)
+     * 0101b (0x5)  80 Mhz (LVD2/Ultra3)
+     * 0110b (0x6)  Undefined
+     * .
+     * 1111b (0xF)  Undefined
+     */
+    word = 0;
+    for (tid = 0; tid <= ADV_MAX_TID; tid++)
+    {
+        if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able)
+        {
+            /* Set Ultra speed for TID 'tid'. */
+            word |= (0x3 << (4 * (tid % 4)));
+        } else
+        {
+            /* Set Fast speed for TID 'tid'. */
+            word |= (0x2 << (4 * (tid % 4)));
+        }
+        if (tid == 3) /* Check if done with sdtr_speed1. */
+        {
+            AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
+            word = 0;
+        } else if (tid == 7) /* Check if done with sdtr_speed2. */
+        {
+            AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
+            word = 0;
+        } else if (tid == 11) /* Check if done with sdtr_speed3. */
+        {
+            AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
+            word = 0;
+        } else if (tid == 15) /* Check if done with sdtr_speed4. */
+        {
+            AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
+            /* End of loop. */
+        }
+    }
+
+    /*
+     * Set microcode operating variable for the disconnect per TID bitmask.
      */
-    AdvWriteWordLram(iop_base, ASC_MC_ULTRA_ABLE, asc_dvc->ultra_able);
     AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
 
 
@@ -14444,7 +15929,7 @@ AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
      */
     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
         PARITY_EN | SEL_TMO_LONG | OUR_ID_EN | asc_dvc->chip_scsi_id);
-  
+
     /*
      * Determine SCSI_CFG1 Microcode Default Value.
      *
@@ -14461,8 +15946,8 @@ AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
     if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
         (scsi_cfg1 & CABLE_ILLEGAL_B) == 0)
     {
-        asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
-        return ADV_ERROR;
+            asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
+            return ADV_ERROR;
     }
 
     /*
@@ -14491,7 +15976,7 @@ AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
      * termination value based on a table listed in a_condor.h.
      *
      * If manual termination was specified with an EEPROM setting
-     * then 'termination' was set-up in AdvInitFromEEP() and
+     * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
      * is ready to be 'ored' into SCSI_CFG1.
      */
     if (asc_dvc->cfg->termination == 0)
@@ -14543,7 +16028,21 @@ AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
      * after it is started below.
      */
     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
-                       FLTR_11_TO_20NS | scsi_cfg1);
+        FLTR_11_TO_20NS | scsi_cfg1);
+
+    /*
+     * Set MEM_CFG Microcode Default Value
+     *
+     * The microcode will set the MEM_CFG register using this value
+     * after it is started below.
+     *
+     * MEM_CFG may be accessed as a word or byte, but only bits 0-7
+     * are defined.
+     *
+     * ASC-3550 has 8KB internal memory.
+     */
+    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
+        BIOS_EN | RAM_SZ_8KB);
 
     /*
      * Set SEL_MASK Microcode Default Value
@@ -14552,49 +16051,109 @@ AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
      * after it is started below.
      */
     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
-                        ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
+        ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
 
     /*
-     * Link all the RISC Queue Lists together in a doubly-linked
-     * NULL terminated list.
+     * Build carrier freelist.
      *
-     * Skip the NULL (0) queue which is not used.
+     * Driver must have already allocated memory and set 'carrier_buf'.
      */
-    for (i = 1, rql_addr = ASC_MC_RISC_Q_LIST_BASE + ASC_MC_RISC_Q_LIST_SIZE;
-         i < ASC_MC_RISC_Q_TOTAL_CNT;
-         i++, rql_addr += ASC_MC_RISC_Q_LIST_SIZE)
+    ADV_ASSERT(asc_dvc->carrier_buf != NULL);
+
+    carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
+    asc_dvc->carr_freelist = NULL;
+    if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
+    {
+        buf_size = ADV_CARRIER_BUFSIZE;
+    } else
     {
+        buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
+    }
+
+    do {
+        /*
+         * Get physical address of the carrier 'carrp'.
+         */
+        contig_len = sizeof(ADV_CARR_T);
+        carr_paddr = DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
+            (long *) &contig_len, ADV_IS_CARRIER_FLAG);
+
+        buf_size -= sizeof(ADV_CARR_T);
+
         /*
-         * Set the current RISC Queue List's RQL_FWD and RQL_BWD pointers
-         * in a one word write and set the state (RQL_STATE) to free.
+         * If the current carrier is not physically contiguous, then
+         * maybe there was a page crossing. Try the next carrier aligned
+         * start address.
          */
-        AdvWriteWordLram(iop_base, rql_addr, ((i + 1) + ((i - 1) << 8)));
-        AdvWriteByteLram(iop_base, rql_addr + RQL_STATE, ASC_MC_QS_FREE);
+        if (contig_len < sizeof(ADV_CARR_T))
+        {
+            carrp++;
+            continue;
+        }
+
+        carrp->carr_pa = carr_paddr;
+        carrp->carr_va = (ulong) carrp;
+
+        /*
+         * Insert the carrier at the beginning of the freelist.
+         */
+        carrp->next_vpa = (ulong) asc_dvc->carr_freelist;
+        asc_dvc->carr_freelist = carrp;
+
+        carrp++;
     }
+    while (buf_size > 0);
 
     /*
-     * Set the Host and RISC Queue List pointers.
-     *
-     * Both sets of pointers are initialized with the same values:
-     * ASC_MC_RISC_Q_FIRST(0x01) and ASC_MC_RISC_Q_LAST (0xFF).
+     * Set-up the Host->RISC Initiator Command Queue (ICQ).
+     */
+
+    if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
+    {
+        asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
+        return ADV_ERROR;
+    }
+    asc_dvc->carr_freelist = (ADV_CARR_T *) asc_dvc->icq_sp->next_vpa;
+
+    /*
+     * The first command issued will be placed in the stopper carrier.
      */
-    AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_READY, ASC_MC_RISC_Q_FIRST);
-    AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_DONE, ASC_MC_RISC_Q_LAST);
+    asc_dvc->icq_sp->next_vpa = ASC_CQ_STOPPER;
+
+    /*
+     * Set RISC ICQ physical address start value.
+     */
+    AdvWriteDWordLram(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
+
+    /*
+     * Set-up the RISC->Host Initiator Response Queue (IRQ).
+     */
+    if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
+    {
+        asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
+        return ADV_ERROR;
+    }
+    asc_dvc->carr_freelist = (ADV_CARR_T *) asc_dvc->irq_sp->next_vpa;
 
-    AdvWriteByteLram(iop_base, ASC_MC_RISC_NEXT_READY, ASC_MC_RISC_Q_FIRST);
-    AdvWriteByteLram(iop_base, ASC_MC_RISC_NEXT_DONE, ASC_MC_RISC_Q_LAST);
+    /*
+     * The first command completed by the RISC will be placed in
+     * the stopper.
+     *
+     * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
+     * completed the RISC will set the ASC_RQ_STOPPER bit.
+     */
+    asc_dvc->irq_sp->next_vpa = ASC_CQ_STOPPER;
 
     /*
-     * Finally, set up the last RISC Queue List (255) with
-     * a NULL forward pointer.
+     * Set RISC IRQ physical address start value.
      */
-    AdvWriteWordLram(iop_base, rql_addr, (ASC_MC_NULL_Q + ((i - 1) << 8)));
-    AdvWriteByteLram(iop_base, rql_addr + RQL_STATE, ASC_MC_QS_FREE);
+    AdvWriteDWordLram(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
+    asc_dvc->carr_pending_cnt = 0;
 
     AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
-         (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
+        (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
 
-    /* 
+    /*
      * Note: Don't remove the use of a temporary variable in
      * the following code, otherwise the Microsoft C compiler
      * will turn the following lines into a no-op.
@@ -14604,30 +16163,918 @@ AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
 
     /* finally, finally, gentlemen, start your engine */
     AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
-    return warn_code;
-}
 
-/*
- * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
- * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
- * all of this is done.
- *
- * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
- *
+    /*
+     * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
+     * Resets should be performed. The RISC has to be running
+     * to issue a SCSI Bus Reset.
+     */
+    if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
+    {
+        /*
+         * If the BIOS Signature is present in memory, restore the
+         * BIOS Handshake Configuration Table and do not perform
+         * a SCSI Bus Reset.
+         */
+        if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
+        {
+            /*
+             * Restore per TID negotiated values.
+             */
+            AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
+            AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
+            AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
+            for (tid = 0; tid <= ADV_MAX_TID; tid++)
+            {
+                AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
+                    max_cmd[tid]);
+            }
+        } else
+        {
+            if (AdvResetSB(asc_dvc) != ADV_TRUE)
+            {
+                warn_code = ASC_WARN_BUSRESET_ERROR;
+            }
+        }
+    }
+
+    return warn_code;
+}
+
+/*
+ * Initialize the ASC-38C0800.
+ *
+ * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
+ *
+ * For a non-fatal error return a warning code. If there are no warnings
+ * then 0 is returned.
+ */
+STATIC int
+AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
+{
+    AdvPortAddr iop_base;
+    ushort      warn_code;
+    ulong       sum;
+    int         begin_addr;
+    int         end_addr;
+    ushort      code_sum;
+    int         word;
+    int         j;
+    int         adv_asc38C0800_expanded_size;
+    ADV_CARR_T  *carrp;
+    ulong       contig_len;
+    long        buf_size;
+    ulong       carr_paddr;
+    int         i;
+    ushort      scsi_cfg1;
+    uchar       byte;
+    uchar       tid;
+    ushort      bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
+    ushort      wdtr_able, sdtr_able, tagqng_able;
+    uchar       max_cmd[ADV_MAX_TID + 1];
+
+    /* If there is already an error, don't continue. */
+    if (asc_dvc->err_code != 0)
+    {
+        return ADV_ERROR;
+    }
+
+    /*
+     * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
+     */
+    if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800)
+    {
+        asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
+        return ADV_ERROR;
+    }
+
+    warn_code = 0;
+    iop_base = asc_dvc->iop_base;
+
+    /*
+     * Save the RISC memory BIOS region before writing the microcode.
+     * The BIOS may already be loaded and using its RISC LRAM region
+     * so its region must be saved and restored.
+     *
+     * Note: This code makes the assumption, which is currently true,
+     * that a chip reset does not clear RISC LRAM.
+     */
+    for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
+    {
+        AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
+    }
+
+    /*
+     * Save current per TID negotiated values.
+     */
+    AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
+    AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
+    AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
+    for (tid = 0; tid <= ADV_MAX_TID; tid++)
+    {
+        AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
+            max_cmd[tid]);
+    }
+
+    /*
+     * RAM BIST (RAM Built-In Self Test)
+     *
+     * Address : I/O base + offset 0x38h register (byte).
+     * Function: Bit 7-6(RW) : RAM mode
+     *                          Normal Mode   : 0x00
+     *                          Pre-test Mode : 0x40
+     *                          RAM Test Mode : 0x80
+     *           Bit 5       : unused
+     *           Bit 4(RO)   : Done bit
+     *           Bit 3-0(RO) : Status
+     *                          Host Error    : 0x08
+     *                          Int_RAM Error : 0x04
+     *                          RISC Error    : 0x02
+     *                          SCSI Error    : 0x01
+     *                          No Error      : 0x00
+     *
+     * Note: RAM BIST code should be put right here, before loading the
+     * microcode and after saving the RISC memory BIOS region.
+     */
+
+    /*
+     * LRAM Pre-test
+     *
+     * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
+     * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
+     * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
+     * to NORMAL_MODE, return an error too.
+     */
+    for (i = 0; i < 2; i++)
+    {
+        AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
+        DvcSleepMilliSecond(10);  /* Wait for 10ms before reading back. */
+        byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
+        if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE)
+        {
+            asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
+            return ADV_ERROR;
+        }
+
+        AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
+        DvcSleepMilliSecond(10);  /* Wait for 10ms before reading back. */
+        if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
+            != NORMAL_VALUE)
+        {
+            asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
+            return ADV_ERROR;
+        }
+    }
+
+    /*
+     * LRAM Test - It takes about 1.5 ms to run through the test.
+     *
+     * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
+     * If Done bit not set or Status not 0, save register byte, set the
+     * err_code, and return an error.
+     */
+    AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
+    DvcSleepMilliSecond(10);  /* Wait for 10ms before checking status. */
+
+    byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
+    if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0)
+    {
+        /* Get here if Done bit not set or Status not 0. */
+        asc_dvc->bist_err_code = byte;  /* for BIOS display message */
+        asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
+        return ADV_ERROR;
+    }
+
+    /* We need to reset back to normal mode after LRAM test passes. */
+    AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
+
+    /*
+     * Load the Microcode
+     *
+     * Write the microcode image to RISC memory starting at address 0.
+     *
+     */
+    AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
+
+    /* Assume the following compressed format of the microcode buffer:
+     *
+     *  254 word (508 byte) table indexed by byte code followed
+     *  by the following byte codes:
+     *
+     *    1-Byte Code:
+     *      00: Emit word 0 in table.
+     *      01: Emit word 1 in table.
+     *      .
+     *      FD: Emit word 253 in table.
+     *
+     *    Multi-Byte Code:
+     *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
+     *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
+     */
+    word = 0;
+    for (i = 253 * 2; i < _adv_asc38C0800_size; i++)
+    {
+        if (_adv_asc38C0800_buf[i] == 0xff)
+        {
+            for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++)
+            {
+                AdvWriteWordAutoIncLram(iop_base,
+                    *((ushort *) (&_adv_asc38C0800_buf[i + 2])));
+                word++;
+            }
+           i += 3;
+        } else if (_adv_asc38C0800_buf[i] == 0xfe)
+        {
+            AdvWriteWordAutoIncLram(iop_base,
+                *((ushort *) (&_adv_asc38C0800_buf[i + 1])));
+            i += 2;
+            word++;
+        } else
+        {
+            AdvWriteWordAutoIncLram(iop_base, *((ushort *)
+                &_adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2]));
+            word++;
+        }
+    }
+
+    /*
+     * Set 'word' for later use to clear the rest of memory and save
+     * the expanded mcode size.
+     */
+    word *= 2;
+    adv_asc38C0800_expanded_size = word;
+
+    /*
+     * Clear the rest of ASC-38C0800 Internal RAM (16KB).
+     */
+    for (; word < ADV_38C0800_MEMSIZE; word += 2)
+    {
+        AdvWriteWordAutoIncLram(iop_base, 0);
+    }
+
+    /*
+     * Verify the microcode checksum.
+     */
+    sum = 0;
+    AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
+
+    for (word = 0; word < adv_asc38C0800_expanded_size; word += 2)
+    {
+        sum += AdvReadWordAutoIncLram(iop_base);
+    }
+
+    if (sum != _adv_asc38C0800_chksum)
+    {
+        asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
+        return ADV_ERROR;
+    }
+
+    /*
+     * Restore the RISC memory BIOS region.
+     */
+    for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
+    {
+        AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
+    }
+
+    /*
+     * Calculate and write the microcode code checksum to the microcode
+     * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
+     */
+    AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
+    AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
+    code_sum = 0;
+    AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
+    for (word = begin_addr; word < end_addr; word += 2)
+    {
+        code_sum += AdvReadWordAutoIncLram(iop_base);
+    }
+    AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
+
+    /*
+     * Read microcode version and date.
+     */
+    AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
+    AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
+
+    /*
+     * Set the chip type to indicate the ASC38C0800.
+     */
+    AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
+
+    /*
+     * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
+     * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
+     * cable detection and then we are able to read C_DET[3:0].
+     *
+     * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
+     * Microcode Default Value' section below.
+     */
+    scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
+    AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, scsi_cfg1 | DIS_TERM_DRV);
+
+    /*
+     * If the PCI Configuration Command Register "Parity Error Response
+     * Control" Bit was clear (0), then set the microcode variable
+     * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
+     * to ignore DMA parity errors.
+     */
+    if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
+    {
+        /*
+         * Note: Don't remove the use of a temporary variable in
+         * the following code, otherwise the Microsoft C compiler
+         * will turn the following lines into a no-op.
+         */
+        AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
+        word |= CONTROL_FLAG_IGNORE_PERR;
+        AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
+    }
+
+    /*
+     * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
+     * bits for the default FIFO threshold.
+     *
+     * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
+     *
+     * For DMA Errata #4 set the BC_THRESH_ENB bit.
+     */
+    AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
+        BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
+
+    /*
+     * Microcode operating variables for WDTR, SDTR, and command tag
+     * queuing will be set in AdvInquiryHandling() based on what a
+     * device reports it is capable of in Inquiry byte 7.
+     *
+     * If SCSI Bus Resets have been disabled, then directly set
+     * SDTR and WDTR from the EEPROM configuration. This will allow
+     * the BIOS and warm boot to work without a SCSI bus hang on
+     * the Inquiry caused by host and target mismatched DTR values.
+     * Without the SCSI Bus Reset, before an Inquiry a device can't
+     * be assumed to be in Asynchronous, Narrow mode.
+     */
+    if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
+    {
+        AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
+        AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
+    }
+
+    /*
+     * Set microcode operating variables for DISC and SDTR_SPEED1,
+     * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
+     * configuration values.
+     *
+     * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
+     * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
+     * without determining here whether the device supports SDTR.
+     */
+    AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
+    AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
+    AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
+    AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
+    AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
+
+    /*
+     * Set SCSI_CFG0 Microcode Default Value.
+     *
+     * The microcode will set the SCSI_CFG0 register using this value
+     * after it is started below.
+     */
+    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
+        PARITY_EN | SEL_TMO_LONG | OUR_ID_EN | asc_dvc->chip_scsi_id);
+
+    /*
+     * Determine SCSI_CFG1 Microcode Default Value.
+     *
+     * The microcode will set the SCSI_CFG1 register using this value
+     * after it is started below.
+     */
+
+    /* Read current SCSI_CFG1 Register value. */
+    scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
+
+    /*
+     * If the internal narrow cable is reversed all of the SCSI_CTRL
+     * register signals will be set. Check for and return an error if
+     * this condition is found.
+     */
+    if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
+    {
+        asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
+        return ADV_ERROR;
+    }
+
+    /*
+     * All kind of combinations of devices attached to one of four connectors
+     * are acceptable except HVD device attached. For example, LVD device can
+     * be attached to SE connector while SE device attached to LVD connector.
+     * If LVD device attached to SE connector, it only runs up to Ultra speed.
+     *
+     * If an HVD device is attached to one of LVD connectors, return an error.
+     * However, there is no way to detect HVD device attached to SE connectors.
+     */
+    if (scsi_cfg1 & HVD)
+    {
+        asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
+        return ADV_ERROR;
+    }
+
+    /*
+     * If either SE or LVD automatic termination control is enabled, then
+     * set the termination value based on a table listed in a_condor.h.
+     *
+     * If manual termination was specified with an EEPROM setting then
+     * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to
+     * be 'ored' into SCSI_CFG1.
+     */
+    if ((asc_dvc->cfg->termination & TERM_SE) == 0)
+    {
+        /* SE automatic termination control is enabled. */
+        switch(scsi_cfg1 & C_DET_SE)
+        {
+            /* TERM_SE_HI: on, TERM_SE_LO: on */
+            case 0x1: case 0x2: case 0x3:
+                asc_dvc->cfg->termination |= TERM_SE;
+                break;
+
+            /* TERM_SE_HI: on, TERM_SE_LO: off */
+            case 0x0:
+                asc_dvc->cfg->termination |= TERM_SE_HI;
+                break;
+        }
+    }
+
+    if ((asc_dvc->cfg->termination & TERM_LVD) == 0)
+    {
+        /* LVD automatic termination control is enabled. */
+        switch(scsi_cfg1 & C_DET_LVD)
+        {
+            /* TERM_LVD_HI: on, TERM_LVD_LO: on */
+            case 0x4: case 0x8: case 0xC:
+                asc_dvc->cfg->termination |= TERM_LVD;
+                break;
+
+            /* TERM_LVD_HI: off, TERM_LVD_LO: off */
+            case 0x0:
+                break;
+        }
+    }
+
+    /*
+     * Clear any set TERM_SE and TERM_LVD bits.
+     */
+    scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
+
+    /*
+     * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
+     */
+    scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
+
+    /*
+     * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits
+     * and set possibly modified termination control bits in the Microcode
+     * SCSI_CFG1 Register Value.
+     */
+    scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
+
+    /*
+     * Set SCSI_CFG1 Microcode Default Value
+     *
+     * Set possibly modified termination control and reset DIS_TERM_DRV
+     * bits in the Microcode SCSI_CFG1 Register Value.
+     *
+     * The microcode will set the SCSI_CFG1 register using this value
+     * after it is started below.
+     */
+    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
+
+    /*
+     * Set MEM_CFG Microcode Default Value
+     *
+     * The microcode will set the MEM_CFG register using this value
+     * after it is started below.
+     *
+     * MEM_CFG may be accessed as a word or byte, but only bits 0-7
+     * are defined.
+     *
+     * ASC-38C0800 has 16KB internal memory.
+     */
+    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
+        BIOS_EN | RAM_SZ_16KB);
+
+    /*
+     * Set SEL_MASK Microcode Default Value
+     *
+     * The microcode will set the SEL_MASK register using this value
+     * after it is started below.
+     */
+    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
+        ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
+
+    /*
+     * Build the carrier freelist.
+     *
+     * Driver must have already allocated memory and set 'carrier_buf'.
+     */
+
+    ADV_ASSERT(asc_dvc->carrier_buf != NULL);
+
+    carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
+    asc_dvc->carr_freelist = NULL;
+    if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
+    {
+        buf_size = ADV_CARRIER_BUFSIZE;
+    } else
+    {
+        buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
+    }
+
+    do {
+        /*
+         * Get physical address for the carrier 'carrp'.
+         */
+        contig_len = sizeof(ADV_CARR_T);
+        carr_paddr = DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
+            (long *) &contig_len, ADV_IS_CARRIER_FLAG);
+
+        buf_size -= sizeof(ADV_CARR_T);
+
+        /*
+         * If the current carrier is not physically contiguous, then
+         * maybe there was a page crossing. Try the next carrier aligned
+         * start address.
+         */
+        if (contig_len < sizeof(ADV_CARR_T))
+        {
+            carrp++;
+            continue;
+        }
+
+        carrp->carr_pa = carr_paddr;
+        carrp->carr_va = (ulong) carrp;
+
+        /*
+         * Insert the carrier at the beginning of the freelist.
+         */
+        carrp->next_vpa = (ulong) asc_dvc->carr_freelist;
+        asc_dvc->carr_freelist = carrp;
+
+        carrp++;
+    }
+    while (buf_size > 0);
+
+    /*
+     * Set-up the Host->RISC Initiator Command Queue (ICQ).
+     */
+
+    if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
+    {
+        asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
+        return ADV_ERROR;
+    }
+    asc_dvc->carr_freelist = (ADV_CARR_T *) asc_dvc->icq_sp->next_vpa;
+
+    /*
+     * The first command issued will be placed in the stopper carrier.
+     */
+    asc_dvc->icq_sp->next_vpa = ASC_CQ_STOPPER;
+
+    /*
+     * Set RISC ICQ physical address start value.
+     */
+    AdvWriteDWordLram(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
+
+    /*
+     * Set-up the RISC->Host Initiator Response Queue (IRQ).
+     */
+    if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
+    {
+        asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
+        return ADV_ERROR;
+    }
+    asc_dvc->carr_freelist = (ADV_CARR_T *) asc_dvc->irq_sp->next_vpa;
+
+    /*
+     * The first command completed by the RISC will be placed in
+     * the stopper.
+     *
+     * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
+     * completed the RISC will set the ASC_RQ_STOPPER bit.
+     */
+    asc_dvc->irq_sp->next_vpa = ASC_CQ_STOPPER;
+
+    /*
+     * Set RISC IRQ physical address start value.
+     */
+    AdvWriteDWordLram(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
+    asc_dvc->carr_pending_cnt = 0;
+
+    AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
+        (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
+    /*
+     * Note: Don't remove the use of a temporary variable in
+     * the following code, otherwise the Microsoft C compiler
+     * will turn the following lines into a no-op.
+     */
+    AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
+    AdvWriteWordRegister(iop_base, IOPW_PC, word);
+
+    /* finally, finally, gentlemen, start your engine */
+    AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
+
+    /*
+     * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
+     * Resets should be performed. The RISC has to be running
+     * to issue a SCSI Bus Reset.
+     */
+    if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
+    {
+        /*
+         * If the BIOS Signature is present in memory, restore the
+         * BIOS Handshake Configuration Table and do not perform
+         * a SCSI Bus Reset.
+         */
+        if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
+        {
+            /*
+             * Restore per TID negotiated values.
+             */
+            AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
+            AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
+            AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
+            for (tid = 0; tid <= ADV_MAX_TID; tid++)
+            {
+                AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
+                    max_cmd[tid]);
+            }
+        } else
+        {
+            if (AdvResetSB(asc_dvc) != ADV_TRUE)
+            {
+                warn_code = ASC_WARN_BUSRESET_ERROR;
+            }
+        }
+    }
+
+    return warn_code;
+}
+
+/*
+ * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
+ * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
+ * all of this is done.
+ *
+ * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
+ *
+ * For a non-fatal error return a warning code. If there are no warnings
+ * then 0 is returned.
+ *
+ * Note: Chip is stopped on entry.
+ */
+ASC_INITFUNC(
+STATIC int,
+AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
+)
+{
+    AdvPortAddr              iop_base;
+    ushort                   warn_code;
+    ADVEEP_38C0800_CONFIG    eep_config;
+    int                      i;
+    uchar                    tid, termination;
+    ushort                   sdtr_speed = 0;
+
+    iop_base = asc_dvc->iop_base;
+
+    warn_code = 0;
+
+    /*
+     * Read the board's EEPROM configuration.
+     *
+     * Set default values if a bad checksum is found.
+     */
+    if (AdvGet38C0800EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
+    {
+        warn_code |= ASC_WARN_EEPROM_CHKSUM;
+
+        /*
+         * Set EEPROM default values.
+         */
+        for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++)
+        {
+            *((uchar *) &eep_config + i) =
+                *((uchar *) &Default_38C0800_EEPROM_Config + i);
+        }
+
+        /*
+         * Assume the 6 byte board serial number that was read
+         * from EEPROM is correct even if the EEPROM checksum
+         * failed.
+         */
+        eep_config.serial_number_word3 =
+            AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 1);
+
+        eep_config.serial_number_word2 =
+            AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 2);
+
+        eep_config.serial_number_word1 =
+            AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 3);
+
+        AdvSet38C0800EEPConfig(iop_base, &eep_config);
+    }
+    /*
+     * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
+     * EEPROM configuration that was read.
+     *
+     * This is the mapping of EEPROM fields to Adv Library fields.
+     */
+    asc_dvc->wdtr_able = eep_config.wdtr_able;
+    asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
+    asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
+    asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
+    asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
+    asc_dvc->tagqng_able = eep_config.tagqng_able;
+    asc_dvc->cfg->disc_enable = eep_config.disc_enable;
+    asc_dvc->max_host_qng = eep_config.max_host_qng;
+    asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
+    asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
+    asc_dvc->start_motor = eep_config.start_motor;
+    asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
+    asc_dvc->bios_ctrl = eep_config.bios_ctrl;
+    asc_dvc->no_scam = eep_config.scam_tolerant;
+    asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
+    asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
+    asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
+
+    /*
+     * For every Target ID if any of its 'sdtr_speed[1234]' bits
+     * are set, then set an 'sdtr_able' bit for it.
+     */
+    asc_dvc->sdtr_able = 0;
+    for (tid = 0; tid <= ADV_MAX_TID; tid++)
+    {
+        if (tid == 0)
+        {
+            sdtr_speed = asc_dvc->sdtr_speed1;
+        } else if (tid == 4)
+        {
+            sdtr_speed = asc_dvc->sdtr_speed2;
+        } else if (tid == 8)
+        {
+            sdtr_speed = asc_dvc->sdtr_speed3;
+        } else if (tid == 12)
+        {
+            sdtr_speed = asc_dvc->sdtr_speed4;
+        }
+        if (sdtr_speed & ADV_MAX_TID)
+        {
+            asc_dvc->sdtr_able |= (1 << tid);
+        }
+        sdtr_speed >>= 4;
+    }
+
+    /*
+     * Set the host maximum queuing (max. 253, min. 16) and the per device
+     * maximum queuing (max. 63, min. 4).
+     */
+    if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
+    {
+        eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
+    } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
+    {
+        /* If the value is zero, assume it is uninitialized. */
+        if (eep_config.max_host_qng == 0)
+        {
+            eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
+        } else
+        {
+            eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
+        }
+    }
+
+    if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
+    {
+        eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
+    } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
+    {
+        /* If the value is zero, assume it is uninitialized. */
+        if (eep_config.max_dvc_qng == 0)
+        {
+            eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
+        } else
+        {
+            eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
+        }
+    }
+
+    /*
+     * If 'max_dvc_qng' is greater than 'max_host_qng', then
+     * set 'max_dvc_qng' to 'max_host_qng'.
+     */
+    if (eep_config.max_dvc_qng > eep_config.max_host_qng)
+    {
+        eep_config.max_dvc_qng = eep_config.max_host_qng;
+    }
+
+    /*
+     * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
+     * values based on possibly adjusted EEPROM values.
+     */
+    asc_dvc->max_host_qng = eep_config.max_host_qng;
+    asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
+
+    /*
+     * If the EEPROM 'termination' field is set to automatic (0), then set
+     * the ADV_DVC_CFG 'termination' field to automatic also.
+     *
+     * If the termination is specified with a non-zero 'termination'
+     * value check that a legal value is set and set the ADV_DVC_CFG
+     * 'termination' field appropriately.
+     */
+    if (eep_config.termination_se == 0)
+    {
+        termination = 0;                         /* auto termination for SE */
+    } else
+    {
+        /* Enable manual control with low off / high off. */
+        if (eep_config.termination_se == 1)
+        {
+            termination = 0;
+
+        /* Enable manual control with low off / high on. */
+        } else if (eep_config.termination_se == 2)
+        {
+            termination = TERM_SE_HI;
+
+        /* Enable manual control with low on / high on. */
+        } else if (eep_config.termination_se == 3)
+        {
+            termination = TERM_SE;
+        } else
+        {
+            /*
+             * The EEPROM 'termination_se' field contains a bad value.
+             * Use automatic termination instead.
+             */
+            termination = 0;
+            warn_code |= ASC_WARN_EEPROM_TERMINATION;
+        }
+    }
+
+    if (eep_config.termination_lvd == 0)
+    {
+        asc_dvc->cfg->termination = termination; /* auto termination for LVD */
+    } else
+    {
+        /* Enable manual control with low off / high off. */
+        if (eep_config.termination_lvd == 1)
+        {
+            asc_dvc->cfg->termination = termination;
+
+        /* Enable manual control with low off / high on. */
+        } else if (eep_config.termination_lvd == 2)
+        {
+            asc_dvc->cfg->termination = termination | TERM_LVD_HI;
+
+        /* Enable manual control with low on / high on. */
+        } else if (eep_config.termination_lvd == 3)
+        {
+            asc_dvc->cfg->termination =
+                termination | TERM_LVD;
+        } else
+        {
+            /*
+             * The EEPROM 'termination_lvd' field contains a bad value.
+             * Use automatic termination instead.
+             */
+            asc_dvc->cfg->termination = termination;
+            warn_code |= ASC_WARN_EEPROM_TERMINATION;
+        }
+    }
+
+    return warn_code;
+}
+
+/*
+ * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
+ * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
+ * all of this is done.
+ *
+ * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
+ *
  * For a non-fatal error return a warning code. If there are no warnings
  * then 0 is returned.
  *
  * Note: Chip is stopped on entry.
  */
 ASC_INITFUNC(
-STATIC int
-AdvInitFromEEP(ADV_DVC_VAR *asc_dvc)
+STATIC int,
+AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
 )
 {
     AdvPortAddr         iop_base;
     ushort              warn_code;
-    ADVEEP_CONFIG       eep_config;
+    ADVEEP_3550_CONFIG  eep_config;
     int                 i;
 
     iop_base = asc_dvc->iop_base;
@@ -14639,17 +17086,17 @@ AdvInitFromEEP(ADV_DVC_VAR *asc_dvc)
      *
      * Set default values if a bad checksum is found.
      */
-    if (AdvGetEEPConfig(iop_base, &eep_config) != eep_config.check_sum)
+    if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
     {
         warn_code |= ASC_WARN_EEPROM_CHKSUM;
 
         /*
          * Set EEPROM default values.
          */
-        for (i = 0; i < sizeof(ADVEEP_CONFIG); i++)
+        for (i = 0; i < sizeof(ADVEEP_3550_CONFIG); i++)
         {
             *((uchar *) &eep_config + i) =
-                *((uchar *) &Default_EEPROM_Config + i);
+                *((uchar *) &Default_3550_EEPROM_Config + i);
         }
 
         /*
@@ -14659,15 +17106,17 @@ AdvInitFromEEP(ADV_DVC_VAR *asc_dvc)
          */
         eep_config.serial_number_word3 =
             AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 1);
+
         eep_config.serial_number_word2 =
             AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 2);
+
         eep_config.serial_number_word1 =
             AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 3);
-        AdvSetEEPConfig(iop_base, &eep_config);
-    }
 
+        AdvSet3550EEPConfig(iop_base, &eep_config);
+    }
     /*
-     * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
+     * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
      * EEPROM configuration that was read.
      *
      * This is the mapping of EEPROM fields to Adv Library fields.
@@ -14682,7 +17131,6 @@ AdvInitFromEEP(ADV_DVC_VAR *asc_dvc)
     asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
     asc_dvc->start_motor = eep_config.start_motor;
     asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
-    asc_dvc->cfg->bios_boot_wait = eep_config.bios_boot_delay;
     asc_dvc->bios_ctrl = eep_config.bios_ctrl;
     asc_dvc->no_scam = eep_config.scam_tolerant;
     asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
@@ -14733,7 +17181,7 @@ AdvInitFromEEP(ADV_DVC_VAR *asc_dvc)
     }
 
     /*
-     * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_CFG 'max_dvc_qng'
+     * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
      * values based on possibly adjusted EEPROM values.
      */
     asc_dvc->max_host_qng = eep_config.max_host_qng;
@@ -14787,8 +17235,46 @@ AdvInitFromEEP(ADV_DVC_VAR *asc_dvc)
  * Return a checksum based on the EEPROM configuration read.
  */
 ASC_INITFUNC(
-STATIC ushort
-AdvGetEEPConfig(AdvPortAddr iop_base, ADVEEP_CONFIG *cfg_buf)
+STATIC ushort,
+AdvGet38C0800EEPConfig(AdvPortAddr iop_base,
+                       ADVEEP_38C0800_CONFIG *cfg_buf)
+)
+{
+    ushort              wval, chksum;
+    ushort              *wbuf;
+    int                 eep_addr;
+
+    wbuf = (ushort *) cfg_buf;
+    chksum = 0;
+
+    for (eep_addr = ASC_EEP_DVC_CFG_BEGIN;
+         eep_addr < ASC_EEP_DVC_CFG_END;
+         eep_addr++, wbuf++)
+    {
+        wval = AdvReadEEPWord(iop_base, eep_addr);
+        chksum += wval;
+        *wbuf = wval;
+    }
+    *wbuf = AdvReadEEPWord(iop_base, eep_addr);
+    wbuf++;
+    for (eep_addr = ASC_EEP_DVC_CTL_BEGIN;
+         eep_addr < ASC_EEP_MAX_WORD_ADDR;
+         eep_addr++, wbuf++)
+    {
+        *wbuf = AdvReadEEPWord(iop_base, eep_addr);
+    }
+    return chksum;
+}
+
+
+/*
+ * Read EEPROM configuration into the specified buffer.
+ *
+ * Return a checksum based on the EEPROM configuration read.
+ */
+ASC_INITFUNC(
+STATIC ushort,
+AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
 )
 {
     ushort              wval, chksum;
@@ -14821,7 +17307,7 @@ AdvGetEEPConfig(AdvPortAddr iop_base, ADVEEP_CONFIG *cfg_buf)
  * Read the EEPROM from specified location
  */
 ASC_INITFUNC(
-STATIC ushort
+STATIC ushort,
 AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
 )
 {
@@ -14835,7 +17321,7 @@ AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
  * Wait for EEPROM command to complete
  */
 ASC_INITFUNC(
-STATIC void
+STATIC void,
 AdvWaitEEPCmd(AdvPortAddr iop_base)
 )
 {
@@ -14859,190 +17345,361 @@ AdvWaitEEPCmd(AdvPortAddr iop_base)
 /*
  * Write the EEPROM from 'cfg_buf'.
  */
-ASC_INITFUNC(
-STATIC void
-AdvSetEEPConfig(AdvPortAddr iop_base, ADVEEP_CONFIG *cfg_buf)
-)
+void
+AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
+{
+    ushort *wbuf;
+    ushort addr, chksum;
+
+    wbuf = (ushort *) cfg_buf;
+    chksum = 0;
+
+    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
+    AdvWaitEEPCmd(iop_base);
+
+    /*
+     * Write EEPROM from word 0 to word 20
+     */
+    for (addr = ASC_EEP_DVC_CFG_BEGIN;
+         addr < ASC_EEP_DVC_CFG_END; addr++, wbuf++)
+    {
+        chksum += *wbuf;
+        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf);
+        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
+        AdvWaitEEPCmd(iop_base);
+        DvcSleepMilliSecond(ASC_EEP_DELAY_MS);
+    }
+
+    /*
+     * Write EEPROM checksum at word 21
+     */
+    AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
+    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
+    AdvWaitEEPCmd(iop_base);
+    wbuf++;        /* skip over check_sum */
+
+    /*
+     * Write EEPROM OEM name at words 22 to 29
+     */
+    for (addr = ASC_EEP_DVC_CTL_BEGIN;
+         addr < ASC_EEP_MAX_WORD_ADDR; addr++, wbuf++)
+    {
+        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf);
+        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
+        AdvWaitEEPCmd(iop_base);
+    }
+    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
+    AdvWaitEEPCmd(iop_base);
+    return;
+}
+
+/*
+ * Write the EEPROM from 'cfg_buf'.
+ */
+void
+AdvSet38C0800EEPConfig(AdvPortAddr iop_base,
+                       ADVEEP_38C0800_CONFIG *cfg_buf)
+{
+    ushort *wbuf;
+    ushort addr, chksum;
+
+    wbuf = (ushort *) cfg_buf;
+    chksum = 0;
+
+    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
+    AdvWaitEEPCmd(iop_base);
+
+    /*
+     * Write EEPROM from word 0 to word 20
+     */
+    for (addr = ASC_EEP_DVC_CFG_BEGIN;
+         addr < ASC_EEP_DVC_CFG_END; addr++, wbuf++)
+    {
+        chksum += *wbuf;
+        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf);
+        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
+        AdvWaitEEPCmd(iop_base);
+        DvcSleepMilliSecond(ASC_EEP_DELAY_MS);
+    }
+
+    /*
+     * Write EEPROM checksum at word 21
+     */
+    AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
+    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
+    AdvWaitEEPCmd(iop_base);
+    wbuf++;        /* skip over check_sum */
+
+    /*
+     * Write EEPROM OEM name at words 22 to 29
+     */
+    for (addr = ASC_EEP_DVC_CTL_BEGIN;
+         addr < ASC_EEP_MAX_WORD_ADDR; addr++, wbuf++)
+    {
+        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf);
+        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
+        AdvWaitEEPCmd(iop_base);
+    }
+    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
+    AdvWaitEEPCmd(iop_base);
+    return;
+}
+
+/* a_advlib.c */
+/*
+ * AdvExeScsiQueue() - Send a request to the RISC microcode program.
+ *
+ *   Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
+ *   add the carrier to the ICQ (Initiator Command Queue), and tickle the
+ *   RISC to notify it a new command is ready to be executed.
+ *
+ * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
+ * set to SCSI_MAX_RETRY.
+ *
+ * Return:
+ *      ADV_SUCCESS(1) - The request was successfully queued.
+ *      ADV_BUSY(0) -    Resource unavailable; Retry again after pending
+ *                       request completes.
+ *      ADV_ERROR(-1) -  Invalid ADV_SCSI_REQ_Q request structure
+ *                       host IC error.
+ */
+STATIC int
+AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc,
+                ADV_SCSI_REQ_Q *scsiq)
 {
-    ushort       *wbuf;
-    ushort       addr, chksum;
+    int                    last_int_level;
+    AdvPortAddr            iop_base;
+    long                   req_size;
+    ulong                  req_paddr;
+    ADV_CARR_T             *new_carrp;
+
+    ADV_ASSERT(scsiq != NULL); /* 'scsiq' should never be NULL. */
+
+    /*
+     * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
+     */
+    if (scsiq->target_id > ADV_MAX_TID)
+    {
+        scsiq->host_status = QHSTA_M_INVALID_DEVICE;
+        scsiq->done_status = QD_WITH_ERROR;
+        return ADV_ERROR;
+    }
+
+    iop_base = asc_dvc->iop_base;
+
+    last_int_level = DvcEnterCritical();
+
+    /*
+     * Allocate a carrier ensuring at least one carrier always
+     * remains on the freelist and initialize fields.
+     */
+    if ((new_carrp = asc_dvc->carr_freelist) == NULL)
+    {
+       return ADV_BUSY;
+    }
+    asc_dvc->carr_freelist = (ADV_CARR_T *) new_carrp->next_vpa;
+    asc_dvc->carr_pending_cnt++;
+
+    /*
+     * Set the carrier to be a stopper by setting 'next_vpa'
+     * to the stopper value. The current stopper will be changed
+     * below to point to the new stopper.
+     */
+    new_carrp->next_vpa = ASC_CQ_STOPPER;
+
+    /*
+     * Clear the ADV_SCSI_REQ_Q done flag.
+     */
+    scsiq->a_flag &= ~ADV_SCSIQ_DONE;
 
-    wbuf = (ushort *) cfg_buf;
-    chksum = 0;
+    req_size = sizeof(ADV_SCSI_REQ_Q);
+    req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *) scsiq,
+        (long *) &req_size, ADV_IS_SCSIQ_FLAG);
 
-    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
-    AdvWaitEEPCmd(iop_base);
+    ADV_ASSERT(ADV_DWALIGN(req_paddr) == req_paddr);
+    ADV_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
+
+    /* Save virtual and physical address of ADV_SCSI_REQ_Q and Carrier. */
+    scsiq->scsiq_ptr = (ADV_SCSI_REQ_Q *) scsiq;
+    scsiq->scsiq_rptr = req_paddr;
+
+    /* XXX - Could have the RISC set these values. */
+    scsiq->carr_va = (ulong) asc_dvc->icq_sp;
+    scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
+
+   /*
+    * Use the current stopper to send the ADV_SCSI_REQ_Q command to
+    * the microcode. The newly allocated stopper will become the new
+    * stopper.
+    */
+    asc_dvc->icq_sp->areq_vpa = (ulong) req_paddr;
 
     /*
-     * Write EEPROM from word 0 to word 15
+     * Set the 'next_vpa' pointer for the old stopper to be the
+     * physical address of the new stopper. The RISC can only
+     * follow physical addresses.
      */
-    for (addr = ASC_EEP_DVC_CFG_BEGIN;
-         addr < ASC_EEP_DVC_CFG_END; addr++, wbuf++)
-    {
-        chksum += *wbuf;
-        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf);
-        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
-        AdvWaitEEPCmd(iop_base);
-        DvcSleepMilliSecond(ASC_EEP_DELAY_MS);
-    }
+    asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
 
     /*
-     * Write EEPROM checksum at word 18
+     * Set the host adapter stopper pointer to point to the new carrier.
      */
-    AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
-    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
-    AdvWaitEEPCmd(iop_base);
-    wbuf++;        /* skip over check_sum */
+    asc_dvc->icq_sp = new_carrp;
 
     /*
-     * Write EEPROM OEM name at words 19 to 26 
+     * Tickle the RISC to tell it to read its Command Queue Head pointer.
      */
-    for (addr = ASC_EEP_DVC_CTL_BEGIN;
-         addr < ASC_EEP_MAX_WORD_ADDR; addr++, wbuf++)
+    AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
+    if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
     {
-        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf);
-        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
-        AdvWaitEEPCmd(iop_base);
+        /*
+         * Clear the tickle value. In the ASC-3550 the RISC flag
+         * command 'clr_tickle_a' does not work unless the host
+         * value is cleared.
+         */
+        AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
     }
-    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
-    AdvWaitEEPCmd(iop_base);
-    return;
+
+    DvcLeaveCritical(last_int_level);
+
+    return ADV_SUCCESS;
 }
 
 /*
- * This function resets the chip and SCSI bus
- *
- * It is up to the caller to add a delay to let the bus settle after
- * calling this function.
- *
- * The SCSI_CFG0, SCSI_CFG1, and MEM_CFG registers are set-up in
- * AdvInitAsc3550Driver(). Here when doing a write to one of these
- * registers read first and then write.
+ * Reset SCSI Bus and purge all outstanding requests.
  *
- * Note: A SCSI Bus Reset can not be done until after the EEPROM
- * configuration is read to determine whether SCSI Bus Resets
- * should be performed.
+ * Return Value:
+ *      ADV_TRUE(1) -   All requests are purged and SCSI Bus is reset.
+ *      ADV_FALSE(0) -  Microcode command failed.
+ *      ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
+ *                      may be hung which requires driver recovery.
  */
-ASC_INITFUNC(
-STATIC void
-AdvResetChip(ADV_DVC_VAR *asc_dvc)
-)
+STATIC int
+AdvResetSB(ADV_DVC_VAR *asc_dvc)
 {
-    AdvPortAddr    iop_base;
-    ushort         word;
-    uchar          byte;
-
-    iop_base = asc_dvc->iop_base;
+    int         status;
 
     /*
-     * Reset Chip.
+     * Send the SCSI Bus Reset idle start idle command which asserts
+     * the SCSI Bus Reset signal.
      */
-    AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
-    DvcSleepMilliSecond(100);
-    AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_WR_IO_REG);
+    status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET_START, 0L);
+    if (status != ADV_TRUE)
+    {
+        return status;
+    }
 
     /*
-     * Initialize Chip registers.
-     * 
-     * Note: Don't remove the use of a temporary variable in the following
-     * code, otherwise the Microsoft C compiler will turn the following lines
-     * into a no-op.
+     * Delay for the specified SCSI Bus Reset hold time.
+     *
+     * The hold time delay is done on the host because the RISC has no
+     * microsecond accurate timer.
      */
-    byte = AdvReadByteRegister(iop_base, IOPB_MEM_CFG);
-    byte |= RAM_SZ_8KB;
-    AdvWriteByteRegister(iop_base, IOPB_MEM_CFG, byte);
-
-    word = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
-    word &= ~BIG_ENDIAN;
-    AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, word);
+    DvcDelayMicroSecond(asc_dvc, (ushort) ASC_SCSI_RESET_HOLD_TIME_US);
 
     /*
-     * Setting the START_CTL_EMFU 3:2 bits sets a FIFO threshold
-     * of 128 bytes. This register is only accessible to the host.
+     * Send the SCSI Bus Reset end idle command which de-asserts
+     * the SCSI Bus Reset signal and purges any pending requests.
      */
-    AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
-        START_CTL_EMFU | READ_CMD_MRM);
-}
-
-/* a_advlib.c */
-/*
- * Description:
- *      Send a SCSI request to the ASC3550 chip
- *
- * If there is no SG list for the request, set 'sg_entry_cnt' to 0.
- *
- * If 'sg_real_addr' is non-zero on entry, AscGetSGList() will not be
- * called. It is assumed the caller has already initialized 'sg_real_addr'.
- *
- * Return:
- *      ADV_SUCCESS(1) - the request is in the mailbox
- *      ADV_BUSY(0) - total request count > 253, try later
- *      ADV_ERROR(-1) - invalid scsi request Q
- */
-STATIC int
-AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc,
-                ADV_SCSI_REQ_Q *scsiq)
-{
-    if (scsiq == (ADV_SCSI_REQ_Q *) 0L)
+    status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET_END, 0L);
+    if (status != ADV_TRUE)
     {
-        /* 'scsiq' should never be NULL. */
-        ADV_ASSERT(0);
-        return ADV_ERROR;
+        return status;
     }
 
-    return AdvSendScsiCmd(asc_dvc, scsiq);
+    DvcSleepMilliSecond((ulong) asc_dvc->scsi_reset_wait * 1000);
+
+    return status;
 }
 
 /*
- * Reset SCSI Bus and purge all outstanding requests.
+ * Reset chip and SCSI Bus.
  *
  * Return Value:
- *      ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
- *
- * Note: Should always return ADV_TRUE.
+ *      ADV_TRUE(1) -   Chip re-initialization and SCSI Bus Reset successful.
+ *      ADV_FALSE(0) -  Chip re-initialization and SCSI Bus Reset failure.
  */
 STATIC int
-AdvResetSB(ADV_DVC_VAR *asc_dvc)
+AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
 {
     int         status;
+    ushort      wdtr_able, sdtr_able, tagqng_able;
+    uchar       tid, max_cmd[ADV_MAX_TID + 1];
+    AdvPortAddr iop_base;
+    ushort      bios_sig;
 
-    status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET, 0L, 0);
+    iop_base = asc_dvc->iop_base;
 
-    AdvResetSCSIBus(asc_dvc);
+    /*
+     * Save current per TID negotiated values.
+     */
+    AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
+    AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
+    AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
+    for (tid = 0; tid <= ADV_MAX_TID; tid++)
+    {
+        AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
+            max_cmd[tid]);
+    }
 
-    return status;
-}
+    /*
+     * Force the AdvInitAsc3550/38C0800Driver() function to
+     * perform a SCSI Bus Reset by clearing the BIOS signature word.
+     * The initialization functions assumes a SCSI Bus Reset is not
+     * needed if the BIOS signature word is present.
+     */
+    AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
+    AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
 
-/*
- * Reset SCSI Bus and delay.
- */
-STATIC void
-AdvResetSCSIBus(ADV_DVC_VAR *asc_dvc)
-{
-    AdvPortAddr    iop_base;
-    ushort         scsi_ctrl;
+    /*
+     * Stop chip and reset it.
+     */
+    AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
+    AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
+    DvcSleepMilliSecond(100);
+    AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_WR_IO_REG);
 
-    iop_base = asc_dvc->iop_base;
+    /*
+     * Reset Adv Library error code, if any, and try
+     * re-initializing the chip.
+     */
+    asc_dvc->err_code = 0;
+    if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
+    {
+        status = AdvInitAsc38C0800Driver(asc_dvc);
+    } else
+    {
+        status = AdvInitAsc3550Driver(asc_dvc);
+    }
+
+    /* Translate initialization return value to status value. */
+    if (status == 0)
+    {
+        status = ADV_TRUE;
+    } else
+    {
+        status = ADV_FALSE;
+    }
 
     /*
-     * The microcode currently sets the SCSI Bus Reset signal while
-     * handling the AscSendIdleCmd() IDLE_CMD_SCSI_RESET command above.
-     * But the SCSI Bus Reset Hold Time in the microcode is not deterministic
-     * (it may in fact be for less than the SCSI Spec. minimum of 25 us).
-     * Therefore on return the Adv Library sets the SCSI Bus Reset signal
-     * for ASC_SCSI_RESET_HOLD_TIME_US, which is defined to be greater
-     * than 25 us.
+     * Restore the BIOS signature word.
      */
-    scsi_ctrl = AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL);
-    AdvWriteWordRegister(iop_base, IOPW_SCSI_CTRL,
-        scsi_ctrl | ADV_SCSI_CTRL_RSTOUT);
-    DvcDelayMicroSecond(asc_dvc, (ushort) ASC_SCSI_RESET_HOLD_TIME_US);
-    AdvWriteWordRegister(iop_base, IOPW_SCSI_CTRL,
-        scsi_ctrl & ~ADV_SCSI_CTRL_RSTOUT);
+    AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
 
-    DvcSleepMilliSecond((ulong) asc_dvc->scsi_reset_wait * 1000);
-}
+    /*
+     * Restore per TID negotiated values.
+     */
+    AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
+    AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
+    AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
+    for (tid = 0; tid <= ADV_MAX_TID; tid++)
+    {
+        AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
+            max_cmd[tid]);
+    }
 
+    return status;
+}
 
 /*
  * Adv Library Interrupt Service Routine
@@ -15068,79 +17725,76 @@ AdvISR(ADV_DVC_VAR *asc_dvc)
 {
     AdvPortAddr                 iop_base;
     uchar                       int_stat;
-    ushort                      next_done_loc, target_bit;
-    int                         completed_q;
+    ushort                      target_bit;
+    ADV_CARR_T                  *free_carrp;
+    ulong                       irq_next_vpa;
     int                         flags;
     ADV_SCSI_REQ_Q              *scsiq;
-    ASC_REQ_SENSE               *sense_data;
-    int                         ret;
 
     flags = DvcEnterCritical();
-    iop_base = asc_dvc->iop_base;
 
-    if (AdvIsIntPending(iop_base))
-    {
-        ret = ADV_TRUE;
-    } else
-    {
-        ret = ADV_FALSE;
-    }
+    iop_base = asc_dvc->iop_base;
 
     /* Reading the register clears the interrupt. */
     int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
 
-    if (int_stat & ADV_INTR_STATUS_INTRB)
+    if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
+         ADV_INTR_STATUS_INTRC)) == 0)
     {
-        asc_dvc->idle_cmd_done = ADV_TRUE;
+        return ADV_FALSE;
     }
 
     /*
-     * Notify the driver of a hardware detected SCSI Bus Reset.
+     * Notify the driver of an asynchronous microcode condition by
+     * calling the ADV_DVC_VAR.async_callback function. The function
+     * is passed the microcode ASC_MC_INTRB_CODE byte value.
      */
-    if (int_stat & ADV_INTR_STATUS_INTRC)
+    if (int_stat & ADV_INTR_STATUS_INTRB)
     {
-        if (asc_dvc->sbreset_callback != 0)
+        uchar intrb_code;
+
+        AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
+        if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
+            asc_dvc->carr_pending_cnt != 0)
+        {
+            AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
+            if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
+            {
+                AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
+            }
+        }
+
+        if (asc_dvc->async_callback != 0)
         {
-            (*(ADV_SBRESET_CALLBACK) asc_dvc->sbreset_callback)(asc_dvc);
+            (*asc_dvc->async_callback)(asc_dvc, intrb_code);
         }
     }
 
     /*
-     * ASC_MC_HOST_NEXT_DONE (0x129) is actually the last completed RISC
-     * Queue List request. Its forward pointer (RQL_FWD) points to the
-     * current completed RISC Queue List request.
+     * Check if the IRQ stopper carrier contains a completed request.
      */
-    AdvReadByteLram(iop_base, ASC_MC_HOST_NEXT_DONE, next_done_loc);
-    next_done_loc = ASC_MC_RISC_Q_LIST_BASE +
-        (next_done_loc * ASC_MC_RISC_Q_LIST_SIZE) + RQL_FWD;
-
-    AdvReadByteLram(iop_base, next_done_loc, completed_q);
-
-    /* Loop until all completed Q's are processed. */
-    while (completed_q != ASC_MC_NULL_Q)
+    while (((irq_next_vpa = asc_dvc->irq_sp->next_vpa) & ASC_RQ_DONE) != 0)
     {
-        AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_DONE, completed_q);
-
-        next_done_loc = ASC_MC_RISC_Q_LIST_BASE +
-          (completed_q * ASC_MC_RISC_Q_LIST_SIZE);
+        /*
+         * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
+         * The RISC will have set 'areq_vpa' to a virtual address.
+         */
+        scsiq = (ADV_SCSI_REQ_Q *) asc_dvc->irq_sp->areq_vpa;
 
         /*
-         * Read the ADV_SCSI_REQ_Q virtual address pointer from
-         * the RISC list entry. The microcode has changed the
-         * ADV_SCSI_REQ_Q physical address to its virtual address.
-         *
-         * Refer to comments at the end of AdvSendScsiCmd() for
-         * more information on the RISC list structure.
+         * Advance the stopper pointer to the next carrier
+         * ignoring the lower four bits. Free the previous
+         * stopper carrier.
          */
-        {
-            ushort lsw, msw;
-            AdvReadWordLram(iop_base, next_done_loc + RQL_PHYADDR, lsw);
-            AdvReadWordLram(iop_base, next_done_loc + RQL_PHYADDR + 2, msw);
+        free_carrp = asc_dvc->irq_sp;
+        asc_dvc->irq_sp = ASC_GET_CARRP(irq_next_vpa);
+
+        free_carrp->next_vpa = (ulong) asc_dvc->carr_freelist;
+        asc_dvc->carr_freelist = (ADV_CARR_T *) free_carrp;
+        asc_dvc->carr_pending_cnt--;
 
-            scsiq = (ADV_SCSI_REQ_Q *) (((ulong) msw << 16) | lsw);
-        }
-        ADV_ASSERT(scsiq != NULL);
 
+        ADV_ASSERT(scsiq != NULL);
         target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
 
         /*
@@ -15152,14 +17806,9 @@ AdvISR(ADV_DVC_VAR *asc_dvc)
          * Check Condition handling
          */
         if ((scsiq->done_status == QD_WITH_ERROR) &&
-            (scsiq->scsi_status == SS_CHK_CONDITION) &&
-            (sense_data = (ASC_REQ_SENSE *) scsiq->vsense_addr) != 0 &&
-            (scsiq->orig_sense_len - scsiq->sense_len) >= ASC_MIN_SENSE_LEN)
+            (scsiq->scsi_status == SS_CHK_CONDITION)
+            )
         {
-            /*
-             * Command returned with a check condition and valid
-             * sense data.
-             */
         }
         /*
          * If the command that completed was a SCSI INQUIRY and
@@ -15167,27 +17816,18 @@ AdvISR(ADV_DVC_VAR *asc_dvc)
          * command information for the device.
          */
         else if (scsiq->done_status == QD_NO_ERROR &&
-                   scsiq->cdb[0] == SCSICMD_Inquiry &&
-                   scsiq->target_lun == 0)
+                 scsiq->cdb[0] == SCSICMD_Inquiry &&
+                 scsiq->target_lun == 0)
         {
             AdvInquiryHandling(asc_dvc, scsiq);
         }
 
-        
-        /* Change the RISC Queue List state to free. */
-        AdvWriteByteLram(iop_base, next_done_loc + RQL_STATE, ASC_MC_QS_FREE);
-
-        /* Get the RISC Queue List forward pointer. */
-        AdvReadByteLram(iop_base, next_done_loc + RQL_FWD, completed_q);
-
         /*
          * Notify the driver of the completed request by passing
          * the ADV_SCSI_REQ_Q pointer to its callback function.
          */
-        ADV_ASSERT(asc_dvc->cur_host_qng > 0);
-        asc_dvc->cur_host_qng--;
         scsiq->a_flag |= ADV_SCSIQ_DONE;
-        (*(ADV_ISR_CALLBACK) asc_dvc->isr_callback)(asc_dvc, scsiq);
+        (*asc_dvc->isr_callback)(asc_dvc, scsiq);
         /*
          * Note: After the driver callback function is called, 'scsiq'
          * can no longer be referenced.
@@ -15207,231 +17847,107 @@ AdvISR(ADV_DVC_VAR *asc_dvc)
         (void) DvcEnterCritical();
     }
     DvcLeaveCritical(flags);
-    return ret;
+    return ADV_TRUE;
 }
 
 /*
  * Send an idle command to the chip and wait for completion.
  *
- * Interrupts do not have to be enabled on entry.
+ * Command completion is polled for once per microsecond.
+ *
+ * The function can be called from anywhere including an interrupt handler.
+ * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
+ * functions to prevent reentrancy.
  *
  * Return Values:
  *   ADV_TRUE - command completed successfully
  *   ADV_FALSE - command failed
+ *   ADV_ERROR - command timed out
  */
 STATIC int
 AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
                ushort idle_cmd,
-               ulong idle_cmd_parameter,
-               int flags)
+               ulong idle_cmd_parameter)
 {
     int         last_int_level;
-    ulong       i;
+    int         result;
+    ulong       i, j;
     AdvPortAddr iop_base;
-    int         ret;
-
-    asc_dvc->idle_cmd_done = 0;
 
     last_int_level = DvcEnterCritical();
+
     iop_base = asc_dvc->iop_base;
 
+    /*
+     * Clear the idle command status which is set by the microcode
+     * to a non-zero value to indicate when the command is completed.
+     * The non-zero result is one of the IDLE_CMD_STATUS_* values
+     * defined in a_advlib.h.
+     */
+    AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort) 0);
+
     /*
      * Write the idle command value after the idle command parameter
      * has been written to avoid a race condition. If the order is not
      * followed, the microcode may process the idle command before the
      * parameters have been written to LRAM.
      */
-    AdvWriteDWordLram(iop_base, ASC_MC_IDLE_PARA_STAT, idle_cmd_parameter);
+    AdvWriteDWordLram(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
+        idle_cmd_parameter);
     AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
-    DvcLeaveCritical(last_int_level);
 
     /*
-     * If the 'flags' argument contains the ADV_NOWAIT flag, then
-     * return with success.
+     * Tickle the RISC to tell it to process the idle command.
      */
-    if (flags & ADV_NOWAIT)
+    AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
+    if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
     {
-        return ADV_TRUE;
-    }
-
-    for (i = 0; i < SCSI_WAIT_10_SEC * SCSI_MS_PER_SEC; i++)
-    {
-        /*
-         * 'idle_cmd_done' is set by AdvISR().
-         */
-        if (asc_dvc->idle_cmd_done)
-        {
-            break;
-        }
-        DvcSleepMilliSecond(1);
-
         /*
-         * If interrupts were disabled on entry to AdvSendIdleCmd(),
-         * then they will still be disabled here. Call AdvISR() to
-         * check for the idle command completion.
+         * Clear the tickle value. In the ASC-3550 the RISC flag
+         * command 'clr_tickle_b' does not work unless the host
+         * value is cleared.
          */
-        (void) AdvISR(asc_dvc);
-    }
-
-    last_int_level = DvcEnterCritical();
-
-    if (asc_dvc->idle_cmd_done == ADV_FALSE)
-    {
-        ADV_ASSERT(0); /* The idle command should never timeout. */
-        return ADV_FALSE;
-    } else
-    {
-        AdvReadWordLram(iop_base, ASC_MC_IDLE_PARA_STAT, ret);
-        return ret;
-    }
-}
-
-/*
- * Send the SCSI request block to the adapter
- *
- * Each of the 255 Adv Library/Microcode RISC Lists or mailboxes has the
- * following structure:
- *
- * 0: RQL_FWD - RISC list forward pointer (1 byte)
- * 1: RQL_BWD - RISC list backward pointer (1 byte)
- * 2: RQL_STATE - RISC list state byte - free, ready, done, aborted (1 byte)
- * 3: RQL_TID - request target id (1 byte)
- * 4: RQL_PHYADDR - ADV_SCSI_REQ_Q physical pointer (4 bytes)
- *
- * Return:
- *      ADV_SUCCESS(1) - the request is in the mailbox
- *      ADV_BUSY(0) - total request count > 253, try later
- */
-STATIC int
-AdvSendScsiCmd(
-    ADV_DVC_VAR *asc_dvc,
-    ADV_SCSI_REQ_Q  *scsiq)
-{
-    ushort                 next_ready_loc;
-    uchar                  next_ready_loc_fwd;
-    int                    last_int_level;
-    AdvPortAddr            iop_base;
-    long                   req_size;
-    ulong                  q_phy_addr;
-
-    /*
-     * The ADV_SCSI_REQ_Q 'target_id' field should never be equal
-     * to the host adapter ID or exceed ADV_MAX_TID.
-     */
-    if (scsiq->target_id == asc_dvc->chip_scsi_id ||
-        scsiq->target_id > ADV_MAX_TID)
-    {
-        scsiq->host_status = QHSTA_M_INVALID_DEVICE;
-        scsiq->done_status = QD_WITH_ERROR;
-        return ADV_ERROR;
+        AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
     }
 
-    iop_base = asc_dvc->iop_base;
-
-    last_int_level = DvcEnterCritical();
-
-    if (asc_dvc->cur_host_qng >= asc_dvc->max_host_qng)
-    {
-        DvcLeaveCritical(last_int_level);
-        return ADV_BUSY;
-    } else
+    /* Wait for up to 100 millisecond for the idle command to timeout. */
+    for (i = 0; i < SCSI_WAIT_100_MSEC; i++)
     {
-        ADV_ASSERT(asc_dvc->cur_host_qng < ASC_MC_RISC_Q_TOTAL_CNT);
-        asc_dvc->cur_host_qng++;
+        /* Poll once each microsecond for command completion. */
+        for (j = 0; j < SCSI_US_PER_MSEC; j++)
+        {
+            AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, result);
+            if (result != 0)
+            {
+                DvcLeaveCritical(last_int_level);
+                return result;
+            }
+            DvcDelayMicroSecond(asc_dvc, (ushort) 1);
+        }
     }
 
-    /*
-     * Clear the ADV_SCSI_REQ_Q done flag.
-     */
-    scsiq->a_flag &= ~ADV_SCSIQ_DONE;
-
-    /*
-     * Save the original sense buffer length.
-     *
-     * After the request completes 'sense_len' will be set to the residual
-     * byte count of the Auto-Request Sense if a command returns CHECK
-     * CONDITION and the Sense Data is valid indicated by 'host_status' not
-     * being set to QHSTA_M_AUTO_REQ_SENSE_FAIL. To determine the valid
-     * Sense Data Length subtract 'sense_len' from 'orig_sense_len'.
-     */
-    scsiq->orig_sense_len = scsiq->sense_len;
-
-    AdvReadByteLram(iop_base, ASC_MC_HOST_NEXT_READY, next_ready_loc);
-    next_ready_loc = ASC_MC_RISC_Q_LIST_BASE +
-        (next_ready_loc * ASC_MC_RISC_Q_LIST_SIZE);
-
-    /*
-     * Write the physical address of the Q to the mailbox.
-     * We need to skip the first four bytes, because the microcode
-     * uses them internally for linking Q's together.
-     */
-    req_size = sizeof(ADV_SCSI_REQ_Q);
-    q_phy_addr = DvcGetPhyAddr(asc_dvc, scsiq,
-                    (uchar *) scsiq, &req_size,
-                    ADV_IS_SCSIQ_FLAG);
-    ADV_ASSERT(ADV_DWALIGN(q_phy_addr) == q_phy_addr);
-    ADV_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
-
-    scsiq->scsiq_ptr = (ADV_SCSI_REQ_Q *) scsiq;
-
-    /*
-     * The RISC list structure, which 'next_ready_loc' is a pointer
-     * to in microcode LRAM, has the format detailed in the comment
-     * header for this function.
-     *
-     * Write the ADV_SCSI_REQ_Q physical pointer to 'next_ready_loc' request.
-     */
-    AdvWriteDWordLram(iop_base, next_ready_loc + RQL_PHYADDR, q_phy_addr);
-
-    /* Write target_id to 'next_ready_loc' request. */
-    AdvWriteByteLram(iop_base, next_ready_loc + RQL_TID, scsiq->target_id);
-
-    /*
-     * Set the ASC_MC_HOST_NEXT_READY (0x128) microcode variable to
-     * the 'next_ready_loc' request forward pointer.
-     *
-     * Do this *before* changing the 'next_ready_loc' queue to QS_READY.
-     * After the state is changed to QS_READY 'RQL_FWD' will be changed
-     * by the microcode.
-     *
-     * NOTE: The temporary variable 'next_ready_loc_fwd' is required to
-     * prevent some compilers from optimizing out 'AdvReadByteLram()' if
-     * it were used as the 3rd argument to 'AdvWriteByteLram()'.
-     */
-    AdvReadByteLram(iop_base, next_ready_loc + RQL_FWD, next_ready_loc_fwd);
-    AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_READY, next_ready_loc_fwd);
-
-    /*
-     * Change the state of 'next_ready_loc' request from QS_FREE to
-     * QS_READY which will cause the microcode to pick it up and
-     * execute it.
-     *
-     * Can't reference 'next_ready_loc' after changing the request
-     * state to QS_READY. The microcode now owns the request.
-     */
-    AdvWriteByteLram(iop_base, next_ready_loc + RQL_STATE, ASC_MC_QS_READY);
-
+    ADV_ASSERT(0); /* The idle command should never timeout. */
     DvcLeaveCritical(last_int_level);
-    return ADV_SUCCESS;
+    return ADV_ERROR;
 }
 
 /*
  * Inquiry Information Byte 7 Handling
  *
  * Handle SCSI Inquiry Command information for a device by setting
- * microcode operating variables that affect WDTR, SDTR, and Tag 
+ * microcode operating variables that affect WDTR, SDTR, and Tag
  * Queuing.
  */
 STATIC void
 AdvInquiryHandling(
-    ADV_DVC_VAR          *asc_dvc,
-    ADV_SCSI_REQ_Q       *scsiq)
+    ADV_DVC_VAR                 *asc_dvc,
+    ADV_SCSI_REQ_Q              *scsiq)
 {
-    AdvPortAddr          iop_base;
-    uchar                tid;
-    ASC_SCSI_INQUIRY     *inq;
-    ushort               tidmask;
-    ushort               cfg_word;
+    AdvPortAddr                 iop_base;
+    uchar                       tid;
+    ADV_SCSI_INQUIRY            *inq;
+    ushort                      tidmask;
+    ushort                      cfg_word;
 
     /*
      * AdvInquiryHandling() requires up to INQUIRY information Byte 7
@@ -15442,6 +17958,7 @@ AdvInquiryHandling(
      * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the
      * microcode to the transfer residual count.
      */
+
     if (scsiq->cdb[4] < 8 || (scsiq->cdb[4] - scsiq->data_cnt) < 8)
     {
         return;
@@ -15449,12 +17966,13 @@ AdvInquiryHandling(
 
     iop_base = asc_dvc->iop_base;
     tid = scsiq->target_id;
-    inq = (ASC_SCSI_INQUIRY *) scsiq->vdata_addr;
+
+    inq = (ADV_SCSI_INQUIRY *) scsiq->vdata_addr;
 
     /*
      * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
      */
-    if (inq->byte3.rsp_data_fmt < 2 && inq->byte2.ansi_apr_ver < 2)
+    if (inq->rsp_data_fmt < 2 && inq->ansi_apr_ver < 2)
     {
         return;
     } else
@@ -15478,7 +17996,7 @@ AdvInquiryHandling(
          * device's 'wdtr_able' bit and write the new value to the
          * microcode.
          */
-        if ((asc_dvc->wdtr_able & tidmask) && inq->byte7.WBus16)
+        if ((asc_dvc->wdtr_able & tidmask) && inq->WBus16)
         {
             AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
             if ((cfg_word & tidmask) == 0)
@@ -15487,10 +18005,15 @@ AdvInquiryHandling(
                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
 
                 /*
-                 * Clear the microcode "WDTR negotiation" done indicator
-                 * for the target to cause it to negotiate with the new
-                 * setting set above.
+                 * Clear the microcode "SDTR negotiation" and "WDTR
+                 * negotiation" done indicators for the target to cause
+                 * it to negotiate with the new setting set above.
+                 * WDTR when accepted causes the target to enter
+                 * asynchronous mode, so SDTR must be negotiated.
                  */
+                AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
+                cfg_word &= ~tidmask;
+                AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
                 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
                 cfg_word &= ~tidmask;
                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
@@ -15504,7 +18027,7 @@ AdvInquiryHandling(
          * supports synchronous transfers, then turn on the device's
          * 'sdtr_able' bit. Write the new value to the microcode.
          */
-        if ((asc_dvc->sdtr_able & tidmask) && inq->byte7.Sync)
+        if ((asc_dvc->sdtr_able & tidmask) && inq->Sync)
         {
             AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
             if ((cfg_word & tidmask) == 0)
@@ -15524,8 +18047,8 @@ AdvInquiryHandling(
         }
 
         /*
-         * If the EEPROM enabled Tag Queuing for device and the
-         * device supports Tag Queuing, then turn on the device's
+         * If the EEPROM enabled Tag Queuing for the device and the
+         * device supports Tag Queueing, then turn on the device's
          * 'tagqng_enable' bit in the microcode and set the microcode
          * maximum command count to the ADV_DVC_VAR 'max_dvc_qng'
          * value.
@@ -15535,11 +18058,12 @@ AdvInquiryHandling(
          * disabling Tag Queuing in the BIOS devices with Tag Queuing
          * bugs will at least work with the BIOS.
          */
-        if ((asc_dvc->tagqng_able & tidmask) && inq->byte7.CmdQue)
+        if ((asc_dvc->tagqng_able & tidmask) && inq->CmdQue)
         {
             AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
             cfg_word |= tidmask;
             AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
+
             AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
                 asc_dvc->max_dvc_qng);
         }
index 3211c4e8f77a24b945f951dd1045b7126e808d20..dcff980ffc8f5aaf30ce0dea5e92ee7dd23183de 100644 (file)
@@ -191,13 +191,13 @@ create_elf_tables(char *p, int argc, int envc,
        current->mm->arg_start = (unsigned long) p;
        while (argc-->0) {
                __put_user((elf_caddr_t)(unsigned long)p,argv++);
-               p += strlen_user(p);
+               p += strnlen_user(p, 65536);
        }
        __put_user(NULL, argv);
        current->mm->arg_end = current->mm->env_start = (unsigned long) p;
        while (envc-->0) {
                __put_user((elf_caddr_t)(unsigned long)p,envp++);
-               p += strlen_user(p);
+               p += strnlen_user(p, 65536);
        }
        __put_user(NULL, envp);
        current->mm->env_end = (unsigned long) p;
index bb4b5c0bf7e7ed481b822faf2078eb0344c22412..7898a3f64224ae615dc14ddd15ae208fd0ab71e6 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -244,8 +244,8 @@ unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
        char *str;
        mm_segment_t old_fs;
 
-       if (!p)
-               return 0;       /* bullet-proofing */
+       if ((long)p <= 0)
+               return p;       /* bullet-proofing */
        old_fs = get_fs();
        if (from_kmem==2)
                set_fs(KERNEL_DS);
@@ -259,15 +259,14 @@ unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
                if (!str)
                {
                        set_fs(old_fs);
-                       return 0;
-//                     panic("VFS: argc is wrong");
+                       return -EFAULT;
                }
                if (from_kmem == 1)
                        set_fs(old_fs);
-               len = strlen_user(str); /* includes the '\0' */
-               if (!len || p < len) {  /* strlen_user() returns 0 on error */
-                       set_fs(old_fs);
-                       return 0;
+               len = strnlen_user(str, p);     /* includes the '\0' */
+               if (!len || len > p) {  /* EFAULT or E2BIG */
+                       set_fs(old_fs);
+                       return len ? -E2BIG : -EFAULT;
                }
                p -= len;
                pos = p;
@@ -281,7 +280,7 @@ unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
                              (unsigned long *) get_free_page(GFP_USER))) {
                                if (from_kmem==2)
                                        set_fs(old_fs);
-                               return 0;
+                               return -EFAULT;
                        }
                        bytes_to_copy = PAGE_SIZE - offset;
                        if (bytes_to_copy > len)
@@ -840,8 +839,8 @@ int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs
                bprm.exec = bprm.p;
                bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p,0);
                bprm.p = copy_strings(bprm.argc,argv,bprm.page,bprm.p,0);
-               if (!bprm.p)
-                       retval = -E2BIG;
+               if ((long)bprm.p < 0)
+                       retval = (long)bprm.p;
        }
 
        if (retval >= 0)
index 82b3fd71df8a025975c233cda268fb0c98a47eb7..b9edef0bb12e8efb9131405fa2564f81b2844928 100644 (file)
@@ -845,6 +845,7 @@ static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentr
                }
                pid *= 10;
                pid += c;
+               if (!pid) break;
                if (pid & 0xffff0000) {
                        pid = 0;
                        break;
index 6261670444a9723cfaebe93dc82994ec09628f11..b53c215b6672fe1098b95bbcebcbba669810301b 100644 (file)
@@ -26,7 +26,6 @@
 
 #define QNX4_VERSION  4
 #define QNX4_BMNAME   ".bitmap"
-#define CHECK_BOOT_SIGNATURE 0
 
 static struct super_operations qnx4_sops;
 
@@ -256,9 +255,6 @@ static const char *qnx4_checkroot(struct super_block *s)
        int i, j;
        int found = 0;
 
-       if (s == NULL) {
-               return "no qnx4 filesystem (null superblock).";
-       }
        if (*(s->u.qnx4_sb.sb->RootDir.di_fname) != '/') {
                return "no qnx4 filesystem (no root dir).";
        } else {
@@ -281,6 +277,8 @@ static const char *qnx4_checkroot(struct super_block *s)
                                        }
                                }
                        }
+                       /* WAIT! s->u.qnx4_sb.BitMap points into bh->b_data
+                          and now we release bh?? */
                        brelse(bh);
                        if (found != 0) {
                                break;
@@ -298,9 +296,8 @@ static struct super_block *qnx4_read_super(struct super_block *s,
 {
        struct buffer_head *bh;
        kdev_t dev = s->s_dev;
-#if CHECK_BOOT_SIGNATURE
+       struct inode *root;
        char *tmpc;
-#endif
        const char *errmsg;
 
        MOD_INC_USE_COUNT;
@@ -310,7 +307,9 @@ static struct super_block *qnx4_read_super(struct super_block *s,
        s->s_blocksize_bits = 9;
        s->s_dev = dev;
 
-#if CHECK_BOOT_SIGNATURE
+       /* Check the boot signature. Since the qnx4 code is
+          dangerous, we should leave as quickly as possible
+          if we don't belong here... */
        bh = bread(dev, 0, QNX4_BLOCK_SIZE);
        if (!bh) {
                printk("qnx4: unable to read the boot sector\n");
@@ -319,11 +318,12 @@ static struct super_block *qnx4_read_super(struct super_block *s,
        tmpc = (char *) bh->b_data;
        if (tmpc[4] != 'Q' || tmpc[5] != 'N' || tmpc[6] != 'X' ||
            tmpc[7] != '4' || tmpc[8] != 'F' || tmpc[9] != 'S') {
-               printk("qnx4: wrong fsid in boot sector.\n");
+               if (!silent)
+                       printk("qnx4: wrong fsid in boot sector.\n");
                goto out;
        }
        brelse(bh);
-#endif
+
        bh = bread(dev, 1, QNX4_BLOCK_SIZE);
        if (!bh) {
                printk("qnx4: unable to read the superblock\n");
@@ -336,23 +336,34 @@ static struct super_block *qnx4_read_super(struct super_block *s,
 #endif
        s->u.qnx4_sb.sb_buf = bh;
        s->u.qnx4_sb.sb = (struct qnx4_super_block *) bh->b_data;
-       s->s_root =
-           d_alloc_root(iget(s, QNX4_ROOT_INO * QNX4_INODES_PER_BLOCK), NULL);
-       if (s->s_root == NULL) {
-               printk("qnx4: get inode failed\n");
-               goto out;
-       }
+
+       /* check before allocating dentries, inodes, .. */
        errmsg = qnx4_checkroot(s);
        if (errmsg != NULL) {
-               printk("qnx4: %s\n", errmsg);
+               if (!silent)
+                       printk("qnx4: %s\n", errmsg);
                goto out;
        }
+
+       /* does root not have inode number QNX4_ROOT_INO ?? */
+       root = iget(s, QNX4_ROOT_INO * QNX4_INODES_PER_BLOCK);
+       if (!root) {
+               printk("qnx4: get inode failed\n");
+               goto out;
+       }
+
+       s->s_root = d_alloc_root(root, NULL);
+       if (s->s_root == NULL)
+               goto outi;
+
        brelse(bh);
        unlock_super(s);
        s->s_dirt = 1;
 
        return s;
 
+      outi:
+       iput(root);
       out:
        brelse(bh);
       outnobh:
index f615339f8856878c6d16b14f79c3c954e35165d9..80d1efcbd6cf310a9b058fef742a3fd7a15e880a 100644 (file)
@@ -487,6 +487,15 @@ extern inline long strlen_user(const char *str)
        return access_ok(VERIFY_READ,str,0) ? __strlen_user(str) : 0;
 }
 
+/* Returns: 0 if exception before NUL or reaching the supplied limit (N),
+ * a value greater than N if the limit would be exceeded, else strlen.  */
+extern long __strnlen_user(const char *, long);
+
+extern inline long strnlen_user(const char *str, long n)
+{
+       return access_ok(VERIFY_READ,str,0) ? __strnlen_user(str, n) : 0;
+}
+
 /*
  * About the exception table:
  *
index a44ca6c785f656bdea6b58baaef37dbba601946e..521dc65c9c61e72c1822233a5d3b8ffb1968903e 100644 (file)
@@ -597,7 +597,8 @@ __constant_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
 
 long strncpy_from_user(char *dst, const char *src, long count);
 long __strncpy_from_user(char *dst, const char *src, long count);
-long strlen_user(const char *str);
+#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
+long strnlen_user(const char *str, long n);
 unsigned long clear_user(void *mem, unsigned long len);
 unsigned long __clear_user(void *mem, unsigned long len);
 
index 07d554cac97b46047299d6da19653e269d0cf91f..03c93dadde0e391491c553247bc3ceef83f93b22 100644 (file)
@@ -89,9 +89,9 @@ typedef __u32 kernel_cap_t;
 /* Overrides the following restrictions that the effective user ID
    shall match the file owner ID when setting the S_ISUID and S_ISGID
    bits on that file; that the effective group ID (or one of the
-   supplementary group IDs shall match the file owner ID when setting
+   supplementary group IDs) shall match the file owner ID when setting
    the S_ISGID bit on that file; that the S_ISUID and S_ISGID bits are
-   cleared on successful return from chown(2). */
+   cleared on successful return from chown(2) (not implemented). */
 
 #define CAP_FSETID           4
 
index 4598d440b9d5316494cd98c9cf4f12244fccd0cd..d579eaaa2354e735b8e182e3c9a69b217240b521 100644 (file)
 #define PCI_DEVICE_ID_VIA_82C585       0x0585
 #define PCI_DEVICE_ID_VIA_82C586_0     0x0586
 #define PCI_DEVICE_ID_VIA_82C595       0x0595
+#define PCI_DEVICE_ID_VIA_82C596_0     0x0596
 #define PCI_DEVICE_ID_VIA_82C597_0     0x0597
 #define PCI_DEVICE_ID_VIA_82C598_0      0x0598
 #define PCI_DEVICE_ID_VIA_82C926       0x0926
index aba1498a73de81a44f80db82a4eab1e8defa0935..ba147ec6e6b56d1dd55ee03d0cefa4c09ad71c50 100644 (file)
@@ -224,7 +224,8 @@ enum
        NET_IPV4_ICMP_PARAMPROB_RATE=62,
        NET_IPV4_ICMP_ECHOREPLY_RATE=63,
        NET_IPV4_ICMP_IGNORE_BOGUS_ERROR_RESPONSES=64,
-       NET_IPV4_IGMP_MAX_MEMBERSHIPS=65
+       NET_IPV4_IGMP_MAX_MEMBERSHIPS=65,
+       NET_IPV4_ALWAYS_DEFRAG=67
 };
 
 enum {
index 4ec7403d8f69abe460cb44650bbfccb09b2acc59..100bfc96bf8be2ede83ac1775b9ca80363d3cc4c 100644 (file)
@@ -44,10 +44,10 @@ void release(struct task_struct * p)
                }
 #endif
                free_uid(p);
-               nr_tasks--;
                add_free_taskslot(p->tarray_ptr);
 
                write_lock_irq(&tasklist_lock);
+               nr_tasks--;
                unhash_pid(p);
                REMOVE_LINKS(p);
                write_unlock_irq(&tasklist_lock);
index 05ed71cb79deaa4c5b7b85ae4f58dd14d32a589d..9e307c058cb279d0496f977668caf3bd1465d6fc 100644 (file)
@@ -705,10 +705,10 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
                write_lock_irq(&tasklist_lock);
                SET_LINKS(p);
                hash_pid(p);
-               write_unlock_irq(&tasklist_lock);
-
                nr_tasks++;
 
+               write_unlock_irq(&tasklist_lock);
+
                p->next_run = NULL;
                p->prev_run = NULL;
                wake_up_process(p);             /* do this last */
index a5fe1bd1f60b443e00764ca23e65e4fbfcc5286c..87bafcb868811ce5a49f859c702f90e5969065f0 100644 (file)
@@ -792,6 +792,8 @@ sys_kill(int pid, int sig)
 {
        struct siginfo info;
 
+       memset(&info, 0, sizeof(info));
+       
        info.si_signo = sig;
        info.si_errno = 0;
        info.si_code = SI_USER;
index fd938f27318c24019e27a2f3462aa13e234bc9d5..f727f91e04d5f3f46af8c239712c15741d28dbdc 100644 (file)
@@ -35,17 +35,19 @@ int nr_free_pages = 0;
 #else
 #define NR_MEM_LISTS 10
 #endif
+#define NR_MEM_TYPES 2         /* GFP_DMA vs not for now. */
 
 /* The start of this MUST match the start of "struct page" */
 struct free_area_struct {
        struct page *next;
        struct page *prev;
        unsigned int * map;
+       unsigned long count;
 };
 
 #define memory_head(x) ((struct page *)(x))
 
-static struct free_area_struct free_area[NR_MEM_LISTS];
+static struct free_area_struct free_area[NR_MEM_TYPES][NR_MEM_LISTS];
 
 static inline void init_mem_queue(struct free_area_struct * head)
 {
@@ -61,6 +63,7 @@ static inline void add_mem_queue(struct free_area_struct * head, struct page * e
        entry->next = next;
        next->prev = entry;
        head->next = entry;
+       head->count++;
 }
 
 static inline void remove_mem_queue(struct page * entry)
@@ -90,9 +93,9 @@ static inline void remove_mem_queue(struct page * entry)
  */
 spinlock_t page_alloc_lock = SPIN_LOCK_UNLOCKED;
 
-static inline void free_pages_ok(unsigned long map_nr, unsigned long order)
+static inline void free_pages_ok(unsigned long map_nr, unsigned long order, unsigned type)
 {
-       struct free_area_struct *area = free_area + order;
+       struct free_area_struct *area = free_area[type] + order;
        unsigned long index = map_nr >> (1 + order);
        unsigned long mask = (~0UL) << order;
        unsigned long flags;
@@ -106,6 +109,7 @@ static inline void free_pages_ok(unsigned long map_nr, unsigned long order)
        while (mask + (1 << (NR_MEM_LISTS-1))) {
                if (!test_and_change_bit(index, area->map))
                        break;
+               area->count--;
                remove_mem_queue(list(map_nr ^ -mask));
                mask <<= 1;
                area++;
@@ -119,33 +123,28 @@ static inline void free_pages_ok(unsigned long map_nr, unsigned long order)
        spin_unlock_irqrestore(&page_alloc_lock, flags);
 }
 
-void __free_page(struct page *page)
+static inline void __free_pages(struct page *page, unsigned long order)
 {
        if (!PageReserved(page) && atomic_dec_and_test(&page->count)) {
                if (PageSwapCache(page))
                        panic ("Freeing swap cache page");
                page->flags &= ~(1 << PG_referenced);
-               free_pages_ok(page - mem_map, 0);
+               free_pages_ok(page - mem_map, order, PageDMA(page) ? 1 : 0);
                return;
        }
 }
 
+void __free_page(struct page *page)
+{
+       __free_pages(page, 0);
+}
+
 void free_pages(unsigned long addr, unsigned long order)
 {
        unsigned long map_nr = MAP_NR(addr);
 
-       if (map_nr < max_mapnr) {
-               mem_map_t * map = mem_map + map_nr;
-               if (PageReserved(map))
-                       return;
-               if (atomic_dec_and_test(&map->count)) {
-                       if (PageSwapCache(map))
-                               panic ("Freeing swap cache pages");
-                       map->flags &= ~(1 << PG_referenced);
-                       free_pages_ok(map_nr, order);
-                       return;
-               }
-       }
+       if (map_nr < max_mapnr)
+               __free_pages(mem_map + map_nr, order);
 }
 
 /*
@@ -153,52 +152,9 @@ void free_pages(unsigned long addr, unsigned long order)
  */
 #define MARK_USED(index, order, area) \
        change_bit((index) >> (1+(order)), (area)->map)
-#define CAN_DMA(x) (PageDMA(x))
 #define ADDRESS(x) (PAGE_OFFSET + ((x) << PAGE_SHIFT))
-#define RMQUEUE_DMA(order) \
-do { struct free_area_struct * area = free_area+order; \
-     unsigned long new_order = order; \
-       do { struct page *prev = memory_head(area), *ret = prev->next; \
-               while (memory_head(area) != ret) { \
-                       if (CAN_DMA(ret)) { \
-                               unsigned long map_nr; \
-                               (prev->next = ret->next)->prev = prev; \
-                               map_nr = ret - mem_map; \
-                               MARK_USED(map_nr, new_order, area); \
-                               nr_free_pages -= 1 << order; \
-                               EXPAND(ret, map_nr, order, new_order, area); \
-                               spin_unlock_irqrestore(&page_alloc_lock, flags); \
-                               return ADDRESS(map_nr); \
-                       } \
-                       prev = ret; \
-                       ret = ret->next; \
-               } \
-               new_order++; area++; \
-       } while (new_order < NR_MEM_LISTS); \
-} while (0)
-#define RMQUEUE_NODMA(order) \
-do { struct free_area_struct * area = free_area+order; \
-     unsigned long new_order = order; \
-       do { struct page *prev = memory_head(area), *ret = prev->next; \
-               while (memory_head(area) != ret) { \
-                       if (!CAN_DMA(ret)) { \
-                               unsigned long map_nr; \
-                               (prev->next = ret->next)->prev = prev; \
-                               map_nr = ret - mem_map; \
-                               MARK_USED(map_nr, new_order, area); \
-                               nr_free_pages -= 1 << order; \
-                               EXPAND(ret, map_nr, order, new_order, area); \
-                               spin_unlock_irqrestore(&page_alloc_lock, flags); \
-                               return ADDRESS(map_nr); \
-                       } \
-                       prev = ret; \
-                       ret = ret->next; \
-               } \
-               new_order++; area++; \
-       } while (new_order < NR_MEM_LISTS); \
-} while (0)
-#define RMQUEUE_ANY(order) \
-do { struct free_area_struct * area = free_area+order; \
+#define RMQUEUE_TYPE(order, type) \
+do { struct free_area_struct * area = free_area[type]+order; \
      unsigned long new_order = order; \
        do { struct page *prev = memory_head(area), *ret = prev->next; \
                if (memory_head(area) != ret) { \
@@ -207,10 +163,10 @@ do { struct free_area_struct * area = free_area+order; \
                        map_nr = ret - mem_map; \
                        MARK_USED(map_nr, new_order, area); \
                        nr_free_pages -= 1 << order; \
+                       area->count--; \
                        EXPAND(ret, map_nr, order, new_order, area); \
                        spin_unlock_irqrestore(&page_alloc_lock, flags); \
                        return ADDRESS(map_nr); \
-                \
                } \
                new_order++; area++; \
        } while (new_order < NR_MEM_LISTS); \
@@ -275,12 +231,10 @@ unsigned long __get_free_pages(int gfp_mask, unsigned long order)
        }
 ok_to_allocate:
        spin_lock_irqsave(&page_alloc_lock, flags);
-       if (gfp_mask & __GFP_DMA)
-               RMQUEUE_DMA(order);
-       else {
-               RMQUEUE_NODMA(order);
-               RMQUEUE_ANY(order);
-       }
+       /* if it's not a dma request, try non-dma first */
+       if (!(gfp_mask & __GFP_DMA))
+               RMQUEUE_TYPE(order, 0);
+       RMQUEUE_TYPE(order, 1);
        spin_unlock_irqrestore(&page_alloc_lock, flags);
 
        /*
@@ -305,26 +259,27 @@ nopage:
 void show_free_areas(void)
 {
        unsigned long order, flags;
-       unsigned long total = 0;
+       unsigned type;
 
+       spin_lock_irqsave(&page_alloc_lock, flags);
        printk("Free pages:      %6dkB\n ( ",nr_free_pages<<(PAGE_SHIFT-10));
        printk("Free: %d (%d %d %d)\n",
                nr_free_pages,
                freepages.min,
                freepages.low,
                freepages.high);
-       spin_lock_irqsave(&page_alloc_lock, flags);
-       for (order=0 ; order < NR_MEM_LISTS; order++) {
-               struct page * tmp;
-               unsigned long nr = 0;
-               for (tmp = free_area[order].next ; tmp != memory_head(free_area+order) ; tmp = tmp->next) {
-                       nr ++;
+       for (type = 0; type < NR_MEM_TYPES; type++) {
+               unsigned long total = 0;
+               printk("%sDMA: ", type ? "" : "Non");
+               for (order=0 ; order < NR_MEM_LISTS; order++) {
+                       unsigned long nr = free_area[type][order].count;
+
+                       total += nr * ((PAGE_SIZE>>10) << order);
+                       printk("%lu*%lukB ", nr, (unsigned long)((PAGE_SIZE>>10) << order));
                }
-               total += nr * ((PAGE_SIZE>>10) << order);
-               printk("%lu*%lukB ", nr, (unsigned long)((PAGE_SIZE>>10) << order));
+               printk("= %lukB)\n", total);
        }
        spin_unlock_irqrestore(&page_alloc_lock, flags);
-       printk("= %lukB)\n", total);
 #ifdef SWAP_CACHE_INFO
        show_swap_cache_info();
 #endif 
@@ -341,8 +296,7 @@ void show_free_areas(void)
 unsigned long __init free_area_init(unsigned long start_mem, unsigned long end_mem)
 {
        mem_map_t * p;
-       unsigned long mask = PAGE_MASK;
-       unsigned long i;
+       unsigned long i, j;
 
        /*
         * Select nr of pages we try to keep free for important stuff
@@ -369,17 +323,20 @@ unsigned long __init free_area_init(unsigned long start_mem, unsigned long end_m
                p->flags = (1 << PG_DMA) | (1 << PG_reserved);
        } while (p > mem_map);
 
-       for (i = 0 ; i < NR_MEM_LISTS ; i++) {
-               unsigned long bitmap_size;
-               init_mem_queue(free_area+i);
-               mask += mask;
-               end_mem = (end_mem + ~mask) & mask;
-               bitmap_size = (end_mem - PAGE_OFFSET) >> (PAGE_SHIFT + i);
-               bitmap_size = (bitmap_size + 7) >> 3;
-               bitmap_size = LONG_ALIGN(bitmap_size);
-               free_area[i].map = (unsigned int *) start_mem;
-               memset((void *) start_mem, 0, bitmap_size);
-               start_mem += bitmap_size;
+       for (j = 0; j < NR_MEM_TYPES; j++) {
+               unsigned long mask = PAGE_MASK;
+               for (i = 0 ; i < NR_MEM_LISTS ; i++) {
+                       unsigned long bitmap_size;
+                       init_mem_queue(free_area[j]+i);
+                       mask += mask;
+                       end_mem = (end_mem + ~mask) & mask;
+                       bitmap_size = (end_mem - PAGE_OFFSET) >> (PAGE_SHIFT + i);
+                       bitmap_size = (bitmap_size + 7) >> 3;
+                       bitmap_size = LONG_ALIGN(bitmap_size);
+                       free_area[j][i].map = (unsigned int *) start_mem;
+                       memset((void *) start_mem, 0, bitmap_size);
+                       start_mem += bitmap_size;
+               }
        }
        return start_mem;
 }
index 29786da5e96be521fc50e56cbbf7564d65671083..8982bc1e971a792a9bd9e50b7b50939d698f9507 100644 (file)
@@ -31,14 +31,12 @@ if [ "$CONFIG_FIREWALL" = "y" ]; then
            define_bool CONFIG_NETLINK_DEV y
        fi
     fi
-    bool 'IP: always defragment (required for masquerading)' CONFIG_IP_ALWAYS_DEFRAG
     if [ "$CONFIG_IP_MULTIPLE_TABLES" = "y" ]; then
        bool 'IP: use FWMARK value as routing key' CONFIG_IP_ROUTE_FWMARK
     fi
   fi
 fi
 if [ "$CONFIG_IP_FIREWALL" = "y" ]; then
-  if [ "$CONFIG_IP_ALWAYS_DEFRAG" != "n" ]; then
     bool 'IP: transparent proxy support' CONFIG_IP_TRANSPARENT_PROXY
     bool 'IP: masquerading' CONFIG_IP_MASQUERADE
     if [ "$CONFIG_IP_MASQUERADE" != "n" ]; then
@@ -54,7 +52,6 @@ if [ "$CONFIG_IP_FIREWALL" = "y" ]; then
        fi
       fi
     fi
-  fi
 fi
 bool 'IP: optimize as router not host' CONFIG_IP_ROUTER
 tristate 'IP: tunneling' CONFIG_NET_IPIP
index 34b48a93c184bbcef7759cd7ed2884d0bb6c6419..4994e718ef160f113a4b0003ad6e4ded253cd940 100644 (file)
@@ -320,6 +320,8 @@ int sysctl_icmp_echo_ignore_broadcasts = 0;
 /* Control parameter - ignore bogus broadcast responses? */
 int sysctl_icmp_ignore_bogus_error_responses =0;
 
+extern int sysctl_ip_always_defrag;
+
 /*
  *     ICMP control array. This specifies what to do with each ICMP.
  */
@@ -537,10 +539,9 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, unsigned long info)
         *      Now check at the protocol level
         */
        if (!rt) {
-#ifndef CONFIG_IP_ALWAYS_DEFRAG
-               if (net_ratelimit())
+                if (sysctl_ip_always_defrag == 0 &&
+                    net_ratelimit())
                        printk(KERN_DEBUG "icmp_send: destinationless packet\n");
-#endif
                return;
        }
        if (rt->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST))
@@ -698,7 +699,7 @@ static void icmp_unreach(struct icmphdr *icmph, struct sk_buff *skb, int len)
                                break;
                        case ICMP_FRAG_NEEDED:
                                if (ipv4_config.no_pmtu_disc) {
-                                       if (net_ratelimit())
+                                       if (sysctl_ip_always_defrag == 0 && net_ratelimit())
                                                printk(KERN_INFO "ICMP: %d.%d.%d.%d: fragmentation needed and DF set.\n",
                                               NIPQUAD(iph->daddr));
                                } else {
@@ -710,7 +711,7 @@ static void icmp_unreach(struct icmphdr *icmph, struct sk_buff *skb, int len)
                                }
                                break;
                        case ICMP_SR_FAILED:
-                               if (net_ratelimit())
+                               if (sysctl_ip_always_defrag == 0 && net_ratelimit())
                                        printk(KERN_INFO "ICMP: %d.%d.%d.%d: Source Route Failed.\n", NIPQUAD(iph->daddr));
                                break;
                        default:
@@ -923,7 +924,7 @@ static void icmp_timestamp(struct icmphdr *icmph, struct sk_buff *skb, int len)
 static void icmp_address(struct icmphdr *icmph, struct sk_buff *skb, int len)
 {
 #if 0
-       if (net_ratelimit())
+       if (sysctl_ip_always_defrag == 0 && net_ratelimit())
                printk(KERN_DEBUG "a guy asks for address mask. Who is it?\n");
 #endif         
 }
@@ -953,7 +954,7 @@ static void icmp_address_reply(struct icmphdr *icmph, struct sk_buff *skb, int l
                if (mask == ifa->ifa_mask && inet_ifa_match(rt->rt_src, ifa))
                        return;
        }
-       if (net_ratelimit())
+       if (sysctl_ip_always_defrag == 0 && net_ratelimit())
                printk(KERN_INFO "Wrong address mask %08lX from %08lX/%s\n",
                       ntohl(mask), ntohl(rt->rt_src), dev->name);
 }
index 99a91d53a9ab17519c9743db98d1d59690ab792e..5e2b1170d5928bc36f18204dc11ff8254a4c3382 100644 (file)
@@ -484,6 +484,11 @@ static int find_special(ip_chainlabel label, int *answer)
                return 1;
 #ifdef CONFIG_IP_TRANSPARENT_PROXY
        } else if (strcmp(label,IP_FW_LABEL_REDIRECT) == 0) {
+                extern int sysctl_ip_always_defrag;
+                static int enabled = 0;
+
+                if(!enabled)
+                        sysctl_ip_always_defrag++;
                *answer = FW_REDIRECT;
                return 1;
 #endif
index 7a3e2618bd90b952f1302331868e463f5502a3d7..b1725fa308ef5b5fb1a725868dd40a6bdda8c8f6 100644 (file)
 
 struct ip_mib ip_statistics={2,IPDEFTTL,};     /* Forwarding=No, Default TTL=64 */
 
+int sysctl_ip_always_defrag = 0;
 
 /*
  *     Handle the issuing of an ioctl() request
@@ -170,11 +171,6 @@ int ip_ioctl(struct sock *sk, int cmd, unsigned long arg)
        }
 }
 
-
-#if defined(CONFIG_IP_TRANSPARENT_PROXY) && !defined(CONFIG_IP_ALWAYS_DEFRAG)
-#define CONFIG_IP_ALWAYS_DEFRAG 1
-#endif
-
 /*
  *     0 - deliver
  *     1 - block
@@ -235,18 +231,17 @@ int ip_local_deliver(struct sk_buff *skb)
        unsigned char hash;
        int flag = 0;
 
-#ifndef CONFIG_IP_ALWAYS_DEFRAG
        /*
         *      Reassemble IP fragments.
         */
 
-       if (iph->frag_off & htons(IP_MF|IP_OFFSET)) {
+        if (sysctl_ip_always_defrag == 0 &&
+            (iph->frag_off & htons(IP_MF|IP_OFFSET))) {
                skb = ip_defrag(skb);
                if (!skb)
                        return 0;
                iph = skb->nh.iph;
        }
-#endif
 
 #ifdef CONFIG_IP_MASQUERADE
        /*
@@ -443,16 +438,15 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
        __skb_trim(skb, len);
        }
        
-#ifdef CONFIG_IP_ALWAYS_DEFRAG
        /* Won't send ICMP reply, since skb->dst == NULL. --RR */
-       if (iph->frag_off & htons(IP_MF|IP_OFFSET)) {
+        if (sysctl_ip_always_defrag != 0 &&
+            iph->frag_off & htons(IP_MF|IP_OFFSET)) {
                skb = ip_defrag(skb);
                if (!skb)
                        return 0;
                iph = skb->nh.iph;
                ip_send_check(iph);
        }
-#endif
 
 #ifdef CONFIG_FIREWALL
        /*
index 0187c58d7c5c2cd601b64d8b906332546180feac..847bc919bffdb881129855bb9c8075532e704ebe 100644 (file)
@@ -880,6 +880,8 @@ static __u16 get_next_mport(void)
  *     Be careful, it can be called from u-space
  */
 
+extern int sysctl_ip_always_defrag;
+
 struct ip_masq * ip_masq_new(int proto, __u32 maddr, __u16 mport, __u32 saddr, __u16 sport, __u32 daddr, __u16 dport, unsigned mflags)
 {
         struct ip_masq *ms, *mst;
@@ -910,6 +912,7 @@ struct ip_masq * ip_masq_new(int proto, __u32 maddr, __u16 mport, __u32 saddr, _
                 return NULL;
         }
        MOD_INC_USE_COUNT;
+       sysctl_ip_always_defrag++;
         memset(ms, 0, sizeof(*ms));
        INIT_LIST_HEAD(&ms->s_list);
        INIT_LIST_HEAD(&ms->m_list);
@@ -1057,6 +1060,7 @@ struct ip_masq * ip_masq_new(int proto, __u32 maddr, __u16 mport, __u32 saddr, _
 mport_nono:
         kfree_s(ms, sizeof(*ms));
 
+       sysctl_ip_always_defrag--;
        MOD_DEC_USE_COUNT;
         return NULL;
 }
index ce24c9ceb13557af148dceb2b95f80a129091233..6adf189a27c5c62fa122ed31185bd4913ebad835 100644 (file)
@@ -216,6 +216,7 @@ static int mfw_delhost(struct ip_masq_mfw *mfw, struct ip_mfw_user *mu)
                        (!mu->rport || h->port == mu->rport)) {
                        /* HIT */
                        atomic_dec(&mfw->nhosts);
+                       e = h->list.prev;
                        list_del(&h->list);
                        kfree_s(h, sizeof(*h));
                        MOD_DEC_USE_COUNT;
index 6c697a1029bc8abca9b74f615e1a45567e860731..d745e8923d1a0c2fba3d132202f0e279975dbd0e 100644 (file)
@@ -85,7 +85,8 @@ static __inline__ int ip_portfw_del(__u16 protocol, __u16 lport, __u32 laddr, __
                                (!laddr || n->laddr == laddr) &&
                                (!raddr || n->raddr == raddr) && 
                                (!rport || n->rport == rport)) {
-                       list_del(entry);
+                       entry = n->list.prev;
+                       list_del(&n->list);
                        ip_masq_mod_dec_nent(mmod_self);
                        kfree_s(n, sizeof(struct ip_portfw));
                        MOD_DEC_USE_COUNT;
index 44d635573378abd7f85cf2b81c0b3734f2b43d0e..4a9cfd20f2b477ba7184805959160a4ebe5ca7b3 100644 (file)
@@ -320,7 +320,7 @@ void ip_queue_xmit(struct sk_buff *skb)
                if (skb2 == NULL)
                        return;
                if (sk)
-                       skb_set_owner_w(skb, sk);
+                       skb_set_owner_w(skb2, sk);
                skb = skb2;
                iph = skb->nh.iph;
        }
index e578e4e7c49f35e0e478ce7fbca667edb5c625c3..5c9374637d9a84d22cb0826894cea8cdf39624fb 100644 (file)
@@ -41,6 +41,9 @@ extern int sysctl_ipfrag_time;
 /* From ip_output.c */
 extern int sysctl_ip_dynaddr;
 
+/* From ip_input.c */
+extern int sysctl_ip_always_defrag;
+
 /* From ip_masq.c */
 extern int sysctl_ip_masq_debug;
 
@@ -141,6 +144,8 @@ ctl_table ipv4_table[] = {
         &sysctl_ipfrag_low_thresh, sizeof(int), 0644, NULL, &proc_dointvec},
        {NET_IPV4_DYNADDR, "ip_dynaddr",
         &sysctl_ip_dynaddr, sizeof(int), 0644, NULL, &proc_dointvec},
+        {NET_IPV4_ALWAYS_DEFRAG, "ip_always_defrag",
+         &sysctl_ip_always_defrag, sizeof(int), 0644, NULL, &proc_dointvec},
 #ifdef CONFIG_IP_MASQUERADE
        {NET_IPV4_IP_MASQ_DEBUG, "ip_masq_debug",
         &sysctl_ip_masq_debug, sizeof(int), 0644, NULL, &proc_dointvec},
index 08ce050299859e34cba71b8feb10b0c6f823f3a3..1dfaad196320ffff684c78b6a1944dbf696d1324 100644 (file)
@@ -94,6 +94,7 @@ extern void destroy_8023_client(struct datalink_proto *);
 
 #ifdef CONFIG_SYSCTL
 extern int sysctl_max_syn_backlog;
+extern int sysctl_ip_always_defrag;
 #endif
 
 EXPORT_SYMBOL(dev_lockct);
@@ -350,6 +351,7 @@ EXPORT_SYMBOL(tcp_regs);
 
 #ifdef CONFIG_SYSCTL
 EXPORT_SYMBOL(sysctl_max_syn_backlog);
+EXPORT_SYMBOL(sysctl_ip_always_defrag);
 #endif
 #endif