Annotation of Gnu-Mach/i386/i386at/gpl/linux/scsi/advansys.c, revision 1.1

1.1     ! root        1: /* $Id: advansys.c,v 1.1.1.1 1997/02/25 21:27:45 thomas Exp $ */
        !             2: /*
        !             3:  * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
        !             4:  * 
        !             5:  * Copyright (c) 1995-1996 Advanced System Products, Inc.
        !             6:  * All Rights Reserved.
        !             7:  *
        !             8:  * This driver may be modified and freely distributed provided that
        !             9:  * the above copyright message and this comment are included in the
        !            10:  * distribution. The latest version of this driver is available at
        !            11:  * the AdvanSys FTP and BBS sites listed below.
        !            12:  *
        !            13:  * Please send questions, comments, bug reports to:
        !            14:  * [email protected] (Bob Frey)
        !            15:  */
        !            16: 
        !            17: /* The driver has been tested with Linux 1.2.1 and 1.3.57 kernels. */
        !            18: #define ASC_VERSION "1.2"      /* AdvanSys Driver Version */
        !            19: 
        !            20: /*
        !            21: 
        !            22:   Documentation for the AdvanSys Driver
        !            23: 
        !            24:   A. Adapters Supported by this Driver
        !            25:   B. Linux 1.2.X - Directions for Adding the AdvanSys Driver
        !            26:   C. Linux 1.3.X - Directions for Adding the AdvanSys Driver
        !            27:   D. Source Comments
        !            28:   E. Driver Compile Time Options and Debugging
        !            29:   F. Driver LILO Option
        !            30:   G. Release History
        !            31:   H. Known Problems or Issues
        !            32:   I. Credits
        !            33:   J. AdvanSys Contact Information
        !            34: 
        !            35: 
        !            36:   A. Adapters Supported by this Driver
        !            37:  
        !            38:      AdvanSys (Advanced System Products, Inc.) manufactures the following
        !            39:      Bus-Mastering SCSI-2 Host Adapters for the ISA, EISA, VL, and PCI
        !            40:      buses. This Linux driver supports all of these adapters.
        !            41:      
        !            42:      The CDB counts below indicate the number of SCSI CDB (Command
        !            43:      Descriptor Block) requests that can be stored in the RISC chip
        !            44:      cache and board LRAM. The driver detect routine will display the
        !            45:      number of CDBs available for each adapter detected. This value
        !            46:      can be lowered in the BIOS by changing the 'Host Queue Size'
        !            47:      adapter setting.
        !            48: 
        !            49:      Connectivity Products:
        !            50:        ABP920 - Bus-Master PCI 16 CDB
        !            51:        ABP930 - Bus-Master PCI 16 CDB
        !            52:        ABP5140 - Bus-Master PnP ISA 16 CDB
        !            53:    
        !            54:      Single Channel Products:
        !            55:        ABP542 - Bus-Master ISA 240 CDB
        !            56:        ABP5150 - Bus-Master ISA 240 CDB *
        !            57:        ABP742 - Bus-Master EISA 240 CDB
        !            58:        ABP842 - Bus-Master VL 240 CDB
        !            59:        ABP940 - Bus-Master PCI 240 CDB
        !            60:    
        !            61:      Dual Channel Products:
        !            62:        ABP950 - Dual Channel Bus-Master PCI 240 CDB Per Channel
        !            63:        ABP852 - Dual Channel Bus-Master VL 240 CDB Per Channel
        !            64:        ABP752 - Dual Channel Bus-Master EISA 240 CDB Per Channel
        !            65: 
        !            66:      * This board is shipped by HP with the 4020i CD-R drive. It has
        !            67:        no BIOS so it cannot control a boot device, but it can control
        !            68:        any secondary devices.
        !            69:  
        !            70:   B. Linux 1.2.X - Directions for Adding the AdvanSys Driver
        !            71:  
        !            72:      There are two source files: advansys.h and advansys.c. Copy
        !            73:      both of these files to the directory /usr/src/linux/drivers/scsi.
        !            74:     
        !            75:      1. Add the following line to /usr/src/linux/arch/i386/config.in
        !            76:         after "comment 'SCSI low-level drivers'":
        !            77:     
        !            78:           bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y
        !            79:     
        !            80:      2. Add the following lines to /usr/src/linux/drivers/scsi/hosts.c
        !            81:         after "#include "hosts.h"":
        !            82:     
        !            83:           #ifdef CONFIG_SCSI_ADVANSYS
        !            84:           #include "advansys.h"
        !            85:           #endif
        !            86:     
        !            87:         and after "static Scsi_Host_Template builtin_scsi_hosts[] =":
        !            88:     
        !            89:           #ifdef CONFIG_SCSI_ADVANSYS
        !            90:           ADVANSYS,
        !            91:           #endif
        !            92:     
        !            93:      3. Add the following lines to /usr/src/linux/drivers/scsi/Makefile:
        !            94:     
        !            95:           ifdef CONFIG_SCSI_ADVANSYS
        !            96:           SCSI_SRCS := $(SCSI_SRCS) advansys.c
        !            97:           SCSI_OBJS := $(SCSI_OBJS) advansys.o
        !            98:           else
        !            99:           SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o
        !           100:           endif
        !           101: 
        !           102:      4. (Optional) If you would like to enable the LILO command line
        !           103:         and /etc/lilo.conf 'advansys' option, make the following changes.
        !           104:         This option can be used to disable I/O port scanning or to limit
        !           105:         I/O port scanning to specific addresses. Refer to the 'Driver
        !           106:         LILO Option' section below. Add the following lines to
        !           107:         /usr/src/linux/init/main.c in the prototype section:
        !           108: 
        !           109:           extern void advansys_setup(char *str, int *ints);
        !           110: 
        !           111:         and add the following lines to the bootsetups[] array.
        !           112: 
        !           113:           #ifdef CONFIG_SCSI_ADVANSYS
        !           114:              { "advansys=", advansys_setup },
        !           115:           #endif
        !           116: 
        !           117:      5. If you have the HP 4020i CD-R driver and Linux 1.2.X you should
        !           118:         add a fix to the CD-ROM target driver. This fix will allow
        !           119:         you to mount CDs with the iso9660 file system. Linux 1.3.X
        !           120:         already has this fix. In the file /usr/src/linux/drivers/scsi/sr.c
        !           121:         and function get_sectorsize() after the line:
        !           122: 
        !           123:         if(scsi_CDs[i].sector_size == 0) scsi_CDs[i].sector_size = 2048;
        !           124: 
        !           125:         add the following line:
        !           126: 
        !           127:         if(scsi_CDs[i].sector_size == 2340) scsi_CDs[i].sector_size = 2048;
        !           128: 
        !           129:      6. In the directory /usr/src/linux run 'make config' to configure
        !           130:         the AdvanSys driver, then run 'make vmlinux' or 'make zlilo' to
        !           131:         make the kernel. If the AdvanSys driver is not configured, then
        !           132:         a loadable module can be built by running 'make modules' and
        !           133:         'make modules_install'. Use 'insmod' and 'rmmod' to install
        !           134:         and remove advansys.o.
        !           135:  
        !           136:   C. Linux 1.3.X - Directions for Adding the AdvanSys Driver
        !           137: 
        !           138:      There are two source files: advansys.h and advansys.c. Copy
        !           139:      both of these files to the directory /usr/src/linux/drivers/scsi.
        !           140:    
        !           141:      1. Add the following line to /usr/src/linux/drivers/scsi/Config.in
        !           142:         after "comment 'SCSI low-level drivers'":
        !           143:    
        !           144:           dep_tristate 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS $CONFIG_SCSI
        !           145:    
        !           146:      2. Add the following lines to /usr/src/linux/drivers/scsi/hosts.c
        !           147:         after "#include "hosts.h"":
        !           148:    
        !           149:           #ifdef CONFIG_SCSI_ADVANSYS
        !           150:           #include "advansys.h"
        !           151:           #endif
        !           152:    
        !           153:         and after "static Scsi_Host_Template builtin_scsi_hosts[] =":
        !           154:    
        !           155:           #ifdef CONFIG_SCSI_ADVANSYS
        !           156:           ADVANSYS,
        !           157:           #endif
        !           158:    
        !           159:      3. Add the following lines to /usr/src/linux/drivers/scsi/Makefile:
        !           160:    
        !           161:           ifeq ($(CONFIG_SCSI_ADVANSYS),y)
        !           162:           L_OBJS += advansys.o
        !           163:           else
        !           164:             ifeq ($(CONFIG_SCSI_ADVANSYS),m)
        !           165:             M_OBJS += advansys.o
        !           166:             endif
        !           167:           endif
        !           168:    
        !           169:      4. Add the following line to /usr/src/linux/include/linux/proc_fs.h
        !           170:         in the enum scsi_directory_inos array:
        !           171:    
        !           172:           PROC_SCSI_ADVANSYS,
        !           173:    
        !           174:      5. (Optional) If you would like to enable the LILO command line
        !           175:         and /etc/lilo.conf 'advansys' option, make the following changes.
        !           176:         This option can be used to disable I/O port scanning or to limit
        !           177:         I/O port scanning to specific addresses. Refer to the 'Driver
        !           178:         LILO Option' section below. Add the following lines to
        !           179:         /usr/src/linux/init/main.c in the prototype section:
        !           180:    
        !           181:           extern void advansys_setup(char *str, int *ints);
        !           182:    
        !           183:         and add the following lines to the bootsetups[] array.
        !           184:    
        !           185:           #ifdef CONFIG_SCSI_ADVANSYS
        !           186:              { "advansys=", advansys_setup },
        !           187:           #endif
        !           188:    
        !           189:      6. In the directory /usr/src/linux run 'make config' to configure
        !           190:         the AdvanSys driver, then run 'make vmlinux' or 'make zlilo' to
        !           191:         make the kernel. If the AdvanSys driver is not configured, then
        !           192:         a loadable module can be built by running 'make modules' and
        !           193:         'make modules_install'. Use 'insmod' and 'rmmod' to install
        !           194:         and remove advansys.o.
        !           195: 
        !           196:   D. Source Comments
        !           197:  
        !           198:      1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'.
        !           199:  
        !           200:      2. This driver should be maintained in multiple files. But to make
        !           201:         it easier to include with Linux and to follow Linux conventions,
        !           202:         the whole driver is maintained in the source files advansys.h and
        !           203:         advansys.c. In this file logical sections of the driver begin with
        !           204:         a comment that contains '---'. The following are the logical sections
        !           205:         of the driver below.
        !           206:  
        !           207:            --- Linux Version
        !           208:            --- Linux Include Files 
        !           209:            --- Driver Options
        !           210:            --- Asc Library Constants and Macros
        !           211:            --- Debugging Header
        !           212:            --- Driver Constants
        !           213:            --- Driver Macros
        !           214:            --- Driver Structures
        !           215:            --- Driver Data
        !           216:            --- Driver Function Prototypes
        !           217:            --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
        !           218:            --- Loadable Driver Support
        !           219:            --- Miscellaneous Driver Functions
        !           220:            --- Functions Required by the Asc Library
        !           221:            --- Tracing and Debugging Functions
        !           222:            --- Asc Library Functions
        !           223:  
        !           224:      3. The string 'XXX' is used to flag code that needs to be re-written
        !           225:         or that contains a problem that needs to be addressed.
        !           226:  
        !           227:      4. I have stripped comments from and reformatted the source for the
        !           228:         Asc Library which is included in this file. I haven't done this
        !           229:         to obfuscate the code. Actually I have done this to deobfuscate
        !           230:         the code. The Asc Library source can be found under the following
        !           231:         headings.
        !           232:  
        !           233:            --- Asc Library Constants and Macros
        !           234:            --- Asc Library Functions
        !           235:  
        !           236:   E. Driver Compile Time Options and Debugging
        !           237:  
        !           238:      In this source file the following constants can be defined. They are
        !           239:      defined in the source below. Both of these options are enabled by
        !           240:      default.
        !           241:  
        !           242:      1. ADVANSYS_DEBUG - enable for debugging and assertions
        !           243:  
        !           244:         The amount of debugging output can be controlled with the global
        !           245:         variable 'asc_dbglvl'. The higher the number the more output. By
        !           246:         default the debug level is 0.
        !           247:         
        !           248:         If the driver is loaded at boot time and the LILO Driver Option
        !           249:         is included in the system, the debug level can be changed by
        !           250:         specifying a 5th (ASC_NUM_BOARD_SUPPORTED + 1) I/O Port. The
        !           251:         first three hex digits of the pseudo I/O Port must be set to
        !           252:         'deb' and the fourth hex digit specifies the debug level: 0 - F.
        !           253:         The following command line will look for an adapter at 0x330
        !           254:         and set the debug level to 2.
        !           255: 
        !           256:            linux advansys=0x330,0x0,0x0,0x0,0xdeb2
        !           257: 
        !           258:         If the driver is built as a loadable module this variable can be
        !           259:         defined when the driver is loaded. The following insmod command
        !           260:         will set the debug level to one.
        !           261:   
        !           262:            insmod advansys.o asc_dbglvl=1
        !           263:  
        !           264:  
        !           265:         Debugging Message Levels:
        !           266:            0: Errors Only
        !           267:            1: High-Level Tracing
        !           268:            2-N: Verbose Tracing
        !           269:  
        !           270:         I don't know the approved way for turning on printk()s to the
        !           271:         console. Here's a program I use to do this. Debug output is
        !           272:         logged in /var/adm/messages.
        !           273:  
        !           274:           main()
        !           275:           {
        !           276:                   syscall(103, 7, 0, 0);
        !           277:           }
        !           278:  
        !           279:         I found that increasing LOG_BUF_LEN to 40960 in kernel/printk.c
        !           280:         prevents most level 1 debug messages from being lost.
        !           281:  
        !           282:      2. ADVANSYS_STATS - enable statistics and tracing
        !           283:  
        !           284:         For Linux 1.2.X if ADVANSYS_STATS_1_2_PRINT is defined every
        !           285:         10,000 I/O operations the driver will print statistics to the
        !           286:         console. This value can be changed by modifying the constant
        !           287:         used in advansys_queuecommand(). ADVANSYS_STATS_1_2_PRINT is
        !           288:         off by default.
        !           289: 
        !           290:         For Linux 1.3.X statistics can be accessed by reading the
        !           291:         /proc/scsi/advansys/[0-9] files.
        !           292: 
        !           293:         Note: these statistics are currently maintained on a global driver
        !           294:         basis and not per board.
        !           295: 
        !           296:   F. Driver LILO Option
        !           297:  
        !           298:      If init/main.c is modified as described in the 'Directions for Adding
        !           299:      the AdvanSys Driver to Linux' section (B.4.) above, the driver will
        !           300:      recognize the 'advansys' LILO command line and /etc/lilo.conf option.
        !           301:      This option can be used to either disable I/O port scanning or to limit
        !           302:      scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and
        !           303:      PCI boards will still be searched for and detected. This option only
        !           304:      affects searching for ISA and VL boards.
        !           305: 
        !           306:      Examples:
        !           307:        1. Eliminate I/O port scanning:
        !           308:             boot: linux advansys=
        !           309:               or
        !           310:             boot: linux advansys=0x0
        !           311:        2. Limit I/O port scanning to one I/O port:
        !           312:             boot: linux advansys=0x110
        !           313:        3. Limit I/O port scanning to four I/O ports:
        !           314:             boot: linux advansys=0x110,0x210,0x230,0x330
        !           315: 
        !           316:      For a loadable module the same effect can be achieved by setting
        !           317:      the 'asc_iopflag' variable and 'asc_ioport' array when loading
        !           318:      the driver, e.g.
        !           319: 
        !           320:            insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330
        !           321: 
        !           322:      If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_BOARD_SUPPORTED + 1)
        !           323:      I/O Port may be added to specify the driver debug level. Refer to
        !           324:      the 'Driver Compile Time Options and Debugging' section above for
        !           325:      more information.
        !           326: 
        !           327:   G. Release History
        !           328: 
        !           329:      12/23/95 BETA-1.0:
        !           330:          First Release
        !           331: 
        !           332:      12/28/95 BETA-1.1:
        !           333:          1. Prevent advansys_detect() from being called twice.
        !           334:          2. Add LILO 0xdeb[0-f] option to set 'asc_dbglvl'.
        !           335: 
        !           336:      1/12/96 1.2:
        !           337:          1. Prevent re-entrancy in the interrupt handler which
        !           338:             resulted in the driver hanging Linux.
        !           339:          2. Fix problem that prevented ABP-940 cards from being
        !           340:             recognized on some PCI motherboards.
        !           341:          3. Add support for the ABP-5140 PnP ISA card.
        !           342:          4. Fix check condition return status.
        !           343:          5. Add conditionally compiled code for Linux 1.3.X.
        !           344:         
        !           345:   H. Known Problems or Issues
        !           346: 
        !           347:      1. The setting for 'cmd_per_lun' needs to be changed. It is currently
        !           348:         less then what the AdvanSys boards can queue. Because the target and
        !           349:         mid-level Linux drivers base memory allocation on 'cmd_per_lun' (as
        !           350:         well as 'sg_tablesize') memory use gets out of hand with a large
        !           351:         'cmd_per_lun'. 'cmd_per_lun' should be per device instead of per
        !           352:         adapter. When the driver is compiled as a loadable module both
        !           353:         'cmd_per_lun' and 'sg_tablesize' are tuned down to try to prevent
        !           354:         memory allocation errors.
        !           355: 
        !           356:      2. For the first scsi command sent to a device the driver increases
        !           357:         the timeout value. This gives the driver more time to perform
        !           358:         its own initialization for the board and each device. The timeout
        !           359:         value is only changed on the first scsi command for each device
        !           360:         and never thereafter.
        !           361: 
        !           362:   I. Credits
        !           363: 
        !           364:      Nathan Hartwell ([email protected]) provided the directions and
        !           365:      and basis for the Linux 1.3.X changes which were included in the
        !           366:      1.2 release.
        !           367: 
        !           368:   J. AdvanSys Contact Information
        !           369:  
        !           370:      Mail:                   Advanced System Products, Inc.
        !           371:                              1150 Ringwood Court
        !           372:                              San Jose, CA 95131 USA
        !           373:      Operator:               1-408-383-9400
        !           374:      FAX:                    1-408-383-9612
        !           375:      Tech Support:           1-800-525-7440
        !           376:      BBS:                    1-408-383-9540 (9600,N,8,1)
        !           377:      Interactive FAX:        1-408-383-9753
        !           378:      Customer Direct Sales:  1-800-883-1099
        !           379:      Tech Support E-Mail:    [email protected]
        !           380:      Linux Support E-Mail:   [email protected]
        !           381:      FTP Site:               ftp.advansys.com (login: anonymous)
        !           382:      Web Site:               http://www.advansys.com
        !           383: 
        !           384: */
        !           385: 
        !           386: 
        !           387: /*
        !           388:  * --- Linux Version
        !           389:  */
        !           390: 
        !           391: /*
        !           392:  * The driver can be used in Linux 1.2.X or 1.3.X.
        !           393:  */
        !           394: #if !defined(LINUX_1_2) && !defined(LINUX_1_3)
        !           395: #ifndef LINUX_VERSION_CODE
        !           396: #include <linux/version.h>
        !           397: #endif /* LINUX_VERSION_CODE */
        !           398: #if LINUX_VERSION_CODE > 65536 + 3 * 256
        !           399: #define LINUX_1_3
        !           400: #else /* LINUX_VERSION_CODE */
        !           401: #define LINUX_1_2
        !           402: #endif /* LINUX_VERSION_CODE */
        !           403: #endif /* !defined(LINUX_1_2) && !defined(LINUX_1_3) */
        !           404: 
        !           405: 
        !           406: /*
        !           407:  * --- Linux Include Files 
        !           408:  */
        !           409: 
        !           410: #ifdef MODULE
        !           411: #ifdef LINUX_1_3
        !           412: #include <linux/autoconf.h>
        !           413: #endif /* LINUX_1_3 */ 
        !           414: #include <linux/module.h>
        !           415: #endif /* MODULE */
        !           416: #include <linux/string.h>
        !           417: #include <linux/sched.h>
        !           418: #include <linux/kernel.h>
        !           419: #include <linux/head.h>
        !           420: #include <linux/types.h>
        !           421: #include <linux/ioport.h>
        !           422: #include <linux/delay.h>
        !           423: #include <linux/malloc.h>
        !           424: #include <linux/config.h>
        !           425: #ifdef LINUX_1_3
        !           426: #include <linux/proc_fs.h>
        !           427: #endif /* LINUX_1_3 */ 
        !           428: #include <asm/io.h>
        !           429: #include <asm/system.h>
        !           430: #include <asm/dma.h>
        !           431: #ifdef LINUX_1_2
        !           432: #include "../block/blk.h"
        !           433: #else /* LINUX_1_3 */ 
        !           434: #include <linux/blk.h>
        !           435: #include <linux/stat.h>
        !           436: #endif /* LINUX_1_3 */ 
        !           437: #include "scsi.h"
        !           438: #include "hosts.h"
        !           439: #include "sd.h"
        !           440: #include "advansys.h"
        !           441: 
        !           442: 
        !           443: /*
        !           444:  * --- Driver Options
        !           445:  */
        !           446: #define ADVANSYS_DEBUG /* Enable for debugging and assertions. */
        !           447: #define ADVANSYS_STATS /* Enable for statistics and tracing. */
        !           448: #ifdef LINUX_1_2
        !           449: #undef ADVANSYS_STATS_1_2_PRINT /* Enable to print statistics to console. */
        !           450: #endif /* LINUX_1_2 */
        !           451: 
        !           452: 
        !           453: /*
        !           454:  * --- Asc Library Constants and Macros
        !           455:  */
        !           456: 
        !           457: #define ASC_LIB_VERSION_MAJOR  1
        !           458: #define ASC_LIB_VERSION_MINOR  16
        !           459: #define ASC_LIB_SERIAL_NUMBER  53
        !           460: 
        !           461: typedef unsigned char uchar;
        !           462: typedef unsigned char BYTE;
        !           463: typedef unsigned short WORD;
        !           464: typedef unsigned long DWORD;
        !           465: 
        !           466: typedef int         BOOL;
        !           467: 
        !           468: #ifndef NULL
        !           469: #define NULL     (0)
        !           470: #endif
        !           471: 
        !           472: #ifndef TRUE
        !           473: #define TRUE     (1)
        !           474: #endif
        !           475: 
        !           476: #ifndef FALSE
        !           477: #define FALSE    (0)
        !           478: #endif
        !           479: 
        !           480: #define  REG     register
        !           481: 
        !           482: #define rchar    REG char
        !           483: #define rshort   REG short
        !           484: #define rint     REG int
        !           485: #define rlong    REG long
        !           486: 
        !           487: #define ruchar   REG uchar
        !           488: #define rushort  REG ushort
        !           489: #define ruint    REG uint
        !           490: #define rulong   REG ulong
        !           491: 
        !           492: #define NULLPTR   ( void *)0
        !           493: #define FNULLPTR  ( void dosfar *)0UL
        !           494: #define EOF      (-1)
        !           495: #define EOS      '\0'
        !           496: #define ERR      (-1)
        !           497: #define UB_ERR   (uchar)(0xFF)
        !           498: #define UW_ERR   (uint)(0xFFFF)
        !           499: #define UL_ERR   (ulong)(0xFFFFFFFFUL)
        !           500: 
        !           501: #define iseven_word( val )  ( ( ( ( uint )val) & ( uint )0x0001 ) == 0 )
        !           502: #define isodd_word( val )   ( ( ( ( uint )val) & ( uint )0x0001 ) != 0 )
        !           503: #define toeven_word( val )  ( ( ( uint )val ) & ( uint )0xFFFE )
        !           504: 
        !           505: #define biton( val, bits )   ((( uint )( val >> bits ) & (uint)0x0001 ) != 0 )
        !           506: #define bitoff( val, bits )  ((( uint )( val >> bits ) & (uint)0x0001 ) == 0 )
        !           507: #define lbiton( val, bits )  ((( ulong )( val >> bits ) & (ulong)0x00000001UL ) != 0 )
        !           508: #define lbitoff( val, bits ) ((( ulong )( val >> bits ) & (ulong)0x00000001UL ) == 0 )
        !           509: 
        !           510: #define  absh( val )    ( ( val ) < 0 ? -( val ) : ( val ) )
        !           511: 
        !           512: #define  swapbyte( ch )  ( ( ( (ch) << 4 ) | ( (ch) >> 4 ) ) )
        !           513: 
        !           514: #ifndef GBYTE
        !           515: #define GBYTE       (0x40000000UL)
        !           516: #endif
        !           517: 
        !           518: #ifndef MBYTE
        !           519: #define MBYTE       (0x100000UL)
        !           520: #endif
        !           521: 
        !           522: #ifndef KBYTE
        !           523: #define KBYTE       (0x400)
        !           524: #endif
        !           525: 
        !           526: #define HI_BYTE(x) ( *( ( BYTE *)(&x)+1 ) )
        !           527: #define LO_BYTE(x) ( *( ( BYTE *)&x ) )
        !           528: 
        !           529: #define HI_WORD(x) ( *( ( WORD *)(&x)+1 ) )
        !           530: #define LO_WORD(x) ( *( ( WORD *)&x ) )
        !           531: 
        !           532: #ifndef MAKEWORD
        !           533: #define MAKEWORD(lo, hi)    ((WORD) (((WORD) lo) | ((WORD) hi << 8)))
        !           534: #endif
        !           535: 
        !           536: #ifndef MAKELONG
        !           537: #define MAKELONG(lo, hi)    ((DWORD) (((DWORD) lo) | ((DWORD) hi << 16)))
        !           538: #endif
        !           539: 
        !           540: #define SwapWords(dWord)        ((DWORD) ((dWord >> 16) | (dWord << 16)))
        !           541: #define SwapBytes(word)         ((WORD) ((word >> 8) | (word << 8)))
        !           542: 
        !           543: #define BigToLittle(dWord) \
        !           544:     ((DWORD) (SwapWords(MAKELONG(SwapBytes(LO_WORD(dWord)), SwapBytes(HI_WORD(dWord))))))
        !           545: #define LittleToBig(dWord)      BigToLittle(dWord)
        !           546: 
        !           547: #define Lptr
        !           548: #define dosfar
        !           549: #define far
        !           550: #define PortAddr                       unsigned short
        !           551: #define Ptr2Func               ulong
        !           552: 
        !           553: #define inp(port)              inb(port)
        !           554: #define inpw(port)             inw(port)
        !           555: #define outp(port, byte)    outb((byte), (port))
        !           556: #define outpw(port, word)   outw((word), (port))
        !           557: 
        !           558: #define ASC_MAX_SG_QUEUE       5
        !           559: #define ASC_MAX_SG_LIST                (1 + ((ASC_SG_LIST_PER_Q) * (ASC_MAX_SG_QUEUE)))
        !           560: 
        !           561: #define CC_INIT_INQ_DISPLAY     FALSE
        !           562: 
        !           563: #define CC_CLEAR_LRAM_SRB_PTR   FALSE
        !           564: #define CC_VERIFY_LRAM_COPY     FALSE
        !           565: 
        !           566: #define CC_DEBUG_SG_LIST        FALSE
        !           567: #define CC_FAST_STRING_IO       FALSE
        !           568: 
        !           569: #define CC_WRITE_IO_COUNT       FALSE
        !           570: #define CC_CLEAR_DMA_REMAIN     FALSE
        !           571: 
        !           572: #define CC_DISABLE_PCI_PARITY_INT TRUE
        !           573: 
        !           574: #define CC_LINK_BUSY_Q         FALSE
        !           575: 
        !           576: #define CC_TARGET_MODE         FALSE
        !           577: 
        !           578: #define CC_SCAM                FALSE
        !           579: 
        !           580: #define CC_LITTLE_ENDIAN_HOST  TRUE
        !           581: 
        !           582: #ifndef CC_TEST_LRAM_ENDIAN
        !           583: 
        !           584: #if CC_LITTLE_ENDIAN_HOST
        !           585: #define CC_TEST_LRAM_ENDIAN     FALSE
        !           586: #else
        !           587: #define CC_TEST_LRAM_ENDIAN     TRUE
        !           588: #endif
        !           589: 
        !           590: #endif
        !           591: 
        !           592: #define CC_STRUCT_ALIGNED      TRUE
        !           593: 
        !           594: #define CC_MEMORY_MAPPED_IO    FALSE
        !           595: 
        !           596: #ifndef CC_TARGET_MODE
        !           597: #define CC_TARGET_MODE         FALSE
        !           598: #endif
        !           599: 
        !           600: #ifndef CC_STRUCT_ALIGNED
        !           601: #define CC_STRUCT_ALIGNED      FALSE
        !           602: #endif
        !           603: 
        !           604: #ifndef CC_LITTLE_ENDIAN_HOST
        !           605: #define CC_LITTLE_ENDIAN_HOST  TRUE
        !           606: #endif
        !           607: 
        !           608: #if !CC_LITTLE_ENDIAN_HOST
        !           609: 
        !           610: #ifndef CC_TEST_LRAM_ENDIAN
        !           611: #define CC_TEST_LRAM_ENDIAN    TRUE
        !           612: #endif
        !           613: 
        !           614: #endif
        !           615: 
        !           616: #ifndef CC_MEMORY_MAPPED_IO
        !           617: #define CC_MEMORY_MAPPED_IO    FALSE
        !           618: #endif
        !           619: 
        !           620: #ifndef CC_WRITE_IO_COUNT
        !           621: #define CC_WRITE_IO_COUNT      FALSE
        !           622: #endif
        !           623: 
        !           624: #ifndef CC_CLEAR_DMA_REMAIN
        !           625: #define CC_CLEAR_DMA_REMAIN    FALSE
        !           626: #endif
        !           627: 
        !           628: #define ASC_CS_TYPE  unsigned short
        !           629: 
        !           630: #ifndef asc_ptr_type
        !           631: #define asc_ptr_type
        !           632: #endif
        !           633: 
        !           634: #ifndef CC_SCAM
        !           635: #define CC_SCAM  FALSE
        !           636: #endif
        !           637: 
        !           638: #ifndef ASC_GET_PTR2FUNC
        !           639: #define ASC_GET_PTR2FUNC( fun )  ( Ptr2Func )( fun )
        !           640: #endif
        !           641: 
        !           642: #define FLIP_BYTE_NIBBLE( x )    ( ((x<<4)& 0xFF) | (x>>4) )
        !           643: 
        !           644: #define ASC_IS_ISA          (0x0001)
        !           645: #define ASC_IS_ISAPNP       (0x0081)
        !           646: #define ASC_IS_EISA         (0x0002)
        !           647: #define ASC_IS_PCI          (0x0004)
        !           648: #define ASC_IS_PCMCIA       (0x0008)
        !           649: #define ASC_IS_PNP          (0x0010)
        !           650: #define ASC_IS_MCA          (0x0020)
        !           651: #define ASC_IS_VL           (0x0040)
        !           652: 
        !           653: #define ASC_ISA_PNP_PORT_ADDR  (0x279)
        !           654: #define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
        !           655: 
        !           656: #define ASC_IS_WIDESCSI_16  (0x0100)
        !           657: #define ASC_IS_WIDESCSI_32  (0x0200)
        !           658: 
        !           659: #define ASC_IS_BIG_ENDIAN   (0x8000)
        !           660: 
        !           661: #define ASC_CHIP_MIN_VER_VL      (0x01)
        !           662: #define ASC_CHIP_MAX_VER_VL      (0x07)
        !           663: 
        !           664: #define ASC_CHIP_MIN_VER_PCI     (0x09)
        !           665: #define ASC_CHIP_MAX_VER_PCI     (0x0F)
        !           666: #define ASC_CHIP_VER_PCI_BIT     (0x08)
        !           667: 
        !           668: #define ASC_CHIP_MIN_VER_ISA     (0x11)
        !           669: #define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
        !           670: #define ASC_CHIP_MAX_VER_ISA     (0x27)
        !           671: #define ASC_CHIP_VER_ISA_BIT     (0x30)
        !           672: #define ASC_CHIP_VER_ISAPNP_BIT  (0x20)
        !           673: 
        !           674: #define ASC_CHIP_VER_ASYN_BUG    (0x21)
        !           675: 
        !           676: #define ASC_CHIP_MIN_VER_EISA (0x41)
        !           677: #define ASC_CHIP_MAX_VER_EISA (0x47)
        !           678: #define ASC_CHIP_VER_EISA_BIT (0x40)
        !           679: 
        !           680: #define ASC_MAX_VL_DMA_ADDR     (0x07FFFFFFL)
        !           681: #define ASC_MAX_VL_DMA_COUNT    (0x07FFFFFFL)
        !           682: 
        !           683: #define ASC_MAX_PCI_DMA_ADDR    (0xFFFFFFFFL)
        !           684: #define ASC_MAX_PCI_DMA_COUNT   (0xFFFFFFFFL)
        !           685: 
        !           686: #define ASC_MAX_ISA_DMA_ADDR    (0x00FFFFFFL)
        !           687: #define ASC_MAX_ISA_DMA_COUNT   (0x00FFFFFFL)
        !           688: 
        !           689: #define ASC_MAX_EISA_DMA_ADDR   (0x07FFFFFFL)
        !           690: #define ASC_MAX_EISA_DMA_COUNT  (0x07FFFFFFL)
        !           691: 
        !           692: #if !CC_STRUCT_ALIGNED
        !           693: 
        !           694: #define DvcGetQinfo( iop_base, s_addr, outbuf, words)  \
        !           695:         AscMemWordCopyFromLram( iop_base, s_addr, outbuf, words)
        !           696: 
        !           697: #define DvcPutScsiQ( iop_base, s_addr, outbuf, words) \
        !           698:         AscMemWordCopyToLram( iop_base, s_addr, outbuf, words)
        !           699: 
        !           700: #endif
        !           701: 
        !           702: #define ASC_SCSI_ID_BITS  3
        !           703: #define ASC_SCSI_TIX_TYPE     uchar
        !           704: #define ASC_ALL_DEVICE_BIT_SET  0xFF
        !           705: 
        !           706: #ifdef ASC_WIDESCSI_16
        !           707: 
        !           708: #undef  ASC_SCSI_ID_BITS
        !           709: #define ASC_SCSI_ID_BITS  4
        !           710: #define ASC_ALL_DEVICE_BIT_SET  0xFFFF
        !           711: 
        !           712: #endif
        !           713: 
        !           714: #ifdef ASC_WIDESCSI_32
        !           715: 
        !           716: #undef  ASC_SCSI_ID_BITS
        !           717: #define ASC_SCSI_ID_BITS  5
        !           718: #define ASC_ALL_DEVICE_BIT_SET  0xFFFFFFFFL
        !           719: 
        !           720: #endif
        !           721: 
        !           722: #if ASC_SCSI_ID_BITS == 3
        !           723: 
        !           724: #define ASC_SCSI_BIT_ID_TYPE  uchar
        !           725: #define ASC_MAX_TID       7
        !           726: #define ASC_MAX_LUN       7
        !           727: #define ASC_SCSI_WIDTH_BIT_SET  0xFF
        !           728: 
        !           729: #elif ASC_SCSI_ID_BITS == 4
        !           730: 
        !           731: #define ASC_SCSI_BIT_ID_TYPE   ushort
        !           732: #define ASC_MAX_TID         15
        !           733: #define ASC_MAX_LUN         7
        !           734: #define ASC_SCSI_WIDTH_BIT_SET  0xFFFF
        !           735: 
        !           736: #elif ASC_SCSI_ID_BITS == 5
        !           737: 
        !           738: #define ASC_SCSI_BIT_ID_TYPE    ulong
        !           739: #define ASC_MAX_TID         31
        !           740: #define ASC_MAX_LUN         7
        !           741: #define ASC_SCSI_WIDTH_BIT_SET  0xFFFFFFFF
        !           742: 
        !           743: #else
        !           744: 
        !           745: #error  ASC_SCSI_ID_BITS definition is wrong
        !           746: 
        !           747: #endif
        !           748: 
        !           749: #define ASC_MAX_SENSE_LEN   32
        !           750: #define ASC_MIN_SENSE_LEN   14
        !           751: 
        !           752: #define ASC_MAX_CDB_LEN     12
        !           753: 
        !           754: #define SCSICMD_TestUnitReady     0x00
        !           755: #define SCSICMD_Rewind            0x01
        !           756: #define SCSICMD_Rezero            0x01
        !           757: #define SCSICMD_RequestSense      0x03
        !           758: #define SCSICMD_Format            0x04
        !           759: #define SCSICMD_FormatUnit        0x04
        !           760: #define SCSICMD_Read6             0x08
        !           761: #define SCSICMD_Write6            0x0A
        !           762: #define SCSICMD_Seek6             0x0B
        !           763: #define SCSICMD_Inquiry           0x12
        !           764: #define SCSICMD_Verify6           0x13
        !           765: #define SCSICMD_ModeSelect6       0x15
        !           766: #define SCSICMD_ModeSense6        0x1A
        !           767: 
        !           768: #define SCSICMD_StartStopUnit     0x1B
        !           769: #define SCSICMD_LoadUnloadTape    0x1B
        !           770: #define SCSICMD_ReadCapacity      0x25
        !           771: #define SCSICMD_Read10            0x28
        !           772: #define SCSICMD_Write10           0x2A
        !           773: #define SCSICMD_Seek10            0x2B
        !           774: #define SCSICMD_Erase10           0x2C
        !           775: #define SCSICMD_WriteAndVerify10  0x2E
        !           776: #define SCSICMD_Verify10          0x2F
        !           777: 
        !           778: #define SCSICMD_ModeSelect10      0x55
        !           779: #define SCSICMD_ModeSense10       0x5A
        !           780: 
        !           781: #define SCSI_TYPE_DASD     0x00
        !           782: #define SCSI_TYPE_SASD     0x01
        !           783: #define SCSI_TYPE_PRN      0x02
        !           784: #define SCSI_TYPE_PROC     0x03
        !           785: 
        !           786: #define SCSI_TYPE_WORM     0x04
        !           787: #define SCSI_TYPE_CDROM    0x05
        !           788: #define SCSI_TYPE_SCANNER  0x06
        !           789: #define SCSI_TYPE_OPTMEM   0x07
        !           790: #define SCSI_TYPE_MED_CHG  0x08
        !           791: #define SCSI_TYPE_COMM     0x09
        !           792: #define SCSI_TYPE_UNKNOWN  0x1F
        !           793: #define SCSI_TYPE_NO_DVC   0xFF
        !           794: 
        !           795: #define ASC_SCSIDIR_NOCHK    0x00
        !           796: 
        !           797: #define ASC_SCSIDIR_T2H      0x08
        !           798: 
        !           799: #define ASC_SCSIDIR_H2T      0x10
        !           800: 
        !           801: #define ASC_SCSIDIR_NODATA   0x18
        !           802: 
        !           803: #define SCSI_SENKEY_NO_SENSE      0x00
        !           804: #define SCSI_SENKEY_UNDEFINED     0x01
        !           805: #define SCSI_SENKEY_NOT_READY     0x02
        !           806: #define SCSI_SENKEY_MEDIUM_ERR    0x03
        !           807: #define SCSI_SENKEY_HW_ERR        0x04
        !           808: #define SCSI_SENKEY_ILLEGAL       0x05
        !           809: #define SCSI_SENKEY_ATTENSION     0x06
        !           810: #define SCSI_SENKEY_PROTECTED     0x07
        !           811: #define SCSI_SENKEY_BLANK         0x08
        !           812: #define SCSI_SENKEY_V_UNIQUE      0x09
        !           813: #define SCSI_SENKEY_CPY_ABORT     0x0A
        !           814: #define SCSI_SENKEY_ABORT         0x0B
        !           815: #define SCSI_SENKEY_EQUAL         0x0C
        !           816: #define SCSI_SENKEY_VOL_OVERFLOW  0x0D
        !           817: #define SCSI_SENKEY_MISCOMP       0x0E
        !           818: #define SCSI_SENKEY_RESERVED      0x0F
        !           819: 
        !           820: #define ASC_SRB_HOST( x )  ( ( uchar )( ( uchar )( x ) >> 4 ) )
        !           821: #define ASC_SRB_TID( x )   ( ( uchar )( ( uchar )( x ) & ( uchar )0x0F ) )
        !           822: 
        !           823: #define ASC_SRB_LUN( x )   ( ( uchar )( ( uint )( x ) >> 13 ) )
        !           824: 
        !           825: #define PUT_CDB1( x )   ( ( uchar )( ( uint )( x ) >> 8 ) )
        !           826: 
        !           827: #define SS_GOOD              0x00
        !           828: #define SS_CHK_CONDITION     0x02
        !           829: #define SS_CONDITION_MET     0x04
        !           830: #define SS_TARGET_BUSY       0x08
        !           831: #define SS_INTERMID          0x10
        !           832: #define SS_INTERMID_COND_MET 0x14
        !           833: 
        !           834: #define SS_RSERV_CONFLICT    0x18
        !           835: #define SS_CMD_TERMINATED    0x22
        !           836: 
        !           837: #define SS_QUEUE_FULL        0x28
        !           838: 
        !           839: #define MS_CMD_DONE    0x00
        !           840: #define MS_EXTEND      0x01
        !           841: #define MS_SDTR_LEN    0x03
        !           842: #define MS_SDTR_CODE   0x01
        !           843: 
        !           844: #define M1_SAVE_DATA_PTR        0x02
        !           845: #define M1_RESTORE_PTRS         0x03
        !           846: #define M1_DISCONNECT           0x04
        !           847: #define M1_INIT_DETECTED_ERR    0x05
        !           848: #define M1_ABORT                0x06
        !           849: #define M1_MSG_REJECT           0x07
        !           850: #define M1_NO_OP                0x08
        !           851: #define M1_MSG_PARITY_ERR       0x09
        !           852: #define M1_LINK_CMD_DONE        0x0A
        !           853: #define M1_LINK_CMD_DONE_WFLAG  0x0B
        !           854: #define M1_BUS_DVC_RESET        0x0C
        !           855: #define M1_ABORT_TAG            0x0D
        !           856: #define M1_CLR_QUEUE            0x0E
        !           857: #define M1_INIT_RECOVERY        0x0F
        !           858: #define M1_RELEASE_RECOVERY     0x10
        !           859: #define M1_KILL_IO_PROC         0x11
        !           860: 
        !           861: #define M2_QTAG_MSG_SIMPLE      0x20
        !           862: #define M2_QTAG_MSG_HEAD        0x21
        !           863: #define M2_QTAG_MSG_ORDERED     0x22
        !           864: #define M2_IGNORE_WIDE_RESIDUE  0x23
        !           865: 
        !           866: typedef struct {
        !           867:        uchar               peri_dvc_type:5;
        !           868:        uchar               peri_qualifier:3;
        !           869: } ASC_SCSI_INQ0;
        !           870: 
        !           871: typedef struct {
        !           872:        uchar               dvc_type_modifier:7;
        !           873:        uchar               rmb:1;
        !           874: } ASC_SCSI_INQ1;
        !           875: 
        !           876: typedef struct {
        !           877:        uchar               ansi_apr_ver:3;
        !           878:        uchar               ecma_ver:3;
        !           879:        uchar               iso_ver:2;
        !           880: } ASC_SCSI_INQ2;
        !           881: 
        !           882: typedef struct {
        !           883:        uchar               rsp_data_fmt:4;
        !           884: 
        !           885:        uchar               res:2;
        !           886:        uchar               TemIOP:1;
        !           887:        uchar               aenc:1;
        !           888: } ASC_SCSI_INQ3;
        !           889: 
        !           890: typedef struct {
        !           891:        uchar               StfRe:1;
        !           892:        uchar               CmdQue:1;
        !           893:        uchar               Reserved:1;
        !           894:        uchar               Linked:1;
        !           895:        uchar               Sync:1;
        !           896:        uchar               WBus16:1;
        !           897:        uchar               WBus32:1;
        !           898:        uchar               RelAdr:1;
        !           899: } ASC_SCSI_INQ7;
        !           900: 
        !           901: typedef struct {
        !           902:        ASC_SCSI_INQ0       byte0;
        !           903:        ASC_SCSI_INQ1       byte1;
        !           904:        ASC_SCSI_INQ2       byte2;
        !           905:        ASC_SCSI_INQ3       byte3;
        !           906:        uchar               add_len;
        !           907:        uchar               res1;
        !           908:        uchar               res2;
        !           909:        ASC_SCSI_INQ7       byte7;
        !           910:        uchar               vendor_id[8];
        !           911:        uchar               product_id[16];
        !           912:        uchar               product_rev_level[4];
        !           913: } ASC_SCSI_INQUIRY;
        !           914: 
        !           915: typedef struct asc_req_sense {
        !           916:        uchar               err_code:7;
        !           917:        uchar               info_valid:1;
        !           918:        uchar               segment_no;
        !           919:        uchar               sense_key:4;
        !           920:        uchar               reserved_bit:1;
        !           921:        uchar               sense_ILI:1;
        !           922:        uchar               sense_EOM:1;
        !           923:        uchar               file_mark:1;
        !           924:        uchar               info1[4];
        !           925:        uchar               add_sense_len;
        !           926:        uchar               cmd_sp_info[4];
        !           927:        uchar               asc;
        !           928:        uchar               ascq;
        !           929: 
        !           930:        uchar               fruc;
        !           931:        uchar               sks_byte0:7;
        !           932:        uchar               sks_valid:1;
        !           933:        uchar               sks_bytes[2];
        !           934:        uchar               notused[2];
        !           935:        uchar               ex_sense_code;
        !           936:        uchar               info2[4];
        !           937: } ASC_REQ_SENSE;
        !           938: 
        !           939: #define ASC_SG_LIST_PER_Q   7
        !           940: 
        !           941: #define QS_FREE        0x00
        !           942: #define QS_READY       0x01
        !           943: #define QS_DISC1       0x02
        !           944: #define QS_DISC2       0x04
        !           945: #define QS_BUSY        0x08
        !           946: 
        !           947: #define QS_ABORTED     0x40
        !           948: #define QS_DONE        0x80
        !           949: 
        !           950: #define QC_NO_CALLBACK   0x01
        !           951: 
        !           952: #define QC_SG_SWAP_QUEUE 0x02
        !           953: #define QC_SG_HEAD       0x04
        !           954: #define QC_DATA_IN       0x08
        !           955: #define QC_DATA_OUT      0x10
        !           956: 
        !           957: #define QC_URGENT        0x20
        !           958: #define QC_MSG_OUT       0x40
        !           959: #define QC_REQ_SENSE     0x80
        !           960: 
        !           961: #define QCSG_SG_XFER_LIST  0x02
        !           962: #define QCSG_SG_XFER_MORE  0x04
        !           963: #define QCSG_SG_XFER_END   0x08
        !           964: 
        !           965: #define QD_IN_PROGRESS       0x00
        !           966: #define QD_NO_ERROR          0x01
        !           967: #define QD_ABORTED_BY_HOST   0x02
        !           968: #define QD_WITH_ERROR        0x04
        !           969: #define QD_INVALID_REQUEST   0x80
        !           970: #define QD_INVALID_HOST_NUM  0x81
        !           971: #define QD_INVALID_DEVICE    0x82
        !           972: #define QD_ERR_INTERNAL      0xFF
        !           973: 
        !           974: #define QHSTA_NO_ERROR               0x00
        !           975: #define QHSTA_M_SEL_TIMEOUT          0x11
        !           976: #define QHSTA_M_DATA_OVER_RUN        0x12
        !           977: #define QHSTA_M_DATA_UNDER_RUN       0x12
        !           978: #define QHSTA_M_UNEXPECTED_BUS_FREE  0x13
        !           979: #define QHSTA_M_BAD_BUS_PHASE_SEQ    0x14
        !           980: 
        !           981: #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
        !           982: #define QHSTA_D_ASC_DVC_ERROR_CODE_SET  0x22
        !           983: #define QHSTA_D_HOST_ABORT_FAILED       0x23
        !           984: #define QHSTA_D_EXE_SCSI_Q_FAILED       0x24
        !           985: #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
        !           986: 
        !           987: #define QHSTA_D_ASPI_NO_BUF_POOL        0x26
        !           988: 
        !           989: #define QHSTA_M_WTM_TIMEOUT         0x41
        !           990: #define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
        !           991: #define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
        !           992: #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
        !           993: #define QHSTA_M_TARGET_STATUS_BUSY  0x45
        !           994: #define QHSTA_M_BAD_TAG_CODE        0x46
        !           995: 
        !           996: #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY  0x47
        !           997: 
        !           998: #define QHSTA_D_LRAM_CMP_ERROR        0x81
        !           999: #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
        !          1000: 
        !          1001: #define ASC_FLAG_SCSIQ_REQ        0x01
        !          1002: #define ASC_FLAG_BIOS_SCSIQ_REQ   0x02
        !          1003: #define ASC_FLAG_BIOS_ASYNC_IO    0x04
        !          1004: #define ASC_FLAG_SRB_LINEAR_ADDR  0x08
        !          1005: 
        !          1006: #define ASC_FLAG_WIN16            0x10
        !          1007: #define ASC_FLAG_WIN32            0x20
        !          1008: 
        !          1009: #define ASC_FLAG_DOS_VM_CALLBACK  0x80
        !          1010: 
        !          1011: #define ASC_TAG_FLAG_ADD_ONE_BYTE     0x10
        !          1012: #define ASC_TAG_FLAG_ISAPNP_ADD_BYTES 0x40
        !          1013: 
        !          1014: #define ASC_SCSIQ_CPY_BEG              4
        !          1015: #define ASC_SCSIQ_SGHD_CPY_BEG         2
        !          1016: 
        !          1017: #define ASC_SCSIQ_B_FWD                0
        !          1018: #define ASC_SCSIQ_B_BWD                1
        !          1019: 
        !          1020: #define ASC_SCSIQ_B_STATUS             2
        !          1021: #define ASC_SCSIQ_B_QNO                3
        !          1022: 
        !          1023: #define ASC_SCSIQ_B_CNTL               4
        !          1024: #define ASC_SCSIQ_B_SG_QUEUE_CNT       5
        !          1025: 
        !          1026: #define ASC_SCSIQ_D_DATA_ADDR          8
        !          1027: #define ASC_SCSIQ_D_DATA_CNT          12
        !          1028: #define ASC_SCSIQ_B_SENSE_LEN         20
        !          1029: #define ASC_SCSIQ_DONE_INFO_BEG       22
        !          1030: #define ASC_SCSIQ_D_SRBPTR            22
        !          1031: #define ASC_SCSIQ_B_TARGET_IX         26
        !          1032: #define ASC_SCSIQ_B_CDB_LEN           28
        !          1033: #define ASC_SCSIQ_B_TAG_CODE          29
        !          1034: #define ASC_SCSIQ_W_VM_ID             30
        !          1035: #define ASC_SCSIQ_DONE_STATUS         32
        !          1036: #define ASC_SCSIQ_HOST_STATUS         33
        !          1037: #define ASC_SCSIQ_SCSI_STATUS         34
        !          1038: #define ASC_SCSIQ_CDB_BEG             36
        !          1039: #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
        !          1040: #define ASC_SCSIQ_DW_REMAIN_XFER_CNT  60
        !          1041: #define ASC_SCSIQ_B_SG_WK_QP          49
        !          1042: #define ASC_SCSIQ_B_SG_WK_IX          50
        !          1043: #define ASC_SCSIQ_W_REQ_COUNT         52
        !          1044: #define ASC_SCSIQ_B_LIST_CNT          6
        !          1045: #define ASC_SCSIQ_B_CUR_LIST_CNT      7
        !          1046: 
        !          1047: #define ASC_SGQ_B_SG_CNTL             4
        !          1048: #define ASC_SGQ_B_SG_HEAD_QP          5
        !          1049: #define ASC_SGQ_B_SG_LIST_CNT         6
        !          1050: #define ASC_SGQ_B_SG_CUR_LIST_CNT     7
        !          1051: #define ASC_SGQ_LIST_BEG              8
        !          1052: 
        !          1053: #define ASC_DEF_SCSI1_QNG    2
        !          1054: #define ASC_MAX_SCSI1_QNG    2
        !          1055: #define ASC_DEF_SCSI2_QNG    16
        !          1056: #define ASC_MAX_SCSI2_QNG    32
        !          1057: 
        !          1058: #define ASC_TAG_CODE_MASK    0x23
        !          1059: 
        !          1060: #define ASC_STOP_REQ_RISC_STOP      0x01
        !          1061: 
        !          1062: #define ASC_STOP_ACK_RISC_STOP      0x03
        !          1063: 
        !          1064: #define ASC_STOP_CLEAN_UP_BUSY_Q    0x10
        !          1065: #define ASC_STOP_CLEAN_UP_DISC_Q    0x20
        !          1066: #define ASC_STOP_HOST_REQ_RISC_HALT 0x40
        !          1067: #define ASC_STOP_SEND_INT_TO_HOST   0x80
        !          1068: 
        !          1069: #define ASC_TIDLUN_TO_IX( tid, lun )  ( ASC_SCSI_TIX_TYPE )( (tid) + ((lun)<<ASC_SCSI_ID_BITS) )
        !          1070: 
        !          1071: #define ASC_TID_TO_TARGET_ID( tid )   ( ASC_SCSI_BIT_ID_TYPE )( 0x01 << (tid) )
        !          1072: #define ASC_TIX_TO_TARGET_ID( tix )   ( 0x01 << ( (tix) & ASC_MAX_TID ) )
        !          1073: #define ASC_TIX_TO_TID( tix )  ( (tix) & ASC_MAX_TID )
        !          1074: #define ASC_TID_TO_TIX( tid )  ( (tid) & ASC_MAX_TID )
        !          1075: #define ASC_TIX_TO_LUN( tix )  ( ( (tix) >> ASC_SCSI_ID_BITS ) & ASC_MAX_LUN )
        !          1076: 
        !          1077: #define ASC_QNO_TO_QADDR( q_no )      ( (ASC_QADR_BEG)+( ( int )(q_no) << 6 ) )
        !          1078: 
        !          1079: typedef struct asc_scisq_1 {
        !          1080:        uchar               status;
        !          1081:        uchar               q_no;
        !          1082:        uchar               cntl;
        !          1083:        uchar               sg_queue_cnt;
        !          1084: 
        !          1085:        uchar               target_id;
        !          1086:        uchar               target_lun;
        !          1087: 
        !          1088:        ulong               data_addr;
        !          1089:        ulong               data_cnt;
        !          1090:        ulong               sense_addr;
        !          1091:        uchar               sense_len;
        !          1092:        uchar               user_def;
        !          1093: } ASC_SCSIQ_1;
        !          1094: 
        !          1095: typedef struct asc_scisq_2 {
        !          1096:        ulong               srb_ptr;
        !          1097:        uchar               target_ix;
        !          1098: 
        !          1099:        uchar               flag;
        !          1100:        uchar               cdb_len;
        !          1101:        uchar               tag_code;
        !          1102: 
        !          1103:        ushort              vm_id;
        !          1104: } ASC_SCSIQ_2;
        !          1105: 
        !          1106: typedef struct asc_scsiq_3 {
        !          1107:        uchar               done_stat;
        !          1108:        uchar               host_stat;
        !          1109:        uchar               scsi_stat;
        !          1110:        uchar               scsi_msg;
        !          1111: } ASC_SCSIQ_3;
        !          1112: 
        !          1113: typedef struct asc_scsiq_4 {
        !          1114:        uchar               cdb[ASC_MAX_CDB_LEN];
        !          1115:        uchar               y_first_sg_list_qp;
        !          1116:        uchar               y_working_sg_qp;
        !          1117:        uchar               y_working_sg_ix;
        !          1118:        uchar               y_cntl;
        !          1119:        ushort              x_req_count;
        !          1120:        ushort              x_reconnect_rtn;
        !          1121:        ulong               x_saved_data_addr;
        !          1122:        ulong               x_saved_data_cnt;
        !          1123: } ASC_SCSIQ_4;
        !          1124: 
        !          1125: typedef struct asc_q_done_info {
        !          1126:        ASC_SCSIQ_2         d2;
        !          1127:        ASC_SCSIQ_3         d3;
        !          1128:        uchar               q_status;
        !          1129:        uchar               q_no;
        !          1130:        uchar               cntl;
        !          1131:        uchar               sense_len;
        !          1132:        uchar               user_def;
        !          1133:        uchar               res;
        !          1134:        ulong               remain_bytes;
        !          1135: } ASC_QDONE_INFO;
        !          1136: 
        !          1137: typedef struct asc_sg_list {
        !          1138:        ulong               addr;
        !          1139:        ulong               bytes;
        !          1140: } ASC_SG_LIST;
        !          1141: 
        !          1142: typedef struct asc_sg_head {
        !          1143:        uchar               entry_cnt;
        !          1144: 
        !          1145:        uchar               queue_cnt;
        !          1146: 
        !          1147:        uchar               entry_to_copy;
        !          1148:        uchar               res;
        !          1149:        ASC_SG_LIST         sg_list[ASC_MAX_SG_LIST];
        !          1150: } ASC_SG_HEAD;
        !          1151: 
        !          1152: #define ASC_MIN_SG_LIST   2
        !          1153: 
        !          1154: typedef struct asc_min_sg_head {
        !          1155:        uchar               entry_cnt;
        !          1156: 
        !          1157:        uchar               queue_cnt;
        !          1158: 
        !          1159:        uchar               entry_to_copy;
        !          1160:        uchar               res;
        !          1161:        ASC_SG_LIST         sg_list[ASC_MIN_SG_LIST];
        !          1162: } ASC_MIN_SG_HEAD;
        !          1163: 
        !          1164: #define QCX_SORT        (0x0001)
        !          1165: #define QCX_COALEASE    (0x0002)
        !          1166: 
        !          1167: #if CC_LINK_BUSY_Q
        !          1168: typedef struct asc_ext_scsi_q {
        !          1169:        ulong               lba;
        !          1170:        ushort              lba_len;
        !          1171:        struct asc_scsi_q dosfar *next;
        !          1172:        struct asc_scsi_q dosfar *join;
        !          1173:        ushort              cntl;
        !          1174:        ushort              buffer_id;
        !          1175:        uchar               q_required;
        !          1176:        uchar               res;
        !          1177: } ASC_EXT_SCSI_Q;
        !          1178: 
        !          1179: #endif
        !          1180: 
        !          1181: typedef struct asc_scsi_q {
        !          1182:        ASC_SCSIQ_1         q1;
        !          1183:        ASC_SCSIQ_2         q2;
        !          1184:        uchar dosfar       *cdbptr;
        !          1185: 
        !          1186:        ASC_SG_HEAD dosfar *sg_head;
        !          1187: 
        !          1188: #if CC_LINK_BUSY_Q
        !          1189:        ASC_EXT_SCSI_Q      ext;
        !          1190: #endif
        !          1191: 
        !          1192: } ASC_SCSI_Q;
        !          1193: 
        !          1194: typedef struct asc_scsi_req_q {
        !          1195:        ASC_SCSIQ_1         r1;
        !          1196:        ASC_SCSIQ_2         r2;
        !          1197:        uchar dosfar       *cdbptr;
        !          1198:        ASC_SG_HEAD dosfar *sg_head;
        !          1199: 
        !          1200: #if CC_LINK_BUSY_Q
        !          1201:        ASC_EXT_SCSI_Q      ext;
        !          1202: #endif
        !          1203: 
        !          1204:        uchar dosfar       *sense_ptr;
        !          1205: 
        !          1206:        ASC_SCSIQ_3         r3;
        !          1207:        uchar               cdb[ASC_MAX_CDB_LEN];
        !          1208:        uchar               sense[ASC_MIN_SENSE_LEN];
        !          1209: } ASC_SCSI_REQ_Q;
        !          1210: 
        !          1211: typedef struct asc_risc_q {
        !          1212:        uchar               fwd;
        !          1213:        uchar               bwd;
        !          1214:        ASC_SCSIQ_1         i1;
        !          1215:        ASC_SCSIQ_2         i2;
        !          1216:        ASC_SCSIQ_3         i3;
        !          1217:        ASC_SCSIQ_4         i4;
        !          1218: } ASC_RISC_Q;
        !          1219: 
        !          1220: typedef struct asc_sg_list_q {
        !          1221: 
        !          1222:        uchar               seq_no;
        !          1223:        uchar               q_no;
        !          1224:        uchar               cntl;
        !          1225:        uchar               sg_head_qp;
        !          1226:        uchar               sg_list_cnt;
        !          1227:        uchar               sg_cur_list_cnt;
        !          1228: 
        !          1229: } ASC_SG_LIST_Q;
        !          1230: 
        !          1231: typedef struct asc_risc_sg_list_q {
        !          1232:        uchar               fwd;
        !          1233:        uchar               bwd;
        !          1234:        ASC_SG_LIST_Q       sg;
        !          1235:        ASC_SG_LIST         sg_list[7];
        !          1236: } ASC_RISC_SG_LIST_Q;
        !          1237: 
        !          1238: #define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP  0x1000000UL
        !          1239: #define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP  1024
        !          1240: 
        !          1241: #define ASCQ_ERR_NO_ERROR             0
        !          1242: #define ASCQ_ERR_IO_NOT_FOUND         1
        !          1243: #define ASCQ_ERR_LOCAL_MEM            2
        !          1244: #define ASCQ_ERR_CHKSUM               3
        !          1245: #define ASCQ_ERR_START_CHIP           4
        !          1246: #define ASCQ_ERR_INT_TARGET_ID        5
        !          1247: #define ASCQ_ERR_INT_LOCAL_MEM        6
        !          1248: #define ASCQ_ERR_HALT_RISC            7
        !          1249: #define ASCQ_ERR_GET_ASPI_ENTRY       8
        !          1250: #define ASCQ_ERR_CLOSE_ASPI           9
        !          1251: #define ASCQ_ERR_HOST_INQUIRY         0x0A
        !          1252: #define ASCQ_ERR_SAVED_SRB_BAD        0x0B
        !          1253: #define ASCQ_ERR_QCNTL_SG_LIST        0x0C
        !          1254: #define ASCQ_ERR_Q_STATUS             0x0D
        !          1255: #define ASCQ_ERR_WR_SCSIQ             0x0E
        !          1256: #define ASCQ_ERR_PC_ADDR              0x0F
        !          1257: #define ASCQ_ERR_SYN_OFFSET           0x10
        !          1258: #define ASCQ_ERR_SYN_XFER_TIME        0x11
        !          1259: #define ASCQ_ERR_LOCK_DMA             0x12
        !          1260: #define ASCQ_ERR_UNLOCK_DMA           0x13
        !          1261: #define ASCQ_ERR_VDS_CHK_INSTALL      0x14
        !          1262: #define ASCQ_ERR_MICRO_CODE_HALT      0x15
        !          1263: #define ASCQ_ERR_SET_LRAM_ADDR        0x16
        !          1264: #define ASCQ_ERR_CUR_QNG              0x17
        !          1265: #define ASCQ_ERR_SG_Q_LINKS           0x18
        !          1266: #define ASCQ_ERR_SCSIQ_PTR            0x19
        !          1267: #define ASCQ_ERR_ISR_RE_ENTRY         0x1A
        !          1268: #define ASCQ_ERR_CRITICAL_RE_ENTRY    0x1B
        !          1269: #define ASCQ_ERR_ISR_ON_CRITICAL      0x1C
        !          1270: #define ASCQ_ERR_SG_LIST_ODD_ADDRESS  0x1D
        !          1271: #define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
        !          1272: #define ASCQ_ERR_SCSIQ_NULL_PTR       0x1F
        !          1273: #define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR   0x20
        !          1274: #define ASCQ_ERR_GET_NUM_OF_FREE_Q    0x21
        !          1275: #define ASCQ_ERR_SEND_SCSI_Q          0x22
        !          1276: #define ASCQ_ERR_HOST_REQ_RISC_HALT   0x23
        !          1277: #define ASCQ_ERR_RESET_SDTR           0x24
        !          1278: 
        !          1279: #define ASC_WARN_NO_ERROR             0x0000
        !          1280: #define ASC_WARN_IO_PORT_ROTATE       0x0001
        !          1281: #define ASC_WARN_EEPROM_CHKSUM        0x0002
        !          1282: #define ASC_WARN_IRQ_MODIFIED         0x0004
        !          1283: #define ASC_WARN_AUTO_CONFIG          0x0008
        !          1284: #define ASC_WARN_CMD_QNG_CONFLICT     0x0010
        !          1285: 
        !          1286: #define ASC_WARN_EEPROM_RECOVER       0x0020
        !          1287: #define ASC_WARN_CFG_MSW_RECOVER      0x0040
        !          1288: 
        !          1289: #define ASC_IERR_WRITE_EEPROM         0x0001
        !          1290: #define ASC_IERR_MCODE_CHKSUM         0x0002
        !          1291: #define ASC_IERR_SET_PC_ADDR          0x0004
        !          1292: #define ASC_IERR_START_STOP_CHIP      0x0008
        !          1293: 
        !          1294: #define ASC_IERR_IRQ_NO               0x0010
        !          1295: 
        !          1296: #define ASC_IERR_SET_IRQ_NO           0x0020
        !          1297: #define ASC_IERR_CHIP_VERSION         0x0040
        !          1298: #define ASC_IERR_SET_SCSI_ID          0x0080
        !          1299: #define ASC_IERR_GET_PHY_ADDR         0x0100
        !          1300: #define ASC_IERR_BAD_SIGNATURE        0x0200
        !          1301: #define ASC_IERR_NO_BUS_TYPE          0x0400
        !          1302: #define ASC_IERR_SCAM                 0x0800
        !          1303: #define ASC_IERR_SET_SDTR             0x1000
        !          1304: #define ASC_IERR_RW_LRAM              0x8000
        !          1305: 
        !          1306: #define ASC_DEF_IRQ_NO  10
        !          1307: #define ASC_MAX_IRQ_NO  15
        !          1308: #define ASC_MIN_IRQ_NO  10
        !          1309: 
        !          1310: #define ASC_MIN_REMAIN_Q        (0x02)
        !          1311: #define ASC_DEF_MAX_TOTAL_QNG   (0x40)
        !          1312: 
        !          1313: #define ASC_MIN_TAG_Q_PER_DVC   (0x04)
        !          1314: #define ASC_DEF_TAG_Q_PER_DVC   (0x04)
        !          1315: 
        !          1316: #define ASC_MIN_FREE_Q        ASC_MIN_REMAIN_Q
        !          1317: 
        !          1318: #define ASC_MIN_TOTAL_QNG     (( ASC_MAX_SG_QUEUE )+( ASC_MIN_FREE_Q ))
        !          1319: 
        !          1320: #define ASC_MAX_TOTAL_QNG 240
        !          1321: #define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
        !          1322: 
        !          1323: #define ASC_MAX_INRAM_TAG_QNG   16
        !          1324: 
        !          1325: typedef struct asc_dvc_cfg {
        !          1326:        ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
        !          1327: 
        !          1328:        ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
        !          1329:        ASC_SCSI_BIT_ID_TYPE disc_enable;
        !          1330:        uchar               res;
        !          1331:        uchar               chip_scsi_id:4;
        !          1332: 
        !          1333:        uchar               isa_dma_speed:4;
        !          1334: 
        !          1335:        uchar               isa_dma_channel;
        !          1336:        uchar               chip_version;
        !          1337:        ushort              pci_device_id;
        !          1338:        ushort              lib_serial_no;
        !          1339:        ushort              lib_version;
        !          1340:        ushort              mcode_date;
        !          1341:        ushort              mcode_version;
        !          1342:        uchar               sdtr_data[ASC_MAX_TID + 1];
        !          1343:        uchar               max_tag_qng[ASC_MAX_TID + 1];
        !          1344:        uchar dosfar       *overrun_buf;
        !          1345: 
        !          1346: } ASC_DVC_CFG;
        !          1347: 
        !          1348: #define ASC_DEF_DVC_CNTL       0xFFFF
        !          1349: #define ASC_DEF_CHIP_SCSI_ID   7
        !          1350: #define ASC_DEF_ISA_DMA_SPEED  4
        !          1351: 
        !          1352: #define ASC_INIT_STATE_NULL          0x0000
        !          1353: #define ASC_INIT_STATE_BEG_GET_CFG   0x0001
        !          1354: #define ASC_INIT_STATE_END_GET_CFG   0x0002
        !          1355: #define ASC_INIT_STATE_BEG_SET_CFG   0x0004
        !          1356: #define ASC_INIT_STATE_END_SET_CFG   0x0008
        !          1357: #define ASC_INIT_STATE_BEG_LOAD_MC   0x0010
        !          1358: #define ASC_INIT_STATE_END_LOAD_MC   0x0020
        !          1359: #define ASC_INIT_STATE_BEG_INQUIRY   0x0040
        !          1360: #define ASC_INIT_STATE_END_INQUIRY   0x0080
        !          1361: #define ASC_INIT_RESET_SCSI_DONE     0x0100
        !          1362: 
        !          1363: #define ASC_PCI_DEVICE_ID_REV_A      0x1100
        !          1364: #define ASC_PCI_DEVICE_ID_REV_B      0x1200
        !          1365: 
        !          1366: #define ASC_BUG_FIX_ADD_ONE_BYTE     0x0001
        !          1367: 
        !          1368: #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
        !          1369: 
        !          1370: #define ASC_MIN_TAGGED_CMD  7
        !          1371: 
        !          1372: typedef struct asc_dvc_var {
        !          1373:        PortAddr            iop_base;
        !          1374:        ushort              err_code;
        !          1375:        ushort              dvc_cntl;
        !          1376:        ushort              bug_fix_cntl;
        !          1377:        ushort              bus_type;
        !          1378:        Ptr2Func            isr_callback;
        !          1379:        Ptr2Func            exe_callback;
        !          1380: 
        !          1381:        ASC_SCSI_BIT_ID_TYPE init_sdtr;
        !          1382: 
        !          1383:        ASC_SCSI_BIT_ID_TYPE sdtr_done;
        !          1384: 
        !          1385:        ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
        !          1386: 
        !          1387:        ASC_SCSI_BIT_ID_TYPE unit_not_ready;
        !          1388: 
        !          1389:        ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
        !          1390: 
        !          1391:        ASC_SCSI_BIT_ID_TYPE start_motor;
        !          1392:        uchar               scsi_reset_wait;
        !          1393:        uchar               chip_no;
        !          1394: 
        !          1395:        char                is_in_int;
        !          1396:        uchar               max_total_qng;
        !          1397: 
        !          1398:        uchar               cur_total_qng;
        !          1399: 
        !          1400:        uchar               in_critical_cnt;
        !          1401: 
        !          1402:        uchar               irq_no;
        !          1403:        uchar               last_q_shortage;
        !          1404: 
        !          1405:        ushort              init_state;
        !          1406:        uchar               cur_dvc_qng[ASC_MAX_TID + 1];
        !          1407:        uchar               max_dvc_qng[ASC_MAX_TID + 1];
        !          1408: 
        !          1409:        ASC_SCSI_Q dosfar  *scsiq_busy_head[ASC_MAX_TID + 1];
        !          1410:        ASC_SCSI_Q dosfar  *scsiq_busy_tail[ASC_MAX_TID + 1];
        !          1411: 
        !          1412:        ulong               int_count;
        !          1413:        ulong               req_count;
        !          1414:        ulong               busy_count;
        !          1415: 
        !          1416:        ASC_DVC_CFG dosfar *cfg;
        !          1417:        Ptr2Func            saved_ptr2func;
        !          1418:        ulong               reserved2;
        !          1419:        ulong               reserved3;
        !          1420:        ulong               max_dma_count;
        !          1421:        ASC_SCSI_BIT_ID_TYPE no_scam;
        !          1422:        ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
        !          1423: } ASC_DVC_VAR;
        !          1424: 
        !          1425: typedef int         (dosfar * ASC_ISR_CALLBACK) (ASC_DVC_VAR asc_ptr_type *, ASC_QDONE_INFO dosfar *);
        !          1426: typedef int         (dosfar * ASC_EXE_CALLBACK) (ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q dosfar *);
        !          1427: 
        !          1428: typedef struct asc_dvc_inq_info {
        !          1429:        uchar               type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
        !          1430: } ASC_DVC_INQ_INFO;
        !          1431: 
        !          1432: typedef struct asc_cap_info {
        !          1433:        ulong               lba;
        !          1434:        ulong               blk_size;
        !          1435: } ASC_CAP_INFO;
        !          1436: 
        !          1437: typedef struct asc_cap_info_array {
        !          1438:        ASC_CAP_INFO        cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
        !          1439: } ASC_CAP_INFO_ARRAY;
        !          1440: 
        !          1441: #define ASC_IOADR_TABLE_MAX_IX  11
        !          1442: #define ASC_IOADR_GAP   0x10
        !          1443: #define ASC_SEARCH_IOP_GAP 0x10
        !          1444: #define ASC_MIN_IOP_ADDR   ( PortAddr )0x0100
        !          1445: #define ASC_MAX_IOP_ADDR   ( PortAddr )0x3F0
        !          1446: 
        !          1447: #define ASC_IOADR_1     ( PortAddr )0x0110
        !          1448: #define ASC_IOADR_2     ( PortAddr )0x0130
        !          1449: #define ASC_IOADR_3     ( PortAddr )0x0150
        !          1450: #define ASC_IOADR_4     ( PortAddr )0x0190
        !          1451: #define ASC_IOADR_5     ( PortAddr )0x0210
        !          1452: #define ASC_IOADR_6     ( PortAddr )0x0230
        !          1453: #define ASC_IOADR_7     ( PortAddr )0x0250
        !          1454: #define ASC_IOADR_8     ( PortAddr )0x0330
        !          1455: #define ASC_IOADR_DEF   ASC_IOADR_8
        !          1456: 
        !          1457: #define ASC_SYN_XFER_NO   8
        !          1458: #define ASC_MAX_SDTR_PERIOD_INDEX  7
        !          1459: #define ASC_SYN_MAX_OFFSET   0x0F
        !          1460: #define ASC_DEF_SDTR_OFFSET  0x0F
        !          1461: #define ASC_DEF_SDTR_INDEX   0x00
        !          1462: 
        !          1463: #define SYN_XFER_NS_0  25
        !          1464: #define SYN_XFER_NS_1  30
        !          1465: #define SYN_XFER_NS_2  35
        !          1466: #define SYN_XFER_NS_3  40
        !          1467: #define SYN_XFER_NS_4  50
        !          1468: #define SYN_XFER_NS_5  60
        !          1469: #define SYN_XFER_NS_6  70
        !          1470: #define SYN_XFER_NS_7  85
        !          1471: 
        !          1472: #define ASC_SDTR_PERIOD_IX_MIN  7
        !          1473: 
        !          1474: #define SYN_XMSG_WLEN  3
        !          1475: 
        !          1476: typedef struct sdtr_xmsg {
        !          1477:        uchar               msg_type;
        !          1478:        uchar               msg_len;
        !          1479:        uchar               msg_req;
        !          1480:        uchar               xfer_period;
        !          1481:        uchar               req_ack_offset;
        !          1482:        uchar               res;
        !          1483: } SDTR_XMSG;
        !          1484: 
        !          1485: #define ASC_MCNTL_NO_SEL_TIMEOUT  ( ushort )0x0001
        !          1486: #define ASC_MCNTL_NULL_TARGET     ( ushort )0x0002
        !          1487: 
        !          1488: #define ASC_CNTL_INITIATOR         ( ushort )0x0001
        !          1489: #define ASC_CNTL_BIOS_GT_1GB       ( ushort )0x0002
        !          1490: #define ASC_CNTL_BIOS_GT_2_DISK    ( ushort )0x0004
        !          1491: #define ASC_CNTL_BIOS_REMOVABLE    ( ushort )0x0008
        !          1492: #define ASC_CNTL_NO_SCAM           ( ushort )0x0010
        !          1493: #define ASC_CNTL_NO_PCI_FIX_ASYN_XFER ( ushort )0x0020
        !          1494: 
        !          1495: #define ASC_CNTL_INT_MULTI_Q       ( ushort )0x0080
        !          1496: 
        !          1497: #define ASC_CNTL_NO_LUN_SUPPORT    ( ushort )0x0040
        !          1498: 
        !          1499: #define ASC_CNTL_NO_VERIFY_COPY    ( ushort )0x0100
        !          1500: #define ASC_CNTL_RESET_SCSI        ( ushort )0x0200
        !          1501: #define ASC_CNTL_INIT_INQUIRY      ( ushort )0x0400
        !          1502: #define ASC_CNTL_INIT_VERBOSE      ( ushort )0x0800
        !          1503: 
        !          1504: #define ASC_CNTL_SCSI_PARITY       ( ushort )0x1000
        !          1505: #define ASC_CNTL_BURST_MODE        ( ushort )0x2000
        !          1506: 
        !          1507: #define ASC_CNTL_USE_8_IOP_BASE    ( ushort )0x4000
        !          1508: 
        !          1509: #define ASC_EEP_DVC_CFG_BEG_VL    2
        !          1510: #define ASC_EEP_MAX_DVC_ADDR_VL   15
        !          1511: 
        !          1512: #define ASC_EEP_DVC_CFG_BEG      32
        !          1513: #define ASC_EEP_MAX_DVC_ADDR     45
        !          1514: 
        !          1515: #define ASC_EEP_DEFINED_WORDS    10
        !          1516: #define ASC_EEP_MAX_ADDR         63
        !          1517: #define ASC_EEP_RES_WORDS         0
        !          1518: #define ASC_EEP_MAX_RETRY        20
        !          1519: #define ASC_MAX_INIT_BUSY_RETRY   8
        !          1520: 
        !          1521: #define ASC_EEP_ISA_PNP_WSIZE    16
        !          1522: 
        !          1523: typedef struct asceep_config {
        !          1524:        ushort              cfg_lsw;
        !          1525:        ushort              cfg_msw;
        !          1526: 
        !          1527:        uchar               init_sdtr;
        !          1528:        uchar               disc_enable;
        !          1529: 
        !          1530:        uchar               use_cmd_qng;
        !          1531: 
        !          1532:        uchar               start_motor;
        !          1533:        uchar               max_total_qng;
        !          1534:        uchar               max_tag_qng;
        !          1535:        uchar               bios_scan;
        !          1536: 
        !          1537:        uchar               power_up_wait;
        !          1538: 
        !          1539:        uchar               no_scam;
        !          1540:        uchar               chip_scsi_id:4;
        !          1541: 
        !          1542:        uchar               isa_dma_speed:4;
        !          1543: 
        !          1544:        uchar               sdtr_data[ASC_MAX_TID + 1];
        !          1545: 
        !          1546:        uchar               adapter_info[6];
        !          1547: 
        !          1548:        ushort              cntl;
        !          1549: 
        !          1550:        ushort              chksum;
        !          1551: } ASCEEP_CONFIG;
        !          1552: 
        !          1553: #define ASC_EEP_CMD_READ          0x80
        !          1554: #define ASC_EEP_CMD_WRITE         0x40
        !          1555: #define ASC_EEP_CMD_WRITE_ABLE    0x30
        !          1556: #define ASC_EEP_CMD_WRITE_DISABLE 0x00
        !          1557: 
        !          1558: #define ASC_OVERRUN_BSIZE  0x00000048UL
        !          1559: 
        !          1560: #define ASCV_MSGOUT_BEG         0x0000
        !          1561: #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
        !          1562: #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
        !          1563: 
        !          1564: #define ASCV_MSGIN_BEG          (ASCV_MSGOUT_BEG+8)
        !          1565: #define ASCV_MSGIN_SDTR_PERIOD  (ASCV_MSGIN_BEG+3)
        !          1566: #define ASCV_MSGIN_SDTR_OFFSET  (ASCV_MSGIN_BEG+4)
        !          1567: 
        !          1568: #define ASCV_SDTR_DATA_BEG      (ASCV_MSGIN_BEG+8)
        !          1569: #define ASCV_SDTR_DONE_BEG      (ASCV_SDTR_DATA_BEG+8)
        !          1570: #define ASCV_MAX_DVC_QNG_BEG    ( ushort )0x0020
        !          1571: 
        !          1572: #define ASCV_ASCDVC_ERR_CODE_W  ( ushort )0x0030
        !          1573: #define ASCV_MCODE_CHKSUM_W   ( ushort )0x0032
        !          1574: #define ASCV_MCODE_SIZE_W     ( ushort )0x0034
        !          1575: #define ASCV_STOP_CODE_B      ( ushort )0x0036
        !          1576: #define ASCV_DVC_ERR_CODE_B   ( ushort )0x0037
        !          1577: 
        !          1578: #define ASCV_OVERRUN_PADDR_D  ( ushort )0x0038
        !          1579: #define ASCV_OVERRUN_BSIZE_D  ( ushort )0x003C
        !          1580: 
        !          1581: #define ASCV_HALTCODE_W       ( ushort )0x0040
        !          1582: #define ASCV_CHKSUM_W         ( ushort )0x0042
        !          1583: #define ASCV_MC_DATE_W        ( ushort )0x0044
        !          1584: #define ASCV_MC_VER_W         ( ushort )0x0046
        !          1585: #define ASCV_NEXTRDY_B        ( ushort )0x0048
        !          1586: #define ASCV_DONENEXT_B       ( ushort )0x0049
        !          1587: #define ASCV_USE_TAGGED_QNG_B ( ushort )0x004A
        !          1588: #define ASCV_SCSIBUSY_B       ( ushort )0x004B
        !          1589: #define ASCV_CDBCNT_B         ( ushort )0x004C
        !          1590: #define ASCV_CURCDB_B         ( ushort )0x004D
        !          1591: #define ASCV_RCLUN_B          ( ushort )0x004E
        !          1592: #define ASCV_BUSY_QHEAD_B     ( ushort )0x004F
        !          1593: #define ASCV_DISC1_QHEAD_B    ( ushort )0x0050
        !          1594: 
        !          1595: #define ASCV_DISC_ENABLE_B    ( ushort )0x0052
        !          1596: #define ASCV_CAN_TAGGED_QNG_B ( ushort )0x0053
        !          1597: #define ASCV_HOSTSCSI_ID_B    ( ushort )0x0055
        !          1598: #define ASCV_MCODE_CNTL_B     ( ushort )0x0056
        !          1599: #define ASCV_NULL_TARGET_B    ( ushort )0x0057
        !          1600: 
        !          1601: #define ASCV_FREE_Q_HEAD_W    ( ushort )0x0058
        !          1602: #define ASCV_DONE_Q_TAIL_W    ( ushort )0x005A
        !          1603: #define ASCV_FREE_Q_HEAD_B    ( ushort )(ASCV_FREE_Q_HEAD_W+1)
        !          1604: #define ASCV_DONE_Q_TAIL_B    ( ushort )(ASCV_DONE_Q_TAIL_W+1)
        !          1605: 
        !          1606: #define ASCV_HOST_FLAG_B      ( ushort )0x005D
        !          1607: 
        !          1608: #define ASCV_TOTAL_READY_Q_B  ( ushort )0x0064
        !          1609: #define ASCV_VER_SERIAL_B     ( ushort )0x0065
        !          1610: #define ASCV_HALTCODE_SAVED_W ( ushort )0x0066
        !          1611: #define ASCV_WTM_FLAG_B       ( ushort )0x0068
        !          1612: #define ASCV_RISC_FLAG_B      ( ushort )0x006A
        !          1613: #define ASCV_REQ_SG_LIST_QP   ( ushort )0x006B
        !          1614: 
        !          1615: #define ASC_HOST_FLAG_IN_ISR        0x01
        !          1616: #define ASC_HOST_FLAG_ACK_INT       0x02
        !          1617: 
        !          1618: #define ASC_RISC_FLAG_GEN_INT      0x01
        !          1619: #define ASC_RISC_FLAG_REQ_SG_LIST  0x02
        !          1620: 
        !          1621: #define IOP_CTRL         (0x0F)
        !          1622: #define IOP_STATUS       (0x0E)
        !          1623: #define IOP_INT_ACK      IOP_STATUS
        !          1624: 
        !          1625: #define IOP_REG_IFC      (0x0D)
        !          1626: 
        !          1627: #define IOP_SYN_OFFSET   (0x0B)
        !          1628: #define IOP_REG_PC       (0x0C)
        !          1629: #define IOP_RAM_ADDR     (0x0A)
        !          1630: #define IOP_RAM_DATA     (0x08)
        !          1631: #define IOP_EEP_DATA     (0x06)
        !          1632: #define IOP_EEP_CMD      (0x07)
        !          1633: 
        !          1634: #define IOP_VERSION      (0x03)
        !          1635: #define IOP_CONFIG_HIGH  (0x04)
        !          1636: #define IOP_CONFIG_LOW   (0x02)
        !          1637: #define IOP_ASPI_ID_LOW  (0x01)
        !          1638: #define IOP_ASPI_ID_HIGH (0x00)
        !          1639: 
        !          1640: #define IOP_REG_DC1      (0x0E)
        !          1641: #define IOP_REG_DC0      (0x0C)
        !          1642: #define IOP_REG_SB       (0x0B)
        !          1643: #define IOP_REG_DA1      (0x0A)
        !          1644: #define IOP_REG_DA0      (0x08)
        !          1645: #define IOP_REG_SC       (0x09)
        !          1646: #define IOP_DMA_SPEED    (0x07)
        !          1647: #define IOP_REG_FLAG     (0x07)
        !          1648: #define IOP_FIFO_H       (0x06)
        !          1649: #define IOP_FIFO_L       (0x04)
        !          1650: #define IOP_REG_ID       (0x05)
        !          1651: #define IOP_REG_QP       (0x03)
        !          1652: #define IOP_REG_IH       (0x02)
        !          1653: #define IOP_REG_IX       (0x01)
        !          1654: #define IOP_REG_AX       (0x00)
        !          1655: 
        !          1656: #define IFC_REG_LOCK      (0x00)
        !          1657: #define IFC_REG_UNLOCK    (0x09)
        !          1658: 
        !          1659: #define IFC_WR_EN_FILTER  (0x10)
        !          1660: #define IFC_RD_NO_EEPROM  (0x10)
        !          1661: #define IFC_SLEW_RATE     (0x20)
        !          1662: #define IFC_ACT_NEG       (0x40)
        !          1663: #define IFC_INP_FILTER    (0x80)
        !          1664: 
        !          1665: #define IFC_INIT_DEFAULT  ( IFC_ACT_NEG | IFC_REG_UNLOCK )
        !          1666: 
        !          1667: #define SC_SEL   (0x80)
        !          1668: #define SC_BSY   (0x40)
        !          1669: #define SC_ACK   (0x20)
        !          1670: #define SC_REQ   (0x10)
        !          1671: #define SC_ATN   (0x08)
        !          1672: #define SC_IO    (0x04)
        !          1673: #define SC_CD    (0x02)
        !          1674: #define SC_MSG   (0x01)
        !          1675: 
        !          1676: #define AscGetVarFreeQHead( port )       AscReadLramWord( port, ASCV_FREE_Q_HEAD_W )
        !          1677: #define AscGetVarDoneQTail( port )       AscReadLramWord( port, ASCV_DONE_Q_TAIL_W )
        !          1678: #define AscPutVarFreeQHead( port, val )  AscWriteLramWord( port, ASCV_FREE_Q_HEAD_W, val )
        !          1679: #define AscPutVarDoneQTail( port, val )  AscWriteLramWord( port, ASCV_DONE_Q_TAIL_W, val )
        !          1680: 
        !          1681: #define AscGetRiscVarFreeQHead( port )        AscReadLramByte( port, ASCV_NEXTRDY_B )
        !          1682: #define AscGetRiscVarDoneQTail( port )        AscReadLramByte( port, ASCV_DONENEXT_B )
        !          1683: #define AscPutRiscVarFreeQHead( port, val )   AscWriteLramByte( port, ASCV_NEXTRDY_B, val )
        !          1684: #define AscPutRiscVarDoneQTail( port, val )   AscWriteLramByte( port, ASCV_DONENEXT_B, val )
        !          1685: 
        !          1686: #define AscGetChipIFC( port )               inp( (port)+IOP_REG_IFC )
        !          1687: #define AscPutChipIFC( port, data )         outp( (port)+IOP_REG_IFC, data )
        !          1688: 
        !          1689: #define AscGetChipLramAddr( port )          ( ushort )inpw( ( PortAddr )((port)+IOP_RAM_ADDR) )
        !          1690: #define AscSetChipLramAddr( port, addr )    outpw( ( PortAddr )( (port)+IOP_RAM_ADDR ), addr )
        !          1691: #define AscPutChipLramData( port, data )    outpw( (port)+IOP_RAM_DATA, data )
        !          1692: #define AscGetChipLramData( port )          inpw( (port)+IOP_RAM_DATA )
        !          1693: 
        !          1694: #define AscWriteChipSyn( port, data )       outp( (port)+IOP_SYN_OFFSET, data )
        !          1695: #define AscReadChipSyn( port )              inp( (port)+IOP_SYN_OFFSET )
        !          1696: 
        !          1697: #define AscWriteChipIH( port, data )        outpw( (port)+IOP_REG_IH, data )
        !          1698: #define AscReadChipIH( port )               inpw( (port)+IOP_REG_IH )
        !          1699: 
        !          1700: #define AscWriteChipScsiID( port, data )    outp( (port)+IOP_REG_ID, data )
        !          1701: #define AscReadChipScsiID( port )           inp( (port)+IOP_REG_ID )
        !          1702: 
        !          1703: #define AscGetChipDmaSpeed( port )         ( uchar )inp( (port)+IOP_DMA_SPEED )
        !          1704: #define AscSetChipDmaSpeed( port, data )   outp( (port)+IOP_DMA_SPEED, data )
        !          1705: #define AscGetChipQP( port )               ( uchar )inp( (port)+IOP_REG_QP )
        !          1706: #define AscSetPCAddr( port, data )         outpw( (port)+IOP_REG_PC, data )
        !          1707: #define AscGetPCAddr( port )               inpw( (port)+IOP_REG_PC )
        !          1708: #define AscGetChipVerNo( port )            ( uchar )inp( (port)+IOP_VERSION )
        !          1709: 
        !          1710: #define AscGetChipEEPCmd( port )           ( uchar )inp( (port)+IOP_EEP_CMD )
        !          1711: #define AscSetChipEEPCmd( port, data )     outp( (port)+IOP_EEP_CMD, data )
        !          1712: #define AscGetChipEEPData( port )          inpw( (port)+IOP_EEP_DATA )
        !          1713: #define AscSetChipEEPData( port, data )    outpw( (port)+IOP_EEP_DATA, data )
        !          1714: 
        !          1715: #define AscGetChipControl( port )          ( uchar )inp( (port)+IOP_CTRL )
        !          1716: #define AscSetChipControl( port, cc_val )  outp( (port)+IOP_CTRL, cc_val )
        !          1717: 
        !          1718: #define AscGetChipStatus( port )           ( ASC_CS_TYPE )inpw( (port)+IOP_STATUS )
        !          1719: #define AscSetChipStatus( port, cs_val )   outpw( (port)+IOP_STATUS, cs_val )
        !          1720: 
        !          1721: #define AscGetChipCfgLsw( port )           ( ushort )inpw( (port)+IOP_CONFIG_LOW )
        !          1722: #define AscGetChipCfgMsw( port )           ( ushort )inpw( (port)+IOP_CONFIG_HIGH )
        !          1723: #define AscSetChipCfgLsw( port, data )     outpw( (port)+IOP_CONFIG_LOW, data )
        !          1724: #define AscSetChipCfgMsw( port, data )     outpw( (port)+IOP_CONFIG_HIGH, data )
        !          1725: 
        !          1726: #define AscIsIntPending( port )           ( AscGetChipStatus( port ) & CSW_INT_PENDING )
        !          1727: #define AscGetChipScsiID( port )          ( ( AscGetChipCfgLsw( port ) >> 8 ) & ASC_MAX_TID )
        !          1728: 
        !          1729: #define ASC_HALT_EXTMSG_IN     ( ushort )0x8000
        !          1730: #define ASC_HALT_CHK_CONDITION ( ushort )0x8100
        !          1731: #define ASC_HALT_SS_QUEUE_FULL ( ushort )0x8200
        !          1732: #define ASC_HALT_SDTR_REJECTED ( ushort )0x4000
        !          1733: 
        !          1734: #define ASC_MAX_QNO        0xF8
        !          1735: #define ASC_DATA_SEC_BEG   ( ushort )0x0080
        !          1736: #define ASC_DATA_SEC_END   ( ushort )0x0080
        !          1737: #define ASC_CODE_SEC_BEG   ( ushort )0x0080
        !          1738: #define ASC_CODE_SEC_END   ( ushort )0x0080
        !          1739: #define ASC_QADR_BEG       (0x4000)
        !          1740: #define ASC_QADR_USED      ( ushort )( ASC_MAX_QNO * 64 )
        !          1741: #define ASC_QADR_END       ( ushort )0x7FFF
        !          1742: #define ASC_QLAST_ADR      ( ushort )0x7FC0
        !          1743: #define ASC_QBLK_SIZE      0x40
        !          1744: #define ASC_BIOS_DATA_QBEG 0xF8
        !          1745: 
        !          1746: #define ASC_MIN_ACTIVE_QNO 0x01
        !          1747: 
        !          1748: #define ASC_QLINK_END      0xFF
        !          1749: #define ASC_EEPROM_WORDS   0x10
        !          1750: #define ASC_MAX_MGS_LEN    0x10
        !          1751: 
        !          1752: #define ASC_BIOS_ADDR_DEF  0xDC00
        !          1753: #define ASC_BIOS_SIZE      0x3800
        !          1754: #define ASC_BIOS_RAM_OFF   0x3800
        !          1755: #define ASC_BIOS_RAM_SIZE  0x800
        !          1756: #define ASC_BIOS_MIN_ADDR  0xC000
        !          1757: #define ASC_BIOS_MAX_ADDR  0xEC00
        !          1758: #define ASC_BIOS_BANK_SIZE 0x0400
        !          1759: 
        !          1760: #define ASC_MCODE_START_ADDR  0x0080
        !          1761: 
        !          1762: #define ASC_CFG0_HOST_INT_ON    0x0020
        !          1763: #define ASC_CFG0_BIOS_ON        0x0040
        !          1764: #define ASC_CFG0_VERA_BURST_ON  0x0080
        !          1765: #define ASC_CFG0_SCSI_PARITY_ON 0x0800
        !          1766: 
        !          1767: #define ASC_CFG1_SCSI_TARGET_ON 0x0080
        !          1768: #define ASC_CFG1_LRAM_8BITS_ON  0x0800
        !          1769: 
        !          1770: #define ASC_CFG_MSW_CLR_MASK    0xF0C0
        !          1771: 
        !          1772: #define CSW_TEST1             ( ASC_CS_TYPE )0x8000
        !          1773: #define CSW_AUTO_CONFIG       ( ASC_CS_TYPE )0x4000
        !          1774: #define CSW_RESERVED1         ( ASC_CS_TYPE )0x2000
        !          1775: #define CSW_IRQ_WRITTEN       ( ASC_CS_TYPE )0x1000
        !          1776: #define CSW_33MHZ_SELECTED    ( ASC_CS_TYPE )0x0800
        !          1777: #define CSW_TEST2             ( ASC_CS_TYPE )0x0400
        !          1778: #define CSW_TEST3             ( ASC_CS_TYPE )0x0200
        !          1779: #define CSW_RESERVED2         ( ASC_CS_TYPE )0x0100
        !          1780: #define CSW_DMA_DONE          ( ASC_CS_TYPE )0x0080
        !          1781: #define CSW_FIFO_RDY          ( ASC_CS_TYPE )0x0040
        !          1782: 
        !          1783: #define CSW_EEP_READ_DONE     ( ASC_CS_TYPE )0x0020
        !          1784: 
        !          1785: #define CSW_HALTED            ( ASC_CS_TYPE )0x0010
        !          1786: #define CSW_SCSI_RESET_ACTIVE ( ASC_CS_TYPE )0x0008
        !          1787: 
        !          1788: #define CSW_PARITY_ERR        ( ASC_CS_TYPE )0x0004
        !          1789: #define CSW_SCSI_RESET_LATCH  ( ASC_CS_TYPE )0x0002
        !          1790: 
        !          1791: #define CSW_INT_PENDING       ( ASC_CS_TYPE )0x0001
        !          1792: 
        !          1793: #define CIW_INT_ACK      ( ASC_CS_TYPE )0x0100
        !          1794: #define CIW_TEST1        ( ASC_CS_TYPE )0x0200
        !          1795: #define CIW_TEST2        ( ASC_CS_TYPE )0x0400
        !          1796: #define CIW_SEL_33MHZ    ( ASC_CS_TYPE )0x0800
        !          1797: 
        !          1798: #define CIW_IRQ_ACT      ( ASC_CS_TYPE )0x1000
        !          1799: 
        !          1800: #define CC_CHIP_RESET   ( uchar )0x80
        !          1801: #define CC_SCSI_RESET   ( uchar )0x40
        !          1802: #define CC_HALT         ( uchar )0x20
        !          1803: #define CC_SINGLE_STEP  ( uchar )0x10
        !          1804: #define CC_DMA_ABLE     ( uchar )0x08
        !          1805: #define CC_TEST         ( uchar )0x04
        !          1806: #define CC_BANK_ONE     ( uchar )0x02
        !          1807: #define CC_DIAG         ( uchar )0x01
        !          1808: 
        !          1809: #define ASC_1000_ID0W      0x04C1
        !          1810: #define ASC_1000_ID0W_FIX  0x00C1
        !          1811: #define ASC_1000_ID1B      0x25
        !          1812: 
        !          1813: #define ASC_EISA_BIG_IOP_GAP   (0x1C30-0x0C50)
        !          1814: #define ASC_EISA_SMALL_IOP_GAP (0x0020)
        !          1815: #define ASC_EISA_MIN_IOP_ADDR  (0x0C30)
        !          1816: #define ASC_EISA_MAX_IOP_ADDR  (0xFC50)
        !          1817: #define ASC_EISA_REV_IOP_MASK  (0x0C83)
        !          1818: #define ASC_EISA_PID_IOP_MASK  (0x0C80)
        !          1819: #define ASC_EISA_CFG_IOP_MASK  (0x0C86)
        !          1820: 
        !          1821: #define ASC_GET_EISA_SLOT( iop )  ( PortAddr )( (iop) & 0xF000 )
        !          1822: 
        !          1823: #define ASC_EISA_ID_740    0x01745004UL
        !          1824: #define ASC_EISA_ID_750    0x01755004UL
        !          1825: 
        !          1826: #define INS_HALTINT        ( ushort )0x6281
        !          1827: #define INS_HALT           ( ushort )0x6280
        !          1828: #define INS_SINT           ( ushort )0x6200
        !          1829: #define INS_RFLAG_WTM      ( ushort )0x7380
        !          1830: 
        !          1831: #define ASC_MC_SAVE_CODE_WSIZE  0x500
        !          1832: #define ASC_MC_SAVE_DATA_WSIZE  0x40
        !          1833: 
        !          1834: typedef struct asc_mc_saved {
        !          1835:        ushort              data[ASC_MC_SAVE_DATA_WSIZE];
        !          1836:        ushort              code[ASC_MC_SAVE_CODE_WSIZE];
        !          1837: } ASC_MC_SAVED;
        !          1838: 
        !          1839: int                 AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
        !          1840: int                 AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
        !          1841: void                AscWaitEEPRead(void);
        !          1842: void                AscWaitEEPWrite(void);
        !          1843: ushort              AscReadEEPWord(PortAddr, uchar);
        !          1844: ushort              AscWriteEEPWord(PortAddr, uchar, ushort);
        !          1845: ushort              AscGetEEPConfig(PortAddr, ASCEEP_CONFIG dosfar *, ushort);
        !          1846: int                 AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG dosfar *, ushort);
        !          1847: int                 AscSetEEPConfig(PortAddr, ASCEEP_CONFIG dosfar *, ushort);
        !          1848: ushort              AscEEPSum(PortAddr, uchar, uchar);
        !          1849: 
        !          1850: int                 AscStartChip(PortAddr);
        !          1851: int                 AscStopChip(PortAddr);
        !          1852: void                AscSetChipIH(PortAddr, ushort);
        !          1853: int                 AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
        !          1854: 
        !          1855: int                 AscIsChipHalted(PortAddr);
        !          1856: 
        !          1857: void                AscSetChipCfgDword(PortAddr, ulong);
        !          1858: ulong               AscGetChipCfgDword(PortAddr);
        !          1859: 
        !          1860: void                AscAckInterrupt(PortAddr);
        !          1861: void                AscDisableInterrupt(PortAddr);
        !          1862: void                AscEnableInterrupt(PortAddr);
        !          1863: void                AscSetBank(PortAddr, uchar);
        !          1864: uchar               AscGetBank(PortAddr);
        !          1865: int                 AscResetChipAndScsiBus(PortAddr);
        !          1866: ushort              AscGetIsaDmaChannel(PortAddr);
        !          1867: ushort              AscSetIsaDmaChannel(PortAddr, ushort);
        !          1868: uchar               AscSetIsaDmaSpeed(PortAddr, uchar);
        !          1869: uchar               AscGetIsaDmaSpeed(PortAddr);
        !          1870: 
        !          1871: uchar               AscReadLramByte(PortAddr, ushort);
        !          1872: ushort              AscReadLramWord(PortAddr, ushort);
        !          1873: ulong               AscReadLramDWord(PortAddr, ushort);
        !          1874: void                AscWriteLramWord(PortAddr, ushort, ushort);
        !          1875: void                AscWriteLramDWord(PortAddr, ushort, ulong);
        !          1876: void                AscWriteLramByte(PortAddr, ushort, uchar);
        !          1877: int                 AscVerWriteLramDWord(PortAddr, ushort, ulong);
        !          1878: int                 AscVerWriteLramWord(PortAddr, ushort, ushort);
        !          1879: int                 AscVerWriteLramByte(PortAddr, ushort, uchar);
        !          1880: 
        !          1881: ulong               AscMemSumLramWord(PortAddr, ushort, int);
        !          1882: void                AscMemWordSetLram(PortAddr, ushort, ushort, int);
        !          1883: void                AscMemWordCopyToLram(PortAddr, ushort, ushort dosfar *, int);
        !          1884: void                AscMemDWordCopyToLram(PortAddr, ushort, ulong dosfar *, int);
        !          1885: void                AscMemWordCopyFromLram(PortAddr, ushort, ushort dosfar *, int);
        !          1886: int                 AscMemWordCmpToLram(PortAddr, ushort, ushort dosfar *, int);
        !          1887: 
        !          1888: ushort              AscInitAscDvcVar(ASC_DVC_VAR asc_ptr_type *);
        !          1889: ulong               AscLoadMicroCode(PortAddr, ushort,
        !          1890:                                                                         ushort dosfar *, ushort);
        !          1891: ushort              AscInitFromEEP(ASC_DVC_VAR asc_ptr_type *);
        !          1892: ushort              AscInitFromAscDvcVar(ASC_DVC_VAR asc_ptr_type *);
        !          1893: ushort              AscInitMicroCodeVar(ASC_DVC_VAR asc_ptr_type * asc_dvc);
        !          1894: 
        !          1895: void dosfar         AscInitPollIsrCallBack(ASC_DVC_VAR asc_ptr_type *,
        !          1896:                                                                                   ASC_QDONE_INFO dosfar *);
        !          1897: int                 AscTestExternalLram(ASC_DVC_VAR asc_ptr_type *);
        !          1898: ushort              AscTestLramEndian(PortAddr);
        !          1899: 
        !          1900: uchar               AscMsgOutSDTR(PortAddr, uchar, uchar);
        !          1901: 
        !          1902: uchar               AscCalSDTRData(uchar, uchar);
        !          1903: void                AscSetChipSDTR(PortAddr, uchar, uchar);
        !          1904: int                 AscInitChipAllSynReg(ASC_DVC_VAR asc_ptr_type *, uchar);
        !          1905: uchar               AscGetSynPeriodIndex(uchar);
        !          1906: uchar               AscSynIndexToPeriod(uchar);
        !          1907: uchar               AscAllocFreeQueue(PortAddr, uchar);
        !          1908: uchar               AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
        !          1909: int                 AscRiscHaltedAbortSRB(ASC_DVC_VAR asc_ptr_type *, ulong);
        !          1910: int                 AscRiscHaltedAbortTIX(ASC_DVC_VAR asc_ptr_type *, uchar);
        !          1911: int                 AscRiscHaltedAbortALL(ASC_DVC_VAR asc_ptr_type *);
        !          1912: int                 AscHostReqRiscHalt(PortAddr);
        !          1913: int                 AscStopQueueExe(PortAddr);
        !          1914: int                 AscStartQueueExe(PortAddr);
        !          1915: int                 AscCleanUpDiscQueue(PortAddr);
        !          1916: int                 AscCleanUpBusyQueue(PortAddr);
        !          1917: int                 _AscAbortTidBusyQueue(ASC_DVC_VAR asc_ptr_type *,
        !          1918:                                                                                  ASC_QDONE_INFO dosfar *, uchar);
        !          1919: int                 _AscAbortSrbBusyQueue(ASC_DVC_VAR asc_ptr_type *,
        !          1920:                                                                                  ASC_QDONE_INFO dosfar *, ulong);
        !          1921: int                 AscWaitTixISRDone(ASC_DVC_VAR asc_ptr_type *, uchar);
        !          1922: int                 AscWaitISRDone(ASC_DVC_VAR asc_ptr_type *);
        !          1923: ulong               AscGetOnePhyAddr(ASC_DVC_VAR asc_ptr_type *, uchar dosfar *, ulong);
        !          1924: 
        !          1925: int                 AscSendScsiQueue(ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          1926:                                                                         ASC_SCSI_Q dosfar * scsiq,
        !          1927:                                                                         uchar n_q_required);
        !          1928: int                 AscPutReadyQueue(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q dosfar *, uchar);
        !          1929: int                 AscPutReadySgListQueue(ASC_DVC_VAR asc_ptr_type *,
        !          1930:                                                                                   ASC_SCSI_Q dosfar *, uchar);
        !          1931: int                 AscAbortScsiIO(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q dosfar *);
        !          1932: void                AscExeScsiIO(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q dosfar *);
        !          1933: int                 AscSetChipSynRegAtID(PortAddr, uchar, uchar);
        !          1934: int                 AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
        !          1935: ushort              AscInitLram(ASC_DVC_VAR asc_ptr_type *);
        !          1936: int                 AscReInitLram(ASC_DVC_VAR asc_ptr_type *);
        !          1937: ushort              AscInitQLinkVar(ASC_DVC_VAR asc_ptr_type *);
        !          1938: int                 AscSetLibErrorCode(ASC_DVC_VAR asc_ptr_type *, ushort);
        !          1939: int                 _AscWaitQDone(PortAddr, ASC_SCSI_Q dosfar *);
        !          1940: 
        !          1941: int                 AscEnterCritical(void);
        !          1942: void                AscLeaveCritical(int);
        !          1943: 
        !          1944: int                 AscIsrChipHalted(ASC_DVC_VAR asc_ptr_type *);
        !          1945: uchar               _AscCopyLramScsiDoneQ(PortAddr, ushort,
        !          1946:                                                                                  ASC_QDONE_INFO dosfar *, ulong);
        !          1947: int                 AscIsrQDone(ASC_DVC_VAR asc_ptr_type *);
        !          1948: ushort              AscIsrExeBusyQueue(ASC_DVC_VAR asc_ptr_type *, uchar);
        !          1949: int                 AscScsiSetupCmdQ(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_REQ_Q dosfar *,
        !          1950:                                                                         uchar dosfar *, ulong);
        !          1951: 
        !          1952: int                 AscScsiInquiry(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_REQ_Q dosfar *,
        !          1953:                                                                   uchar dosfar *, int);
        !          1954: int                 AscScsiTestUnitReady(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_REQ_Q dosfar *);
        !          1955: int                 AscScsiStartStopUnit(ASC_DVC_VAR asc_ptr_type *,
        !          1956:                                                                                 ASC_SCSI_REQ_Q dosfar *, uchar);
        !          1957: int                 AscScsiReadCapacity(ASC_DVC_VAR asc_ptr_type *,
        !          1958:                                                                                ASC_SCSI_REQ_Q dosfar *,
        !          1959:                                                                                uchar dosfar *);
        !          1960: 
        !          1961: ulong dosfar       *swapfarbuf4(uchar dosfar *);
        !          1962: int                 PollQueueDone(ASC_DVC_VAR asc_ptr_type *,
        !          1963:                                                                  ASC_SCSI_REQ_Q dosfar *,
        !          1964:                                                                  int);
        !          1965: int                 PollScsiReadCapacity(ASC_DVC_VAR asc_ptr_type *,
        !          1966:                                                                                 ASC_SCSI_REQ_Q dosfar *,
        !          1967:                                                                                 ASC_CAP_INFO dosfar *);
        !          1968: int                 PollScsiInquiry(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_REQ_Q dosfar *,
        !          1969:                                                                        uchar dosfar *, int);
        !          1970: int                 PollScsiTestUnitReady(ASC_DVC_VAR asc_ptr_type *,
        !          1971:                                                                                  ASC_SCSI_REQ_Q dosfar *);
        !          1972: int                 PollScsiStartUnit(ASC_DVC_VAR asc_ptr_type *,
        !          1973:                                                                          ASC_SCSI_REQ_Q dosfar *);
        !          1974: int                 InitTestUnitReady(ASC_DVC_VAR asc_ptr_type *,
        !          1975:                                                                          ASC_SCSI_REQ_Q dosfar *);
        !          1976: void                AscDispInquiry(uchar, uchar, ASC_SCSI_INQUIRY dosfar *);
        !          1977: int                 AscPollQDone(ASC_DVC_VAR asc_ptr_type *,
        !          1978:                                                                 ASC_SCSI_REQ_Q dosfar *, int);
        !          1979: 
        !          1980: int                 AscSetBIOSBank(PortAddr, int, ushort);
        !          1981: int                 AscSetVlBIOSBank(PortAddr, int);
        !          1982: int                 AscSetEisaBIOSBank(PortAddr, int);
        !          1983: int                 AscSetIsaBIOSBank(PortAddr, int);
        !          1984: 
        !          1985: int                 AscIsBiosEnabled(PortAddr, ushort);
        !          1986: void                AscResetScsiBus(PortAddr);
        !          1987: void                AscClrResetScsiBus(PortAddr);
        !          1988: 
        !          1989: void                AscSingleStepChip(PortAddr);
        !          1990: uchar               AscSetChipScsiID(PortAddr, uchar);
        !          1991: ushort              AscGetChipBiosAddress(PortAddr, ushort);
        !          1992: ushort              AscSetChipBiosAddress(PortAddr, ushort, ushort);
        !          1993: uchar               AscGetChipVersion(PortAddr, ushort);
        !          1994: ushort              AscGetChipBusType(PortAddr);
        !          1995: 
        !          1996: PortAddr            AscSearchIOPortAddr11(PortAddr);
        !          1997: PortAddr            AscSearchIOPortAddr100(PortAddr);
        !          1998: int                 AscFindSignature(PortAddr);
        !          1999: void                AscToggleIRQAct(PortAddr);
        !          2000: int                 AscResetChip(PortAddr);
        !          2001: void                AscClrResetChip(PortAddr);
        !          2002: 
        !          2003: short               itos(ushort, uchar dosfar *, short, short);
        !          2004: int                 insnchar(uchar dosfar *, short, short, ruchar, short);
        !          2005: void                itoh(ushort, ruchar dosfar *);
        !          2006: void                btoh(uchar, ruchar dosfar *);
        !          2007: void                ltoh(ulong, ruchar dosfar *);
        !          2008: uchar dosfar       *todstr(ushort, uchar dosfar *);
        !          2009: uchar dosfar       *tohstr(ushort, uchar dosfar *);
        !          2010: uchar dosfar       *tobhstr(uchar, uchar dosfar *);
        !          2011: uchar dosfar       *tolhstr(ulong, uchar dosfar *);
        !          2012: 
        !          2013: void                AscSetISAPNPWaitForKey(void);
        !          2014: uchar               AscGetChipIRQ(PortAddr, ushort);
        !          2015: uchar               AscSetChipIRQ(PortAddr, uchar, ushort);
        !          2016: uchar               AscGetChipScsiCtrl(PortAddr);
        !          2017: 
        !          2018: ushort              AscGetEisaChipCfg(PortAddr);
        !          2019: ushort              AscGetEisaChipGpReg(PortAddr);
        !          2020: ushort              AscSetEisaChipCfg(PortAddr, ushort);
        !          2021: ushort              AscSetEisaChipGpReg(PortAddr, ushort);
        !          2022: 
        !          2023: ulong               AscGetEisaProductID(PortAddr);
        !          2024: PortAddr            AscSearchIOPortAddrEISA(PortAddr);
        !          2025: 
        !          2026: int                 AscPollQTailSync(PortAddr);
        !          2027: int                 AscPollQHeadSync(PortAddr);
        !          2028: int                 AscWaitQTailSync(PortAddr);
        !          2029: 
        !          2030: int                 _AscRestoreMicroCode(PortAddr, ASC_MC_SAVED dosfar *);
        !          2031: 
        !          2032: int                 AscSCAM(ASC_DVC_VAR asc_ptr_type *);
        !          2033: 
        !          2034: ushort              SwapByteOfWord(ushort word_val);
        !          2035: ulong               SwapWordOfDWord(ulong dword_val);
        !          2036: ulong               AdjEndianDword(ulong dword_val);
        !          2037: 
        !          2038: int                 AscAdjEndianScsiQ(ASC_SCSI_Q dosfar *);
        !          2039: int                 AscAdjEndianQDoneInfo(ASC_QDONE_INFO dosfar *);
        !          2040: 
        !          2041: extern int          DvcEnterCritical(void);
        !          2042: extern void         DvcLeaveCritical(int);
        !          2043: 
        !          2044: extern void         DvcInPortWords(PortAddr, ushort dosfar *, int);
        !          2045: extern void         DvcOutPortWords(PortAddr, ushort dosfar *, int);
        !          2046: extern void         DvcOutPortDWords(PortAddr, ulong dosfar *, int);
        !          2047: 
        !          2048: extern void         DvcSleepMilliSecond(ulong);
        !          2049: extern void         DvcDisplayString(uchar dosfar *);
        !          2050: extern ulong        DvcGetPhyAddr(uchar dosfar * buf_addr, ulong buf_len);
        !          2051: extern ulong        DvcGetSGList(ASC_DVC_VAR asc_ptr_type *, uchar dosfar *, ulong,
        !          2052:                                                                 ASC_SG_HEAD dosfar *);
        !          2053: 
        !          2054: extern void         DvcSCAMDelayMS(ulong);
        !          2055: extern int          DvcDisableCPUInterrupt(void);
        !          2056: extern void         DvcRestoreCPUInterrupt(int);
        !          2057: 
        !          2058: void                DvcPutScsiQ(PortAddr, ushort, ushort dosfar *, int);
        !          2059: void                DvcGetQinfo(PortAddr, ushort, ushort dosfar *, int);
        !          2060: 
        !          2061: PortAddr            AscSearchIOPortAddr(PortAddr, ushort);
        !          2062: ushort              AscInitGetConfig(ASC_DVC_VAR asc_ptr_type *);
        !          2063: ushort              AscInitSetConfig(ASC_DVC_VAR asc_ptr_type *);
        !          2064: ushort              AscInitAsc1000Driver(ASC_DVC_VAR asc_ptr_type *);
        !          2065: int                 AscInitScsiTarget(ASC_DVC_VAR asc_ptr_type *,
        !          2066:                                                                          ASC_DVC_INQ_INFO dosfar *,
        !          2067:                                                                          uchar dosfar *,
        !          2068:                                                                          ASC_CAP_INFO_ARRAY dosfar *,
        !          2069:                                                                          ushort);
        !          2070: int                 AscInitPollBegin(ASC_DVC_VAR asc_ptr_type *);
        !          2071: int                 AscInitPollEnd(ASC_DVC_VAR asc_ptr_type *);
        !          2072: int                 AscInitPollTarget(ASC_DVC_VAR asc_ptr_type *,
        !          2073:                                                                          ASC_SCSI_REQ_Q dosfar *,
        !          2074:                                                                          ASC_SCSI_INQUIRY dosfar *,
        !          2075:                                                                          ASC_CAP_INFO dosfar *);
        !          2076: int                 AscExeScsiQueue(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q dosfar *);
        !          2077: 
        !          2078: int                 AscISR(ASC_DVC_VAR asc_ptr_type *);
        !          2079: void                AscISR_AckInterrupt(ASC_DVC_VAR asc_ptr_type *);
        !          2080: int                 AscISR_CheckQDone(ASC_DVC_VAR asc_ptr_type *,
        !          2081:                                                                          ASC_QDONE_INFO dosfar *,
        !          2082:                                                                          uchar dosfar *);
        !          2083: 
        !          2084: int                 AscStartUnit(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_TIX_TYPE);
        !          2085: int                 AscStopUnit(
        !          2086:                                                                   ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          2087:                                                                   ASC_SCSI_TIX_TYPE target_ix
        !          2088: );
        !          2089: 
        !          2090: uint                AscGetNumOfFreeQueue(ASC_DVC_VAR asc_ptr_type *, uchar, uchar);
        !          2091: int                 AscSgListToQueue(int);
        !          2092: int                 AscQueueToSgList(int);
        !          2093: int                 AscSetDvcErrorCode(ASC_DVC_VAR asc_ptr_type *, uchar);
        !          2094: 
        !          2095: int                 AscAbortSRB(ASC_DVC_VAR asc_ptr_type *, ulong);
        !          2096: int                 AscResetDevice(ASC_DVC_VAR asc_ptr_type *, uchar);
        !          2097: int                 AscResetSB(ASC_DVC_VAR asc_ptr_type *);
        !          2098: 
        !          2099: void                AscEnableIsaDma(uchar);
        !          2100: void                AscDisableIsaDma(uchar);
        !          2101: 
        !          2102: ulong               AscGetMaxDmaAddress(ushort);
        !          2103: ulong               AscGetMaxDmaCount(ushort);
        !          2104: 
        !          2105: int                 AscSaveMicroCode(ASC_DVC_VAR asc_ptr_type *, ASC_MC_SAVED dosfar *);
        !          2106: int                 AscRestoreOldMicroCode(ASC_DVC_VAR asc_ptr_type *, ASC_MC_SAVED dosfar *);
        !          2107: int                 AscRestoreNewMicroCode(ASC_DVC_VAR asc_ptr_type *, ASC_MC_SAVED dosfar *);
        !          2108: 
        !          2109: /*
        !          2110:  * --- Debugging Header
        !          2111:  */
        !          2112: 
        !          2113: #ifdef ADVANSYS_DEBUG
        !          2114: #define STATIC
        !          2115: #else /* ADVANSYS_DEBUG */
        !          2116: #define STATIC static
        !          2117: #endif /* ADVANSYS_DEBUG */
        !          2118: 
        !          2119: 
        !          2120: /*
        !          2121:  * --- Driver Constants and Macros
        !          2122:  */
        !          2123: 
        !          2124: #define ASC_NUM_BOARD_SUPPORTED 4
        !          2125: #define ASC_NUM_BUS                            4
        !          2126: 
        !          2127: /* Reference Scsi_Host hostdata */
        !          2128: #define ASC_BOARD(host) ((struct asc_board *) &(host)->hostdata)
        !          2129: 
        !          2130: #define NO_ISA_DMA     0xff            /* No ISA DMA Channel Used */
        !          2131: 
        !          2132: #ifndef min
        !          2133: #define min(a, b) (((a) < (b)) ? (a) : (b))
        !          2134: #endif /* min */
        !          2135: 
        !          2136: /* Asc Library return codes */
        !          2137: #define ASC_TRUE               1
        !          2138: #define ASC_FALSE              0
        !          2139: #define ASC_NOERROR            1
        !          2140: #define ASC_BUSY               0
        !          2141: #define ASC_ERROR              (-1)
        !          2142: 
        !          2143: /* Scsi_Cmnd function return codes */
        !          2144: #define STATUS_BYTE(byte)      (byte)
        !          2145: #define MSG_BYTE(byte)         ((byte) << 8)
        !          2146: #define HOST_BYTE(byte)                ((byte) << 16)
        !          2147: #define DRIVER_BYTE(byte)      ((byte) << 24)
        !          2148: 
        !          2149: /* asc_enqueue() flags */
        !          2150: #define ASC_FRONT              1
        !          2151: #define ASC_BACK               2
        !          2152: 
        !          2153: /* PCI configuration declarations */
        !          2154: 
        !          2155: #define ASC_PCI_REV_A_INIT             0x01
        !          2156: #define ASC_PCI_REV_A_DONE             0x02
        !          2157: #define ASC_PCI_REV_B_INIT             0x04
        !          2158: #define ASC_PCI_REV_B_DONE             0x08
        !          2159: 
        !          2160: #define PCI_BASE_CLASS_PREDEFINED                      0x00
        !          2161: #define PCI_BASE_CLASS_MASS_STORAGE                    0x01
        !          2162: #define PCI_BASE_CLASS_NETWORK                         0x02
        !          2163: #define PCI_BASE_CLASS_DISPLAY                         0x03
        !          2164: #define PCI_BASE_CLASS_MULTIMEDIA                      0x04
        !          2165: #define PCI_BASE_CLASS_MEMORY_CONTROLLER       0x05
        !          2166: #define PCI_BASE_CLASS_BRIDGE_DEVICE           0x06
        !          2167: 
        !          2168: /* MASS STORAGE */
        !          2169: #define PCI_SUB_CLASS_SCSI_CONTROLLER                  0x00
        !          2170: #define PCI_SUB_CLASS_IDE_CONTROLLER                   0x01
        !          2171: #define PCI_SUB_CLASS_FLOPPY_DISK_CONTROLLER   0x02
        !          2172: #define PCI_SUB_CLASS_IPI_BUS_CONTROLLER               0x03
        !          2173: #define PCI_SUB_CLASS_OTHER_MASS_CONTROLLER            0x80
        !          2174: 
        !          2175: /* NETWORK CONTROLLER */
        !          2176: #define PCI_SUB_CLASS_ETHERNET_CONTROLLER              0x00
        !          2177: #define PCI_SUB_CLASS_TOKEN_RING_CONTROLLER            0x01
        !          2178: #define PCI_SUB_CLASS_FDDI_CONTROLLER                  0x02
        !          2179: #define PCI_SUB_CLASS_OTHER_NETWORK_CONTROLLER 0x80
        !          2180: 
        !          2181: /* DISPLAY CONTROLLER */
        !          2182: #define PCI_SUB_CLASS_VGA_CONTROLLER                   0x00
        !          2183: #define PCI_SUB_CLASS_XGA_CONTROLLER                   0x01
        !          2184: #define PCI_SUB_CLASS_OTHER_DISPLAY_CONTROLLER 0x80
        !          2185: 
        !          2186: /* MULTIMEDIA CONTROLLER */
        !          2187: #define PCI_SUB_CLASS_VIDEO_DEVICE                             0x00
        !          2188: #define PCI_SUB_CLASS_AUDIO_DEVICE                             0x01
        !          2189: #define PCI_SUB_CLASS_OTHER_MULTIMEDIA_DEVICE  0x80
        !          2190: 
        !          2191: /* MEMORY CONTROLLER */
        !          2192: #define PCI_SUB_CLASS_RAM_CONTROLLER                   0x00
        !          2193: #define PCI_SUB_CLASS_FLASH_CONTROLLER                 0x01
        !          2194: #define PCI_SUB_CLASS_OTHER_MEMORY_CONTROLLER  0x80
        !          2195: 
        !          2196: /* BRIDGE CONTROLLER */
        !          2197: #define PCI_SUB_CLASS_HOST_BRIDGE_CONTROLLER           0x00
        !          2198: #define PCI_SUB_CLASS_ISA_BRIDGE_CONTROLLER                    0x01
        !          2199: #define PCI_SUB_CLASS_EISA_BRIDGE_CONTROLLER           0x02
        !          2200: #define PCI_SUB_CLASS_MC_BRIDGE_CONTROLLER                     0x03
        !          2201: #define PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER     0x04
        !          2202: #define PCI_SUB_CLASS_PCMCIA_BRIDGE_CONTROLLER         0x05
        !          2203: #define PCI_SUB_CLASS_OTHER_BRIDGE_CONTROLLER          0x80
        !          2204: 
        !          2205: #define PCI_MAX_SLOT                   0x1F
        !          2206: #define PCI_MAX_BUS                            0xFF
        !          2207: #define ASC_PCI_VENDORID               0x10CD
        !          2208: #define PCI_IOADDRESS_MASK             0xFFFE
        !          2209: 
        !          2210: /* PCI IO Port Addresses to generate special cycle */
        !          2211: 
        !          2212: #define PCI_CONFIG_ADDRESS_MECH1               0x0CF8
        !          2213: #define PCI_CONFIG_DATA_MECH1                  0x0CFC
        !          2214: 
        !          2215: #define PCI_CONFIG_FORWARD_REGISTER            0x0CFA  /* 0=type 0; 1=type 1; */
        !          2216: 
        !          2217: #define PCI_CONFIG_BUS_NUMBER_MASK             0x00FF0000
        !          2218: #define PCI_CONFIG_DEVICE_FUNCTION_MASK        0x0000FF00
        !          2219: #define PCI_CONFIG_REGISTER_NUMBER_MASK        0x000000F8
        !          2220: 
        !          2221: #define PCI_DEVICE_FOUND                               0x0000
        !          2222: #define PCI_DEVICE_NOT_FOUND                   0xffff
        !          2223: 
        !          2224: #define SUBCLASS_OFFSET        0x0A
        !          2225: #define CLASSCODE_OFFSET       0x0B
        !          2226: #define VENDORID_OFFSET                0x00
        !          2227: #define DEVICEID_OFFSET                0x02
        !          2228: 
        !          2229: /*
        !          2230:  * --- Driver Macros
        !          2231:  */
        !          2232: 
        !          2233: #ifndef ADVANSYS_STATS
        !          2234: #define ASC_STATS(counter)
        !          2235: #define ASC_STATS_ADD(counter, count)
        !          2236: #else /* ADVANSYS_STATS */
        !          2237: #define ASC_STATS(counter)                             asc_stats.counter++
        !          2238: #define ASC_STATS_ADD(counter, count)  asc_stats.counter += (count)
        !          2239: #endif /* ADVANSYS_STATS */
        !          2240: 
        !          2241: #ifndef ADVANSYS_DEBUG
        !          2242: 
        !          2243: #define        ASC_DBG(lvl, s)
        !          2244: #define        ASC_DBG1(lvl, s, a1)
        !          2245: #define        ASC_DBG2(lvl, s, a1, a2)
        !          2246: #define        ASC_DBG3(lvl, s, a1, a2, a3)
        !          2247: #define        ASC_DBG4(lvl, s, a1, a2, a3, a4)
        !          2248: #define        ASC_DBG_PRT_SCSI_HOST(lvl, s)
        !          2249: #define        ASC_DBG_PRT_DVC_VAR(lvl, v)
        !          2250: #define        ASC_DBG_PRT_DVC_CFG(lvl, c)
        !          2251: #define        ASC_DBG_PRT_SCSI_Q(lvl, scsiqp)
        !          2252: #define        ASC_DBG_PRT_QDONE_INFO(lvl, qdone)
        !          2253: #define        ASC_DBG_PRT_HEX(lvl, name, start, length)
        !          2254: #define        ASC_DBG_PRT_CDB(lvl, cdb, len)
        !          2255: #define        ASC_DBG_PRT_SENSE(lvl, sense, len)
        !          2256: #define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
        !          2257: #define ASC_ASSERT(a)
        !          2258: 
        !          2259: #else /* ADVANSYS_DEBUG */
        !          2260: 
        !          2261: /*
        !          2262:  * Debugging Message Levels:
        !          2263:  * 0: Errors Only
        !          2264:  * 1: High-Level Tracing
        !          2265:  * 2-N: Verbose Tracing
        !          2266:  */
        !          2267: 
        !          2268: #define        ASC_DBG(lvl, s) \
        !          2269:        { \
        !          2270:                if (asc_dbglvl >= (lvl)) { \
        !          2271:                        printk(s); \
        !          2272:                } \
        !          2273:        }
        !          2274: 
        !          2275: #define        ASC_DBG1(lvl, s, a1) \
        !          2276:        { \
        !          2277:                if (asc_dbglvl >= (lvl)) { \
        !          2278:                        printk((s), (a1)); \
        !          2279:                } \
        !          2280:        }
        !          2281: 
        !          2282: #define        ASC_DBG2(lvl, s, a1, a2) \
        !          2283:        { \
        !          2284:                if (asc_dbglvl >= (lvl)) { \
        !          2285:                        printk((s), (a1), (a2)); \
        !          2286:                } \
        !          2287:        }
        !          2288: 
        !          2289: #define        ASC_DBG3(lvl, s, a1, a2, a3) \
        !          2290:        { \
        !          2291:                if (asc_dbglvl >= (lvl)) { \
        !          2292:                        printk((s), (a1), (a2), (a3)); \
        !          2293:                } \
        !          2294:        }
        !          2295: 
        !          2296: #define        ASC_DBG4(lvl, s, a1, a2, a3, a4) \
        !          2297:        { \
        !          2298:                if (asc_dbglvl >= (lvl)) { \
        !          2299:                        printk((s), (a1), (a2), (a3), (a4)); \
        !          2300:                } \
        !          2301:        }
        !          2302: 
        !          2303: #define        ASC_DBG_PRT_SCSI_HOST(lvl, s) \
        !          2304:        { \
        !          2305:                if (asc_dbglvl >= (lvl)) { \
        !          2306:                        asc_prt_scsi_host(s); \
        !          2307:                } \
        !          2308:        }
        !          2309: 
        !          2310: #define        ASC_DBG_PRT_DVC_VAR(lvl, v) \
        !          2311:        { \
        !          2312:                if (asc_dbglvl >= (lvl)) { \
        !          2313:                        asc_prt_dvc_var(v); \
        !          2314:                } \
        !          2315:        }
        !          2316: 
        !          2317: #define        ASC_DBG_PRT_DVC_CFG(lvl, c) \
        !          2318:        { \
        !          2319:                if (asc_dbglvl >= (lvl)) { \
        !          2320:                        asc_prt_dvc_cfg(c); \
        !          2321:                } \
        !          2322:        }
        !          2323: 
        !          2324: #define        ASC_DBG_PRT_SCSI_Q(lvl, scsiqp) \
        !          2325:        { \
        !          2326:                if (asc_dbglvl >= (lvl)) { \
        !          2327:                        asc_prt_scsi_q(scsiqp); \
        !          2328:                } \
        !          2329:        }
        !          2330: 
        !          2331: #define        ASC_DBG_PRT_QDONE_INFO(lvl, qdone) \
        !          2332:        { \
        !          2333:                if (asc_dbglvl >= (lvl)) { \
        !          2334:                        asc_prt_qdone_info(qdone); \
        !          2335:                } \
        !          2336:        }
        !          2337: 
        !          2338: #define        ASC_DBG_PRT_HEX(lvl, name, start, length) \
        !          2339:        { \
        !          2340:                if (asc_dbglvl >= (lvl)) { \
        !          2341:                        asc_prt_hex((name), (start), (length)); \
        !          2342:                } \
        !          2343:        }
        !          2344: 
        !          2345: #define        ASC_DBG_PRT_CDB(lvl, cdb, len) \
        !          2346:                ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
        !          2347: 
        !          2348: #define        ASC_DBG_PRT_SENSE(lvl, sense, len) \
        !          2349:                ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
        !          2350: 
        !          2351: #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
        !          2352:                ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
        !          2353: 
        !          2354: #define ASC_ASSERT(a) \
        !          2355:        { \
        !          2356:                if (!(a)) { \
        !          2357:                        printk("ASC_ASSERT() Failure: file %s, line %d\n", \
        !          2358:                                __FILE__, __LINE__); \
        !          2359:                } \
        !          2360:        }
        !          2361: #endif /* ADVANSYS_DEBUG */
        !          2362: 
        !          2363: 
        !          2364: /*
        !          2365:  * --- Driver Structures
        !          2366:  */
        !          2367: 
        !          2368: /*
        !          2369:  * Structure allocated for each board.
        !          2370:  *
        !          2371:  * This structure is allocated by scsi_register() at the end
        !          2372:  * of the 'Scsi_Host' structure starting at the 'hostdata'
        !          2373:  * field. It is guaranteed to be allocated from DMA-able memory.
        !          2374:  */
        !          2375: struct asc_board {
        !          2376:        /* Asc Library */
        !          2377:        ASC_DVC_VAR                      board;                                 /* Board configuration */
        !          2378:        ASC_DVC_CFG                      cfg;                                   /* Device configuration */
        !          2379:        uchar                            overrun_buf[ASC_OVERRUN_BSIZE];
        !          2380:        /* Queued Commands */
        !          2381:        ASC_SCSI_BIT_ID_TYPE pending_tidmask;           /* Pending command mask */
        !          2382:        Scsi_Cmnd                        *pending[ASC_MAX_TID];
        !          2383:        /* Target Initialization */
        !          2384:        ASC_SCSI_BIT_ID_TYPE init_tidmask;                      /* Target initialized mask */
        !          2385:        ASC_SCSI_REQ_Q           scsireqq;
        !          2386:        ASC_CAP_INFO             cap_info;
        !          2387:        ASC_SCSI_INQUIRY         inquiry;
        !          2388: };
        !          2389: 
        !          2390: /*
        !          2391:  * PCI configuration structures
        !          2392:  */
        !          2393: typedef struct _PCI_DATA_
        !          2394: {
        !          2395:        uchar   type;
        !          2396:        uchar   bus;
        !          2397:        uchar   slot;
        !          2398:        uchar   func;
        !          2399:        uchar   offset;
        !          2400: } PCI_DATA;
        !          2401: 
        !          2402: typedef struct _PCI_DEVICE_
        !          2403: {
        !          2404:        ushort  vendorID;
        !          2405:        ushort  deviceID;
        !          2406:        ushort  slotNumber;
        !          2407:        ushort  slotFound;
        !          2408:        uchar   busNumber;
        !          2409:        uchar   maxBusNumber;
        !          2410:        uchar   devFunc;
        !          2411:        ushort  startSlot;
        !          2412:        ushort  endSlot;
        !          2413:        uchar   bridge;
        !          2414:        uchar   type;
        !          2415: } PCI_DEVICE;
        !          2416: 
        !          2417: typedef struct _PCI_CONFIG_SPACE_
        !          2418: {
        !          2419:        ushort  vendorID;
        !          2420:        ushort  deviceID;
        !          2421:        ushort  command;
        !          2422:        ushort  status;
        !          2423:        uchar   revision;
        !          2424:        uchar   classCode[3];
        !          2425:        uchar   cacheSize;
        !          2426:        uchar   latencyTimer;
        !          2427:        uchar   headerType;
        !          2428:        uchar   bist;
        !          2429:        ulong   baseAddress[6];
        !          2430:        ushort  reserved[4];
        !          2431:        ulong   optionRomAddr;
        !          2432:        ushort  reserved2[4];
        !          2433:        uchar   irqLine;
        !          2434:        uchar   irqPin;
        !          2435:        uchar   minGnt;
        !          2436:        uchar   maxLatency;
        !          2437: } PCI_CONFIG_SPACE;
        !          2438: 
        !          2439: #ifdef ADVANSYS_STATS
        !          2440: struct asc_stats {
        !          2441:        ulong   command;                /* # calls to advansys_command() */
        !          2442:        ulong   queuecommand;   /* # calls to advansys_queuecommand() */
        !          2443:        ulong   abort;                  /* # calls to advansys_abort() */
        !          2444:        ulong   reset;                  /* # calls to advansys_reset() */
        !          2445:        ulong   biosparam;              /* # calls to advansys_biosparam() */
        !          2446:        ulong   interrupt;              /* # calls to advansys_interrupt() */
        !          2447:        ulong   callback;               /* # calls asc_isr_callback() */
        !          2448:        ulong   cont_cnt;               /* # non-scatter-gather I/O requests received */
        !          2449:        ulong   cont_xfer;              /* contiguous transfer total (512 byte units) */
        !          2450:        ulong   sg_cnt;                 /* # scatter-gather I/O requests received */
        !          2451:        ulong   sg_elem;                /* scatter-gather element total */
        !          2452:        ulong   sg_xfer;                /* scatter-gather tranfer total (512 byte units) */
        !          2453:        ulong   error;                  /* # AscExeScsiQueue() ASC_ERROR returns. */
        !          2454:        /*
        !          2455:         * Number of times interrupts disabled in advansys_queuecommand() and
        !          2456:         * asc_isr_callback(), respectively. For the former indicates how many
        !          2457:         * times commands were pending when a new command was received.
        !          2458:         */
        !          2459:        ulong   cmd_disable;
        !          2460:        ulong   intr_disable;
        !          2461:        /*
        !          2462:         * Number of times asc_enqueue() called. Indicates how many ASC_BUSY
        !          2463:         * returns have occurred.
        !          2464:         */
        !          2465:        ulong   enqueue;
        !          2466:        ulong   dequeue;                /* # calls to asc_dequeue(). */
        !          2467:        /*
        !          2468:         * Number of times asc_rmqueue() called and the specified command
        !          2469:         * was found and removed.
        !          2470:         */
        !          2471:        ulong   rmqueue;
        !          2472: } asc_stats;
        !          2473: #endif /* ADVANSYS_STATS */
        !          2474: 
        !          2475: 
        !          2476: /*
        !          2477:  * --- Driver Data
        !          2478:  */
        !          2479: 
        !          2480: #ifdef LINUX_1_3
        !          2481: struct proc_dir_entry proc_scsi_advansys =
        !          2482: {
        !          2483:        PROC_SCSI_ADVANSYS,                             /* unsigned short low_ino */
        !          2484:        8,                                                              /* unsigned short namelen */
        !          2485:        "advansys",                                             /* const char *name */
        !          2486:        S_IFDIR | S_IRUGO | S_IXUGO,    /* mode_t mode */
        !          2487:        2                                                               /* nlink_t nlink */
        !          2488: };
        !          2489: #endif /* LINUX_1_3 */
        !          2490: 
        !          2491: STATIC int asc_board_count; /* Number of boards detected in system. */
        !          2492: STATIC struct Scsi_Host        *asc_host[ASC_NUM_BOARD_SUPPORTED];
        !          2493: STATIC Scsi_Cmnd *asc_scsi_done; /* Commands needing done function call. */
        !          2494: 
        !          2495: STATIC ushort asc_bus[ASC_NUM_BUS] = {
        !          2496:        ASC_IS_ISA,
        !          2497:        ASC_IS_VL,
        !          2498:        ASC_IS_EISA,
        !          2499:        ASC_IS_PCI,
        !          2500: };
        !          2501: 
        !          2502: /*
        !          2503:  * Used with the LILO 'advansys' option to eliminate or
        !          2504:  * limit I/O port probing at boot time, cf. advansys_setup().
        !          2505:  */
        !          2506: int asc_iopflag = ASC_FALSE;
        !          2507: int asc_ioport[ASC_NUM_BOARD_SUPPORTED] = { 0, 0, 0, 0 };
        !          2508: 
        !          2509: #ifdef ADVANSYS_DEBUG
        !          2510: char *
        !          2511: asc_bus_name[ASC_NUM_BUS] = {
        !          2512:        "ASC_IS_ISA",
        !          2513:        "ASC_IS_VL",
        !          2514:        "ASC_IS_EISA",
        !          2515:        "ASC_IS_PCI",
        !          2516: };
        !          2517: 
        !          2518: int            asc_dbglvl = 0;
        !          2519: #endif /* ADVANSYS_DEBUG */
        !          2520: 
        !          2521: 
        !          2522: /*
        !          2523:  * --- Driver Function Prototypes
        !          2524:  *
        !          2525:  * advansys.h contains function prototypes for functions global to Linux.
        !          2526:  */
        !          2527: 
        !          2528: #ifdef LINUX_1_3
        !          2529: STATIC int                     asc_proc_copy(off_t, off_t, char *, int , char *, int);
        !          2530: #endif /* LINUX_1_3 */
        !          2531: STATIC void            advansys_interrupt(int, struct pt_regs *);
        !          2532: STATIC void            advansys_command_done(Scsi_Cmnd *);
        !          2533: STATIC int                     asc_execute_scsi_cmnd(Scsi_Cmnd *);
        !          2534: STATIC void            asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
        !          2535: STATIC void                    asc_execute_pending(struct Scsi_Host *);
        !          2536: STATIC int                     asc_init_dev(ASC_DVC_VAR *, Scsi_Cmnd *);
        !          2537: STATIC int                     asc_srch_pci_dev(PCI_DEVICE *);
        !          2538: STATIC uchar           asc_scan_method(PCI_DEVICE *);
        !          2539: STATIC int                     asc_pci_find_dev(PCI_DEVICE *);
        !          2540: STATIC void            asc_get_pci_cfg(PCI_DEVICE *, PCI_CONFIG_SPACE *);
        !          2541: STATIC ushort          asc_get_cfg_word(PCI_DATA *);
        !          2542: STATIC uchar           asc_get_cfg_byte(PCI_DATA *);
        !          2543: STATIC void                    asc_enqueue(struct Scsi_Host *, Scsi_Cmnd *, int, int);
        !          2544: STATIC Scsi_Cmnd       *asc_dequeue(struct Scsi_Host *, int);
        !          2545: STATIC int                     asc_rmqueue(struct Scsi_Host *, Scsi_Cmnd *, int);
        !          2546: 
        !          2547: /* XXX - Asc Library Routines not supposed to be used directly */
        !          2548: ushort                         AscGetChipBiosAddress(PortAddr, ushort);
        !          2549: int             AscFindSignature(PortAddr);
        !          2550: 
        !          2551: #ifdef ADVANSYS_STATS
        !          2552: STATIC int             asc_prt_stats(char *, int);
        !          2553: STATIC int             asc_prt_stats_line(char *, int, char *fmt, ...);
        !          2554: #endif /* ADVANSYS_STATS */
        !          2555: #ifdef ADVANSYS_DEBUG
        !          2556: STATIC void    asc_prt_scsi_host(struct Scsi_Host *);
        !          2557: STATIC void    asc_prt_dvc_cfg(ASC_DVC_CFG *);
        !          2558: STATIC void    asc_prt_dvc_var(ASC_DVC_VAR *);
        !          2559: STATIC void    asc_prt_scsi_q(ASC_SCSI_Q *);
        !          2560: STATIC void    asc_prt_qdone_info(ASC_QDONE_INFO *);
        !          2561: STATIC void    asc_prt_hex(char *f, uchar *, int);
        !          2562: STATIC int             interrupts_enabled(void);
        !          2563: #endif /* ADVANSYS_DEBUG */
        !          2564: 
        !          2565: 
        !          2566: /*
        !          2567:  * --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
        !          2568:  */
        !          2569: 
        !          2570: #ifdef LINUX_1_3
        !          2571: /*
        !          2572:  * advansys_proc_info() - /proc/scsi/advansys/[0-ASC_NUM_BOARD_SUPPORTED]
        !          2573:  *
        !          2574:  * *buffer: I/O buffer
        !          2575:  * **start: if inout == FALSE pointer into buffer where user read should start
        !          2576:  * offset: current offset into /proc/scsi/advansys file
        !          2577:  * length: length of buffer
        !          2578:  * hostno: Scsi_Host host_no
        !          2579:  * inout: TRUE - user is writing; FALSE - user is reading
        !          2580:  *
        !          2581:  * Return the number of bytes read from or written to
        !          2582:  * /proc/scsi/advansys file.
        !          2583:  */
        !          2584: int
        !          2585: advansys_proc_info(char *buffer, char **start, off_t offset, int length, 
        !          2586:                                   int hostno, int inout)
        !          2587: {
        !          2588:        struct Scsi_Host        *shp;
        !          2589:        int                                     i;
        !          2590:        char                            *cp;
        !          2591:        int                                     cplen;
        !          2592:        int                                     cnt;
        !          2593:        int                                     totcnt;
        !          2594:        int                                     leftlen;
        !          2595:        char                            *curbuf;
        !          2596:        off_t                           advoffset;
        !          2597:     Scsi_Device                        *scd;
        !          2598:        char                            prtbuf[480];    /* 6 lines */
        !          2599: 
        !          2600:        ASC_DBG(1, "advansys_proc_info: begin\n");
        !          2601: 
        !          2602:        /*
        !          2603:         * User write not supported.
        !          2604:         */
        !          2605:        if (inout == TRUE) {
        !          2606:                return(-ENOSYS);
        !          2607:        }
        !          2608: 
        !          2609:        /*
        !          2610:         * User read of /proc/scsi/advansys file.
        !          2611:         */
        !          2612: 
        !          2613:        /* Find the specified board. */
        !          2614:        for (i = 0; i < asc_board_count; i++) {
        !          2615:                if (asc_host[i]->host_no == hostno) {
        !          2616:                        break;
        !          2617:                }
        !          2618:        }
        !          2619:        if (i == asc_board_count) {
        !          2620:                return(-ENOENT);
        !          2621:        }
        !          2622:        shp = asc_host[i];
        !          2623: 
        !          2624:        /* Always copy read data to the beginning of the buffer. */
        !          2625:        *start = buffer;
        !          2626: 
        !          2627:        curbuf = buffer;
        !          2628:        advoffset = 0;
        !          2629:        totcnt = 0;
        !          2630:        leftlen = length;
        !          2631: 
        !          2632:        /* Get board information. */
        !          2633:        cp = (char *) advansys_info(shp);
        !          2634:        strcat(cp, "\n");
        !          2635:        cplen = strlen(cp);
        !          2636: 
        !          2637:        /* Copy board information. */
        !          2638:        cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
        !          2639:        totcnt += cnt;
        !          2640:        leftlen -= cnt;
        !          2641:        if (leftlen == 0) {
        !          2642:                ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
        !          2643:                return totcnt;
        !          2644:        }
        !          2645:        advoffset += cplen;
        !          2646:        curbuf += cnt;
        !          2647: 
        !          2648:        /*
        !          2649:         * Get and copy information for each device attached to the board.
        !          2650:         */
        !          2651:        cp = &prtbuf[0];
        !          2652:        sprintf(cp, "\nDevices attached to SCSI Host %d:\n", shp->host_no);
        !          2653:        cplen = strlen(cp);
        !          2654:        cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
        !          2655:        totcnt += cnt;
        !          2656:        leftlen -= cnt;
        !          2657:        if (leftlen == 0) {
        !          2658:                ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
        !          2659:                return totcnt;
        !          2660:        }
        !          2661:        advoffset += cplen;
        !          2662:        curbuf += cnt;
        !          2663: 
        !          2664:        cp = &prtbuf[0];
        !          2665:     for (scd = scsi_devices; scd; scd = scd->next) {
        !          2666:                if (scd->host == shp) {
        !          2667:                proc_print_scsidevice(scd, cp, &cplen, 0);
        !          2668:                        cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
        !          2669:                        totcnt += cnt;
        !          2670:                        leftlen -= cnt;
        !          2671:                        if (leftlen == 0) {
        !          2672:                                ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
        !          2673:                                return totcnt;
        !          2674:                        }
        !          2675:                        advoffset += cplen;
        !          2676:                        curbuf += cnt;
        !          2677:                }
        !          2678:     }
        !          2679:     
        !          2680: #ifdef ADVANSYS_STATS
        !          2681:        /*
        !          2682:         * prtbuf[] has about 6 lines worth of space. If the statistics ever
        !          2683:         * get longer than 6 lines, prtbuf[] should be increased in size. If
        !          2684:         * prtbuf[] is too small it will not be overwritten. Instead the user
        !          2685:         * just won't get all of the available statistics.
        !          2686:         */
        !          2687:        cp = &prtbuf[0];
        !          2688:        cplen = asc_prt_stats(cp, sizeof(prtbuf));
        !          2689:        cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
        !          2690:        totcnt += cnt;
        !          2691:        leftlen -= cnt;
        !          2692:        if (leftlen == 0) {
        !          2693:                ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
        !          2694:                return totcnt;
        !          2695:        }
        !          2696:        advoffset += cplen;
        !          2697:        curbuf += cnt;
        !          2698: #endif /* ADVANSYS_STATS */
        !          2699: 
        !          2700:        ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
        !          2701: 
        !          2702:        return totcnt;
        !          2703: }
        !          2704: #endif /* LINUX_1_3 */
        !          2705: 
        !          2706: 
        !          2707: /*
        !          2708:  * advansys_detect()
        !          2709:  *
        !          2710:  * Detect function for AdvanSys adapters.
        !          2711:  *
        !          2712:  * Argument is a pointer to the host driver's scsi_hosts entry.
        !          2713:  *
        !          2714:  * Return number of adapters found.
        !          2715:  *
        !          2716:  * Note: Because this function is called during system initialization
        !          2717:  * it must not call SCSI mid-level functions including scsi_malloc()
        !          2718:  * and scsi_free().
        !          2719:  */
        !          2720: int
        !          2721: advansys_detect(Scsi_Host_Template *tpnt)
        !          2722: {
        !          2723:        static int                      detect_called = ASC_FALSE;
        !          2724:        int                                     iop;
        !          2725:        int                                     bus;
        !          2726:        struct Scsi_Host        *shp;
        !          2727:        ASC_DVC_VAR                     *boardp;
        !          2728:        int                                     ioport = 0;
        !          2729:        PCI_DEVICE                      pciDevice;
        !          2730:        PCI_CONFIG_SPACE        pciConfig;
        !          2731:        int                                     ret;
        !          2732:        extern PortAddr         _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX];
        !          2733: 
        !          2734: 
        !          2735:        if (detect_called == ASC_FALSE) {
        !          2736:                detect_called = ASC_TRUE;
        !          2737:        } else {
        !          2738:                printk("AdvanSys SCSI: advansys_detect() mulitple calls ignored\n");
        !          2739:                return 0;
        !          2740:        }
        !          2741: 
        !          2742:        ASC_DBG(1, "advansys_detect: begin\n");
        !          2743: 
        !          2744: #ifdef LINUX_1_3
        !          2745:        tpnt->proc_dir = &proc_scsi_advansys;
        !          2746: #endif /* LINUX_1_3 */
        !          2747: 
        !          2748: #ifdef ADVANSYS_STATS
        !          2749:        memset(&asc_stats, 0, sizeof(asc_stats));
        !          2750: #endif /* ADVANSYS_STATS */
        !          2751: 
        !          2752:        asc_board_count = 0;
        !          2753: 
        !          2754:        /*
        !          2755:         * If I/O port probing has been modified, then verify and
        !          2756:         * clean-up the 'asc_ioport' list.
        !          2757:         */
        !          2758:        if (asc_iopflag == ASC_TRUE) {
        !          2759:                for (ioport = 0; ioport < ASC_NUM_BOARD_SUPPORTED; ioport++) {
        !          2760:                        ASC_DBG2(1, "asdvansys_detect: asc_ioport[%d] %x\n",
        !          2761:                                ioport, asc_ioport[ioport]);
        !          2762:                        if (asc_ioport[ioport] != 0) {
        !          2763:                                for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX; iop++) {
        !          2764:                                        if (_asc_def_iop_base[iop] == asc_ioport[ioport]) {
        !          2765:                                                break;
        !          2766:                                        }
        !          2767:                                }
        !          2768:                                if (iop == ASC_IOADR_TABLE_MAX_IX) {
        !          2769:                                        printk("AdvanSys SCSI: specified I/O Port 0x%X is invalid\n",
        !          2770:                                                asc_ioport[ioport]);
        !          2771:                                        asc_ioport[ioport] = 0;
        !          2772:                                }
        !          2773:                        }
        !          2774:                }
        !          2775:                ioport = 0;
        !          2776:        }
        !          2777: 
        !          2778:        memset(&pciDevice, 0, sizeof(PCI_DEVICE));
        !          2779:        memset(&pciConfig, 0, sizeof(PCI_CONFIG_SPACE));
        !          2780:        pciDevice.maxBusNumber = PCI_MAX_BUS;
        !          2781:        pciDevice.endSlot = PCI_MAX_SLOT;
        !          2782: 
        !          2783:        for (bus = 0; bus < ASC_NUM_BUS; bus++) {
        !          2784: 
        !          2785:                ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n",
        !          2786:                        bus, asc_bus_name[bus]);
        !          2787:                iop = 0;
        !          2788: 
        !          2789:                while (asc_board_count < ASC_NUM_BOARD_SUPPORTED) {
        !          2790: 
        !          2791:                        ASC_DBG1(2, "advansys_detect: asc_board_count %d\n",
        !          2792:                                asc_board_count);
        !          2793: 
        !          2794:                        switch (asc_bus[bus]) {
        !          2795:                        case ASC_IS_ISA:
        !          2796:                        case ASC_IS_VL:
        !          2797:                                if (asc_iopflag == ASC_FALSE) {
        !          2798:                                        iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
        !          2799:                                } else {
        !          2800:                                        /*
        !          2801:                                         * ISA and VL I/O port scanning has either been
        !          2802:                                         * eliminated or limited to selected ports on
        !          2803:                                         * the LILO command line, /etc/lilo.conf, or
        !          2804:                                         * by setting variables when the module was loaded.
        !          2805:                                         */
        !          2806:                                        ASC_DBG(1, "advansys_detect: I/O port scanning modified\n");
        !          2807:                                ioport_try_again:
        !          2808:                                        iop = 0;
        !          2809:                                        for (; ioport < ASC_NUM_BOARD_SUPPORTED; ioport++) {
        !          2810:                                                if ((iop = asc_ioport[ioport]) != 0) {
        !          2811:                                                        break;
        !          2812:                                                }
        !          2813:                                        }
        !          2814:                                        if (iop) {
        !          2815:                                                ASC_DBG1(1, "advansys_detect: probing I/O port %x...\n",
        !          2816:                                                        iop);
        !          2817:                                                if (check_region(iop, ASC_IOADR_GAP) != 0) {
        !          2818:                                                        printk("AdvanSys SCSI: specified I/O Port 0x%X is busy\n", iop);
        !          2819:                                                        /* Don't try this I/O port twice. */
        !          2820:                                                        asc_ioport[ioport] = 0;
        !          2821:                                                        goto ioport_try_again;
        !          2822:                                                } else if (AscFindSignature(iop) == ASC_FALSE) {
        !          2823:                                                        printk("AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n", iop);
        !          2824:                                                        /* Don't try this I/O port twice. */
        !          2825:                                                        asc_ioport[ioport] = 0;
        !          2826:                                                        goto ioport_try_again;
        !          2827:                                                } else {
        !          2828:                                                        /*
        !          2829:                                                         * If this isn't an ISA board, then it must be
        !          2830:                                                         * a VL board. If currently looking an ISA
        !          2831:                                                         * board is being looked for then try for
        !          2832:                                                         * another ISA board in 'asc_ioport'.
        !          2833:                                                         */
        !          2834:                                                        if (asc_bus[bus] == ASC_IS_ISA &&
        !          2835:                                                            (AscGetChipVersion(iop, ASC_IS_ISA) &
        !          2836:                                                                 ASC_CHIP_VER_ISA_BIT) == 0) {
        !          2837:                                                                /*
        !          2838:                                                                 * Don't clear 'asc_ioport[ioport]'. Try
        !          2839:                                                                 * this board again for VL. Increment
        !          2840:                                                                 * 'ioport' past this board.
        !          2841:                                                                 */
        !          2842:                                                                 ioport++;
        !          2843:                                                                 goto ioport_try_again;
        !          2844:                                                        }
        !          2845:                                                }
        !          2846:                                                /*
        !          2847:                                                 * This board appears good, don't try the I/O port
        !          2848:                                                 * again by clearing its value. Increment 'ioport'
        !          2849:                                                 * for the next iteration.
        !          2850:                                                 */
        !          2851:                                                asc_ioport[ioport++] = 0;
        !          2852:                                        }
        !          2853:                                }
        !          2854:                                break;
        !          2855: 
        !          2856:                        case ASC_IS_EISA:
        !          2857:                                iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
        !          2858:                                break;
        !          2859: 
        !          2860:                        case ASC_IS_PCI:
        !          2861:                                        if (asc_srch_pci_dev(&pciDevice) != PCI_DEVICE_FOUND) {
        !          2862:                                                iop = 0;
        !          2863:                                        } else {
        !          2864:                                                ASC_DBG2(2,
        !          2865:                                                        "advansys_detect: slotFound %d, busNumber %d\n",
        !          2866:                                                        pciDevice.slotFound, pciDevice.busNumber);
        !          2867:                                                asc_get_pci_cfg(&pciDevice, &pciConfig);
        !          2868:                                                iop = pciConfig.baseAddress[0] & PCI_IOADDRESS_MASK;
        !          2869:                                                ASC_DBG2(2, "advansys_detect: iop %x, irqLine %d\n",
        !          2870:                                                        iop, pciConfig.irqLine);
        !          2871:                                        }
        !          2872:                                break;
        !          2873: 
        !          2874:                        default:
        !          2875:                                ASC_DBG(0, "advansys_detect: unknown bus type\n");
        !          2876:                                break;
        !          2877:                        }
        !          2878:                        ASC_DBG1(1, "advansys_detect: iop %x\n", iop);
        !          2879: 
        !          2880:                        /*
        !          2881:                         * Adapter not found, try next bus type.
        !          2882:                         */
        !          2883:                        if (iop == 0) {
        !          2884:                                break;
        !          2885:                        }
        !          2886: 
        !          2887:                        /*
        !          2888:                         * Adapter found.
        !          2889:                         *
        !          2890:                         * Register the adapter, get its configuration, and
        !          2891:                         * initialize it.
        !          2892:                         */
        !          2893:                        ASC_DBG(2, "advansys_detect: scsi_register()\n");
        !          2894:                        shp = scsi_register(tpnt, sizeof(struct asc_board));
        !          2895: 
        !          2896:                        /* Save a pointer to the Scsi_host of each found board. */
        !          2897:                        asc_host[asc_board_count++] = shp;
        !          2898: 
        !          2899:                        /* Initialize private per board data */
        !          2900:                        memset(ASC_BOARD(shp), 0, sizeof(struct asc_board));
        !          2901:                        boardp = &ASC_BOARD(shp)->board;
        !          2902:                        boardp->cfg = &ASC_BOARD(shp)->cfg;
        !          2903:                        boardp->cfg->overrun_buf = &ASC_BOARD(shp)->overrun_buf[0];
        !          2904:                        boardp->iop_base = iop;
        !          2905: 
        !          2906:                        /*
        !          2907:                         * Set the board bus type and PCI IRQ for AscInitGetConfig().
        !          2908:                         */
        !          2909:                        boardp->bus_type = asc_bus[bus];
        !          2910:                        switch (boardp->bus_type) {
        !          2911:                        case ASC_IS_ISA:
        !          2912:                                shp->unchecked_isa_dma = TRUE;
        !          2913:                                break;
        !          2914:                        case ASC_IS_EISA:
        !          2915:                                shp->unchecked_isa_dma = FALSE;
        !          2916:                                break;
        !          2917:                        case ASC_IS_VL:
        !          2918:                                shp->unchecked_isa_dma = FALSE;
        !          2919:                                break;
        !          2920:                        case ASC_IS_PCI:
        !          2921:                                shp->irq = boardp->irq_no = pciConfig.irqLine;
        !          2922:                                boardp->cfg->pci_device_id = pciConfig.deviceID;
        !          2923:                                shp->unchecked_isa_dma = FALSE;
        !          2924:                                break;
        !          2925:                        default:
        !          2926:                                ASC_DBG(0, "advansys_detect: unknown adapter type");
        !          2927:                                shp->unchecked_isa_dma = TRUE;
        !          2928:                                break;
        !          2929:                        }
        !          2930: 
        !          2931:                        /*
        !          2932:                         * Get the board configuration.  AscInitGetConfig() may change
        !          2933:                         * the board's bus_type value. The asc_bus[bus] value should no
        !          2934:                         * longer be used.
        !          2935:                         */
        !          2936:                        ASC_DBG(2, "advansys_detect: AscInitGetConfig()\n");
        !          2937:                        switch(ret = AscInitGetConfig(boardp)) {
        !          2938:                        case 0: /* No error */
        !          2939:                                break;
        !          2940:                        case ASC_WARN_IO_PORT_ROTATE:
        !          2941:                                ASC_DBG(0, "AscInitGetConfig: I/O port address modified\n");
        !          2942:                                break;
        !          2943:                        case ASC_WARN_EEPROM_CHKSUM:
        !          2944:                                ASC_DBG(0, "AscInitGetConfig: EEPROM checksum error\n");
        !          2945:                                break;
        !          2946:                        case ASC_WARN_IRQ_MODIFIED:
        !          2947:                                ASC_DBG(0, "AscInitGetConfig: IRQ modified\n");
        !          2948:                                break;
        !          2949:                        case ASC_WARN_CMD_QNG_CONFLICT:
        !          2950:                                ASC_DBG(0,
        !          2951:                                        "AscInitGetConfig: Tag queuing enabled w/o disconnects\n");
        !          2952:                                break;
        !          2953:                        default:
        !          2954:                                ASC_DBG1(0, "AscInitGetConfig: Unknown warning: %x\n", ret);
        !          2955:                                break;
        !          2956:                        }
        !          2957:                        if (boardp->err_code != 0) {
        !          2958:                                ASC_DBG2(0,
        !          2959:                                        "AscInitGetConfig: error: init_state %x, err_code %x\n",
        !          2960:                                        boardp->init_state, boardp->err_code);
        !          2961:                                scsi_unregister(shp);
        !          2962:                                asc_board_count--;
        !          2963:                                continue;
        !          2964:                        }
        !          2965: 
        !          2966:                        /*
        !          2967:                         * Modify board configuration.
        !          2968:                         */
        !          2969:                        boardp->isr_callback = (Ptr2Func) asc_isr_callback;
        !          2970:                        boardp->exe_callback = (Ptr2Func) NULL;
        !          2971: 
        !          2972:                        ASC_DBG(2, "advansys_detect: AscInitSetConfig()\n");
        !          2973:                        switch (ret = AscInitSetConfig(boardp)) {
        !          2974:                        case 0: /* No error. */
        !          2975:                                break;
        !          2976:                        case ASC_WARN_IO_PORT_ROTATE:
        !          2977:                                ASC_DBG(0, "AscInitSetConfig: I/O port address modified\n");
        !          2978:                                break;
        !          2979:                        case ASC_WARN_EEPROM_CHKSUM:
        !          2980:                                ASC_DBG(0, "AscInitSetConfig: EEPROM checksum error\n");
        !          2981:                                break;
        !          2982:                        case ASC_WARN_IRQ_MODIFIED:
        !          2983:                                ASC_DBG(0, "AscInitSetConfig: IRQ modified\n");
        !          2984:                                break;
        !          2985:                        case ASC_WARN_CMD_QNG_CONFLICT:
        !          2986:                                ASC_DBG(0, "AscInitSetConfig: Tag queuing w/o disconnects\n");
        !          2987:                                break;
        !          2988:                        default:
        !          2989:                                ASC_DBG1(0, "AscInitSetConfig: Unknown warning: %x\n", ret);
        !          2990:                                break;
        !          2991:                        }
        !          2992:                        if (boardp->err_code != 0) {
        !          2993:                                ASC_DBG2(0,
        !          2994:                                        "AscInitSetConfig: error: init_state %x, err_code %x\n",
        !          2995:                                        boardp->init_state, boardp->err_code);
        !          2996:                                scsi_unregister(shp);
        !          2997:                                asc_board_count--;
        !          2998:                                continue;
        !          2999:                        }
        !          3000: 
        !          3001:                        /*
        !          3002:                         * Finish initializing the 'Scsi_Host' structure.
        !          3003:                         */
        !          3004: 
        !          3005:                        /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
        !          3006:                        if (boardp->bus_type != ASC_IS_PCI) {
        !          3007:                                shp->irq = boardp->irq_no;
        !          3008:                        }
        !          3009: 
        !          3010:                        shp->io_port = boardp->iop_base;
        !          3011:                        shp->n_io_port = ASC_IOADR_GAP;
        !          3012:                        shp->this_id = boardp->cfg->chip_scsi_id;
        !          3013: 
        !          3014:                        /* Maximum number of queues this adapter can handle. */
        !          3015:                        shp->can_queue = boardp->max_total_qng;
        !          3016: 
        !          3017:                        /*
        !          3018:                         * XXX - Command queuing limits are maintained per target
        !          3019:                         * by AdvanSys adapters. Set 'cmd_per_lun' to the minimum
        !          3020:                         * value of the all the target settings for the adapter.
        !          3021:                         *
        !          3022:                         * For now set 'cmd_per_lun' to 'max_total_qng'. This
        !          3023:                         * value should be adjusted every time a new device is
        !          3024:                         * found in asc_init_dev().
        !          3025:                         *
        !          3026:                         * XXX - memory allocation is done by the mid-level scsi
        !          3027:                         * driver based on 'cmd_per_lun'. If 'sg_tablesize' is too large
        !          3028:                         * allocation failures can occur in scsi_register_host().
        !          3029:                         * A 'Scsi_Cmnd' structure is pre-allocated for each command
        !          3030:                         * also DMA memory is reserved. Set it artificially low for now.
        !          3031:                         *
        !          3032:                         * shp->cmd_per_lun = boardp->max_total_qng;
        !          3033:                         */
        !          3034: #ifdef MODULE
        !          3035:                        shp->cmd_per_lun = 1;
        !          3036: #else /* MODULE */
        !          3037:                        shp->cmd_per_lun = 4;
        !          3038: #endif /* MODULE */
        !          3039:                        ASC_DBG1(1, "advansys_detect: cmd_per_lun: %d\n", shp->cmd_per_lun);
        !          3040:                        
        !          3041:                        /* Maximum number of scatter-gather elements adapter can handle. */
        !          3042:                        /*
        !          3043:                         * XXX - memory allocation is done by the mid-level scsi
        !          3044:                         * driver based on sg_tablesize. If 'sg_tablesize' is too large
        !          3045:                         * allocation failures can occur in scsi_register_host().
        !          3046:                         */
        !          3047: #ifdef MODULE
        !          3048:                        shp->sg_tablesize = 8;
        !          3049: #else /* MODULE */
        !          3050:                        shp->sg_tablesize = ASC_MAX_SG_LIST;
        !          3051: #endif /* MODULE */
        !          3052:                        ASC_DBG1(1, "advansys_detect: sg_tablesize: %d\n",
        !          3053:                                shp->sg_tablesize);
        !          3054: 
        !          3055:                        /* BIOS start address. */
        !          3056:                        shp->base = (char *) ((ulong) AscGetChipBiosAddress(
        !          3057:                                                                                                boardp->iop_base,
        !          3058:                                                                                                boardp->bus_type));
        !          3059: 
        !          3060:                        /*
        !          3061:                         * Register Board Resources - I/O Port, DMA, IRQ
        !          3062:                         */
        !          3063: 
        !          3064:                        /* Register I/O port range */
        !          3065:                        ASC_DBG(2, "advansys_detect: request_region()\n");
        !          3066:                        request_region(shp->io_port, shp->n_io_port, "advansys");
        !          3067: 
        !          3068:                        /* Register DMA channel for ISA bus. */
        !          3069:                        if ((boardp->bus_type & ASC_IS_ISA) == 0) {
        !          3070:                                shp->dma_channel = NO_ISA_DMA;
        !          3071:                        } else {
        !          3072:                                shp->dma_channel = boardp->cfg->isa_dma_channel;
        !          3073:                                if ((ret = request_dma(shp->dma_channel, "advansys")) != 0) {
        !          3074:                                        ASC_DBG2(0, "advansys_detect: request_dma() %d failed %d\n",
        !          3075:                                                shp->dma_channel, ret);
        !          3076:                                        release_region(shp->io_port, shp->n_io_port);
        !          3077:                                        scsi_unregister(shp);
        !          3078:                                        asc_board_count--;
        !          3079:                                        continue;
        !          3080:                                }
        !          3081:                                AscEnableIsaDma(shp->dma_channel);
        !          3082:                        }
        !          3083: 
        !          3084:                        /* Register IRQ Number. */
        !          3085:                        ASC_DBG1(2, "advansys_detect: request_irq() %d\n", shp->irq);
        !          3086:                        if ((ret = request_irq(shp->irq, advansys_interrupt,
        !          3087:                                                                SA_INTERRUPT, "advansys")) != 0) {
        !          3088:                                ASC_DBG1(0, "advansys_detect: request_irq() failed %d\n", ret);
        !          3089:                                release_region(shp->io_port, shp->n_io_port);
        !          3090:                                if (shp->dma_channel != NO_ISA_DMA) {
        !          3091:                                        free_dma(shp->dma_channel);
        !          3092:                                }
        !          3093:                                scsi_unregister(shp);
        !          3094:                                asc_board_count--;
        !          3095:                                continue;
        !          3096:                        }
        !          3097: 
        !          3098:                        /*
        !          3099:                         * Initialize board RISC chip and enable interrupts.
        !          3100:                         */
        !          3101:                        ASC_DBG(2, "advansys_detect: AscInitAsc1000Driver()\n");
        !          3102:                        if (AscInitAsc1000Driver(boardp)) {
        !          3103:                                ASC_DBG2(0,
        !          3104:                                        "AscInitAsc1000Driver: error: init_state %x, err_code %x\n",
        !          3105:                                        boardp->init_state, boardp->err_code);
        !          3106:                                release_region(shp->io_port, shp->n_io_port);
        !          3107:                                if (shp->dma_channel != NO_ISA_DMA) {
        !          3108:                                        free_dma(shp->dma_channel);
        !          3109:                                }
        !          3110:                                free_irq(shp->irq);
        !          3111:                                scsi_unregister(shp);
        !          3112:                                asc_board_count--;
        !          3113:                                continue;
        !          3114:                        }
        !          3115:                        ASC_DBG_PRT_SCSI_HOST(2, shp);
        !          3116:                }
        !          3117:        }
        !          3118: 
        !          3119:        ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n", asc_board_count);
        !          3120:        return asc_board_count;
        !          3121: }
        !          3122: 
        !          3123: /*
        !          3124:  * advansys_release()
        !          3125:  *
        !          3126:  * Release resources allocated for a single AdvanSys adapter.
        !          3127:  */
        !          3128: int
        !          3129: advansys_release(struct Scsi_Host *shp)
        !          3130: {
        !          3131:        ASC_DBG(1, "advansys_release: begin\n");
        !          3132:        free_irq(shp->irq);
        !          3133:        if (shp->dma_channel != NO_ISA_DMA) {
        !          3134:                ASC_DBG(1, "advansys_release: free_dma()\n");
        !          3135:                free_dma(shp->dma_channel);
        !          3136:        }
        !          3137:        release_region(shp->io_port, shp->n_io_port);
        !          3138:        scsi_unregister(shp);
        !          3139:        ASC_DBG(1, "advansys_release: end\n");
        !          3140:        return 0;
        !          3141: }
        !          3142: 
        !          3143: /*
        !          3144:  * advansys_info()
        !          3145:  *
        !          3146:  * Return suitable for printing on the console with the argument
        !          3147:  * adapter's configuration information.
        !          3148:  */
        !          3149: const char *
        !          3150: advansys_info(struct Scsi_Host *shp)
        !          3151: {
        !          3152:        static char     info[128];
        !          3153:        ASC_DVC_VAR             *boardp;
        !          3154:        char                    *busname;
        !          3155: 
        !          3156:        boardp = &ASC_BOARD(shp)->board;
        !          3157:        ASC_DBG(1, "advansys_info: begin\n");
        !          3158:        if (boardp->bus_type & ASC_IS_ISA) {
        !          3159:                sprintf(info,
        !          3160:                        "AdvanSys SCSI %s: ISA (%u CDB): BIOS %X, IO %X-%X, IRQ %u, DMA %u",
        !          3161:                        ASC_VERSION, ASC_BOARD(shp)->board.max_total_qng,
        !          3162:                        (unsigned) shp->base, shp->io_port,
        !          3163:                        shp->io_port + (shp->n_io_port - 1), shp->irq, shp->dma_channel);
        !          3164:        } else {
        !          3165:                switch (boardp->bus_type) {
        !          3166:                case ASC_IS_EISA:
        !          3167:                        busname = "EISA";
        !          3168:                        break;
        !          3169:                case ASC_IS_VL:
        !          3170:                        busname = "VL";
        !          3171:                        break;
        !          3172:                case ASC_IS_PCI:
        !          3173:                        busname = "PCI";
        !          3174:                        break;
        !          3175:                default:
        !          3176:                        busname = "?";
        !          3177:                        ASC_DBG1(0, "advansys_info: unknown bus type %d\n",
        !          3178:                                boardp->bus_type);
        !          3179:                        break;
        !          3180:                }
        !          3181:                /* No DMA channel for non-ISA busses. */
        !          3182:                sprintf(info,
        !          3183:                        "AdvanSys SCSI %s: %s (%u CDB): BIOS %X, IO %X-%X, IRQ %u",
        !          3184:                        ASC_VERSION, busname, ASC_BOARD(shp)->board.max_total_qng,
        !          3185:                        (unsigned) shp->base, shp->io_port,
        !          3186:                        shp->io_port + (shp->n_io_port - 1), shp->irq);
        !          3187:        }
        !          3188:        ASC_DBG(1, "advansys_info: end\n");
        !          3189:        return info;
        !          3190: }
        !          3191: 
        !          3192: /*
        !          3193:  * advansys_command()
        !          3194:  *
        !          3195:  * Polled-I/O. Apparently host driver shouldn't return until
        !          3196:  * command is finished.
        !          3197:  *
        !          3198:  * XXX - Can host driver block here instead of spinning on command status?
        !          3199:  */
        !          3200: int
        !          3201: advansys_command(Scsi_Cmnd *scp)
        !          3202: {
        !          3203:        ASC_DBG1(1, "advansys_command: scp %x\n", (unsigned) scp);
        !          3204:        ASC_STATS(command);
        !          3205:        scp->SCp.Status = 0; /* Set to a known state */
        !          3206:        advansys_queuecommand(scp, advansys_command_done);
        !          3207:        while (scp->SCp.Status == 0) {
        !          3208:                continue;
        !          3209:        }
        !          3210:        ASC_DBG1(1, "advansys_command: result %x\n", scp->result);
        !          3211:        return scp->result;
        !          3212: }
        !          3213: 
        !          3214: /*
        !          3215:  * advansys_queuecommand()
        !          3216:  *
        !          3217:  * This function always returns 0. Command return status is saved
        !          3218:  * in the 'scp' result field.
        !          3219:  */
        !          3220: int
        !          3221: advansys_queuecommand(Scsi_Cmnd *scp, void (*done)(Scsi_Cmnd *))
        !          3222: {
        !          3223:        struct Scsi_Host                *shp;
        !          3224:        int                                             flags = 0;
        !          3225:        int                                             interrupts_disabled;
        !          3226: 
        !          3227:        ASC_STATS(queuecommand);
        !          3228:        shp = scp->host;
        !          3229: 
        !          3230: #ifdef LINUX_1_2
        !          3231:        /*
        !          3232:         * For LINUX_1_3, if statistics are enabled they can be accessed
        !          3233:         * by reading /proc/scsi/advansys/[0-9].
        !          3234:         */
        !          3235: #ifdef ADVANSYS_STATS_1_2_PRINT
        !          3236:        /* Display statistics every 10000 commands. */
        !          3237:        if ((asc_stats.queuecommand % 10000) == 0) {
        !          3238:                printk("\n");
        !          3239:                (void) asc_prt_stats(NULL, 0);
        !          3240:                printk("\n");
        !          3241:        }
        !          3242: #endif /* ADVANSYS_STATS_1_2_PRINT */
        !          3243: #endif /* LINUX_1_2 */
        !          3244: 
        !          3245:        /*
        !          3246:         * If there are any pending commands for this board before trying
        !          3247:         * to execute them, disable interrupts to preserve request ordering.
        !          3248:         *
        !          3249:         * The typical case will be no pending commands and interrupts
        !          3250:         * not disabled.
        !          3251:         */
        !          3252:        if (ASC_BOARD(shp)->pending_tidmask == 0) {
        !          3253:                interrupts_disabled = ASC_FALSE;
        !          3254:        } else {
        !          3255:                ASC_STATS(cmd_disable);
        !          3256:                /* Disable interrupts */
        !          3257:                interrupts_disabled = ASC_TRUE;
        !          3258:                save_flags(flags);
        !          3259:                cli();
        !          3260:                ASC_DBG1(1, "advansys_queuecommand: asc_execute_pending() %x\n",
        !          3261:                        ASC_BOARD(shp)->pending_tidmask);
        !          3262:                asc_execute_pending(shp);
        !          3263:        }
        !          3264: 
        !          3265:        /*
        !          3266:         * Save the function pointer to Linux mid-level 'done' function and
        !          3267:         * execute the command.
        !          3268:         */
        !          3269:        scp->scsi_done = done;
        !          3270:        if (asc_execute_scsi_cmnd(scp) == ASC_BUSY) {
        !          3271:                if (interrupts_disabled == ASC_FALSE) {
        !          3272:                        save_flags(flags);
        !          3273:                        cli();
        !          3274:                        interrupts_disabled = ASC_TRUE;
        !          3275:                }
        !          3276:                asc_enqueue(shp, scp, scp->target, ASC_BACK);
        !          3277:        }
        !          3278: 
        !          3279:        if (interrupts_disabled == ASC_TRUE) {
        !          3280:                restore_flags(flags);
        !          3281:        }
        !          3282: 
        !          3283:        return 0;
        !          3284: }
        !          3285: 
        !          3286: /*
        !          3287:  * advansys_abort()
        !          3288:  *
        !          3289:  * Abort the specified command and reset the device
        !          3290:  * associated with the command 'scp'.
        !          3291:  */
        !          3292: int
        !          3293: advansys_abort(Scsi_Cmnd *scp)
        !          3294: {
        !          3295:        ASC_DVC_VAR             *boardp;
        !          3296:        int                             flags;
        !          3297:        int                             ret;
        !          3298: 
        !          3299:        ASC_DBG1(1, "advansys_abort: scp %x\n", (unsigned) scp);
        !          3300:        save_flags(flags);
        !          3301:        cli();
        !          3302:        ASC_STATS(abort);
        !          3303:        if (scp->host == NULL) {
        !          3304:                scp->result = HOST_BYTE(DID_ERROR);
        !          3305:                ret = SCSI_ABORT_ERROR;
        !          3306:        } else if (asc_rmqueue(scp->host, scp, scp->target) == ASC_TRUE) {
        !          3307:                scp->result = HOST_BYTE(DID_ABORT);
        !          3308:                ret = SCSI_ABORT_SUCCESS;
        !          3309:                (void) AscResetDevice(&ASC_BOARD(scp->host)->board, scp->target);
        !          3310:        } else {
        !          3311:                /* Must enable interrupts for AscAbortSRB() */
        !          3312:                sti();
        !          3313:                boardp = &ASC_BOARD(scp->host)->board;
        !          3314:                scp->result = HOST_BYTE(DID_ABORT);
        !          3315:                switch (AscAbortSRB(boardp, (ulong) scp)) {
        !          3316:                case ASC_TRUE:
        !          3317:                        /* asc_isr_callback() will be called */
        !          3318:                        ASC_DBG(1, "advansys_abort: AscAbortSRB() TRUE\n");
        !          3319:                        ret = SCSI_ABORT_PENDING;
        !          3320:                        break;
        !          3321:                case ASC_FALSE:
        !          3322:                        /* Request has apparently already completed. */
        !          3323:                        ASC_DBG(1, "advansys_abort: AscAbortSRB() FALSE\n");
        !          3324:                        ret = SCSI_ABORT_NOT_RUNNING;
        !          3325:                        break;
        !          3326:                case ASC_ERROR:
        !          3327:                default:
        !          3328:                        ASC_DBG(1, "advansys_abort: AscAbortSRB() ERROR\n");
        !          3329:                        ret = SCSI_ABORT_ERROR;
        !          3330:                        break;
        !          3331:                }
        !          3332:                (void) AscResetDevice(boardp, scp->target);
        !          3333:        }
        !          3334:        restore_flags(flags);
        !          3335:        ASC_DBG1(1, "advansys_abort: ret %d\n", ret);
        !          3336:        return ret;
        !          3337: }
        !          3338: 
        !          3339: /*
        !          3340:  * advansys_reset()
        !          3341:  *
        !          3342:  * Reset all devices and the SCSI bus for the board
        !          3343:  * associated with 'scp'.
        !          3344:  */
        !          3345: int
        !          3346: advansys_reset(Scsi_Cmnd *scp)
        !          3347: {
        !          3348:        ASC_DVC_VAR             *boardp;
        !          3349:        int                             flags;
        !          3350:        Scsi_Cmnd               *tscp;
        !          3351:        int                             i;
        !          3352:        int                             ret;
        !          3353: 
        !          3354:        ASC_DBG1(1, "advansys_reset: %x\n", (unsigned) scp);
        !          3355:        save_flags(flags);
        !          3356:        cli();
        !          3357:        ASC_STATS(reset);
        !          3358:        if (scp->host == NULL) {
        !          3359:                scp->result = HOST_BYTE(DID_ERROR);
        !          3360:                ret = SCSI_RESET_ERROR;
        !          3361:        } else {
        !          3362:                /* Remove any pending commands, set DID_RESET, and done them.  */
        !          3363:                for (i = 0; i < ASC_MAX_TID; i++) {
        !          3364:                        while ((tscp = asc_dequeue(scp->host, i)) != NULL) {
        !          3365:                                tscp->result = HOST_BYTE(DID_RESET);
        !          3366:                                tscp->scsi_done(tscp);
        !          3367:                        }
        !          3368:                }
        !          3369:                /* Must enable interrupts for AscResetSB() */
        !          3370:                sti();
        !          3371:                boardp = &ASC_BOARD(scp->host)->board;
        !          3372:                scp->result = HOST_BYTE(DID_RESET);
        !          3373:                switch (AscResetSB(boardp)) {
        !          3374:                case ASC_TRUE:
        !          3375:                        ASC_DBG(1, "advansys_abort: AscResetSB() TRUE\n");
        !          3376:                        ret = SCSI_RESET_SUCCESS;
        !          3377:                        break;
        !          3378:                case ASC_ERROR:
        !          3379:                default:
        !          3380:                        ASC_DBG(1, "advansys_abort: AscResetSB() ERROR\n");
        !          3381:                        ret = SCSI_RESET_ERROR;
        !          3382:                        break;
        !          3383:                }
        !          3384:        }
        !          3385:        restore_flags(flags);
        !          3386:        ASC_DBG1(1, "advansys_reset: ret %d", ret);
        !          3387:        return ret;
        !          3388: }
        !          3389: 
        !          3390: /*
        !          3391:  * advansys_biosparam()
        !          3392:  *
        !          3393:  * Translate disk drive geometry if the "BIOS greater than 1 GB"
        !          3394:  * support is enabled for a drive.
        !          3395:  *
        !          3396:  * ip (information pointer) is an int array with the following definition:
        !          3397:  * ip[0]: heads
        !          3398:  * ip[1]: sectors
        !          3399:  * ip[2]: cylinders
        !          3400:  */
        !          3401: int
        !          3402: #ifdef LINUX_1_2
        !          3403: advansys_biosparam(Disk *dp, int dep, int ip[])
        !          3404: #else /* LINUX_1_3 */
        !          3405: advansys_biosparam(Disk *dp, kdev_t dep, int ip[])
        !          3406: #endif /* LINUX_1_3 */
        !          3407: {
        !          3408:        ASC_DBG(1, "advansys_biosparam: begin\n");
        !          3409:        ASC_STATS(biosparam);
        !          3410:        if ((ASC_BOARD(dp->device->host)->board.dvc_cntl & ASC_CNTL_BIOS_GT_1GB) &&
        !          3411:                dp->capacity > 0x200000) {
        !          3412:                        ip[0] = 255;
        !          3413:                        ip[1] = 64;
        !          3414:        } else {
        !          3415:                        ip[0] = 64;
        !          3416:                        ip[1] = 32;
        !          3417:        }
        !          3418:        ip[2] = dp->capacity / (ip[0] * ip[1]);
        !          3419:        ASC_DBG(1, "advansys_biosparam: end\n");
        !          3420:        return 0;
        !          3421: }
        !          3422: 
        !          3423: /*
        !          3424:  * advansys_setup()
        !          3425:  *
        !          3426:  * This function is called from init/main.c at boot time.
        !          3427:  * It it passed LILO parameters that can be set from the
        !          3428:  * LILO command line or in /etc/lilo.conf.
        !          3429:  *
        !          3430:  * It is used by the AdvanSys driver to either disable I/O
        !          3431:  * port scanning or to limit scanning to 1 - 4 I/O ports.
        !          3432:  * Regardless of the option setting EISA and PCI boards
        !          3433:  * will still be searched for and detected. This option
        !          3434:  * only affects searching for ISA and VL boards.
        !          3435:  *
        !          3436:  * If ADVANSYS_DEBUG is defined the driver debug level may
        !          3437:  * be set using the 5th (ASC_NUM_BOARD_SUPPORTED + 1) I/O Port.
        !          3438:  *
        !          3439:  * Examples:
        !          3440:  * 1. Eliminate I/O port scanning:
        !          3441:  *             boot: linux advansys=
        !          3442:  *       or
        !          3443:  *             boot: linux advansys=0x0
        !          3444:  * 2. Limit I/O port scanning to one I/O port:
        !          3445:  *             boot: linux advansys=0x110
        !          3446:  * 3. Limit I/O port scanning to four I/O ports:
        !          3447:  *             boot: linux advansys=0x110,0x210,0x230,0x330
        !          3448:  * 4. If ADVANSYS_DEBUG, limit I/O port scanning to four I/O ports and
        !          3449:  *    set the driver debug level to 2.
        !          3450:  *             boot: linux advansys=0x110,0x210,0x230,0x330,0xdeb2
        !          3451:  *
        !          3452:  * ints[0] - number of arguments
        !          3453:  * ints[1] - first argument
        !          3454:  * ints[2] - second argument
        !          3455:  * ...
        !          3456:  */
        !          3457: void
        !          3458: advansys_setup(char *str, int *ints)
        !          3459: {
        !          3460:        int     i;
        !          3461: 
        !          3462:        if (asc_iopflag == ASC_TRUE) {
        !          3463:                printk("AdvanSys SCSI: 'advansys' LILO option may appear only once\n");
        !          3464:                return;
        !          3465:        }
        !          3466: 
        !          3467:        asc_iopflag = ASC_TRUE;
        !          3468: 
        !          3469:        if (ints[0] > ASC_NUM_BOARD_SUPPORTED) {
        !          3470: #ifdef ADVANSYS_DEBUG
        !          3471:                if ((ints[0] == ASC_NUM_BOARD_SUPPORTED + 1) &&
        !          3472:                    (ints[ASC_NUM_BOARD_SUPPORTED + 1] >> 4 == 0xdeb)) {
        !          3473:                        asc_dbglvl = ints[ASC_NUM_BOARD_SUPPORTED + 1] & 0xf;
        !          3474:                } else {
        !          3475: #endif /* ADVANSYS_DEBUG */
        !          3476:                        printk("AdvanSys SCSI: only %d I/O ports accepted\n",
        !          3477:                                ASC_NUM_BOARD_SUPPORTED);
        !          3478: #ifdef ADVANSYS_DEBUG
        !          3479:                }
        !          3480: #endif /* ADVANSYS_DEBUG */
        !          3481:        }
        !          3482: 
        !          3483: #ifdef ADVANSYS_DEBUG
        !          3484:        ASC_DBG1(1, "advansys_setup: ints[0] %d\n", ints[0]);
        !          3485:        for (i = 1; i < ints[0]; i++) {
        !          3486:                ASC_DBG2(1, " ints[%d] %x", i, ints[i]);
        !          3487:        }
        !          3488:        ASC_DBG(1, "\n");
        !          3489: #endif /* ADVANSYS_DEBUG */
        !          3490: 
        !          3491:        for (i = 1; i <= ints[0] && i <= ASC_NUM_BOARD_SUPPORTED; i++) {
        !          3492:                asc_ioport[i-1] = ints[i];
        !          3493:                ASC_DBG2(1, "advansys_setup: asc_ioport[%d] %x\n",
        !          3494:                        i - 1, asc_ioport[i-1]);
        !          3495:        }
        !          3496: }
        !          3497: 
        !          3498: 
        !          3499: /*
        !          3500:  * --- Loadable Driver Support
        !          3501:  */
        !          3502: 
        !          3503: #ifdef MODULE
        !          3504: Scsi_Host_Template driver_template = ADVANSYS;
        !          3505: # include "scsi_module.c"
        !          3506: #endif /* MODULE */
        !          3507: 
        !          3508: 
        !          3509: /*
        !          3510:  * --- Miscellaneous Driver Functions
        !          3511:  */
        !          3512: 
        !          3513: #ifdef LINUX_1_3
        !          3514: /*
        !          3515:  * asc_proc_copy() 
        !          3516:  *
        !          3517:  * Copy proc information to a read buffer considering the current read
        !          3518:  * offset in the file and the remaining space in the read buffer.
        !          3519:  */
        !          3520: STATIC int
        !          3521: asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
        !          3522:                          char *cp, int cplen)
        !          3523: {
        !          3524:        int cnt = 0;
        !          3525:        
        !          3526:        ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
        !          3527:                        (unsigned) offset, (unsigned) advoffset, cplen);
        !          3528:        if (offset <= advoffset) {
        !          3529:                /* Read offset below current offset, copy everything. */
        !          3530:                cnt = min(cplen, leftlen);
        !          3531:                ASC_DBG3(2, "asc_proc_copy: curbuf %x, cp %x, cnt %d\n",
        !          3532:                                (unsigned) curbuf, (unsigned) cp, cnt);
        !          3533:                memcpy(curbuf, cp, cnt);
        !          3534:        } else if (offset < advoffset + cplen) {
        !          3535:                /* Read offset within current range, partial copy. */
        !          3536:                cnt = (advoffset + cplen) - offset;
        !          3537:                cp = (cp + cplen) - cnt;
        !          3538:                cnt = min(cnt, leftlen);
        !          3539:                ASC_DBG3(2, "asc_proc_copy: curbuf %x, cp %x, cnt %d\n",
        !          3540:                                (unsigned) curbuf, (unsigned) cp, cnt);
        !          3541:                memcpy(curbuf, cp, cnt);
        !          3542:        }
        !          3543:        return cnt;
        !          3544: }
        !          3545: #endif /* LINUX_1_3 */
        !          3546: 
        !          3547: /*
        !          3548:  * First-level interrupt handler.
        !          3549:  */
        !          3550: STATIC void
        !          3551: advansys_interrupt(int irq, struct pt_regs *regs)
        !          3552: {
        !          3553:        int                     i;
        !          3554:        int                     flags;
        !          3555:        Scsi_Cmnd       *scp;
        !          3556:        Scsi_Cmnd       *tscp;
        !          3557: 
        !          3558:        /* Disable interrupts, if the aren't already disabled. */
        !          3559:        save_flags(flags);
        !          3560:        cli();
        !          3561: 
        !          3562:        ASC_DBG(1, "advansys_interrupt: begin\n");
        !          3563:        ASC_STATS(interrupt);
        !          3564:        /*
        !          3565:         * Check for interrupts on all boards.
        !          3566:         * AscISR() will call asc_isr_callback().
        !          3567:         */
        !          3568:        for (i = 0; i < asc_board_count; i++) {
        !          3569:                while (AscIsIntPending(asc_host[i]->io_port)) {
        !          3570:                        ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
        !          3571:                        AscISR(&ASC_BOARD(asc_host[i])->board);
        !          3572:                }
        !          3573:        }
        !          3574:        ASC_DBG(1, "advansys_interrupt: end\n");
        !          3575: 
        !          3576:        /*
        !          3577:         * While interrupts are still disabled save the list of requests that
        !          3578:         * need their done function called. After re-enabling interrupts call
        !          3579:         * the done function which may re-enable interrupts anyway.
        !          3580:         */
        !          3581:        if ((scp = asc_scsi_done) != NULL) {
        !          3582:                asc_scsi_done = NULL;
        !          3583:        }
        !          3584: 
        !          3585:        /* Re-enable interrupts, if they were enabled on entry. */
        !          3586:        restore_flags(flags);
        !          3587: 
        !          3588:        while (scp) {
        !          3589:                tscp = (Scsi_Cmnd *) scp->host_scribble;
        !          3590:                scp->scsi_done(scp);
        !          3591:                scp = tscp;
        !          3592:        }
        !          3593: 
        !          3594:        return;
        !          3595: }
        !          3596: 
        !          3597: /*
        !          3598:  * Function used only with polled I/O requests that are initiated by
        !          3599:  * advansys_command().
        !          3600:  */
        !          3601: STATIC void
        !          3602: advansys_command_done(Scsi_Cmnd *scp)
        !          3603: {
        !          3604:        ASC_DBG1(1, "advansys_command_done: scp %x\n", (unsigned) scp);
        !          3605:        scp->SCp.Status = 1;
        !          3606: }
        !          3607: 
        !          3608: /*
        !          3609:  * Execute a single 'Scsi_Cmnd'.
        !          3610:  *
        !          3611:  * The function 'done' is called when the request has been completed.
        !          3612:  *
        !          3613:  * Scsi_Cmnd:
        !          3614:  *
        !          3615:  *  host - board controlling device
        !          3616:  *  device - device to send command
        !          3617:  *  target - target of device
        !          3618:  *  lun - lun of device
        !          3619:  *  cmd_len - length of SCSI CDB
        !          3620:  *     cmnd - buffer for SCSI 8, 10, or 12 byte CDB
        !          3621:  *  use_sg - if non-zero indicates scatter-gather request with use_sg elements
        !          3622:  *
        !          3623:  *  if (use_sg == 0)
        !          3624:  *             request_buffer - buffer address for request
        !          3625:  *             request_bufflen - length of request buffer
        !          3626:  *  else
        !          3627:  *             request_buffer - pointer to scatterlist structure
        !          3628:  *
        !          3629:  *  sense_buffer - sense command buffer
        !          3630:  *
        !          3631:  *  result (4 bytes of an int):
        !          3632:  *   Byte Meaning
        !          3633:  *   0   SCSI Status Byte Code
        !          3634:  *   1   SCSI One Byte Message Code
        !          3635:  *   2           Host Error Code
        !          3636:  *   3   Mid-Level Error Code
        !          3637:  *
        !          3638:  *  host driver fields:
        !          3639:  *  SCp - Scsi_Pointer used for command processing status
        !          3640:  *  scsi_done - used to save caller's done function
        !          3641:  *     host_scribble - used for pointer to another Scsi_Cmnd
        !          3642:  *
        !          3643:  * If this function returns ASC_NOERROR or ASC_ERROR the done
        !          3644:  * function has been called. If ASC_BUSY is returned the request
        !          3645:  * must be enqueued by the caller and re-tried later.
        !          3646:  */
        !          3647: STATIC int
        !          3648: asc_execute_scsi_cmnd(Scsi_Cmnd *scp)
        !          3649: {
        !          3650:        ASC_DVC_VAR             *boardp;
        !          3651:        ASC_SCSI_Q              scsiq;
        !          3652:        ASC_SG_HEAD             sghead;
        !          3653:        int                             ret;
        !          3654: 
        !          3655:        ASC_DBG2(1, "asc_execute_scsi_cmnd: scp %x, done %x\n",
        !          3656:                (unsigned) scp, (unsigned) scp->scsi_done);
        !          3657: 
        !          3658:        boardp = &ASC_BOARD(scp->host)->board;
        !          3659: 
        !          3660:        /*
        !          3661:         * If this is the first command, then initialize the device. If
        !          3662:         * no device is found set 'DID_BAD_TARGET' and return.
        !          3663:         */
        !          3664:        if ((ASC_BOARD(scp->host)->init_tidmask &
        !          3665:                 ASC_TIX_TO_TARGET_ID(scp->target)) == 0) {
        !          3666:                if (asc_init_dev(boardp, scp) == ASC_FALSE) {
        !          3667:                        scp->result = HOST_BYTE(DID_BAD_TARGET);
        !          3668:                        scp->scsi_done(scp);
        !          3669:                        return ASC_ERROR;
        !          3670:                }
        !          3671:                ASC_BOARD(scp->host)->init_tidmask |= ASC_TIX_TO_TARGET_ID(scp->target);
        !          3672:        }
        !          3673: 
        !          3674:        memset(&scsiq, 0, sizeof(ASC_SCSI_Q));
        !          3675: 
        !          3676:        /*
        !          3677:         * Point the ASC_SCSI_Q to the 'Scsi_Cmnd'.
        !          3678:         */
        !          3679:        scsiq.q2.srb_ptr = (ulong) scp;
        !          3680: 
        !          3681:        /*
        !          3682:         * Build the ASC_SCSI_Q request.
        !          3683:         */
        !          3684:        scsiq.cdbptr = &scp->cmnd[0];
        !          3685:        scsiq.q2.cdb_len = scp->cmd_len;
        !          3686:        scsiq.q1.target_id = ASC_TID_TO_TARGET_ID(scp->target);
        !          3687:        scsiq.q1.target_lun = scp->lun;
        !          3688:        scsiq.q2.target_ix = ASC_TIDLUN_TO_IX(scp->target, scp->lun);
        !          3689:        scsiq.q1.sense_addr = (ulong) &scp->sense_buffer[0];
        !          3690:        scsiq.q1.sense_len = sizeof(scp->sense_buffer);
        !          3691:        scsiq.q2.tag_code = M2_QTAG_MSG_SIMPLE;
        !          3692: 
        !          3693:        /*
        !          3694:         * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
        !          3695:         * buffer command.
        !          3696:         */
        !          3697:        if (scp->use_sg == 0) {
        !          3698:                /*
        !          3699:                 * CDB request of single contiguous buffer.
        !          3700:                 */
        !          3701:                ASC_STATS(cont_cnt);
        !          3702:                /* request_buffer is already a real address. */
        !          3703:                scsiq.q1.data_addr = (ulong) scp->request_buffer;
        !          3704:                scsiq.q1.data_cnt = scp->request_bufflen;
        !          3705:                ASC_STATS_ADD(cont_xfer, (scp->request_bufflen + 511) >> 9);
        !          3706:                scsiq.q1.sg_queue_cnt = 0;
        !          3707:                scsiq.sg_head = NULL;
        !          3708:        } else {
        !          3709:                /*
        !          3710:                 * CDB scatter-gather request list.
        !          3711:                 */
        !          3712:                int                                     sgcnt;
        !          3713:                struct scatterlist      *slp;
        !          3714: 
        !          3715:                if (scp->use_sg > ASC_MAX_SG_LIST) {
        !          3716:                        ASC_DBG2(0, "asc_execute_scsi_cmnd: use_sg %d > %d\n",
        !          3717:                                scp->use_sg, ASC_MAX_SG_LIST);
        !          3718:                        scp->result = HOST_BYTE(DID_ERROR);
        !          3719:                        scp->scsi_done(scp);
        !          3720:                        return ASC_ERROR;
        !          3721:                }
        !          3722: 
        !          3723:                ASC_STATS(sg_cnt);
        !          3724: 
        !          3725:                /*
        !          3726:                 * Allocate a ASC_SG_HEAD structure and set the ASC_SCSI_Q
        !          3727:                 * to point to it.
        !          3728:                 */
        !          3729:                memset(&sghead, 0, sizeof(ASC_SG_HEAD));
        !          3730: 
        !          3731:                scsiq.q1.cntl |= QC_SG_HEAD;
        !          3732:                scsiq.sg_head = &sghead;
        !          3733:                scsiq.q1.data_cnt = 0;
        !          3734:                scsiq.q1.data_addr = 0;
        !          3735:                sghead.entry_cnt = scsiq.q1.sg_queue_cnt = scp->use_sg;
        !          3736:                ASC_STATS_ADD(sg_elem, sghead.entry_cnt);
        !          3737: 
        !          3738:                /*
        !          3739:                 * Convert scatter-gather list into ASC_SG_HEAD list.
        !          3740:                 */
        !          3741:                slp = (struct scatterlist *) scp->request_buffer;
        !          3742:                for (sgcnt = 0; sgcnt < scp->use_sg; sgcnt++, slp++) {
        !          3743:                        sghead.sg_list[sgcnt].addr = (ulong) slp->address;
        !          3744:                        sghead.sg_list[sgcnt].bytes = slp->length;
        !          3745:                        ASC_STATS_ADD(sg_xfer, (slp->length + 511) >> 9);
        !          3746:                }
        !          3747:        }
        !          3748: 
        !          3749:        ASC_DBG_PRT_SCSI_Q(2, &scsiq);
        !          3750:        ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
        !          3751: 
        !          3752:        switch (ret = AscExeScsiQueue(boardp, &scsiq)) {
        !          3753:        case ASC_NOERROR:
        !          3754:                ASC_DBG(1, "asc_execute_scsi_cmnd: AscExeScsiQueue() ASC_NOERROR\n");
        !          3755:                break;
        !          3756:        case ASC_BUSY:
        !          3757:                /* Caller must enqueue request and retry later. */
        !          3758:                break;
        !          3759:        case ASC_ERROR:
        !          3760:                ASC_DBG1(0,
        !          3761:                        "asc_execute_scsi_cmnd: AscExeScsiQueue() ASC_ERROR err_code %x\n",
        !          3762:                        boardp->err_code);
        !          3763:                ASC_STATS(error);
        !          3764:                scp->result = HOST_BYTE(DID_ERROR);
        !          3765:                scp->scsi_done(scp);
        !          3766:                break;
        !          3767:        }
        !          3768: 
        !          3769:        ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
        !          3770:        return ret;
        !          3771: }
        !          3772: 
        !          3773: /*
        !          3774:  * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
        !          3775:  */
        !          3776: void
        !          3777: asc_isr_callback(ASC_DVC_VAR *boardp, ASC_QDONE_INFO *qdonep)
        !          3778: {
        !          3779:        Scsi_Cmnd                       *scp;
        !          3780:        struct Scsi_Host        *shp;
        !          3781:        int                                     flags;
        !          3782:        Scsi_Cmnd                       **scpp;
        !          3783: 
        !          3784:        ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
        !          3785:        ASC_DBG2(1, "asc_isr_callback: boardp %x, qdonep %x\n",
        !          3786:                (unsigned) boardp, (unsigned) qdonep);
        !          3787:        ASC_STATS(callback);
        !          3788:        ASC_DBG_PRT_QDONE_INFO(2, qdonep);
        !          3789: 
        !          3790:        /*
        !          3791:         * Get the Scsi_Cmnd structure and Scsi_Host structure for the
        !          3792:         * command that has been completed.
        !          3793:         */
        !          3794:        scp = (Scsi_Cmnd *) qdonep->d2.srb_ptr;
        !          3795:        ASC_DBG1(1, "asc_isr_callback: scp %x\n", (unsigned) scp);
        !          3796:        ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
        !          3797: 
        !          3798:        shp = scp->host;
        !          3799:        ASC_ASSERT(shp);
        !          3800:        ASC_DBG1(1, "asc_isr_callback: shp %x\n", (unsigned) shp);
        !          3801: 
        !          3802:        /*
        !          3803:         * 'qdonep' contains the command's ending status.
        !          3804:         */
        !          3805:        switch (qdonep->d3.done_stat) {
        !          3806:        case QD_NO_ERROR:
        !          3807:                ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
        !          3808:                switch (qdonep->d3.host_stat) {
        !          3809:                case QHSTA_NO_ERROR:
        !          3810:                        scp->result = 0;
        !          3811:                        break;
        !          3812:                default:
        !          3813:                        /* QHSTA error occurred */
        !          3814:                        scp->result = HOST_BYTE(DID_ERROR);
        !          3815:                        break;
        !          3816:                }
        !          3817:                break;
        !          3818: 
        !          3819:        case QD_WITH_ERROR:
        !          3820:                ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
        !          3821:                switch (qdonep->d3.host_stat) {
        !          3822:                case QHSTA_NO_ERROR:
        !          3823:                        if (qdonep->d3.scsi_stat == SS_CHK_CONDITION) {
        !          3824:                                ASC_DBG(2, "asc_isr_callback: SS_CHK_CONDITION\n");
        !          3825:                                ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
        !          3826:                                        sizeof(scp->sense_buffer));
        !          3827:                                /*
        !          3828:                                 * Note: The status_byte() macro used by target drivers
        !          3829:                                 * defined in scsi.h shifts the status byte returned by
        !          3830:                                 * host drivers right by 1 bit. This is why target drivers
        !          3831:                                 * also use left shifted status byte definitions. For instance
        !          3832:                                 * target drivers use CHECK_CONDITION, defined to 0x1, instead
        !          3833:                                 * of the SCSI defined check condition value of 0x2.
        !          3834:                                 */
        !          3835:                                scp->result = DRIVER_BYTE(DRIVER_SENSE) |
        !          3836:                                        STATUS_BYTE(qdonep->d3.scsi_stat); 
        !          3837:                        } else {
        !          3838:                                scp->result = STATUS_BYTE(qdonep->d3.scsi_stat); 
        !          3839:                        }
        !          3840:                        break;
        !          3841: 
        !          3842:                default:
        !          3843:                        /* QHSTA error occurred */
        !          3844:                        ASC_DBG1(2, "asc_isr_callback: host_stat %x\n",
        !          3845:                                qdonep->d3.host_stat);
        !          3846:                        scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.scsi_msg) |
        !          3847:                                STATUS_BYTE(qdonep->d3.scsi_stat);
        !          3848:                        break;
        !          3849:                }
        !          3850:                break;
        !          3851: 
        !          3852:        case QD_ABORTED_BY_HOST:
        !          3853:                ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
        !          3854:                scp->result = HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.scsi_msg) |
        !          3855:                                STATUS_BYTE(qdonep->d3.scsi_stat);
        !          3856:                break;
        !          3857: 
        !          3858:        default:
        !          3859:                ASC_DBG1(0, "asc_isr_callback: done_stat %x\n", qdonep->d3.done_stat );
        !          3860:                scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.scsi_msg) |
        !          3861:                                STATUS_BYTE(qdonep->d3.scsi_stat);
        !          3862:                break;
        !          3863:        }
        !          3864: 
        !          3865:        /*
        !          3866:         * Before calling 'scsi_done' for the current 'Scsi_Cmnd' and possibly
        !          3867:         * triggering more commands to be issued, try to start any pending
        !          3868:         * commands.
        !          3869:         */
        !          3870:        if (ASC_BOARD(shp)->pending_tidmask != 0) {
        !          3871:                /*
        !          3872:                 * If there are any pending commands for this board before trying
        !          3873:                 * to execute them, disable interrupts to preserve request ordering.
        !          3874:                 */
        !          3875:                ASC_STATS(intr_disable);
        !          3876:                save_flags(flags);
        !          3877:                cli();
        !          3878:                ASC_DBG1(1, "asc_isr_callback: asc_execute_pending() %x\n",
        !          3879:                        ASC_BOARD(shp)->pending_tidmask);
        !          3880:                asc_execute_pending(shp);
        !          3881:                restore_flags(flags);
        !          3882:        }
        !          3883: 
        !          3884:        /* 
        !          3885:         * Because interrupts may be enabled by the 'Scsi_Cmnd' done function,
        !          3886:         * add the command to the end of the global done list. The done function
        !          3887:         * for the command will be called in advansys_interrupt().
        !          3888:         */
        !          3889:        for (scpp = &asc_scsi_done; *scpp;
        !          3890:             scpp = (Scsi_Cmnd **) &(*scpp)->host_scribble) {
        !          3891:                ;
        !          3892:        }
        !          3893:        *scpp = scp;
        !          3894:        scp->host_scribble = NULL;
        !          3895:        return;
        !          3896: }
        !          3897: 
        !          3898: /*
        !          3899:  * Execute as many pending requests as possible for the
        !          3900:  * board specified by 'Scsi_Host'.
        !          3901:  */
        !          3902: STATIC void
        !          3903: asc_execute_pending(struct Scsi_Host *shp)
        !          3904: {
        !          3905:        ASC_SCSI_BIT_ID_TYPE    scan_tidmask;
        !          3906:        Scsi_Cmnd                               *scp;
        !          3907:        int                                             i;
        !          3908: 
        !          3909:        ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
        !          3910:        /*
        !          3911:         * Execute pending commands for devices attached to
        !          3912:         * the current board in round-robin fashion.
        !          3913:         */
        !          3914:        scan_tidmask = ASC_BOARD(shp)->pending_tidmask;
        !          3915:        do {
        !          3916:                for (i = 0; i < ASC_MAX_TID; i++) {
        !          3917:                        if (scan_tidmask & ASC_TIX_TO_TARGET_ID(i)) {
        !          3918:                                if ((scp = asc_dequeue(shp, i)) == NULL) {
        !          3919:                                        scan_tidmask &= ~ASC_TIX_TO_TARGET_ID(i);
        !          3920:                                } else if (asc_execute_scsi_cmnd(scp) == ASC_BUSY) {
        !          3921:                                        scan_tidmask &= ~ASC_TIX_TO_TARGET_ID(i);
        !          3922:                                        /* Put the request back at front of the list. */
        !          3923:                                        asc_enqueue(shp, scp, i, ASC_FRONT);
        !          3924:                                }
        !          3925:                        }
        !          3926:                }
        !          3927:        } while (scan_tidmask);
        !          3928:        return;
        !          3929: }
        !          3930: 
        !          3931: /*
        !          3932:  * asc_init_dev()
        !          3933:  *
        !          3934:  * Perform one-time initialization of a device.
        !          3935:  */
        !          3936: STATIC int
        !          3937: asc_init_dev(ASC_DVC_VAR *boardp, Scsi_Cmnd *scp)
        !          3938: {
        !          3939:        ASC_SCSI_REQ_Q                  *scsireqq;
        !          3940:        ASC_CAP_INFO                    *cap_info;
        !          3941:        ASC_SCSI_INQUIRY                *inquiry;
        !          3942:        int                                             found;
        !          3943:        ASC_SCSI_BIT_ID_TYPE    save_use_tagged_qng;
        !          3944:        ASC_SCSI_BIT_ID_TYPE    save_can_tagged_qng;
        !          3945:        int                                             ret;
        !          3946: #ifdef ADVANSYS_DEBUG
        !          3947:        ASC_SCSI_BIT_ID_TYPE    tidmask; /* target id bit mask: 1 - 128 */
        !          3948: #endif /* ADVANSYS_DEBUG */
        !          3949: 
        !          3950:        ASC_DBG1(1, "asc_init_dev: target %d\n", (unsigned) scp->target);
        !          3951: 
        !          3952:        /* Return true for the board's target id. */
        !          3953:        if (boardp->cfg->chip_scsi_id == scp->target) {
        !          3954:                return ASC_TRUE;
        !          3955:        }
        !          3956: 
        !          3957:        /*
        !          3958:         * XXX - Host drivers should not modify the timeout field.
        !          3959:         * But on the first command only add some extra time to
        !          3960:         * allow the driver to complete its initialization for the
        !          3961:         * device.
        !          3962:         */
        !          3963:        scp->timeout += 2000;   /* Add 5 seconds to the request timeout. */
        !          3964: 
        !          3965:        /* Set-up AscInitPollTarget() arguments. */
        !          3966:        scsireqq = &ASC_BOARD(scp->host)->scsireqq;
        !          3967:        memset(scsireqq, 0, sizeof(ASC_SCSI_REQ_Q));
        !          3968:        cap_info = &ASC_BOARD(scp->host)->cap_info;
        !          3969:        memset(cap_info, 0, sizeof(ASC_CAP_INFO));
        !          3970:        inquiry = &ASC_BOARD(scp->host)->inquiry;
        !          3971:        memset(inquiry, 0, sizeof(ASC_SCSI_INQUIRY));
        !          3972: 
        !          3973:        /*
        !          3974:         * XXX - AscInitPollBegin() re-initializes these fields to
        !          3975:         * zero. 'Or' in the new values and restore them before calling 
        !          3976:         * AscInitPollEnd(). Normally all targets are initialized within
        !          3977:         * a call to AscInitPollBegin() and AscInitPollEnd().
        !          3978:         */
        !          3979:        save_use_tagged_qng = boardp->use_tagged_qng;
        !          3980:     save_can_tagged_qng = boardp->cfg->can_tagged_qng;
        !          3981: 
        !          3982:        ASC_DBG(2, "asc_init_dev: AscInitPollBegin()\n");
        !          3983:        if (AscInitPollBegin(boardp)) {
        !          3984:                ASC_DBG(0, "asc_init_dev: AscInitPollBegin() failed\n");
        !          3985:                return ASC_FALSE;
        !          3986:        }
        !          3987: 
        !          3988:        scsireqq->sense_ptr = &scsireqq->sense[0];
        !          3989:        scsireqq->r1.sense_len = ASC_MIN_SENSE_LEN;
        !          3990:        scsireqq->r1.target_id = ASC_TID_TO_TARGET_ID(scp->target);
        !          3991:        scsireqq->r1.target_lun = 0;
        !          3992:        scsireqq->r2.target_ix = ASC_TIDLUN_TO_IX(scp->target, 0);
        !          3993: 
        !          3994:        found = ASC_FALSE;
        !          3995:        ASC_DBG(2, "asc_init_dev: AscInitPollTarget()\n");
        !          3996:        switch (ret = AscInitPollTarget(boardp, scsireqq, inquiry, cap_info)) {
        !          3997:        case ASC_TRUE:
        !          3998:                found = ASC_TRUE;
        !          3999: #ifdef ADVANSYS_DEBUG
        !          4000:                tidmask = ASC_TIX_TO_TARGET_ID(scp->target);
        !          4001:                ASC_DBG2(1, "asc_init_dev: lba %lu, blk_size %lu\n",
        !          4002:                        cap_info->lba, cap_info->blk_size);
        !          4003:                ASC_DBG1(1, "asc_init_dev: peri_dvc_type %x\n",
        !          4004:                        inquiry->byte0.peri_dvc_type);
        !          4005:                if (boardp->use_tagged_qng & tidmask) {
        !          4006:                        ASC_DBG1(1, "asc_init_dev: command queuing enabled: %d\n",
        !          4007:                                boardp->max_dvc_qng[scp->target]);
        !          4008:                } else {
        !          4009:                        ASC_DBG(1, "asc_init_dev: command queuing disabled\n");
        !          4010:                }
        !          4011:                if (boardp->init_sdtr & tidmask) {
        !          4012:                        ASC_DBG(1, "asc_init_dev: synchronous transfers enabled\n");
        !          4013:                } else {
        !          4014:                        ASC_DBG(1, "asc_init_dev: synchronous transfers disabled\n");
        !          4015:                }
        !          4016:                /* Set bit means fix disabled. */
        !          4017:                if (boardp->pci_fix_asyn_xfer & tidmask) {
        !          4018:                        ASC_DBG(1, "asc_init_dev: synchronous transfer fix disabled\n");
        !          4019:                } else {
        !          4020:                        ASC_DBG(1, "asc_init_dev: synchronous transfer fix enabled\n");
        !          4021:                }
        !          4022: #endif /* ADVANSYS_DEBUG */
        !          4023:                break;
        !          4024:        case ASC_FALSE:
        !          4025:                ASC_DBG(1, "asc_init_dev: no device found\n");
        !          4026:                break;
        !          4027:        case ASC_ERROR:
        !          4028:                ASC_DBG(0, "asc_init_dev: AscInitPollTarget() ASC_ERROR\n");
        !          4029:                break;
        !          4030:        default:
        !          4031:                ASC_DBG1(0, "asc_init_dev: AscInitPollTarget() unknown ret %d\n", ret);
        !          4032:                break;
        !          4033:        }
        !          4034: 
        !          4035:        /* XXX - 'Or' in original tag bits. */
        !          4036:        boardp->use_tagged_qng |= save_use_tagged_qng;
        !          4037:        boardp->cfg->can_tagged_qng |= save_can_tagged_qng;
        !          4038: 
        !          4039:        ASC_DBG(2, "asc_init_dev: AscInitPollEnd()\n");
        !          4040:        AscInitPollEnd(boardp);
        !          4041: 
        !          4042: #ifdef ASC_SET_CMD_PER_LUN
        !          4043:        /*
        !          4044:         * XXX - Refer to the comment in advansys_detect()
        !          4045:         * regarding cmd_per_lun.
        !          4046:         */
        !          4047:        for (i = 0; i <= ASC_MAX_TID; i++) {
        !          4048:                if (boardp->max_dvc_qng[i] < scp->host->cmd_per_lun) {
        !          4049:                        scp->host->cmd_per_lun = boardp->max_dvc_qng[i];
        !          4050:                }
        !          4051:        }
        !          4052: #endif /* ASC_SET_CMD_PER_LUN */
        !          4053: 
        !          4054:        return found;
        !          4055: }
        !          4056: 
        !          4057: /*
        !          4058:  * Search for an AdvanSys PCI device in the PCI configuration space.
        !          4059:  */
        !          4060: STATIC int
        !          4061: asc_srch_pci_dev(PCI_DEVICE *pciDevice)
        !          4062: {
        !          4063:        int ret;
        !          4064:        static int scan = 1;
        !          4065: 
        !          4066:        ASC_DBG(2, "asc_srch_pci_dev: begin\n");
        !          4067: 
        !          4068:        if (scan) {
        !          4069:                pciDevice->type = asc_scan_method(pciDevice);
        !          4070:                scan = 0;
        !          4071:                ASC_DBG1(2, "asc_srch_pci_dev: type %d\n", pciDevice->type);
        !          4072:        }
        !          4073:        ret = asc_pci_find_dev(pciDevice);
        !          4074:        ASC_DBG1(2, "asc_srch_pci_dev: asc_pci_find_dev() return %d\n", ret);
        !          4075:        if (ret == PCI_DEVICE_FOUND) {
        !          4076:                pciDevice->slotNumber = pciDevice->slotFound + 1;
        !          4077:                pciDevice->startSlot = pciDevice->slotFound + 1;
        !          4078:        } else {
        !          4079:                if (pciDevice->bridge > pciDevice->busNumber) {
        !          4080:                        ASC_DBG2(2, "asc_srch_pci_dev: bridge %x, busNumber %x\n",
        !          4081:                                pciDevice->bridge, pciDevice->busNumber);
        !          4082:                        pciDevice->busNumber++;
        !          4083:                        pciDevice->slotNumber = 0;
        !          4084:                        pciDevice->startSlot = 0;
        !          4085:                        pciDevice->endSlot = 0x0f;
        !          4086:                        ret = asc_srch_pci_dev(pciDevice);
        !          4087:                        ASC_DBG1(2, "asc_srch_pci_dev recursive call return %d\n", ret);
        !          4088:                }
        !          4089:        }
        !          4090:        ASC_DBG1(2, "asc_srch_pci_dev: return %d\n", ret);
        !          4091:        return ret;
        !          4092: }
        !          4093: 
        !          4094: /*
        !          4095:  * Determine the access method to be used for 'pciDevice'.
        !          4096:  */
        !          4097: STATIC uchar
        !          4098: asc_scan_method(PCI_DEVICE *pciDevice)
        !          4099: {
        !          4100:        ushort data;
        !          4101:        PCI_DATA pciData;
        !          4102:        uchar type;
        !          4103:        uchar slot;
        !          4104: 
        !          4105:        ASC_DBG(2, "asc_scan_method: begin\n");
        !          4106:        memset(&pciData, 0, sizeof(pciData));
        !          4107:        for (type = 1; type < 3; type++) {
        !          4108:                pciData.type = type;
        !          4109:                for (slot = 0; slot < PCI_MAX_SLOT; slot++) {
        !          4110:                        pciData.slot = slot;
        !          4111:                        data = asc_get_cfg_word(&pciData);
        !          4112:                        if ((data != 0xFFFF) && (data != 0x0000)) {
        !          4113:                                ASC_DBG2(4, "asc_scan_method: data %x, type %d\n", data, type);
        !          4114:                                return (type);
        !          4115:                        }
        !          4116:                }
        !          4117:        }
        !          4118:        ASC_DBG1(4, "asc_scan_method: type %d\n", type);
        !          4119:        return (type);
        !          4120: }
        !          4121: 
        !          4122: /*
        !          4123:  * Check for an AdvanSys PCI device in 'pciDevice'.
        !          4124:  *
        !          4125:  * Return PCI_DEVICE_FOUND if found, otherwise return PCI_DEVICE_NOT_FOUND.
        !          4126:  */
        !          4127: STATIC int
        !          4128: asc_pci_find_dev(PCI_DEVICE *pciDevice)
        !          4129: {
        !          4130:        PCI_DATA pciData;
        !          4131:        ushort vendorid, deviceid;
        !          4132:        uchar classcode, subclass;
        !          4133:        uchar lslot;
        !          4134: 
        !          4135:        ASC_DBG(3, "asc_pci_find_dev: begin\n");
        !          4136:        pciData.type = pciDevice->type;
        !          4137:        pciData.bus = pciDevice->busNumber;
        !          4138:        pciData.func = pciDevice->devFunc;
        !          4139:        lslot = pciDevice->startSlot;
        !          4140:        for (; lslot < pciDevice->endSlot; lslot++) {
        !          4141:                pciData.slot = lslot;
        !          4142:                pciData.offset = VENDORID_OFFSET;
        !          4143:                vendorid = asc_get_cfg_word(&pciData);
        !          4144:                ASC_DBG1(3, "asc_pci_find_dev: vendorid %x\n", vendorid);
        !          4145:                if (vendorid != 0xffff) {
        !          4146:                        pciData.offset = DEVICEID_OFFSET;
        !          4147:                        deviceid = asc_get_cfg_word(&pciData);
        !          4148:                        ASC_DBG1(3, "asc_pci_find_dev: deviceid %x\n", deviceid);
        !          4149:                        if ((vendorid == ASC_PCI_VENDORID) &&
        !          4150:                                ((deviceid == ASC_PCI_DEVICE_ID_REV_A) ||
        !          4151:                                (deviceid == ASC_PCI_DEVICE_ID_REV_B))) {
        !          4152:                                pciDevice->slotFound = lslot;
        !          4153:                                ASC_DBG(3, "asc_pci_find_dev: PCI_DEVICE_FOUND\n");
        !          4154:                                return PCI_DEVICE_FOUND;
        !          4155:                        } else {
        !          4156:                                pciData.offset = SUBCLASS_OFFSET;
        !          4157:                                subclass = asc_get_cfg_byte(&pciData);
        !          4158:                                pciData.offset = CLASSCODE_OFFSET;
        !          4159:                                classcode = asc_get_cfg_byte(&pciData);
        !          4160:                                if ((classcode & PCI_BASE_CLASS_BRIDGE_DEVICE) &&
        !          4161:                                        (subclass & PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER)) {
        !          4162:                                        pciDevice->bridge++;
        !          4163:                                }
        !          4164:                                ASC_DBG2(3, "asc_pci_find_dev: subclass %x, classcode %x\n",
        !          4165:                                        subclass, classcode);
        !          4166:                        }
        !          4167:                }
        !          4168:        }
        !          4169:        return PCI_DEVICE_NOT_FOUND;
        !          4170: }
        !          4171: 
        !          4172: /*
        !          4173:  * Read PCI configuration data into 'pciConfig'.
        !          4174:  */
        !          4175: STATIC void
        !          4176: asc_get_pci_cfg(PCI_DEVICE *pciDevice, PCI_CONFIG_SPACE *pciConfig)
        !          4177: {
        !          4178:        PCI_DATA pciData;
        !          4179:        uchar counter;
        !          4180:        uchar *localConfig;
        !          4181: 
        !          4182:        ASC_DBG1(4, "asc_get_pci_cfg: slot found - %d\n ",
        !          4183:                pciDevice->slotFound);
        !          4184: 
        !          4185:        pciData.type = pciDevice->type;
        !          4186:        pciData.bus = pciDevice->busNumber;
        !          4187:        pciData.slot = pciDevice->slotFound;
        !          4188:        pciData.func = pciDevice->devFunc;
        !          4189:        localConfig = (uchar *) pciConfig;
        !          4190: 
        !          4191:        for (counter = 0; counter < sizeof(PCI_CONFIG_SPACE); counter++) {
        !          4192:                pciData.offset = counter;
        !          4193:                *localConfig = asc_get_cfg_byte(&pciData);
        !          4194:                ASC_DBG1(4, "asc_get_pci_cfg: byte %x\n", *localConfig);
        !          4195:                localConfig++;
        !          4196:        }
        !          4197:        ASC_DBG1(4, "asc_get_pci_cfg: counter %d\n", counter);
        !          4198: }
        !          4199: 
        !          4200: /*
        !          4201:  * Read a word (16 bits) from the PCI configuration space.
        !          4202:  *
        !          4203:  * The configuration mechanism is checked for the correct access method.
        !          4204:  */
        !          4205: STATIC ushort
        !          4206: asc_get_cfg_word(PCI_DATA *pciData)
        !          4207: {
        !          4208:        ushort tmp;
        !          4209:        ulong address;
        !          4210:        ulong lbus = pciData->bus;
        !          4211:        ulong lslot = pciData->slot;
        !          4212:        ulong lfunc = pciData->func;
        !          4213:        uchar t2CFA, t2CF8;
        !          4214:        ushort t1CF8, t1CFA, t1CFC, t1CFE;
        !          4215: 
        !          4216:        ASC_DBG4(4, "asc_get_cfg_word: type %d, bus %lu, slot %lu, func %lu\n",
        !          4217:                pciData->type, lbus, lslot, lfunc);
        !          4218: 
        !          4219:        /*
        !          4220:         * check type of configuration mechanism
        !          4221:         */
        !          4222:        if (pciData->type == 2) {
        !          4223:                /*
        !          4224:                 * save these registers so we can restore them after we are done
        !          4225:                 */
        !          4226:                t2CFA = inp(0xCFA);     /* save PCI bus register */
        !          4227:                t2CF8 = inp(0xCF8);     /* save config space enable register */
        !          4228: 
        !          4229:                /*
        !          4230:                 * go out and write the bus and enable registers
        !          4231:                 */
        !          4232:                /* set for type 1 cycle, if needed */
        !          4233:                outp(0xCFA, pciData->bus);
        !          4234:                /* set the function number */
        !          4235:                outp(0xCF8, 0x10 | (pciData->func << 1)) ;
        !          4236: 
        !          4237:                /*
        !          4238:                 * read the configuration space type 2 locations
        !          4239:                 */
        !          4240:                tmp = (ushort) inpw(0xC000 | ((pciData->slot << 8) + pciData->offset));
        !          4241:        } else {
        !          4242:                /*
        !          4243:                 * type 1 configuration mechanism
        !          4244:                 *
        !          4245:                 * save the CONFIG_ADDRESS and CONFIG_DATA register values
        !          4246:                 */
        !          4247:                t1CFC = inpw(0xCFC);
        !          4248:                t1CFE = inpw(0xCFE);
        !          4249:                t1CF8 = inpw(0xCF8);
        !          4250:                t1CFA = inpw(0xCFA);
        !          4251: 
        !          4252:                /*
        !          4253:                 * enable <31>, bus = <23:16>, slot = <15:11>,
        !          4254:                 * func = <10:8>, reg = <7:2>
        !          4255:                 */
        !          4256:                address = (ulong) ((lbus << 16) | (lslot << 11) |
        !          4257:                        (lfunc << 8) | (pciData->offset & 0xFC) | 0x80000000L);
        !          4258: 
        !          4259:                /*
        !          4260:                 * write out the address to CONFIG_ADDRESS
        !          4261:                 */
        !          4262:                outl(address, 0xCF8);
        !          4263: 
        !          4264:                /*
        !          4265:                 * read in the word from CONFIG_DATA
        !          4266:                 */
        !          4267:                tmp = (ushort) ((inl(0xCFC) >>
        !          4268:                                 ((pciData->offset & 2) * 8)) & 0xFFFF);
        !          4269:        }
        !          4270:        ASC_DBG1(4, "asc_get_cfg_word: config data: %x\n", tmp);
        !          4271:        return tmp;
        !          4272: }
        !          4273: 
        !          4274: /*
        !          4275:  * Reads a byte from the PCI configuration space.
        !          4276:  *
        !          4277:  * The configuration mechanism is checked for the correct access method.
        !          4278:  */
        !          4279: STATIC uchar
        !          4280: asc_get_cfg_byte(PCI_DATA *pciData)
        !          4281: {
        !          4282:        uchar tmp;
        !          4283:        ulong address;
        !          4284:        ulong lbus = pciData->bus, lslot = pciData->slot, lfunc = pciData->func;
        !          4285:        uchar t2CFA, t2CF8;
        !          4286:        ushort t1CF8, t1CFA, t1CFC, t1CFE;
        !          4287: 
        !          4288:        ASC_DBG1(4, "asc_get_cfg_byte: type: %d\n", pciData->type);
        !          4289: 
        !          4290:        /*
        !          4291:         * check type of configuration mechanism
        !          4292:         */
        !          4293:        if (pciData->type == 2) {
        !          4294:                /*
        !          4295:                 * save these registers so we can restore them after we are done
        !          4296:                 */
        !          4297:                t2CFA = inp(0xCFA);     /* save PCI bus register */
        !          4298:                t2CF8 = inp(0xCF8);     /* save config space enable register */
        !          4299: 
        !          4300:                /*
        !          4301:                 * go out and write the bus and enable registers
        !          4302:                 */
        !          4303:                /* set for type 1 cycle, if needed */
        !          4304:                outp(0xCFA, pciData->bus);
        !          4305:                /* set the function number */
        !          4306:                outp(0xCF8, 0x10 | (pciData->func << 1));
        !          4307: 
        !          4308:                /*
        !          4309:                 * read the configuration space type 2 locations
        !          4310:                 */
        !          4311:                tmp = inp(0xC000 | ((pciData->slot << 8) + pciData->offset));
        !          4312: 
        !          4313:                /*
        !          4314:                 * restore the registers used for our transaction
        !          4315:                 */
        !          4316:                outp(0xCF8, t2CF8);     /* restore the enable register */
        !          4317:                outp(0xCFA, t2CFA);     /* restore PCI bus register */
        !          4318:        } else {
        !          4319:                /*
        !          4320:                 * type 1 configuration mechanism
        !          4321:                 *
        !          4322:                 * save the CONFIG_ADDRESS and CONFIG_DATA register values
        !          4323:                 */
        !          4324:                t1CFC = inpw(0xCFC);
        !          4325:                t1CFE = inpw(0xCFE);
        !          4326:                t1CF8 = inpw(0xCF8);
        !          4327:                t1CFA = inpw(0xCFA);
        !          4328: 
        !          4329:                /*
        !          4330:                 * enable <31>, bus = <23:16>, slot = <15:11>, func = <10:8>,
        !          4331:                 * reg = <7:2>
        !          4332:                 */
        !          4333:                address = (ulong) ((lbus << 16) | (lslot << 11) |
        !          4334:                        (lfunc << 8) | (pciData->offset & 0xFC) | 0x80000000L);
        !          4335: 
        !          4336:                /*
        !          4337:                 * write out the address to CONFIG_ADDRESS
        !          4338:                 */
        !          4339:                outl(address, 0xCF8);
        !          4340: 
        !          4341:                /*
        !          4342:                 * read in the word from CONFIG_DATA
        !          4343:                 */
        !          4344:                tmp = (uchar) ((inl(0xCFC) >> ((pciData->offset & 3) * 8)) & 0xFF);
        !          4345:        }
        !          4346:        ASC_DBG1(4, "asc_get_cfg_byte: config data: %x\n", tmp);
        !          4347:        return tmp;
        !          4348: }
        !          4349: 
        !          4350: /*
        !          4351:  * Add a 'Scsi_Cmnd' to the end of specified 'Scsi_Host' 
        !          4352:  * target device pending command list. Set 'pending_tidmask'
        !          4353:  * to indicate a command is queued for the device.
        !          4354:  *
        !          4355:  * 'flag' may be either ASC_FRONT or ASC_BACK.
        !          4356:  *
        !          4357:  * The 'Scsi_Cmnd' host_scribble field is used as a next pointer.
        !          4358:  */
        !          4359: STATIC void
        !          4360: asc_enqueue(struct Scsi_Host *shp, Scsi_Cmnd *scp, int tid, int flag)
        !          4361: {
        !          4362:        Scsi_Cmnd       **scpp;
        !          4363: 
        !          4364:        ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
        !          4365:        ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
        !          4366:        ASC_STATS(enqueue);
        !          4367:        if (flag == ASC_FRONT) {
        !          4368:                scp->host_scribble = (unsigned char *) ASC_BOARD(shp)->pending[tid];
        !          4369:                ASC_BOARD(shp)->pending[tid] = (Scsi_Cmnd *) scp;
        !          4370:        } else { /* ASC_BACK */
        !          4371:                for (scpp = &ASC_BOARD(shp)->pending[tid]; *scpp;
        !          4372:                         scpp = (Scsi_Cmnd **) &(*scpp)->host_scribble) {
        !          4373:                        ;
        !          4374:                }
        !          4375:                *scpp = scp;
        !          4376:                scp->host_scribble = NULL;
        !          4377:        }
        !          4378:        ASC_BOARD(shp)->pending_tidmask |= ASC_TIX_TO_TARGET_ID(tid);
        !          4379: }
        !          4380: 
        !          4381: /*
        !          4382:  * Return first pending 'Scsi_Cmnd' on the specified 'Scsi_Host'
        !          4383:  * for the specified target device. Clear the 'pending_tidmask'
        !          4384:  * bit for the device if no more commands are left queued for it.
        !          4385:  *
        !          4386:  * The 'Scsi_Cmnd' host_scribble field is used as a next pointer.
        !          4387:  */
        !          4388: STATIC Scsi_Cmnd *
        !          4389: asc_dequeue(struct Scsi_Host *shp, int tid)
        !          4390: {
        !          4391:        Scsi_Cmnd       *scp;
        !          4392: 
        !          4393:        ASC_STATS(dequeue);
        !          4394:        ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
        !          4395:        if ((scp = ASC_BOARD(shp)->pending[tid]) != NULL) {
        !          4396:                ASC_BOARD(shp)->pending[tid] = (Scsi_Cmnd *) scp->host_scribble;
        !          4397:        }
        !          4398:        if (ASC_BOARD(shp)->pending[tid] == NULL) {
        !          4399:                ASC_BOARD(shp)->pending_tidmask &= ~ASC_TIX_TO_TARGET_ID(tid);
        !          4400:        }
        !          4401:        return scp;
        !          4402: }
        !          4403: 
        !          4404: /*
        !          4405:  * Remove the specified 'Scsi_Cmnd' from the specified 'Scsi_Host'
        !          4406:  * for the specified target device. Clear the 'pending_tidmask'
        !          4407:  * bit for the device if no more commands are left queued for it.
        !          4408:  *
        !          4409:  * The 'Scsi_Cmnd' host_scribble field is used as a next pointer.
        !          4410:  *
        !          4411:  * Return ASC_TRUE if the command was found and removed, otherwise
        !          4412:  * return ASC_FALSE if the command was not found.
        !          4413:  */
        !          4414: STATIC int
        !          4415: asc_rmqueue(struct Scsi_Host *shp, Scsi_Cmnd *scp, int tid)
        !          4416: {
        !          4417:        Scsi_Cmnd       **scpp;
        !          4418:        int                     ret;
        !          4419: 
        !          4420:        ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
        !          4421:        ret = ASC_FALSE;
        !          4422:        for (scpp = &ASC_BOARD(shp)->pending[tid];
        !          4423:             *scpp; scpp = (Scsi_Cmnd **) &(*scpp)->host_scribble) {
        !          4424:                if (*scpp == scp) {
        !          4425:                        *scpp = (Scsi_Cmnd *) scp->host_scribble;       
        !          4426:                        scp->host_scribble = NULL;
        !          4427:                        ASC_STATS(rmqueue);
        !          4428:                        ret = ASC_TRUE;
        !          4429:                }
        !          4430:        }
        !          4431:        if (ASC_BOARD(shp)->pending[tid] == NULL) {
        !          4432:                ASC_BOARD(shp)->pending_tidmask &= ~ASC_TIX_TO_TARGET_ID(tid);
        !          4433:        }
        !          4434:        return ret;
        !          4435: }
        !          4436: 
        !          4437: 
        !          4438: /*
        !          4439:  * --- Functions Required by the Asc Library
        !          4440:  */
        !          4441: 
        !          4442: /*
        !          4443:  * Delay for 'n' milliseconds. Don't use the 'jiffies'
        !          4444:  * global variable which is incremented once every 5 ms
        !          4445:  * from a timer interrupt, because this function may be
        !          4446:  * called when interrupts are disabled.
        !          4447:  */
        !          4448: void
        !          4449: DvcSleepMilliSecond(ulong n)
        !          4450: {
        !          4451:        ulong i;
        !          4452: 
        !          4453:        ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", n);
        !          4454:        for (i = 0; i < n; i++) {
        !          4455:                udelay(1000);
        !          4456:        }
        !          4457: }
        !          4458: 
        !          4459: void
        !          4460: DvcDisplayString(uchar *s)
        !          4461: {
        !          4462:        printk(s);
        !          4463: }
        !          4464: 
        !          4465: int
        !          4466: DvcEnterCritical(void)
        !          4467: {
        !          4468:        int     flags;
        !          4469: 
        !          4470:        save_flags(flags);
        !          4471:        cli();
        !          4472:        return flags;
        !          4473: }
        !          4474: 
        !          4475: void
        !          4476: DvcLeaveCritical(int flags)
        !          4477: {
        !          4478:        restore_flags(flags);
        !          4479: }
        !          4480: 
        !          4481: /*
        !          4482:  * Convert a virtual address to a virtual address.
        !          4483:  *
        !          4484:  * Apparently Linux is loaded V=R (virtual equals real). Just return
        !          4485:  * the virtual address.
        !          4486:  */
        !          4487: ulong
        !          4488: DvcGetPhyAddr(uchar *buf_addr, ulong buf_len)
        !          4489: {
        !          4490:        ulong phys_addr;
        !          4491: 
        !          4492:        phys_addr = (ulong) buf_addr;
        !          4493:        return phys_addr;
        !          4494: }
        !          4495: 
        !          4496: ulong
        !          4497: DvcGetSGList(ASC_DVC_VAR *asc_dvc_sg, uchar *buf_addr, ulong buf_len,
        !          4498:                         ASC_SG_HEAD *asc_sg_head_ptr)
        !          4499: {
        !          4500:        ulong buf_size;
        !          4501: 
        !          4502:        buf_size = buf_len;
        !          4503:        asc_sg_head_ptr->entry_cnt = 1;
        !          4504:        asc_sg_head_ptr->sg_list[0].addr = (ulong) buf_addr;
        !          4505:        asc_sg_head_ptr->sg_list[0].bytes = buf_size;
        !          4506:        return buf_size;
        !          4507: }
        !          4508: 
        !          4509: /*
        !          4510:  * void
        !          4511:  * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, ushort *outbuf, int words)
        !          4512:  *
        !          4513:  * Calling/Exit State:
        !          4514:  *     none
        !          4515:  *
        !          4516:  * Description:
        !          4517:  *     Output an ASC_SCSI_Q structure to the chip
        !          4518:  */
        !          4519: void
        !          4520: DvcPutScsiQ(PortAddr iop_base, ushort s_addr, ushort *outbuf, int words)
        !          4521: {
        !          4522:        int     i;
        !          4523: 
        !          4524:        ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", (uchar *) outbuf, 2 * words);
        !          4525:        AscSetChipLramAddr(iop_base, s_addr);
        !          4526:        for (i = 0; i < words; i++, outbuf++) {
        !          4527:                if (i == 2 || i == 10) {
        !          4528:                        continue;
        !          4529:                }
        !          4530:                AscPutChipLramData(iop_base, *outbuf);
        !          4531:        }
        !          4532: }
        !          4533: 
        !          4534: /*
        !          4535:  * void
        !          4536:  * DvcGetQinfo(PortAddr iop_base, ushort s_addr, ushort *inbuf, int words)
        !          4537:  *
        !          4538:  * Calling/Exit State:
        !          4539:  *     none
        !          4540:  *
        !          4541:  * Description:
        !          4542:  *     Input an ASC_QDONE_INFO structure from the chip
        !          4543:  */
        !          4544: void
        !          4545: DvcGetQinfo(PortAddr iop_base, ushort s_addr, ushort *inbuf, int words)
        !          4546: {
        !          4547:        int     i;
        !          4548: 
        !          4549:        AscSetChipLramAddr(iop_base, s_addr);
        !          4550:        for (i = 0; i < words; i++, inbuf++) {
        !          4551:                if (i == 5) {
        !          4552:                        continue;
        !          4553:                }
        !          4554:                *inbuf = AscGetChipLramData(iop_base);
        !          4555:        }
        !          4556:        ASC_DBG_PRT_HEX(2, "DvcGetQinfo", (uchar *) inbuf, 2 * words);
        !          4557: }
        !          4558: 
        !          4559: /*
        !          4560:  * void        DvcOutPortWords(ushort iop_base, ushort &outbuf, int words)
        !          4561:  *
        !          4562:  * Calling/Exit State:
        !          4563:  *     none
        !          4564:  *
        !          4565:  * Description:
        !          4566:  *     output a buffer to an i/o port address
        !          4567:  */
        !          4568: void
        !          4569: DvcOutPortWords(ushort iop_base, ushort *outbuf, int words)
        !          4570: {
        !          4571:        int     i;
        !          4572: 
        !          4573:        for (i = 0; i < words; i++, outbuf++)
        !          4574:                outpw(iop_base, *outbuf);
        !          4575: }
        !          4576: 
        !          4577: /*
        !          4578:  * void        DvcInPortWords(ushort iop_base, ushort &outbuf, int words)
        !          4579:  *
        !          4580:  * Calling/Exit State:
        !          4581:  *     none
        !          4582:  *
        !          4583:  * Description:
        !          4584:  *     input a buffer from an i/o port address
        !          4585:  */
        !          4586: void
        !          4587: DvcInPortWords(ushort iop_base, ushort *inbuf, int words)
        !          4588: {
        !          4589:        int     i;
        !          4590: 
        !          4591:        for (i = 0; i < words; i++, inbuf++)
        !          4592:                *inbuf = inpw(iop_base);
        !          4593: }
        !          4594: 
        !          4595: 
        !          4596: /*
        !          4597:  * void DvcOutPortDWords(PortAddr port, ulong *pdw, int dwords)
        !          4598:  *
        !          4599:  * Calling/Exit State:
        !          4600:  *     none
        !          4601:  *
        !          4602:  * Description:
        !          4603:  *     output a buffer of 32-bit integers to an i/o port address in
        !          4604:  *  16 bit integer units
        !          4605:  */
        !          4606: void  
        !          4607: DvcOutPortDWords(PortAddr port, ulong *pdw, int dwords)
        !          4608: {
        !          4609:        int             i;
        !          4610:        int             words;
        !          4611:        ushort  *pw;
        !          4612: 
        !          4613:        pw = (ushort *) pdw;
        !          4614:        words = dwords << 1;
        !          4615:        for(i = 0; i < words; i++, pw++) {
        !          4616:                outpw(port, *pw);
        !          4617:        }
        !          4618:        return;
        !          4619: }
        !          4620: 
        !          4621: 
        !          4622: /*
        !          4623:  * --- Tracing and Debugging Functions
        !          4624:  */
        !          4625: 
        !          4626: #ifdef ADVANSYS_STATS
        !          4627: 
        !          4628: #define ASC_PRT_STATS_NEXT() \
        !          4629:        if (cp) { \
        !          4630:                totlen += len; \
        !          4631:                leftlen -= len; \
        !          4632:                if (leftlen == 0) { \
        !          4633:                        return totlen; \
        !          4634:                } \
        !          4635:                cp += len; \
        !          4636:        }
        !          4637: 
        !          4638: /*
        !          4639:  * asc_prt_stats()
        !          4640:  *
        !          4641:  * Note: no single line should be greater than 160 characters, cf.
        !          4642:  * asc_prt_stats_line().
        !          4643:  *
        !          4644:  * Return the number of characters copied into 'cp'. No more than
        !          4645:  * 'cplen' characters will be copied to 'cp'.
        !          4646:  */
        !          4647: STATIC int
        !          4648: asc_prt_stats(char *cp, int cplen)
        !          4649: {
        !          4650:        struct asc_stats        *s;
        !          4651:        int                                     leftlen;
        !          4652:        int                                     totlen;
        !          4653:        int                                     len;
        !          4654: 
        !          4655:        s = &asc_stats;
        !          4656:        leftlen = cplen;
        !          4657:        totlen = len = 0;
        !          4658: 
        !          4659:        len = asc_prt_stats_line(cp, leftlen,
        !          4660: "\nAdvanSys SCSI Host Driver Statistics:\n");
        !          4661:        ASC_PRT_STATS_NEXT();
        !          4662:        
        !          4663:        len = asc_prt_stats_line(cp, leftlen,
        !          4664: " command %lu, queuecommand %lu, abort %lu, reset %lu, biosparam %lu,\n",
        !          4665:                s->command, s->queuecommand, s->abort, s->reset, s->biosparam);
        !          4666:        ASC_PRT_STATS_NEXT();
        !          4667: 
        !          4668:        len = asc_prt_stats_line(cp, leftlen,
        !          4669: " interrupt %lu, callback %lu, cmd_disable %lu, intr_disable %lu,\n",
        !          4670:                s->interrupt, s->callback, s->cmd_disable, s->intr_disable);
        !          4671:        ASC_PRT_STATS_NEXT();
        !          4672: 
        !          4673:        len = asc_prt_stats_line(cp, leftlen,
        !          4674: " error %lu, enqueue %lu, dequeue %lu, rmqueue %lu,\n",
        !          4675:                s->error, s->enqueue, s->dequeue, s->rmqueue);
        !          4676:        ASC_PRT_STATS_NEXT();
        !          4677: 
        !          4678:        if (s->cont_cnt > 0) {
        !          4679:                len = asc_prt_stats_line(cp, leftlen,
        !          4680: " cont_cnt %lu, cont_xfer %lu: avg_xfer=%lu kb\n",
        !          4681:                        s->cont_cnt, s->cont_xfer, (s->cont_xfer/2)/s->cont_cnt);
        !          4682:                ASC_PRT_STATS_NEXT();
        !          4683:        }
        !          4684: 
        !          4685:        if (s->sg_cnt > 0) {
        !          4686:                len = asc_prt_stats_line(cp, leftlen,
        !          4687: " sg_cnt %lu, sg_elem %lu, sg_xfer %lu: avg_elem=%lu, avg_size=%lu kb\n",
        !          4688:                        s->sg_cnt, s->sg_elem, s->sg_xfer,
        !          4689:                        s->sg_elem/s->sg_cnt, (s->sg_xfer/2)/s->sg_cnt);
        !          4690:                ASC_PRT_STATS_NEXT();
        !          4691:        }
        !          4692: 
        !          4693:        return totlen;
        !          4694: }
        !          4695: 
        !          4696: /*
        !          4697:  * asc_prt_stats_line()
        !          4698:  *
        !          4699:  * If 'cp' is NULL print to the console, otherwise print to a buffer.
        !          4700:  *
        !          4701:  * Return 0 if printing to the console, otherwise return the number of
        !          4702:  * bytes written to the buffer.
        !          4703:  *
        !          4704:  * Note: If any single line is greater than 160 bytes the stack
        !          4705:  * will be corrupted. 's[]' is defined to be 160 bytes.
        !          4706:  */
        !          4707: int
        !          4708: asc_prt_stats_line(char *buf, int buflen, char *fmt, ...)
        !          4709: {
        !          4710:        va_list         args;
        !          4711:        int                     ret;
        !          4712:        char            s[160];         /* 2 lines */
        !          4713: 
        !          4714:        va_start(args, fmt);
        !          4715:        ret = vsprintf(s, fmt, args);
        !          4716:        if (buf == NULL) {
        !          4717:                (void) printk(s);
        !          4718:                ret = 0;
        !          4719:        } else {
        !          4720:                ret = min(buflen, ret);
        !          4721:                memcpy(buf, s, ret);
        !          4722:        }
        !          4723:        va_end(args);
        !          4724:        return ret;
        !          4725: }
        !          4726: #endif /* ADVANSYS_STATS */
        !          4727: 
        !          4728: #ifdef ADVANSYS_DEBUG
        !          4729: /*
        !          4730:  * asc_prt_scsi_host()
        !          4731:  */
        !          4732: STATIC void 
        !          4733: asc_prt_scsi_host(struct Scsi_Host *s)
        !          4734: {
        !          4735:        printk("Scsi_Host at addr %x\n", (unsigned) s);
        !          4736:        printk(
        !          4737: " next %x, extra_bytes %u, host_busy %u, host_no %d, last_reset %d,\n",
        !          4738:                (unsigned) s->next, s->extra_bytes, s->host_busy, s->host_no,
        !          4739:                s->last_reset);
        !          4740: 
        !          4741:        printk(
        !          4742: " host_wait %x, host_queue %x, hostt %x, block %x,\n",
        !          4743:                (unsigned) s->host_wait, (unsigned) s->host_queue,
        !          4744:                (unsigned) s->hostt, (unsigned) s->block);
        !          4745: 
        !          4746:        printk(
        !          4747: " wish_block %d, base %x, io_port %d, n_io_port %d, irq %d, dma_channel %d,\n",
        !          4748:                s->wish_block, (unsigned) s->base, s->io_port, s->n_io_port,
        !          4749:                s->irq, s->dma_channel);
        !          4750: 
        !          4751:        printk(
        !          4752: " this_id %d, can_queue %d,\n", s->this_id, s->can_queue);
        !          4753: 
        !          4754:        printk(
        !          4755: " cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d, loaded_as_module %d\n",
        !          4756:                s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma,
        !          4757:                s->loaded_as_module);
        !          4758: 
        !          4759:        printk("hostdata (struct asc_board)\n");
        !          4760:        asc_prt_dvc_var(&ASC_BOARD(s)->board);
        !          4761:        asc_prt_dvc_cfg(&ASC_BOARD(s)->cfg);
        !          4762:        printk(" overrun_buf %x\n", (unsigned) &ASC_BOARD(s)->overrun_buf[0]);
        !          4763: }
        !          4764: 
        !          4765: /*
        !          4766:  * asc_prt_dvc_var()
        !          4767:  */
        !          4768: STATIC void 
        !          4769: asc_prt_dvc_var(ASC_DVC_VAR *h)
        !          4770: {
        !          4771:        printk("ASC_DVC_VAR at addr %x\n", (unsigned) h);
        !          4772: 
        !          4773:        printk(
        !          4774: " iop_base %x, err_code %x, dvc_cntl %x, bug_fix_cntl %d,\n",
        !          4775:                h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
        !          4776: 
        !          4777:        printk(
        !          4778: " bus_type %d, isr_callback %x, exe_callback %x, init_sdtr %x,\n",
        !          4779:                h->bus_type, (unsigned) h->isr_callback, (unsigned) h->exe_callback,
        !          4780:                (unsigned) h->init_sdtr);
        !          4781: 
        !          4782:        printk(
        !          4783: " sdtr_done %x, use_tagged_qng %x, unit_not_ready %x, chip_no %x,\n",
        !          4784:                (unsigned) h->sdtr_done, (unsigned) h->use_tagged_qng,
        !          4785:                (unsigned) h->unit_not_ready, (unsigned) h->chip_no);
        !          4786:                
        !          4787:        printk(
        !          4788: " queue_full_or_busy %x, start_motor %x, scsi_reset_wait %x, irq_no %x,\n",
        !          4789:                (unsigned) h->queue_full_or_busy, (unsigned) h->start_motor,
        !          4790:                (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
        !          4791: 
        !          4792:        printk(
        !          4793: " is_in_int %x, max_total_qng %x, cur_total_qng %x, in_critical_cnt %x,\n",
        !          4794:                (unsigned) h->is_in_int, (unsigned) h->max_total_qng,
        !          4795:                (unsigned) h->cur_total_qng, (unsigned) h->in_critical_cnt);
        !          4796: 
        !          4797:        printk(
        !          4798: " last_q_shortage %x, init_state %x, no_scam %x, pci_fix_asyn_xfer %x,\n",
        !          4799:                (unsigned) h->last_q_shortage, (unsigned) h->init_state,
        !          4800:                (unsigned) h->no_scam, (unsigned) h->pci_fix_asyn_xfer);
        !          4801: 
        !          4802:        printk(
        !          4803: " int_count %ld, req_count %ld, busy_count %ld, cfg %x, saved_ptr2func %x\n",
        !          4804:                h->int_count, h->req_count, h->busy_count, (unsigned) h->cfg,
        !          4805:                (unsigned) h->saved_ptr2func);
        !          4806: }
        !          4807: 
        !          4808: /*
        !          4809:  * asc_prt_dvc_cfg()
        !          4810:  */
        !          4811: STATIC void 
        !          4812: asc_prt_dvc_cfg(ASC_DVC_CFG *h)
        !          4813: {
        !          4814:        printk("ASC_DVC_CFG at addr %x\n", (unsigned) h);
        !          4815: 
        !          4816:        printk(
        !          4817: " can_tagged_qng %x, cmd_qng_enabled %x, disc_enable %x, res %x,\n",
        !          4818:                        h->can_tagged_qng, h->cmd_qng_enabled, h->disc_enable, h->res);
        !          4819: 
        !          4820:        printk(
        !          4821: " chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
        !          4822:                         h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
        !          4823:                         h->chip_version);
        !          4824: 
        !          4825:        printk(
        !          4826: " pci_device_id %d, lib_serial_no %d, lib_version %d, mcode_date %d,\n",
        !          4827:                  h->pci_device_id, h->lib_serial_no, h->lib_version, h->mcode_date);
        !          4828: 
        !          4829:        printk(
        !          4830: " mcode_version %d, overrun_buf %x\n",
        !          4831:                        h->mcode_version, (unsigned) h->overrun_buf);
        !          4832: }
        !          4833: 
        !          4834: /*
        !          4835:  * asc_prt_scsi_q()
        !          4836:  */
        !          4837: STATIC void 
        !          4838: asc_prt_scsi_q(ASC_SCSI_Q *q)
        !          4839: {
        !          4840:        ASC_SG_HEAD     *sgp;
        !          4841:        int i;
        !          4842: 
        !          4843:        printk("ASC_SCSI_Q at addr %x\n", (unsigned) q);
        !          4844: 
        !          4845:        printk(
        !          4846: " target_ix %u, target_lun %u, srb_ptr %x, tag_code %u,\n",
        !          4847:                        q->q2.target_ix, q->q1.target_lun,
        !          4848:                        (unsigned) q->q2.srb_ptr, q->q2.tag_code);
        !          4849: 
        !          4850:        printk(
        !          4851: " data_addr %x, data_cnt %lu, sense_addr %x, sense_len %u,\n",
        !          4852:                        (unsigned) q->q1.data_addr, q->q1.data_cnt,
        !          4853:                        (unsigned) q->q1.sense_addr, q->q1.sense_len);
        !          4854: 
        !          4855:        printk(
        !          4856: " cdbptr %x, cdb_len %u, sg_head %x, sg_queue_cnt %u\n",
        !          4857:                        (unsigned) q->cdbptr, q->q2.cdb_len,
        !          4858:                        (unsigned) q->sg_head, q->q1.sg_queue_cnt);
        !          4859: 
        !          4860:        if (q->sg_head) {
        !          4861:                sgp = q->sg_head;
        !          4862:                printk("ASC_SG_HEAD at addr %x\n", (unsigned) sgp);
        !          4863:                printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, sgp->queue_cnt);
        !          4864:                for (i = 0; i < sgp->entry_cnt; i++) {
        !          4865:                        printk(" [%u]: addr %x, bytes %lu\n",
        !          4866:                                i, (unsigned) sgp->sg_list[i].addr, sgp->sg_list[i].bytes);
        !          4867:                }
        !          4868: 
        !          4869:        }
        !          4870: }
        !          4871: 
        !          4872: /*
        !          4873:  * asc_prt_qdone_info()
        !          4874:  */
        !          4875: STATIC void 
        !          4876: asc_prt_qdone_info(ASC_QDONE_INFO *q)
        !          4877: {
        !          4878:        printk("ASC_QDONE_INFO at addr %x\n", (unsigned) q);
        !          4879:        printk(
        !          4880: " srb_ptr %x, target_ix %u, cdb_len %u, tag_code %u, done_stat %x\n",
        !          4881:                        (unsigned) q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
        !          4882:                        q->d2.tag_code, q->d3.done_stat);
        !          4883:        printk(
        !          4884: " host_stat %x, scsi_stat %x, scsi_msg %x\n",
        !          4885:                        q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
        !          4886: }
        !          4887: 
        !          4888: /*
        !          4889:  * asc_prt_hex()
        !          4890:  *
        !          4891:  * Print hexadecimal output in 4 byte groupings 32 bytes 
        !          4892:  * or 8 double-words per line.
        !          4893:  */
        !          4894: STATIC void 
        !          4895: asc_prt_hex(char *f, uchar *s, int l)
        !          4896: {
        !          4897:        int                     i;
        !          4898:        int                     j;
        !          4899:        int                     k;
        !          4900:        int                     m;
        !          4901: 
        !          4902:        printk("%s: (%d bytes)\n", f, l);
        !          4903: 
        !          4904:        for (i = 0; i < l; i += 32) {
        !          4905:                
        !          4906:                /* Display a maximum of 8 double-words per line. */
        !          4907:                if ((k = (l - i) / 4) >= 8) {
        !          4908:                        k = 8;
        !          4909:                        m = 0;
        !          4910:                } else {
        !          4911:                        m = (l - i) % 4 ;
        !          4912:                }
        !          4913: 
        !          4914:                for (j = 0; j < k; j++) {
        !          4915:                        printk(" %2.2X%2.2X%2.2X%2.2X",
        !          4916:                                (unsigned) s[i+(j*4)], (unsigned) s[i+(j*4)+1],
        !          4917:                                (unsigned) s[i+(j*4)+2], (unsigned) s[i+(j*4)+3]);
        !          4918:                }
        !          4919: 
        !          4920:                switch (m) {
        !          4921:                case 0:
        !          4922:                default:
        !          4923:                        break;
        !          4924:                case 1:
        !          4925:                        printk(" %2.2X",
        !          4926:                                (unsigned) s[i+(j*4)+4]);
        !          4927:                        break;
        !          4928:                case 2:
        !          4929:                        printk(" %2.2X%2.2X",
        !          4930:                                (unsigned) s[i+(j*4)+4],
        !          4931:                                (unsigned) s[i+(j*4)+5]);
        !          4932:                        break;
        !          4933:                case 3:
        !          4934:                        printk(" %2.2X%2.2X%2.2X",
        !          4935:                                (unsigned) s[i+(j*4)+4],
        !          4936:                                (unsigned) s[i+(j*4)+5],
        !          4937:                                (unsigned) s[i+(j*4)+6]);
        !          4938:                        break;
        !          4939:                }
        !          4940: 
        !          4941:                printk("\n");
        !          4942:        }
        !          4943: }
        !          4944: 
        !          4945: /*
        !          4946:  * interrupts_enabled()
        !          4947:  *
        !          4948:  * Return 1 if interrupts are enabled, otherwise return 0.
        !          4949:  */
        !          4950: STATIC int
        !          4951: interrupts_enabled(void)
        !          4952: {
        !          4953:        int flags;
        !          4954: 
        !          4955:        save_flags(flags);
        !          4956:        if (flags & 0x0200) {
        !          4957:                return ASC_TRUE;
        !          4958:        } else {
        !          4959:                return ASC_FALSE;
        !          4960:        }
        !          4961: }
        !          4962: 
        !          4963: #endif /* ADVANSYS_DEBUG */
        !          4964: 
        !          4965: 
        !          4966: /*
        !          4967:  * --- Asc Library Functions
        !          4968:  */
        !          4969: 
        !          4970: ushort
        !          4971: AscGetEisaChipCfg(
        !          4972:                                         PortAddr iop_base
        !          4973: )
        !          4974: {
        !          4975:        PortAddr            eisa_cfg_iop;
        !          4976: 
        !          4977:        eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
        !          4978:          (PortAddr) (ASC_EISA_CFG_IOP_MASK);
        !          4979:        return (inpw(eisa_cfg_iop));
        !          4980: }
        !          4981: 
        !          4982: uchar
        !          4983: AscSetChipScsiID(
        !          4984:                                        PortAddr iop_base,
        !          4985:                                        uchar new_host_id
        !          4986: )
        !          4987: {
        !          4988:        ushort              cfg_lsw;
        !          4989: 
        !          4990:        if (AscGetChipScsiID(iop_base) == new_host_id) {
        !          4991:                return (new_host_id);
        !          4992:        }
        !          4993:        cfg_lsw = AscGetChipCfgLsw(iop_base);
        !          4994:        cfg_lsw &= 0xF8FF;
        !          4995:        cfg_lsw |= (ushort) ((new_host_id & ASC_MAX_TID) << 8);
        !          4996:        AscSetChipCfgLsw(iop_base, cfg_lsw);
        !          4997:        return (AscGetChipScsiID(iop_base));
        !          4998: }
        !          4999: 
        !          5000: ushort
        !          5001: AscGetChipBiosAddress(
        !          5002:                                                 PortAddr iop_base,
        !          5003:                                                 ushort bus_type
        !          5004: )
        !          5005: {
        !          5006:        ushort              cfg_lsw;
        !          5007:        ushort              bios_addr;
        !          5008: 
        !          5009:        if ((bus_type & ASC_IS_EISA) != 0) {
        !          5010:                cfg_lsw = AscGetEisaChipCfg(iop_base);
        !          5011:                cfg_lsw &= 0x000F;
        !          5012:                bios_addr = (ushort) (ASC_BIOS_MIN_ADDR +
        !          5013:                                                          (cfg_lsw * ASC_BIOS_BANK_SIZE));
        !          5014:                return (bios_addr);
        !          5015:        }
        !          5016:        cfg_lsw = AscGetChipCfgLsw(iop_base);
        !          5017:        bios_addr = (ushort) (((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) + ASC_BIOS_MIN_ADDR);
        !          5018:        return (bios_addr);
        !          5019: }
        !          5020: 
        !          5021: uchar
        !          5022: AscGetChipVersion(
        !          5023:                                         PortAddr iop_base,
        !          5024:                                         ushort bus_type
        !          5025: )
        !          5026: {
        !          5027:        if ((bus_type & ASC_IS_EISA) != 0) {
        !          5028: 
        !          5029:                PortAddr            eisa_iop;
        !          5030:                uchar               revision;
        !          5031: 
        !          5032:                eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
        !          5033:                  (PortAddr) ASC_EISA_REV_IOP_MASK;
        !          5034:                revision = inp(eisa_iop);
        !          5035:                return ((uchar) ((ASC_CHIP_MIN_VER_EISA - 1) + revision));
        !          5036:        }
        !          5037:        return (AscGetChipVerNo(iop_base));
        !          5038: }
        !          5039: 
        !          5040: ushort
        !          5041: AscGetChipBusType(
        !          5042:                                         PortAddr iop_base
        !          5043: )
        !          5044: {
        !          5045:        ushort              chip_ver;
        !          5046: 
        !          5047:        chip_ver = AscGetChipVerNo(iop_base);
        !          5048:        if ((chip_ver >= ASC_CHIP_MIN_VER_VL) &&
        !          5049:                (chip_ver <= ASC_CHIP_MAX_VER_VL)) {
        !          5050:                if (((iop_base & 0x0C30) == 0x0C30) ||
        !          5051:                        ((iop_base & 0x0C50) == 0x0C50)) {
        !          5052:                        return (ASC_IS_EISA);
        !          5053:                }
        !          5054:                return (ASC_IS_VL);
        !          5055:        } else if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
        !          5056:                           (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
        !          5057:                if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
        !          5058:                        return (ASC_IS_ISAPNP);
        !          5059:                }
        !          5060:                return (ASC_IS_ISA);
        !          5061:        } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
        !          5062:                           (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
        !          5063:                return (ASC_IS_PCI);
        !          5064:        } else {
        !          5065:                return (0);
        !          5066:        }
        !          5067: }
        !          5068: 
        !          5069: void
        !          5070: AscEnableIsaDma(
        !          5071:                                   uchar dma_channel
        !          5072: )
        !          5073: {
        !          5074:        if (dma_channel < 4) {
        !          5075:                outp(0x000B, (ushort) (0xC0 | dma_channel));
        !          5076:                outp(0x000A, dma_channel);
        !          5077:        } else if (dma_channel < 8) {
        !          5078: 
        !          5079:                outp(0x00D6, (ushort) (0xC0 | (dma_channel - 4)));
        !          5080:                outp(0x00D4, (ushort) (dma_channel - 4));
        !          5081:        }
        !          5082:        return;
        !          5083: }
        !          5084: 
        !          5085: ulong
        !          5086: AscLoadMicroCode(
        !          5087:                                        PortAddr iop_base,
        !          5088:                                        ushort s_addr,
        !          5089:                                        ushort dosfar * mcode_buf,
        !          5090:                                        ushort mcode_size
        !          5091: )
        !          5092: {
        !          5093:        ulong               chksum;
        !          5094:        ushort              mcode_word_size;
        !          5095:        ushort              mcode_chksum;
        !          5096: 
        !          5097:        mcode_word_size = (ushort) (mcode_size >> 1);
        !          5098:        AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
        !          5099:        AscMemWordCopyToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
        !          5100: 
        !          5101:        chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
        !          5102:        mcode_chksum = (ushort) AscMemSumLramWord(iop_base,
        !          5103:                                                                                          (ushort) ASC_CODE_SEC_BEG,
        !          5104:                  (ushort) ((mcode_size - s_addr - (ushort) ASC_CODE_SEC_BEG) / 2));
        !          5105:        AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
        !          5106:        AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
        !          5107:        return (chksum);
        !          5108: }
        !          5109: 
        !          5110: uchar               _hextbl_[16] =
        !          5111: {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        !          5112:  'A', 'B', 'C', 'D', 'E', 'F'};
        !          5113: 
        !          5114: uchar               _isa_pnp_inited = 0;
        !          5115: 
        !          5116: PortAddr            _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] =
        !          5117: {
        !          5118:        0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
        !          5119:        ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
        !          5120: };
        !          5121: 
        !          5122: PortAddr
        !          5123: AscSearchIOPortAddr(
        !          5124:                                           PortAddr iop_beg,
        !          5125:                                           ushort bus_type
        !          5126: )
        !          5127: {
        !          5128:        if (bus_type & ASC_IS_VL) {
        !          5129:                while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
        !          5130:                        if (AscGetChipVersion(iop_beg, bus_type) <= ASC_CHIP_MAX_VER_VL) {
        !          5131:                                return (iop_beg);
        !          5132:                        }
        !          5133:                }
        !          5134:                return (0);
        !          5135:        }
        !          5136:        if (bus_type & ASC_IS_ISA) {
        !          5137:                if (_isa_pnp_inited == 0) {
        !          5138:                        AscSetISAPNPWaitForKey();
        !          5139:                        _isa_pnp_inited++;
        !          5140:                }
        !          5141:                while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
        !          5142:                        if ((AscGetChipVersion(iop_beg, bus_type) & ASC_CHIP_VER_ISA_BIT) != 0) {
        !          5143:                                return (iop_beg);
        !          5144:                        }
        !          5145:                }
        !          5146:                return (0);
        !          5147:        }
        !          5148:        if (bus_type & ASC_IS_EISA) {
        !          5149:                if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) {
        !          5150:                        return (iop_beg);
        !          5151:                }
        !          5152:                return (0);
        !          5153:        }
        !          5154:        return (0);
        !          5155: }
        !          5156: 
        !          5157: PortAddr
        !          5158: AscSearchIOPortAddr11(
        !          5159:                                                 PortAddr s_addr
        !          5160: )
        !          5161: {
        !          5162: 
        !          5163:        int                 i;
        !          5164:        PortAddr            iop_base;
        !          5165: 
        !          5166:        for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) {
        !          5167:                if (_asc_def_iop_base[i] > s_addr) {
        !          5168:                        break;
        !          5169:                }
        !          5170:        }
        !          5171:        for (; i < ASC_IOADR_TABLE_MAX_IX; i++) {
        !          5172:                iop_base = _asc_def_iop_base[i];
        !          5173:                if (AscFindSignature(iop_base)) {
        !          5174:                        return (iop_base);
        !          5175:                }
        !          5176:        }
        !          5177:        return (0);
        !          5178: }
        !          5179: 
        !          5180: int
        !          5181: AscFindSignature(
        !          5182:                                        PortAddr iop_base
        !          5183: )
        !          5184: {
        !          5185:        ushort              sig_word;
        !          5186: 
        !          5187:        if ((inp((PortAddr) (iop_base + 1)) & 0xFF) == (uchar) ASC_1000_ID1B) {
        !          5188:                sig_word = inpw(iop_base);
        !          5189:                if ((sig_word == (ushort) ASC_1000_ID0W) ||
        !          5190:                        (sig_word == (ushort) ASC_1000_ID0W_FIX)) {
        !          5191:                        return (1);
        !          5192:                }
        !          5193:        }
        !          5194:        return (0);
        !          5195: }
        !          5196: 
        !          5197: void
        !          5198: AscToggleIRQAct(
        !          5199:                                   PortAddr iop_base
        !          5200: )
        !          5201: {
        !          5202:        AscSetChipStatus(iop_base, CIW_IRQ_ACT);
        !          5203:        AscSetChipStatus(iop_base, 0);
        !          5204:        return;
        !          5205: }
        !          5206: 
        !          5207: #if CC_INIT_INQ_DISPLAY
        !          5208: 
        !          5209: #endif
        !          5210: 
        !          5211: void
        !          5212: AscSetISAPNPWaitForKey(
        !          5213:                                                  void)
        !          5214: {
        !          5215: 
        !          5216:        outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
        !          5217:        outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
        !          5218:        return;
        !          5219: }
        !          5220: 
        !          5221: uchar
        !          5222: AscGetChipIRQ(
        !          5223:                                 PortAddr iop_base,
        !          5224:                                 ushort bus_type
        !          5225: )
        !          5226: {
        !          5227:        ushort              cfg_lsw;
        !          5228:        uchar               chip_irq;
        !          5229: 
        !          5230:        if ((bus_type & ASC_IS_EISA) != 0) {
        !          5231: 
        !          5232:                cfg_lsw = AscGetEisaChipCfg(iop_base);
        !          5233:                chip_irq = (uchar) (((cfg_lsw >> 8) & 0x07) + 10);
        !          5234:                if ((chip_irq == 13) || (chip_irq > 15)) {
        !          5235: 
        !          5236:                        return (0);
        !          5237:                }
        !          5238:                return (chip_irq);
        !          5239:        } else {
        !          5240: 
        !          5241:                cfg_lsw = AscGetChipCfgLsw(iop_base);
        !          5242: 
        !          5243:                if ((bus_type & ASC_IS_VL) != 0) {
        !          5244: 
        !          5245:                        chip_irq = (uchar) (((cfg_lsw >> 2) & 0x07));
        !          5246:                        if ((chip_irq == 0) ||
        !          5247:                                (chip_irq == 4) ||
        !          5248:                                (chip_irq == 7)) {
        !          5249:                                return (0);
        !          5250:                        }
        !          5251:                        return ((uchar) (chip_irq + (ASC_MIN_IRQ_NO - 1)));
        !          5252:                }
        !          5253:                chip_irq = (uchar) (((cfg_lsw >> 2) & 0x03));
        !          5254:                if (chip_irq == 3)
        !          5255:                        chip_irq += (uchar) 2;
        !          5256:                return ((uchar) (chip_irq + ASC_MIN_IRQ_NO));
        !          5257:        }
        !          5258: }
        !          5259: 
        !          5260: uchar
        !          5261: AscSetChipIRQ(
        !          5262:                                 PortAddr iop_base,
        !          5263:                                 uchar irq_no,
        !          5264:                                 ushort bus_type
        !          5265: )
        !          5266: {
        !          5267:        ushort              cfg_lsw;
        !          5268: 
        !          5269:        if ((bus_type & ASC_IS_VL) != 0) {
        !          5270: 
        !          5271:                if (irq_no != 0) {
        !          5272:                        if ((irq_no < ASC_MIN_IRQ_NO) || (irq_no > ASC_MAX_IRQ_NO)) {
        !          5273:                                irq_no = 0;
        !          5274:                        } else {
        !          5275:                                irq_no -= (uchar) ((ASC_MIN_IRQ_NO - 1));
        !          5276:                        }
        !          5277:                }
        !          5278:                cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE3);
        !          5279:                cfg_lsw |= (ushort) 0x0010;
        !          5280:                AscSetChipCfgLsw(iop_base, cfg_lsw);
        !          5281:                AscToggleIRQAct(iop_base);
        !          5282: 
        !          5283:                cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE0);
        !          5284:                cfg_lsw |= (ushort) ((irq_no & 0x07) << 2);
        !          5285:                AscSetChipCfgLsw(iop_base, cfg_lsw);
        !          5286:                AscToggleIRQAct(iop_base);
        !          5287: 
        !          5288:                return (AscGetChipIRQ(iop_base, bus_type));
        !          5289: 
        !          5290:        } else if ((bus_type & (ASC_IS_ISA)) != 0) {
        !          5291: 
        !          5292:                if (irq_no == 15)
        !          5293:                        irq_no -= (uchar) 2;
        !          5294:                irq_no -= (uchar) ASC_MIN_IRQ_NO;
        !          5295:                cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFF3);
        !          5296:                cfg_lsw |= (ushort) ((irq_no & 0x03) << 2);
        !          5297:                AscSetChipCfgLsw(iop_base, cfg_lsw);
        !          5298:                return (AscGetChipIRQ(iop_base, bus_type));
        !          5299:        } else {
        !          5300: 
        !          5301:                return (0);
        !          5302:        }
        !          5303: }
        !          5304: 
        !          5305: uchar
        !          5306: AscGetChipScsiCtrl(
        !          5307:                                          PortAddr iop_base
        !          5308: )
        !          5309: {
        !          5310:        uchar               sc;
        !          5311: 
        !          5312:        AscSetBank(iop_base, 1);
        !          5313:        sc = inp(iop_base + IOP_REG_SC);
        !          5314:        AscSetBank(iop_base, 0);
        !          5315:        return (sc);
        !          5316: }
        !          5317: 
        !          5318: extern uchar        _sdtr_period_tbl_[];
        !          5319: 
        !          5320: int
        !          5321: AscIsrChipHalted(
        !          5322:                                        ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          5323: )
        !          5324: {
        !          5325:        SDTR_XMSG           sdtr_xmsg;
        !          5326:        SDTR_XMSG           out_msg;
        !          5327:        ushort              halt_q_addr;
        !          5328:        int                 sdtr_accept;
        !          5329:        ushort              int_halt_code;
        !          5330:        ASC_SCSI_BIT_ID_TYPE scsi_busy;
        !          5331:        ASC_SCSI_BIT_ID_TYPE target_id;
        !          5332:        PortAddr            iop_base;
        !          5333:        uchar               tag_code;
        !          5334:        uchar               q_status;
        !          5335:        uchar               halt_qp;
        !          5336:        uchar               sdtr_data;
        !          5337:        uchar               target_ix;
        !          5338:        uchar               q_cntl, tid_no;
        !          5339:        uchar               cur_dvc_qng;
        !          5340:        uchar               asyn_sdtr;
        !          5341:        uchar               scsi_status;
        !          5342: 
        !          5343:        iop_base = asc_dvc->iop_base;
        !          5344:        int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
        !          5345: 
        !          5346:        halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
        !          5347:        halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
        !          5348:        target_ix = AscReadLramByte(iop_base,
        !          5349:                                   (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TARGET_IX));
        !          5350:        q_cntl = AscReadLramByte(iop_base,
        !          5351:                                                (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL));
        !          5352:        tid_no = ASC_TIX_TO_TID(target_ix);
        !          5353:        target_id = (uchar) ASC_TID_TO_TARGET_ID(tid_no);
        !          5354:        if (asc_dvc->pci_fix_asyn_xfer & target_id) {
        !          5355: 
        !          5356:                asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
        !          5357:        } else {
        !          5358:                asyn_sdtr = 0;
        !          5359:        }
        !          5360:        if (int_halt_code == ASC_HALT_EXTMSG_IN) {
        !          5361: 
        !          5362:                AscMemWordCopyFromLram(iop_base,
        !          5363:                                                           ASCV_MSGIN_BEG,
        !          5364:                                                           (ushort dosfar *) & sdtr_xmsg,
        !          5365:                                                           (ushort) (sizeof (SDTR_XMSG) >> 1));
        !          5366:                if ((sdtr_xmsg.msg_type == MS_EXTEND) &&
        !          5367:                        (sdtr_xmsg.msg_len == MS_SDTR_LEN)) {
        !          5368:                        sdtr_accept = TRUE;
        !          5369:                        if (sdtr_xmsg.msg_req == MS_SDTR_CODE) {
        !          5370:                                if (sdtr_xmsg.req_ack_offset > ASC_SYN_MAX_OFFSET) {
        !          5371: 
        !          5372:                                        sdtr_accept = FALSE;
        !          5373:                                        sdtr_xmsg.req_ack_offset = ASC_SYN_MAX_OFFSET;
        !          5374:                                }
        !          5375:                                sdtr_data = AscCalSDTRData(sdtr_xmsg.xfer_period,
        !          5376:                                                                                   sdtr_xmsg.req_ack_offset);
        !          5377:                                if (sdtr_xmsg.req_ack_offset == 0) {
        !          5378: 
        !          5379:                                        q_cntl &= ~QC_MSG_OUT;
        !          5380:                                        asc_dvc->init_sdtr &= ~target_id;
        !          5381:                                        asc_dvc->sdtr_done &= ~target_id;
        !          5382:                                        AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
        !          5383:                                } else if ((sdtr_data == 0xFF)) {
        !          5384: 
        !          5385:                                        q_cntl |= QC_MSG_OUT;
        !          5386:                                        asc_dvc->init_sdtr &= ~target_id;
        !          5387:                                        asc_dvc->sdtr_done &= ~target_id;
        !          5388:                                        AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
        !          5389:                                } else {
        !          5390:                                        if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
        !          5391: 
        !          5392:                                                q_cntl &= ~QC_MSG_OUT;
        !          5393:                                                asc_dvc->sdtr_done |= target_id;
        !          5394:                                                asc_dvc->init_sdtr |= target_id;
        !          5395:                                                asc_dvc->pci_fix_asyn_xfer &= ~target_id;
        !          5396:                                                AscSetChipSDTR(iop_base, sdtr_data, tid_no);
        !          5397:                                        } else {
        !          5398: 
        !          5399:                                                q_cntl |= QC_MSG_OUT;
        !          5400: 
        !          5401:                                                AscMsgOutSDTR(iop_base,
        !          5402:                                                                          sdtr_xmsg.xfer_period,
        !          5403:                                                                          sdtr_xmsg.req_ack_offset);
        !          5404:                                                asc_dvc->pci_fix_asyn_xfer &= ~target_id;
        !          5405:                                                AscSetChipSDTR(iop_base, sdtr_data, tid_no);
        !          5406:                                                asc_dvc->sdtr_done |= target_id;
        !          5407:                                                asc_dvc->init_sdtr |= target_id;
        !          5408:                                        }
        !          5409:                                }
        !          5410: 
        !          5411:                                AscWriteLramByte(iop_base,
        !          5412:                                                 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
        !          5413:                                                                 q_cntl);
        !          5414:                                AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
        !          5415:                                return (0);
        !          5416:                        }
        !          5417:                }
        !          5418:        } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
        !          5419: 
        !          5420:                q_cntl |= QC_REQ_SENSE;
        !          5421:                if (((asc_dvc->init_sdtr & target_id) != 0) &&
        !          5422:                        ((asc_dvc->sdtr_done & target_id) != 0)) {
        !          5423: 
        !          5424:                        sdtr_data = AscReadLramByte(iop_base,
        !          5425:                                  (ushort) ((ushort) ASCV_SDTR_DATA_BEG + (ushort) tid_no));
        !          5426:                        AscMsgOutSDTR(iop_base,
        !          5427:                                                  _sdtr_period_tbl_[(sdtr_data >> 4) & (uchar) (ASC_SYN_XFER_NO - 1)],
        !          5428:                                                  (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
        !          5429:                        q_cntl |= QC_MSG_OUT;
        !          5430:                }
        !          5431:                AscWriteLramByte(iop_base,
        !          5432:                                                 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
        !          5433:                                                 q_cntl);
        !          5434: 
        !          5435:                tag_code = AscReadLramByte(iop_base,
        !          5436:                                        (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE));
        !          5437:                tag_code &= 0xDC;
        !          5438:                AscWriteLramByte(iop_base,
        !          5439:                                         (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE),
        !          5440:                                                 tag_code);
        !          5441: 
        !          5442:                q_status = AscReadLramByte(iop_base,
        !          5443:                                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS));
        !          5444:                q_status |= (QS_READY | QS_BUSY);
        !          5445:                AscWriteLramByte(iop_base,
        !          5446:                                           (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
        !          5447:                                                 q_status);
        !          5448: 
        !          5449:                scsi_busy = AscReadLramByte(iop_base,
        !          5450:                                                                        (ushort) ASCV_SCSIBUSY_B);
        !          5451:                scsi_busy &= ~target_id;
        !          5452:                AscWriteLramByte(iop_base, (ushort) ASCV_SCSIBUSY_B, scsi_busy);
        !          5453: 
        !          5454:                AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
        !          5455:                return (0);
        !          5456:        } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
        !          5457: 
        !          5458:                AscMemWordCopyFromLram(iop_base,
        !          5459:                                                           ASCV_MSGOUT_BEG,
        !          5460:                                                           (ushort dosfar *) & out_msg,
        !          5461:                                                           (ushort) (sizeof (SDTR_XMSG) >> 1));
        !          5462: 
        !          5463:                if ((out_msg.msg_type == MS_EXTEND) &&
        !          5464:                        (out_msg.msg_len == MS_SDTR_LEN) &&
        !          5465:                        (out_msg.msg_req == MS_SDTR_CODE)) {
        !          5466: 
        !          5467:                        asc_dvc->init_sdtr &= ~target_id;
        !          5468:                        asc_dvc->sdtr_done &= ~target_id;
        !          5469:                        AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
        !          5470: 
        !          5471:                } else {
        !          5472: 
        !          5473:                }
        !          5474: 
        !          5475:                q_cntl &= ~QC_MSG_OUT;
        !          5476:                AscWriteLramByte(iop_base,
        !          5477:                                                 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
        !          5478:                                                 q_cntl);
        !          5479:                AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
        !          5480:                return (0);
        !          5481:        } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
        !          5482: 
        !          5483:                scsi_status = AscReadLramByte(iop_base,
        !          5484:                  (ushort) ((ushort) halt_q_addr + (ushort) ASC_SCSIQ_SCSI_STATUS));
        !          5485:                cur_dvc_qng = AscReadLramByte(iop_base,
        !          5486:                                         (ushort) ((ushort) ASC_QADR_BEG + (ushort) target_ix));
        !          5487:                if ((cur_dvc_qng > 0) &&
        !          5488:                        (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
        !          5489: 
        !          5490:                        scsi_busy = AscReadLramByte(iop_base,
        !          5491:                                                                                (ushort) ASCV_SCSIBUSY_B);
        !          5492:                        scsi_busy |= target_id;
        !          5493:                        AscWriteLramByte(iop_base,
        !          5494:                                                         (ushort) ASCV_SCSIBUSY_B, scsi_busy);
        !          5495:                        asc_dvc->queue_full_or_busy |= target_id;
        !          5496: 
        !          5497:                        if (scsi_status == SS_QUEUE_FULL) {
        !          5498:                                if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
        !          5499:                                        cur_dvc_qng -= 1;
        !          5500:                                        asc_dvc->max_dvc_qng[tid_no] = cur_dvc_qng;
        !          5501: 
        !          5502:                                        AscWriteLramByte(iop_base,
        !          5503:                                                                         (ushort) ((ushort) ASCV_MAX_DVC_QNG_BEG + (ushort) tid_no),
        !          5504:                                                                         cur_dvc_qng);
        !          5505:                                }
        !          5506:                        }
        !          5507:                }
        !          5508:                AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
        !          5509:                return (0);
        !          5510:        }
        !          5511:        return (0);
        !          5512: }
        !          5513: 
        !          5514: uchar
        !          5515: _AscCopyLramScsiDoneQ(
        !          5516:                                                 PortAddr iop_base,
        !          5517:                                                 ushort q_addr,
        !          5518:                                                 ASC_QDONE_INFO dosfar * scsiq,
        !          5519:                                                 ulong max_dma_count
        !          5520: )
        !          5521: {
        !          5522:        ushort              _val;
        !          5523:        uchar               sg_queue_cnt;
        !          5524: 
        !          5525:        DvcGetQinfo(iop_base,
        !          5526:                                (ushort) (q_addr + (ushort) ASC_SCSIQ_DONE_INFO_BEG),
        !          5527:                                (ushort dosfar *) scsiq,
        !          5528:                          (ushort) ((sizeof (ASC_SCSIQ_2) + sizeof (ASC_SCSIQ_3)) / 2));
        !          5529: 
        !          5530: #if !CC_LITTLE_ENDIAN_HOST
        !          5531:        AscAdjEndianQDoneInfo(scsiq);
        !          5532: #endif
        !          5533: 
        !          5534:        _val = AscReadLramWord(iop_base,
        !          5535:                                                   (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS));
        !          5536:        scsiq->q_status = (uchar) _val;
        !          5537:        scsiq->q_no = (uchar) (_val >> 8);
        !          5538: 
        !          5539:        _val = AscReadLramWord(iop_base,
        !          5540:                                                   (ushort) (q_addr + (ushort) ASC_SCSIQ_B_CNTL));
        !          5541:        scsiq->cntl = (uchar) _val;
        !          5542:        sg_queue_cnt = (uchar) (_val >> 8);
        !          5543: 
        !          5544:        _val = AscReadLramWord(iop_base,
        !          5545:                                                (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SENSE_LEN));
        !          5546:        scsiq->sense_len = (uchar) _val;
        !          5547:        scsiq->user_def = (uchar) (_val >> 8);
        !          5548: 
        !          5549:        scsiq->remain_bytes = AscReadLramDWord(iop_base,
        !          5550:                                 (ushort) (q_addr + (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT));
        !          5551:        scsiq->remain_bytes &= max_dma_count;
        !          5552: 
        !          5553:        return (sg_queue_cnt);
        !          5554: }
        !          5555: 
        !          5556: int
        !          5557: AscIsrQDone(
        !          5558:                           ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          5559: )
        !          5560: {
        !          5561:        uchar               next_qp;
        !          5562:        uchar               i;
        !          5563:        uchar               n_q_used;
        !          5564:        uchar               sg_list_qp;
        !          5565:        uchar               sg_queue_cnt;
        !          5566:        uchar               done_q_tail;
        !          5567: 
        !          5568:        uchar               tid_no;
        !          5569:        ASC_SCSI_BIT_ID_TYPE scsi_busy;
        !          5570:        ASC_SCSI_BIT_ID_TYPE target_id;
        !          5571:        PortAddr            iop_base;
        !          5572:        ushort              q_addr;
        !          5573:        ushort              sg_q_addr;
        !          5574:        uchar               cur_target_qng;
        !          5575:        ASC_QDONE_INFO      scsiq_buf;
        !          5576:        ASC_QDONE_INFO dosfar *scsiq;
        !          5577:        int                 false_overrun;
        !          5578:        ASC_ISR_CALLBACK    asc_isr_callback;
        !          5579: 
        !          5580:        uchar               tag_code;
        !          5581: 
        !          5582: #if CC_LINK_BUSY_Q
        !          5583:        ushort              n_busy_q_done;
        !          5584: 
        !          5585: #endif
        !          5586: 
        !          5587:        iop_base = asc_dvc->iop_base;
        !          5588:        asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
        !          5589: 
        !          5590:        n_q_used = 1;
        !          5591:        scsiq = (ASC_QDONE_INFO dosfar *) & scsiq_buf;
        !          5592:        done_q_tail = (uchar) AscGetVarDoneQTail(iop_base);
        !          5593:        q_addr = ASC_QNO_TO_QADDR(done_q_tail);
        !          5594:        next_qp = AscReadLramByte(iop_base,
        !          5595:                                                          (ushort) (q_addr + (ushort) ASC_SCSIQ_B_FWD));
        !          5596:        if (next_qp != ASC_QLINK_END) {
        !          5597: 
        !          5598:                AscPutVarDoneQTail(iop_base, next_qp);
        !          5599:                q_addr = ASC_QNO_TO_QADDR(next_qp);
        !          5600: 
        !          5601:                sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count);
        !          5602: 
        !          5603:                AscWriteLramByte(iop_base,
        !          5604:                                                 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
        !          5605:                         (uchar) (scsiq->q_status & (uchar) ~ (QS_READY | QS_ABORTED)));
        !          5606:                tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
        !          5607:                target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
        !          5608:                if ((scsiq->cntl & QC_SG_HEAD) != 0) {
        !          5609:                        sg_q_addr = q_addr;
        !          5610:                        sg_list_qp = next_qp;
        !          5611:                        for (i = 0; i < sg_queue_cnt; i++) {
        !          5612:                                sg_list_qp = AscReadLramByte(iop_base,
        !          5613:                                                   (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_FWD));
        !          5614:                                sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
        !          5615:                                if (sg_list_qp == ASC_QLINK_END) {
        !          5616:                                        AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SG_Q_LINKS);
        !          5617:                                        scsiq->d3.done_stat = QD_WITH_ERROR;
        !          5618:                                        scsiq->d3.host_stat = QHSTA_D_QDONE_SG_LIST_CORRUPTED;
        !          5619:                                        goto FATAL_ERR_QDONE;
        !          5620:                                }
        !          5621:                                AscWriteLramByte(iop_base,
        !          5622:                                                 (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
        !          5623:                                                                 QS_FREE);
        !          5624:                        }
        !          5625: 
        !          5626:                        n_q_used = sg_queue_cnt + 1;
        !          5627:                        AscPutVarDoneQTail(iop_base, sg_list_qp);
        !          5628:                }
        !          5629:                if (asc_dvc->queue_full_or_busy & target_id) {
        !          5630: 
        !          5631:                        cur_target_qng = AscReadLramByte(iop_base,
        !          5632:                        (ushort) ((ushort) ASC_QADR_BEG + (ushort) scsiq->d2.target_ix));
        !          5633:                        if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
        !          5634:                                scsi_busy = AscReadLramByte(iop_base,
        !          5635:                                                                                        (ushort) ASCV_SCSIBUSY_B);
        !          5636:                                scsi_busy &= ~target_id;
        !          5637:                                AscWriteLramByte(iop_base,
        !          5638:                                                                 (ushort) ASCV_SCSIBUSY_B, scsi_busy);
        !          5639:                                asc_dvc->queue_full_or_busy &= ~target_id;
        !          5640:                        }
        !          5641:                }
        !          5642:                if (asc_dvc->cur_total_qng >= n_q_used) {
        !          5643:                        asc_dvc->cur_total_qng -= n_q_used;
        !          5644:                        if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
        !          5645:                                asc_dvc->cur_dvc_qng[tid_no]--;
        !          5646:                        }
        !          5647:                } else {
        !          5648:                        AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
        !          5649:                        scsiq->d3.done_stat = QD_WITH_ERROR;
        !          5650:                        goto FATAL_ERR_QDONE;
        !          5651:                }
        !          5652: 
        !          5653:                if ((scsiq->d2.srb_ptr == 0UL) ||
        !          5654:                        ((scsiq->q_status & QS_ABORTED) != 0)) {
        !          5655: 
        !          5656:                        return (0x11);
        !          5657:                } else if (scsiq->q_status == QS_DONE) {
        !          5658: 
        !          5659:                        false_overrun = FALSE;
        !          5660: 
        !          5661:                        if (asc_dvc->bug_fix_cntl) {
        !          5662:                                if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ADD_ONE_BYTE) {
        !          5663:                                        tag_code = AscReadLramByte(iop_base,
        !          5664:                                                 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE));
        !          5665:                                        if (tag_code & ASC_TAG_FLAG_ADD_ONE_BYTE) {
        !          5666:                                                if (scsiq->remain_bytes != 0UL) {
        !          5667:                                                        scsiq->remain_bytes--;
        !          5668:                                                        if (scsiq->remain_bytes == 0UL) {
        !          5669:                                                                false_overrun = TRUE;
        !          5670:                                                        }
        !          5671:                                                }
        !          5672:                                        }
        !          5673:                                }
        !          5674:                        }
        !          5675:                        if ((scsiq->d3.done_stat == QD_WITH_ERROR) &&
        !          5676:                                (scsiq->d3.host_stat == QHSTA_M_DATA_OVER_RUN)) {
        !          5677:                                if ((scsiq->cntl & (QC_DATA_IN | QC_DATA_OUT)) == 0) {
        !          5678:                                        scsiq->d3.done_stat = QD_NO_ERROR;
        !          5679:                                        scsiq->d3.host_stat = QHSTA_NO_ERROR;
        !          5680:                                } else if (false_overrun) {
        !          5681:                                        scsiq->d3.done_stat = QD_NO_ERROR;
        !          5682:                                        scsiq->d3.host_stat = QHSTA_NO_ERROR;
        !          5683:                                }
        !          5684:                        }
        !          5685: #if CC_CLEAR_LRAM_SRB_PTR
        !          5686:                        AscWriteLramDWord(iop_base,
        !          5687:                                                        (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR),
        !          5688:                                                          asc_dvc->int_count);
        !          5689: #endif
        !          5690: 
        !          5691:                        if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
        !          5692:                                (*asc_isr_callback) (asc_dvc, scsiq);
        !          5693:                        } else {
        !          5694:                                if ((AscReadLramByte(iop_base,
        !          5695:                                                  (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG)) ==
        !          5696:                                         SCSICMD_StartStopUnit)) {
        !          5697: 
        !          5698:                                        asc_dvc->unit_not_ready &= ~target_id;
        !          5699:                                        if (scsiq->d3.done_stat != QD_NO_ERROR) {
        !          5700:                                                asc_dvc->start_motor &= ~target_id;
        !          5701:                                        }
        !          5702:                                }
        !          5703:                        }
        !          5704: 
        !          5705: #if CC_LINK_BUSY_Q
        !          5706:                        n_busy_q_done = AscIsrExeBusyQueue(asc_dvc, tid_no);
        !          5707:                        if (n_busy_q_done == 0) {
        !          5708: 
        !          5709:                                i = tid_no + 1;
        !          5710:                                while (TRUE) {
        !          5711:                                        if (i > ASC_MAX_TID)
        !          5712:                                                i = 0;
        !          5713:                                        if (i == tid_no)
        !          5714:                                                break;
        !          5715:                                        n_busy_q_done = AscIsrExeBusyQueue(asc_dvc, i);
        !          5716:                                        if (n_busy_q_done != 0)
        !          5717:                                                break;
        !          5718:                                        i++;
        !          5719:                                }
        !          5720:                        }
        !          5721:                        if (n_busy_q_done == 0xFFFF)
        !          5722:                                return (0x80);
        !          5723: #endif
        !          5724: 
        !          5725:                        return (1);
        !          5726:                } else {
        !          5727: 
        !          5728:                        AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
        !          5729: 
        !          5730:                  FATAL_ERR_QDONE:
        !          5731:                        if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
        !          5732:                                (*asc_isr_callback) (asc_dvc, scsiq);
        !          5733:                        }
        !          5734:                        return (0x80);
        !          5735:                }
        !          5736:        }
        !          5737:        return (0);
        !          5738: }
        !          5739: 
        !          5740: int
        !          5741: AscISR(
        !          5742:                  ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          5743: )
        !          5744: {
        !          5745:        ASC_CS_TYPE         chipstat;
        !          5746:        PortAddr            iop_base;
        !          5747:        ushort              saved_ram_addr;
        !          5748:        uchar               ctrl_reg;
        !          5749:        uchar               saved_ctrl_reg;
        !          5750:        int                 int_pending;
        !          5751:        int                 status;
        !          5752:        uchar               host_flag;
        !          5753: 
        !          5754:        iop_base = asc_dvc->iop_base;
        !          5755:        int_pending = FALSE;
        !          5756: 
        !          5757:        asc_dvc->int_count++;
        !          5758: 
        !          5759:        if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) ||
        !          5760:                (asc_dvc->isr_callback == 0)) {
        !          5761: 
        !          5762:                return (ERR);
        !          5763:        }
        !          5764:        if (asc_dvc->in_critical_cnt != 0) {
        !          5765:                AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
        !          5766:                return (ERR);
        !          5767:        }
        !          5768:        if (asc_dvc->is_in_int) {
        !          5769:                AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
        !          5770:                asc_dvc->busy_count++;
        !          5771:                return (ERR);
        !          5772:        }
        !          5773:        asc_dvc->is_in_int = TRUE;
        !          5774:        ctrl_reg = AscGetChipControl(iop_base);
        !          5775:        saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
        !          5776:                                                                   CC_SINGLE_STEP | CC_DIAG | CC_TEST));
        !          5777: 
        !          5778:        if ((chipstat = AscGetChipStatus(iop_base)) & CSW_INT_PENDING) {
        !          5779:                int_pending = TRUE;
        !          5780:                AscAckInterrupt(iop_base);
        !          5781: 
        !          5782:                host_flag = AscReadLramByte(iop_base, ASCV_HOST_FLAG_B);
        !          5783:                AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
        !          5784:                                                 (uchar) (host_flag | (uchar) ASC_HOST_FLAG_IN_ISR));
        !          5785:                saved_ram_addr = AscGetChipLramAddr(iop_base);
        !          5786: 
        !          5787:                if ((chipstat & CSW_HALTED) &&
        !          5788:                        (ctrl_reg & CC_SINGLE_STEP)) {
        !          5789:                        if (AscIsrChipHalted(asc_dvc) == ERR) {
        !          5790: 
        !          5791:                                goto ISR_REPORT_QDONE_FATAL_ERROR;
        !          5792: 
        !          5793:                        } else {
        !          5794:                                saved_ctrl_reg &= ~CC_HALT;
        !          5795:                        }
        !          5796:                } else {
        !          5797:                  ISR_REPORT_QDONE_FATAL_ERROR:
        !          5798:                        if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
        !          5799:                                while (((status = AscIsrQDone(asc_dvc)) & 0x01) != 0) {
        !          5800: 
        !          5801:                                }
        !          5802:                        } else {
        !          5803:                                do {
        !          5804:                                        if ((status = AscIsrQDone(asc_dvc)) == 1) {
        !          5805: 
        !          5806:                                                break;
        !          5807:                                        }
        !          5808:                                } while (status == 0x11);
        !          5809:                        }
        !          5810:                        if ((status & 0x80) != 0)
        !          5811:                                int_pending = ERR;
        !          5812:                }
        !          5813:                AscSetChipLramAddr(iop_base, saved_ram_addr);
        !          5814:                if (AscGetChipLramAddr(iop_base) != saved_ram_addr) {
        !          5815:                        AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SET_LRAM_ADDR);
        !          5816:                }
        !          5817:                AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
        !          5818:        }
        !          5819:        AscSetChipControl(iop_base, saved_ctrl_reg);
        !          5820:        asc_dvc->is_in_int = FALSE;
        !          5821:        return (int_pending);
        !          5822: }
        !          5823: 
        !          5824: int
        !          5825: AscScsiSetupCmdQ(
        !          5826:                                        ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          5827:                                        ASC_SCSI_REQ_Q dosfar * scsiq,
        !          5828:                                        uchar dosfar * buf_addr,
        !          5829:                                        ulong buf_len
        !          5830: )
        !          5831: {
        !          5832:        ulong               phy_addr;
        !          5833: 
        !          5834:        scsiq->r1.cntl = 0;
        !          5835:        scsiq->r1.sg_queue_cnt = 0;
        !          5836:        scsiq->r1.q_no = 0;
        !          5837:        scsiq->r1.user_def = 0;
        !          5838:        scsiq->cdbptr = (uchar dosfar *) scsiq->cdb;
        !          5839:        scsiq->r3.scsi_stat = 0;
        !          5840:        scsiq->r3.scsi_msg = 0;
        !          5841:        scsiq->r3.host_stat = 0;
        !          5842:        scsiq->r3.done_stat = 0;
        !          5843:        scsiq->r2.vm_id = 0;
        !          5844:        scsiq->r1.data_cnt = buf_len;
        !          5845: 
        !          5846:        scsiq->r2.tag_code = (uchar) M2_QTAG_MSG_SIMPLE;
        !          5847:        scsiq->r2.flag = (uchar) ASC_FLAG_SCSIQ_REQ;
        !          5848:        scsiq->r2.srb_ptr = (ulong) scsiq;
        !          5849:        scsiq->r1.status = (uchar) QS_READY;
        !          5850:        scsiq->r1.data_addr = 0L;
        !          5851: 
        !          5852:        if (buf_len != 0L) {
        !          5853:                if ((phy_addr = AscGetOnePhyAddr(asc_dvc,
        !          5854:                                        (uchar dosfar *) buf_addr, scsiq->r1.data_cnt)) == 0L) {
        !          5855:                        return (ERR);
        !          5856:                }
        !          5857:                scsiq->r1.data_addr = phy_addr;
        !          5858:        }
        !          5859:        return (0);
        !          5860: }
        !          5861: 
        !          5862: uchar               _mcode_buf[] =
        !          5863: {
        !          5864:        0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          5865:        0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          5866:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          5867:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          5868:        0x00, 0x00, 0x00, 0x00, 0xDD, 0x0A, 0x01, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
        !          5869:        0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !          5870:        0x00, 0x00, 0x00, 0x23, 0x00, 0x16, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
        !          5871:        0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0x88, 0x00, 0x00, 0x00, 0x00,
        !          5872:        0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC8, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
        !          5873:        0xB6, 0x00, 0x36, 0x00, 0x06, 0xD6, 0x0D, 0xD2, 0x15, 0xDE, 0x12, 0xDA, 0x00, 0xA2, 0xC8, 0x00,
        !          5874:        0x92, 0x80, 0xE0, 0x97, 0x50, 0x00, 0xF5, 0x00, 0x0A, 0x98, 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00,
        !          5875:        0x92, 0x80, 0x4F, 0x00, 0xF5, 0x00, 0x0A, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80,
        !          5876:        0x80, 0x62, 0x92, 0x80, 0x00, 0x62, 0x92, 0x80, 0x00, 0x46, 0x17, 0xEE, 0x13, 0xEA, 0x02, 0x01,
        !          5877:        0x09, 0xD8, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDC, 0x00, 0x68, 0x97, 0x7F, 0x23, 0x04, 0x61,
        !          5878:        0x84, 0x01, 0xB2, 0x84, 0xCF, 0xC1, 0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xE8, 0x01,
        !          5879:        0x68, 0x97, 0xD4, 0x81, 0x00, 0x33, 0x02, 0x00, 0x82, 0x88, 0x80, 0x73, 0x80, 0x77, 0x00, 0x01,
        !          5880:        0x01, 0xA1, 0x08, 0x01, 0x4F, 0x00, 0x46, 0x97, 0x07, 0xA6, 0x12, 0x01, 0x00, 0x33, 0x03, 0x00,
        !          5881:        0x82, 0x88, 0x03, 0x03, 0x03, 0xDE, 0x00, 0x33, 0x05, 0x00, 0x82, 0x88, 0xCE, 0x00, 0x69, 0x60,
        !          5882:        0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x86, 0x01, 0x80, 0x63, 0x07, 0xA6, 0x32, 0x01,
        !          5883:        0x86, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6, 0x42, 0x01, 0x00, 0x33, 0x04, 0x00,
        !          5884:        0x82, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23, 0x2A, 0x98, 0x4D, 0x04, 0xD0, 0x84,
        !          5885:        0x05, 0xD8, 0x0D, 0x23, 0x2A, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xB8, 0x88, 0xFB, 0x23, 0x02, 0x61,
        !          5886:        0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x70, 0x01, 0x00, 0x33, 0x0A, 0x00, 0x82, 0x88,
        !          5887:        0x4E, 0x00, 0x07, 0xA3, 0x7C, 0x01, 0x00, 0x33, 0x0B, 0x00, 0x82, 0x88, 0xCD, 0x04, 0x36, 0x2D,
        !          5888:        0x00, 0x33, 0x1A, 0x00, 0x82, 0x88, 0x50, 0x04, 0x96, 0x81, 0x06, 0xAB, 0x90, 0x01, 0x96, 0x81,
        !          5889:        0x4E, 0x00, 0x07, 0xA3, 0xA0, 0x01, 0x50, 0x00, 0x00, 0xA3, 0x4A, 0x01, 0x00, 0x05, 0x8A, 0x81,
        !          5890:        0x08, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, 0xCC, 0x81,
        !          5891:        0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xC2, 0x01,
        !          5892:        0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00, 0x82, 0x88, 0x06, 0x23, 0x2A, 0x98,
        !          5893:        0xCD, 0x04, 0xB2, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xE2, 0x01, 0x57, 0x60, 0x00, 0xA0, 0xE8, 0x01,
        !          5894:        0xB2, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xB2, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61, 0x00, 0xA2,
        !          5895:        0x10, 0x02, 0x04, 0x01, 0x0D, 0xDE, 0x02, 0x01, 0x03, 0xCC, 0x4F, 0x00, 0x46, 0x97, 0x0A, 0x82,
        !          5896:        0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x24, 0x97, 0x48, 0x04, 0xFF, 0x23, 0x84, 0x80,
        !          5897:        0xB2, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29,
        !          5898:        0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x66, 0xEB, 0x11, 0x23, 0xB8, 0x88, 0xC6, 0x97, 0xFA, 0x80,
        !          5899:        0x80, 0x73, 0x80, 0x77, 0x06, 0xA6, 0x3E, 0x02, 0x00, 0x33, 0x31, 0x00, 0x82, 0x88, 0x04, 0x01,
        !          5900:        0x03, 0xD8, 0x74, 0x98, 0x02, 0x96, 0x50, 0x82, 0xA2, 0x95, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
        !          5901:        0xB6, 0x2D, 0x02, 0xA6, 0x7A, 0x02, 0x07, 0xA6, 0x68, 0x02, 0x06, 0xA6, 0x6C, 0x02, 0x03, 0xA6,
        !          5902:        0x70, 0x02, 0x00, 0x33, 0x10, 0x00, 0x82, 0x88, 0x4A, 0x95, 0x52, 0x82, 0xF8, 0x95, 0x52, 0x82,
        !          5903:        0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x16, 0x84, 0x04, 0x01, 0x0C, 0xDC, 0xE0, 0x23,
        !          5904:        0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01, 0x6F, 0x00, 0xA5, 0x01, 0x03, 0x23,
        !          5905:        0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAC, 0x02, 0x07, 0xA6,
        !          5906:        0x68, 0x02, 0x06, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x12, 0x00, 0x82, 0x88, 0x00, 0x0E, 0x80, 0x63,
        !          5907:        0x00, 0x43, 0x00, 0xA0, 0x9A, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61,
        !          5908:        0x84, 0x01, 0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00,
        !          5909:        0xEC, 0x82, 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE4, 0x02, 0x04, 0x01, 0x8E, 0xC8, 0x00, 0x33,
        !          5910:        0x1F, 0x00, 0x82, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x40, 0x98, 0xB6, 0x2D,
        !          5911:        0x01, 0xA6, 0x0E, 0x03, 0x00, 0xA6, 0x1C, 0x03, 0x07, 0xA6, 0x2A, 0x03, 0x06, 0xA6, 0x2E, 0x03,
        !          5912:        0x03, 0xA6, 0xFA, 0x03, 0x02, 0xA6, 0x7A, 0x02, 0x00, 0x33, 0x33, 0x00, 0x82, 0x88, 0x08, 0x23,
        !          5913:        0xB3, 0x01, 0x04, 0x01, 0x0E, 0xD0, 0x00, 0x33, 0x14, 0x00, 0x82, 0x88, 0x10, 0x23, 0xB3, 0x01,
        !          5914:        0x04, 0x01, 0x07, 0xCC, 0x00, 0x33, 0x15, 0x00, 0x82, 0x88, 0x4A, 0x95, 0xF0, 0x82, 0xF8, 0x95,
        !          5915:        0xF0, 0x82, 0x44, 0x98, 0x80, 0x42, 0x40, 0x98, 0x48, 0xE4, 0x04, 0x01, 0x29, 0xC8, 0x31, 0x05,
        !          5916:        0x07, 0x01, 0x00, 0xA2, 0x72, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x48, 0x98, 0x40, 0x98,
        !          5917:        0x00, 0xA6, 0x34, 0x03, 0x07, 0xA6, 0x6A, 0x03, 0x03, 0xA6, 0x16, 0x04, 0x06, 0xA6, 0x6E, 0x03,
        !          5918:        0x01, 0xA6, 0x34, 0x03, 0x00, 0x33, 0x25, 0x00, 0x82, 0x88, 0x4A, 0x95, 0x50, 0x83, 0xF8, 0x95,
        !          5919:        0x50, 0x83, 0x04, 0x01, 0x0C, 0xCE, 0x03, 0xC8, 0x00, 0x33, 0x42, 0x00, 0x82, 0x88, 0x00, 0x01,
        !          5920:        0x05, 0x05, 0xFF, 0xA2, 0x90, 0x03, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x4C, 0x83, 0x05, 0x05,
        !          5921:        0x01, 0xA6, 0x9A, 0x03, 0x00, 0xA6, 0xAA, 0x03, 0xF0, 0x83, 0x68, 0x98, 0x80, 0x42, 0x01, 0xA6,
        !          5922:        0x9A, 0x03, 0xBA, 0x83, 0x00, 0x33, 0x2F, 0x00, 0x82, 0x88, 0x68, 0x98, 0x80, 0x42, 0x00, 0xA6,
        !          5923:        0xAA, 0x03, 0xBA, 0x83, 0x00, 0x33, 0x26, 0x00, 0x82, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36,
        !          5924:        0x04, 0x23, 0xA0, 0x01, 0x12, 0x23, 0xA1, 0x01, 0xF0, 0x83, 0x04, 0xF0, 0x80, 0x6B, 0x00, 0x33,
        !          5925:        0x20, 0x00, 0x82, 0x88, 0x03, 0xA6, 0xEE, 0x03, 0x07, 0xA6, 0xE6, 0x03, 0x06, 0xA6, 0xEA, 0x03,
        !          5926:        0x00, 0x33, 0x17, 0x00, 0x82, 0x88, 0x4A, 0x95, 0xD4, 0x83, 0xF8, 0x95, 0xD4, 0x83, 0xFA, 0x83,
        !          5927:        0x04, 0xF0, 0x80, 0x6B, 0x00, 0x33, 0x20, 0x00, 0x82, 0x88, 0xB6, 0x2D, 0x03, 0xA6, 0x16, 0x04,
        !          5928:        0x07, 0xA6, 0x0E, 0x04, 0x06, 0xA6, 0x12, 0x04, 0x00, 0x33, 0x30, 0x00, 0x82, 0x88, 0x4A, 0x95,
        !          5929:        0xFA, 0x83, 0xF8, 0x95, 0xFA, 0x83, 0xA2, 0x0D, 0x80, 0x63, 0x07, 0xA6, 0x24, 0x04, 0x00, 0x33,
        !          5930:        0x18, 0x00, 0x82, 0x88, 0x03, 0x03, 0x80, 0x63, 0xA3, 0x01, 0x07, 0xA4, 0x2E, 0x04, 0x23, 0x01,
        !          5931:        0x00, 0xA2, 0x50, 0x04, 0x0A, 0xA0, 0x40, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1D, 0x00, 0x82, 0x88,
        !          5932:        0x0B, 0xA0, 0x4C, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00, 0x82, 0x88, 0x42, 0x23, 0xB8, 0x88,
        !          5933:        0x00, 0x23, 0x22, 0xA3, 0xB2, 0x04, 0x08, 0x23, 0x22, 0xA3, 0x6C, 0x04, 0x28, 0x23, 0x22, 0xA3,
        !          5934:        0x78, 0x04, 0x02, 0x23, 0x22, 0xA3, 0x8E, 0x04, 0x42, 0x23, 0xB8, 0x88, 0x4A, 0x00, 0x06, 0x61,
        !          5935:        0x00, 0xA0, 0x78, 0x04, 0x45, 0x23, 0xB8, 0x88, 0xC6, 0x97, 0x00, 0xA2, 0x8A, 0x04, 0x74, 0x98,
        !          5936:        0x00, 0x33, 0x00, 0x82, 0xC0, 0x20, 0x81, 0x62, 0xF6, 0x81, 0x47, 0x23, 0xB8, 0x88, 0x04, 0x01,
        !          5937:        0x0C, 0xDE, 0x14, 0x01, 0x00, 0xA2, 0xA6, 0x04, 0xC6, 0x97, 0x74, 0x98, 0x00, 0x33, 0x00, 0x81,
        !          5938:        0xC0, 0x20, 0x81, 0x62, 0x10, 0x82, 0x43, 0x23, 0xB8, 0x88, 0x04, 0x23, 0xA0, 0x01, 0x44, 0x23,
        !          5939:        0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3, 0xC0, 0x04, 0x00, 0x33, 0x27, 0x00, 0x82, 0x88,
        !          5940:        0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xC6, 0x97, 0xF4, 0x94,
        !          5941:        0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0xEE, 0x04, 0x00, 0x05, 0x76, 0x00,
        !          5942:        0x06, 0x61, 0x00, 0xA2, 0xE8, 0x04, 0xD6, 0x84, 0x08, 0x97, 0xCD, 0x04, 0xF2, 0x84, 0x48, 0x04,
        !          5943:        0xFF, 0x23, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x02, 0x85, 0x02, 0x23,
        !          5944:        0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x0E, 0x05, 0x1D, 0x01, 0x04, 0xD6, 0xFF, 0x23,
        !          5945:        0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x49, 0x00, 0x81, 0x01, 0x04, 0x01,
        !          5946:        0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01, 0xC9, 0x00,
        !          5947:        0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x2E, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00, 0x5D, 0x00,
        !          5948:        0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63, 0x07, 0xA4, 0xA0, 0x05, 0x03, 0x03,
        !          5949:        0x02, 0xA0, 0x5C, 0x05, 0x9C, 0x85, 0x00, 0x33, 0x2D, 0x00, 0x82, 0x88, 0x04, 0xA0, 0x82, 0x05,
        !          5950:        0x80, 0x63, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x6E, 0x05, 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23,
        !          5951:        0x02, 0x41, 0x82, 0x01, 0x50, 0x00, 0x24, 0x97, 0xD0, 0x84, 0x04, 0x23, 0x02, 0x41, 0x82, 0x01,
        !          5952:        0xD0, 0x84, 0x08, 0xA0, 0x88, 0x05, 0x9C, 0x85, 0x03, 0xA0, 0x8E, 0x05, 0x9C, 0x85, 0x01, 0xA0,
        !          5953:        0x9A, 0x05, 0x88, 0x00, 0x80, 0x63, 0x78, 0x96, 0x4A, 0x85, 0x88, 0x86, 0x80, 0x63, 0x4A, 0x85,
        !          5954:        0x00, 0x63, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xDE, 0x05, 0x1D, 0x01, 0x18, 0xD4, 0xC0, 0x23,
        !          5955:        0x07, 0x41, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0xC0, 0x05, 0x00, 0x33, 0x37, 0x00, 0x82, 0x88,
        !          5956:        0x1D, 0x01, 0x02, 0xD6, 0x46, 0x23, 0xB8, 0x88, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6,
        !          5957:        0xD8, 0x05, 0x00, 0x33, 0x38, 0x00, 0x82, 0x88, 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00,
        !          5958:        0x06, 0x41, 0xCB, 0x00, 0x52, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xF2, 0x05, 0xC0, 0x23, 0x07, 0x41,
        !          5959:        0x00, 0x63, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63, 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63,
        !          5960:        0x00, 0x63, 0x06, 0xA6, 0x14, 0x06, 0x07, 0xA6, 0x64, 0x06, 0x02, 0xA6, 0xBC, 0x06, 0x00, 0x33,
        !          5961:        0x39, 0x00, 0x82, 0x88, 0x00, 0x00, 0x01, 0xA0, 0xD6, 0x06, 0xA2, 0x95, 0x83, 0x03, 0x80, 0x63,
        !          5962:        0x06, 0xA6, 0x28, 0x06, 0x07, 0xA6, 0x64, 0x06, 0x00, 0x00, 0x00, 0x2B, 0x40, 0x0E, 0x80, 0x63,
        !          5963:        0x01, 0x00, 0x06, 0xA6, 0x40, 0x06, 0x07, 0xA6, 0x64, 0x06, 0x00, 0x33, 0x3A, 0x00, 0x82, 0x88,
        !          5964:        0x40, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x32, 0x06, 0x06, 0xA6, 0x58, 0x06, 0x07, 0xA6,
        !          5965:        0x64, 0x06, 0x00, 0x33, 0x3B, 0x00, 0x82, 0x88, 0x80, 0x67, 0x40, 0x0E, 0x80, 0x63, 0x07, 0xA6,
        !          5966:        0x64, 0x06, 0x00, 0x63, 0x03, 0x03, 0x80, 0x63, 0x88, 0x00, 0x01, 0xA2, 0x78, 0x06, 0x07, 0xA2,
        !          5967:        0xBC, 0x06, 0x00, 0x33, 0x35, 0x00, 0x82, 0x88, 0x07, 0xA6, 0x82, 0x06, 0x00, 0x33, 0x2A, 0x00,
        !          5968:        0x82, 0x88, 0x03, 0x03, 0x03, 0xA2, 0x8E, 0x06, 0x07, 0x23, 0x80, 0x00, 0xC8, 0x86, 0x80, 0x63,
        !          5969:        0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6, 0x9E, 0x06, 0x00, 0x33, 0x29, 0x00, 0x82, 0x88, 0x00, 0x43,
        !          5970:        0x00, 0xA2, 0xAA, 0x06, 0xC0, 0x0E, 0x80, 0x63, 0x94, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80,
        !          5971:        0xC0, 0x20, 0x81, 0x62, 0x04, 0x01, 0x08, 0xDA, 0x80, 0x63, 0x00, 0x63, 0x80, 0x67, 0x00, 0x33,
        !          5972:        0x00, 0x40, 0xC0, 0x20, 0x81, 0x62, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x20, 0x06,
        !          5973:        0x00, 0x33, 0x2C, 0x00, 0x82, 0x88, 0x0C, 0xA2, 0xF0, 0x06, 0xA2, 0x95, 0x83, 0x03, 0x80, 0x63,
        !          5974:        0x06, 0xA6, 0xEE, 0x06, 0x07, 0xA6, 0x64, 0x06, 0x00, 0x33, 0x3D, 0x00, 0x82, 0x88, 0x00, 0x00,
        !          5975:        0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x06, 0x07, 0x07, 0xA6, 0x64, 0x06, 0xBF, 0x23,
        !          5976:        0x04, 0x61, 0x84, 0x01, 0xB2, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01,
        !          5977:        0xF2, 0x00, 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04, 0x80, 0x05,
        !          5978:        0x81, 0x05, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00,
        !          5979:        0x81, 0x01, 0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00,
        !          5980:        0x80, 0x01, 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01, 0xF1, 0x00,
        !          5981:        0x70, 0x00, 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01, 0x71, 0x04,
        !          5982:        0x70, 0x00, 0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01,
        !          5983:        0xA2, 0x01, 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1, 0x86, 0x07,
        !          5984:        0x00, 0x33, 0x07, 0x00, 0x82, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00,
        !          5985:        0xB0, 0x01, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2,
        !          5986:        0xA6, 0x07, 0x00, 0x05, 0x9C, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x05, 0x05,
        !          5987:        0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43, 0x76, 0x08,
        !          5988:        0x80, 0x02, 0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02,
        !          5989:        0x00, 0xA0, 0xD6, 0x07, 0xD8, 0x87, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63,
        !          5990:        0xF3, 0x04, 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2,
        !          5991:        0x06, 0x08, 0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0xE6, 0x07,
        !          5992:        0xC6, 0x97, 0xF4, 0x94, 0xE6, 0x87, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04, 0x1C, 0x88,
        !          5993:        0x02, 0x01, 0x04, 0xD8, 0x08, 0x97, 0xC6, 0x97, 0xF4, 0x94, 0x0C, 0x88, 0x75, 0x00, 0x00, 0xA3,
        !          5994:        0x26, 0x08, 0x00, 0x05, 0x10, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6,
        !          5995:        0x38, 0x08, 0x00, 0x33, 0x3E, 0x00, 0x82, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63,
        !          5996:        0x38, 0x2B, 0x5E, 0x88, 0x38, 0x2B, 0x54, 0x88, 0x32, 0x09, 0x31, 0x05, 0x54, 0x98, 0x05, 0x05,
        !          5997:        0xB2, 0x09, 0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32,
        !          5998:        0x80, 0x36, 0x80, 0x3A, 0x80, 0x3E, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32, 0x40, 0x36, 0x40, 0x3A,
        !          5999:        0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0x74, 0x08, 0x5D, 0x00, 0xFE, 0xC3,
        !          6000:        0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73,
        !          6001:        0x13, 0x23, 0xB8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01, 0xA1, 0x23, 0xA1, 0x01,
        !          6002:        0x81, 0x62, 0xA2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2,
        !          6003:        0xF1, 0xC7, 0x41, 0x23, 0xB8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xB2, 0x84,
        !          6004: 
        !          6005: };
        !          6006: 
        !          6007: ushort              _mcode_size = sizeof (_mcode_buf);
        !          6008: ulong               _mcode_chksum = 0x012258FBUL;
        !          6009: 
        !          6010: extern uchar        _sdtr_period_tbl_[];
        !          6011: 
        !          6012: int
        !          6013: AscExeScsiQueue(
        !          6014:                                   ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          6015:                                   ASC_SCSI_Q dosfar * scsiq
        !          6016: )
        !          6017: {
        !          6018:        PortAddr            iop_base;
        !          6019:        int                 last_int_level;
        !          6020:        int                 sta;
        !          6021:        ulong               addr;
        !          6022:        uchar               sg_entry_cnt;
        !          6023:        uchar               target_ix;
        !          6024:        int                 n_q_required;
        !          6025:        uchar               sg_entry_cnt_minus_one;
        !          6026:        uchar               tid_no;
        !          6027:        uchar               sdtr_data;
        !          6028:        ASC_EXE_CALLBACK    asc_exe_callback;
        !          6029: 
        !          6030: #if CC_DEBUG_SG_LIST
        !          6031:        int                 i;
        !          6032: 
        !          6033: #endif
        !          6034: #if CC_LINK_BUSY_Q
        !          6035:        ASC_SCSI_Q dosfar  *scsiq_tail;
        !          6036:        ASC_SCSI_Q dosfar  *scsiq_next;
        !          6037:        ASC_SCSI_Q dosfar  *scsiq_prev;
        !          6038: 
        !          6039: #endif
        !          6040: 
        !          6041:        iop_base = asc_dvc->iop_base;
        !          6042:        asc_exe_callback = (ASC_EXE_CALLBACK) asc_dvc->exe_callback;
        !          6043:        if (asc_dvc->err_code != 0)
        !          6044:                return (ERR);
        !          6045:        if (scsiq == (ASC_SCSI_Q dosfar *) 0L) {
        !          6046:                AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
        !          6047:                return (ERR);
        !          6048:        }
        !          6049:        scsiq->q1.q_no = 0;
        !          6050:        sta = 0;
        !          6051:        target_ix = scsiq->q2.target_ix;
        !          6052:        tid_no = ASC_TIX_TO_TID(target_ix);
        !          6053: 
        !          6054:        n_q_required = 1;
        !          6055: 
        !          6056:        if (scsiq->cdbptr[0] == SCSICMD_RequestSense) {
        !          6057: 
        !          6058:                if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
        !          6059:                        ((asc_dvc->sdtr_done & scsiq->q1.target_id) != 0)) {
        !          6060:                        sdtr_data = AscReadLramByte(iop_base,
        !          6061:                                  (ushort) ((ushort) ASCV_SDTR_DATA_BEG + (ushort) tid_no));
        !          6062:                        AscMsgOutSDTR(iop_base,
        !          6063:                                                  _sdtr_period_tbl_[(sdtr_data >> 4) & (uchar) (ASC_SYN_XFER_NO - 1)],
        !          6064:                                                  (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
        !          6065:                        scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
        !          6066:                }
        !          6067:        }
        !          6068:        last_int_level = DvcEnterCritical();
        !          6069:        if (asc_dvc->in_critical_cnt != 0) {
        !          6070:                DvcLeaveCritical(last_int_level);
        !          6071:                AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
        !          6072:                return (ERR);
        !          6073:        }
        !          6074:        asc_dvc->in_critical_cnt++;
        !          6075: 
        !          6076:        if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
        !          6077: 
        !          6078:                if ((sg_entry_cnt = scsiq->sg_head->entry_cnt) == 0) {
        !          6079:                        asc_dvc->in_critical_cnt--;
        !          6080:                        DvcLeaveCritical(last_int_level);
        !          6081:                        return (ERR);
        !          6082:                }
        !          6083:                if (sg_entry_cnt == 1) {
        !          6084:                        scsiq->q1.data_addr = scsiq->sg_head->sg_list[0].addr;
        !          6085:                        scsiq->q1.data_cnt = scsiq->sg_head->sg_list[0].bytes;
        !          6086:                        scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
        !          6087:                        goto NON_SG_LIST_REQ;
        !          6088:                }
        !          6089:                if (sg_entry_cnt > ASC_MAX_SG_LIST) {
        !          6090: 
        !          6091:                        return (ERR);
        !          6092:                }
        !          6093:                sg_entry_cnt_minus_one = sg_entry_cnt - 1;
        !          6094: 
        !          6095: #if CC_DEBUG_SG_LIST
        !          6096:                if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
        !          6097:                        for (i = 0; i < sg_entry_cnt_minus_one; i++) {
        !          6098: 
        !          6099:                                addr = scsiq->sg_head->sg_list[i].addr +
        !          6100:                                  scsiq->sg_head->sg_list[i].bytes;
        !          6101: 
        !          6102:                                if (((ushort) addr & 0x0003) != 0) {
        !          6103:                                        asc_dvc->in_critical_cnt--;
        !          6104:                                        DvcLeaveCritical(last_int_level);
        !          6105:                                        AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SG_LIST_ODD_ADDRESS);
        !          6106:                                        return (ERR);
        !          6107:                                }
        !          6108:                        }
        !          6109:                }
        !          6110: #endif
        !          6111: 
        !          6112:                if (asc_dvc->bug_fix_cntl) {
        !          6113:                        if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ADD_ONE_BYTE) {
        !          6114: 
        !          6115:                                addr = scsiq->sg_head->sg_list[sg_entry_cnt_minus_one].addr +
        !          6116:                                  scsiq->sg_head->sg_list[sg_entry_cnt_minus_one].bytes;
        !          6117:                                if (((ushort) addr & 0x0003) != 0) {
        !          6118:                                        if ((scsiq->cdbptr[0] == SCSICMD_Read6) ||
        !          6119:                                                (scsiq->cdbptr[0] == SCSICMD_Read10)) {
        !          6120:                                                if ((scsiq->q2.tag_code & ASC_TAG_FLAG_ADD_ONE_BYTE) == 0) {
        !          6121: 
        !          6122:                                                        scsiq->sg_head->sg_list[sg_entry_cnt_minus_one].bytes++;
        !          6123:                                                        scsiq->q2.tag_code |= ASC_TAG_FLAG_ADD_ONE_BYTE;
        !          6124:                                                }
        !          6125:                                        }
        !          6126:                                }
        !          6127:                        }
        !          6128:                }
        !          6129:                scsiq->sg_head->entry_to_copy = scsiq->sg_head->entry_cnt;
        !          6130:                n_q_required = AscSgListToQueue(sg_entry_cnt);
        !          6131: 
        !          6132: #if CC_LINK_BUSY_Q
        !          6133:                scsiq_next = (ASC_SCSI_Q dosfar *) asc_dvc->scsiq_busy_head[tid_no];
        !          6134:                if (scsiq_next != (ASC_SCSI_Q dosfar *) 0L) {
        !          6135:                        goto link_scisq_to_busy_list;
        !          6136:                }
        !          6137: #endif
        !          6138: 
        !          6139:                if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required)
        !          6140:                         >= (uint) n_q_required) ||
        !          6141:                        ((scsiq->q1.cntl & QC_URGENT) != 0)) {
        !          6142:                        if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
        !          6143:                                                                                n_q_required)) == 1) {
        !          6144: 
        !          6145:                                asc_dvc->in_critical_cnt--;
        !          6146:                                if (asc_exe_callback != 0) {
        !          6147:                                        (*asc_exe_callback) (asc_dvc, scsiq);
        !          6148:                                }
        !          6149:                                DvcLeaveCritical(last_int_level);
        !          6150:                                return (sta);
        !          6151:                        }
        !          6152:                }
        !          6153:        } else {
        !          6154: 
        !          6155:          NON_SG_LIST_REQ:
        !          6156: 
        !          6157:                if (asc_dvc->bug_fix_cntl) {
        !          6158:                        if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ADD_ONE_BYTE) {
        !          6159: 
        !          6160:                                addr = scsiq->q1.data_addr + scsiq->q1.data_cnt;
        !          6161:                                if ((scsiq->cdbptr[0] == SCSICMD_Read6) ||
        !          6162:                                        (scsiq->cdbptr[0] == SCSICMD_Read10)) {
        !          6163:                                        if (((ushort) addr & 0x0003) != 0) {
        !          6164:                                                if (((ushort) scsiq->q1.data_cnt & 0x01FF) == 0) {
        !          6165: 
        !          6166:                                                        if ((scsiq->q2.tag_code & ASC_TAG_FLAG_ADD_ONE_BYTE) == 0) {
        !          6167: 
        !          6168:                                                                scsiq->q2.tag_code |= ASC_TAG_FLAG_ADD_ONE_BYTE;
        !          6169:                                                                scsiq->q1.data_cnt++;
        !          6170:                                                        }
        !          6171:                                                }
        !          6172:                                        }
        !          6173:                                }
        !          6174:                        }
        !          6175:                }
        !          6176:                n_q_required = 1;
        !          6177: 
        !          6178: #if CC_LINK_BUSY_Q
        !          6179:                scsiq_next = (ASC_SCSI_Q dosfar *) asc_dvc->scsiq_busy_head[tid_no];
        !          6180:                if (scsiq_next != (ASC_SCSI_Q dosfar *) 0L) {
        !          6181:                        goto link_scisq_to_busy_list;
        !          6182:                }
        !          6183: #endif
        !          6184:                if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
        !          6185:                        ((scsiq->q1.cntl & QC_URGENT) != 0)) {
        !          6186:                        if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
        !          6187:                                                                                n_q_required)) == 1) {
        !          6188: 
        !          6189:                                asc_dvc->in_critical_cnt--;
        !          6190:                                if (asc_exe_callback != 0) {
        !          6191:                                        (*asc_exe_callback) (asc_dvc, scsiq);
        !          6192:                                }
        !          6193:                                DvcLeaveCritical(last_int_level);
        !          6194:                                return (sta);
        !          6195:                        }
        !          6196:                }
        !          6197:        }
        !          6198: 
        !          6199: #if CC_LINK_BUSY_Q
        !          6200:        if (sta == 0) {
        !          6201: 
        !          6202:          link_scisq_to_busy_list:
        !          6203:                scsiq->ext.q_required = n_q_required;
        !          6204:                if (scsiq_next == (ASC_SCSI_Q dosfar *) 0L) {
        !          6205:                        asc_dvc->scsiq_busy_head[tid_no] = (ASC_SCSI_Q dosfar *) scsiq;
        !          6206:                        asc_dvc->scsiq_busy_tail[tid_no] = (ASC_SCSI_Q dosfar *) scsiq;
        !          6207:                        scsiq->ext.next = (ASC_SCSI_Q dosfar *) 0L;
        !          6208:                        scsiq->ext.join = (ASC_SCSI_Q dosfar *) 0L;
        !          6209:                        scsiq->q1.status = QS_BUSY;
        !          6210:                        sta = 1;
        !          6211:                } else {
        !          6212:                        scsiq_tail = (ASC_SCSI_Q dosfar *) asc_dvc->scsiq_busy_tail[tid_no];
        !          6213:                        if (scsiq_tail->ext.next == (ASC_SCSI_Q dosfar *) 0L) {
        !          6214:                                if ((scsiq->q1.cntl & QC_URGENT) != 0) {
        !          6215: 
        !          6216:                                        asc_dvc->scsiq_busy_head[tid_no] = (ASC_SCSI_Q dosfar *) scsiq;
        !          6217:                                        scsiq->ext.next = scsiq_next;
        !          6218:                                        scsiq->ext.join = (ASC_SCSI_Q dosfar *) 0L;
        !          6219:                                } else {
        !          6220:                                        if (scsiq->ext.cntl & QCX_SORT) {
        !          6221:                                                do {
        !          6222:                                                        scsiq_prev = scsiq_next;
        !          6223:                                                        scsiq_next = scsiq_next->ext.next;
        !          6224:                                                        if (scsiq->ext.lba < scsiq_prev->ext.lba)
        !          6225:                                                                break;
        !          6226:                                                } while (scsiq_next != (ASC_SCSI_Q dosfar *) 0L);
        !          6227: 
        !          6228:                                                scsiq_prev->ext.next = scsiq;
        !          6229:                                                scsiq->ext.next = scsiq_next;
        !          6230:                                                if (scsiq_next == (ASC_SCSI_Q dosfar *) 0L) {
        !          6231:                                                        asc_dvc->scsiq_busy_tail[tid_no] = (ASC_SCSI_Q dosfar *) scsiq;
        !          6232:                                                }
        !          6233:                                                scsiq->ext.join = (ASC_SCSI_Q dosfar *) 0L;
        !          6234:                                        } else {
        !          6235: 
        !          6236:                                                scsiq_tail->ext.next = (ASC_SCSI_Q dosfar *) scsiq;
        !          6237:                                                asc_dvc->scsiq_busy_tail[tid_no] = (ASC_SCSI_Q dosfar *) scsiq;
        !          6238:                                                scsiq->ext.next = (ASC_SCSI_Q dosfar *) 0L;
        !          6239:                                                scsiq->ext.join = (ASC_SCSI_Q dosfar *) 0L;
        !          6240:                                        }
        !          6241:                                }
        !          6242:                                scsiq->q1.status = QS_BUSY;
        !          6243:                                sta = 1;
        !          6244:                        } else {
        !          6245: 
        !          6246:                                AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_BAD_NEXT_PTR);
        !          6247:                                sta = ERR;
        !          6248:                        }
        !          6249:                }
        !          6250:        }
        !          6251: #endif
        !          6252:        asc_dvc->in_critical_cnt--;
        !          6253:        DvcLeaveCritical(last_int_level);
        !          6254:        return (sta);
        !          6255: }
        !          6256: 
        !          6257: int
        !          6258: AscSendScsiQueue(
        !          6259:                                        ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          6260:                                        ASC_SCSI_Q dosfar * scsiq,
        !          6261:                                        uchar n_q_required
        !          6262: )
        !          6263: {
        !          6264:        PortAddr            iop_base;
        !          6265:        uchar               free_q_head;
        !          6266:        uchar               next_qp;
        !          6267:        uchar               tid_no;
        !          6268:        uchar               target_ix;
        !          6269:        int                 sta;
        !          6270: 
        !          6271:        iop_base = asc_dvc->iop_base;
        !          6272:        target_ix = scsiq->q2.target_ix;
        !          6273:        tid_no = ASC_TIX_TO_TID(target_ix);
        !          6274:        sta = 0;
        !          6275:        free_q_head = (uchar) AscGetVarFreeQHead(iop_base);
        !          6276:        if (n_q_required > 1) {
        !          6277:                if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
        !          6278:                                                                           free_q_head, (uchar) (n_q_required)))
        !          6279:                        != (uchar) ASC_QLINK_END) {
        !          6280:                        asc_dvc->last_q_shortage = 0;
        !          6281:                        scsiq->sg_head->queue_cnt = n_q_required - 1;
        !          6282:                        scsiq->q1.q_no = free_q_head;
        !          6283: 
        !          6284:                        if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
        !          6285:                                                                                          free_q_head)) == 1) {
        !          6286: 
        !          6287: #if CC_WRITE_IO_COUNT
        !          6288:                                asc_dvc->req_count++;
        !          6289: #endif
        !          6290: 
        !          6291:                                AscPutVarFreeQHead(iop_base, next_qp);
        !          6292:                                asc_dvc->cur_total_qng += (uchar) (n_q_required);
        !          6293:                                asc_dvc->cur_dvc_qng[tid_no]++;
        !          6294:                        }
        !          6295:                        return (sta);
        !          6296:                }
        !          6297:        } else if (n_q_required == 1) {
        !          6298: 
        !          6299:                if ((next_qp = AscAllocFreeQueue(iop_base,
        !          6300:                                                                                 free_q_head)) != ASC_QLINK_END) {
        !          6301: 
        !          6302:                        scsiq->q1.q_no = free_q_head;
        !          6303:                        if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
        !          6304:                                                                                free_q_head)) == 1) {
        !          6305: 
        !          6306: #if CC_WRITE_IO_COUNT
        !          6307:                                asc_dvc->req_count++;
        !          6308: #endif
        !          6309: 
        !          6310:                                AscPutVarFreeQHead(iop_base, next_qp);
        !          6311:                                asc_dvc->cur_total_qng++;
        !          6312:                                asc_dvc->cur_dvc_qng[tid_no]++;
        !          6313:                        }
        !          6314:                        return (sta);
        !          6315:                }
        !          6316:        }
        !          6317:        return (sta);
        !          6318: }
        !          6319: 
        !          6320: int
        !          6321: AscSgListToQueue(
        !          6322:                                        int sg_list
        !          6323: )
        !          6324: {
        !          6325:        int                 n_sg_list_qs;
        !          6326: 
        !          6327:        n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
        !          6328:        if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
        !          6329:                n_sg_list_qs++;
        !          6330:        return (n_sg_list_qs + 1);
        !          6331: }
        !          6332: 
        !          6333: uint
        !          6334: AscGetNumOfFreeQueue(
        !          6335:                                                ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          6336:                                                uchar target_ix, uchar n_qs
        !          6337: )
        !          6338: {
        !          6339:        uint                cur_used_qs;
        !          6340:        uint                cur_free_qs;
        !          6341:        ASC_SCSI_BIT_ID_TYPE target_id;
        !          6342:        uchar               tid_no;
        !          6343: 
        !          6344:        target_id = ASC_TIX_TO_TARGET_ID(target_ix);
        !          6345:        tid_no = ASC_TIX_TO_TID(target_ix);
        !          6346:        if ((asc_dvc->unit_not_ready & target_id) ||
        !          6347:                (asc_dvc->queue_full_or_busy & target_id)) {
        !          6348:                return (0);
        !          6349:        }
        !          6350:        if (n_qs == 1) {
        !          6351:                cur_used_qs = (uint) asc_dvc->cur_total_qng +
        !          6352:                  (uint) asc_dvc->last_q_shortage +
        !          6353:                  (uint) ASC_MIN_FREE_Q;
        !          6354:        } else {
        !          6355:                cur_used_qs = (uint) asc_dvc->cur_total_qng +
        !          6356:                  (uint) ASC_MIN_FREE_Q;
        !          6357:        }
        !          6358: 
        !          6359:        if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
        !          6360:                cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
        !          6361:                if (asc_dvc->cur_dvc_qng[tid_no] >=
        !          6362:                        asc_dvc->max_dvc_qng[tid_no]) {
        !          6363:                        return (0);
        !          6364:                }
        !          6365:                return (cur_free_qs);
        !          6366:        }
        !          6367:        if (n_qs > 1) {
        !          6368:                if (n_qs > asc_dvc->last_q_shortage) {
        !          6369:                        asc_dvc->last_q_shortage = n_qs;
        !          6370:                }
        !          6371:        }
        !          6372:        return (0);
        !          6373: }
        !          6374: 
        !          6375: int
        !          6376: AscPutReadyQueue(
        !          6377:                                        ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          6378:                                        ASC_SCSI_Q dosfar * scsiq,
        !          6379:                                        uchar q_no
        !          6380: )
        !          6381: {
        !          6382:        ushort              q_addr;
        !          6383:        uchar               tid_no;
        !          6384:        uchar               sdtr_data;
        !          6385:        uchar               syn_period_ix;
        !          6386:        uchar               syn_offset;
        !          6387:        PortAddr            iop_base;
        !          6388: 
        !          6389:        iop_base = asc_dvc->iop_base;
        !          6390: 
        !          6391:        if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
        !          6392:                ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
        !          6393: 
        !          6394:                tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
        !          6395: 
        !          6396:                sdtr_data = AscReadLramByte(iop_base,
        !          6397:                                  (ushort) ((ushort) ASCV_SDTR_DATA_BEG + (ushort) tid_no));
        !          6398:                syn_period_ix = (sdtr_data >> 4) & (ASC_SYN_XFER_NO - 1);
        !          6399:                syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
        !          6400:                AscMsgOutSDTR(iop_base,
        !          6401:                                          _sdtr_period_tbl_[syn_period_ix],
        !          6402:                                          syn_offset);
        !          6403: 
        !          6404:                scsiq->q1.cntl |= QC_MSG_OUT;
        !          6405:        }
        !          6406:        q_addr = ASC_QNO_TO_QADDR(q_no);
        !          6407: 
        !          6408:        if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
        !          6409:                scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
        !          6410:        }
        !          6411:        scsiq->q1.status = QS_FREE;
        !          6412: 
        !          6413:        AscMemWordCopyToLram(iop_base,
        !          6414:                                                 (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG),
        !          6415:                                                 (ushort dosfar *) scsiq->cdbptr,
        !          6416:                                                 (ushort) ((ushort) scsiq->q2.cdb_len >> 1));
        !          6417: 
        !          6418: #if !CC_LITTLE_ENDIAN_HOST
        !          6419:        AscAdjEndianScsiQ(scsiq);
        !          6420: #endif
        !          6421: 
        !          6422:        DvcPutScsiQ(iop_base,
        !          6423:                                (ushort) (q_addr + (ushort) ASC_SCSIQ_CPY_BEG),
        !          6424:                                (ushort dosfar *) & scsiq->q1.cntl,
        !          6425:          (ushort) ((((sizeof (ASC_SCSIQ_1) + sizeof (ASC_SCSIQ_2)) / 2) - 1)));
        !          6426: 
        !          6427: #if CC_WRITE_IO_COUNT
        !          6428:        AscWriteLramWord(iop_base,
        !          6429:                                         (ushort) (q_addr + (ushort) ASC_SCSIQ_W_REQ_COUNT),
        !          6430:                                         (ushort) asc_dvc->req_count);
        !          6431: 
        !          6432: #endif
        !          6433: 
        !          6434: #if CC_VERIFY_LRAM_COPY
        !          6435:        if ((asc_dvc->dvc_cntl & ASC_CNTL_NO_VERIFY_COPY) == 0) {
        !          6436: 
        !          6437:                if (AscMemWordCmpToLram(iop_base,
        !          6438:                                                         (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG),
        !          6439:                                                                (ushort dosfar *) scsiq->cdbptr,
        !          6440:                                                                (ushort) (scsiq->q2.cdb_len >> 1)) != 0) {
        !          6441:                        AscSetLibErrorCode(asc_dvc, ASCQ_ERR_LOCAL_MEM);
        !          6442:                        return (ERR);
        !          6443:                }
        !          6444:                if (AscMemWordCmpToLram(iop_base,
        !          6445:                                                         (ushort) (q_addr + (ushort) ASC_SCSIQ_CPY_BEG),
        !          6446:                                                                (ushort dosfar *) & scsiq->q1.cntl,
        !          6447:                 (ushort) (((sizeof (ASC_SCSIQ_1) + sizeof (ASC_SCSIQ_2)) / 2) - 1))
        !          6448:                        != 0) {
        !          6449:                        AscSetLibErrorCode(asc_dvc, ASCQ_ERR_LOCAL_MEM);
        !          6450:                        return (ERR);
        !          6451:                }
        !          6452:        }
        !          6453: #endif
        !          6454: 
        !          6455: #if CC_CLEAR_DMA_REMAIN
        !          6456: 
        !          6457:        AscWriteLramDWord(iop_base,
        !          6458:                   (ushort) (q_addr + (ushort) ASC_SCSIQ_DW_REMAIN_XFER_ADDR), 0UL);
        !          6459:        AscWriteLramDWord(iop_base,
        !          6460:                        (ushort) (q_addr + (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT), 0UL);
        !          6461: 
        !          6462: #endif
        !          6463: 
        !          6464:        AscWriteLramWord(iop_base,
        !          6465:                                         (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
        !          6466:                         (ushort) (((ushort) scsiq->q1.q_no << 8) | (ushort) QS_READY));
        !          6467:        return (1);
        !          6468: }
        !          6469: 
        !          6470: int
        !          6471: AscPutReadySgListQueue(
        !          6472:                                                  ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          6473:                                                  ASC_SCSI_Q dosfar * scsiq,
        !          6474:                                                  uchar q_no
        !          6475: )
        !          6476: {
        !          6477:        uchar               sg_list_dwords;
        !          6478:        uchar               sg_index, i;
        !          6479:        uchar               sg_entry_cnt;
        !          6480:        uchar               next_qp;
        !          6481:        ushort              q_addr;
        !          6482:        int                 sta;
        !          6483:        ASC_SG_HEAD dosfar *sg_head;
        !          6484:        ASC_SG_LIST_Q       scsi_sg_q;
        !          6485:        ulong               saved_data_addr;
        !          6486:        ulong               saved_data_cnt;
        !          6487:        PortAddr            iop_base;
        !          6488: 
        !          6489:        iop_base = asc_dvc->iop_base;
        !          6490: 
        !          6491:        sg_head = scsiq->sg_head;
        !          6492: 
        !          6493:        saved_data_addr = scsiq->q1.data_addr;
        !          6494:        saved_data_cnt = scsiq->q1.data_cnt;
        !          6495:        scsiq->q1.data_addr = sg_head->sg_list[0].addr;
        !          6496:        scsiq->q1.data_cnt = sg_head->sg_list[0].bytes;
        !          6497:        sg_entry_cnt = sg_head->entry_cnt - 1;
        !          6498:        if (sg_entry_cnt != 0) {
        !          6499:                scsiq->q1.cntl |= QC_SG_HEAD;
        !          6500:                q_addr = ASC_QNO_TO_QADDR(q_no);
        !          6501:                sg_index = 1;
        !          6502:                scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
        !          6503:                scsi_sg_q.sg_head_qp = q_no;
        !          6504:                scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
        !          6505:                for (i = 0; i < sg_head->queue_cnt; i++) {
        !          6506:                        scsi_sg_q.seq_no = i + 1;
        !          6507:                        if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
        !          6508:                                sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
        !          6509:                                sg_entry_cnt -= ASC_SG_LIST_PER_Q;
        !          6510:                                if (i == 0) {
        !          6511:                                        scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q;
        !          6512:                                        scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q;
        !          6513:                                } else {
        !          6514:                                        scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
        !          6515:                                        scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
        !          6516:                                }
        !          6517:                        } else {
        !          6518: 
        !          6519:                                scsi_sg_q.cntl |= QCSG_SG_XFER_END;
        !          6520:                                sg_list_dwords = sg_entry_cnt << 1;
        !          6521:                                if (i == 0) {
        !          6522:                                        scsi_sg_q.sg_list_cnt = sg_entry_cnt;
        !          6523:                                        scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt;
        !          6524:                                } else {
        !          6525:                                        scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
        !          6526:                                        scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
        !          6527:                                }
        !          6528:                                sg_entry_cnt = 0;
        !          6529:                        }
        !          6530:                        next_qp = AscReadLramByte(iop_base,
        !          6531:                                                                          (ushort) (q_addr + ASC_SCSIQ_B_FWD));
        !          6532:                        scsi_sg_q.q_no = next_qp;
        !          6533:                        q_addr = ASC_QNO_TO_QADDR(next_qp);
        !          6534: 
        !          6535:                        AscMemWordCopyToLram(iop_base,
        !          6536:                                                                 (ushort) (q_addr + ASC_SCSIQ_SGHD_CPY_BEG),
        !          6537:                                                                 (ushort dosfar *) & scsi_sg_q,
        !          6538:                                                                 (ushort) (sizeof (ASC_SG_LIST_Q) >> 1));
        !          6539: 
        !          6540:                        AscMemDWordCopyToLram(iop_base,
        !          6541:                                                                  (ushort) (q_addr + ASC_SGQ_LIST_BEG),
        !          6542:                                                          (ulong dosfar *) & sg_head->sg_list[sg_index],
        !          6543:                                                                  (ushort) sg_list_dwords);
        !          6544: 
        !          6545:                        sg_index += ASC_SG_LIST_PER_Q;
        !          6546:                }
        !          6547:        } else {
        !          6548: 
        !          6549:                scsiq->q1.cntl &= ~QC_SG_HEAD;
        !          6550:        }
        !          6551:        sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
        !          6552: 
        !          6553:        scsiq->q1.data_addr = saved_data_addr;
        !          6554:        scsiq->q1.data_cnt = saved_data_cnt;
        !          6555:        return (sta);
        !          6556: }
        !          6557: 
        !          6558: int
        !          6559: AscAbortSRB(
        !          6560:                           ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          6561:                           ulong srb_ptr
        !          6562: )
        !          6563: {
        !          6564:        int                 sta;
        !          6565:        ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready;
        !          6566:        PortAddr            iop_base;
        !          6567: 
        !          6568:        iop_base = asc_dvc->iop_base;
        !          6569:        sta = ERR;
        !          6570:        saved_unit_not_ready = asc_dvc->unit_not_ready;
        !          6571:        asc_dvc->unit_not_ready = 0xFF;
        !          6572:        AscWaitISRDone(asc_dvc);
        !          6573:        if (AscStopQueueExe(iop_base) == 1) {
        !          6574:                if (AscRiscHaltedAbortSRB(asc_dvc, srb_ptr) == 1) {
        !          6575:                        sta = 1;
        !          6576:                        AscCleanUpBusyQueue(iop_base);
        !          6577:                        AscStartQueueExe(iop_base);
        !          6578: 
        !          6579:                } else {
        !          6580:                        sta = 0;
        !          6581:                        AscStartQueueExe(iop_base);
        !          6582:                }
        !          6583:        }
        !          6584:        asc_dvc->unit_not_ready = saved_unit_not_ready;
        !          6585:        return (sta);
        !          6586: }
        !          6587: 
        !          6588: int
        !          6589: AscResetDevice(
        !          6590:                                  ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          6591:                                  uchar target_ix
        !          6592: )
        !          6593: {
        !          6594:        PortAddr            iop_base;
        !          6595:        int                 sta;
        !          6596:        uchar               tid_no;
        !          6597:        ASC_SCSI_BIT_ID_TYPE target_id;
        !          6598:        int                 i;
        !          6599:        ASC_SCSI_REQ_Q      scsiq_buf;
        !          6600:        ASC_SCSI_REQ_Q dosfar *scsiq;
        !          6601:        uchar dosfar       *buf;
        !          6602:        ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready;
        !          6603: 
        !          6604:        iop_base = asc_dvc->iop_base;
        !          6605:        tid_no = ASC_TIX_TO_TID(target_ix);
        !          6606:        target_id = ASC_TID_TO_TARGET_ID(tid_no);
        !          6607:        saved_unit_not_ready = asc_dvc->unit_not_ready;
        !          6608:        asc_dvc->unit_not_ready = target_id;
        !          6609:        sta = ERR;
        !          6610:        AscWaitTixISRDone(asc_dvc, target_ix);
        !          6611:        if (AscStopQueueExe(iop_base) == 1) {
        !          6612:                if (AscRiscHaltedAbortTIX(asc_dvc, target_ix) == 1) {
        !          6613: 
        !          6614:                        AscCleanUpBusyQueue(iop_base);
        !          6615:                        AscStartQueueExe(iop_base);
        !          6616: 
        !          6617:                        AscWaitTixISRDone(asc_dvc, target_ix);
        !          6618: 
        !          6619:                        sta = TRUE;
        !          6620:                        scsiq = (ASC_SCSI_REQ_Q dosfar *) & scsiq_buf;
        !          6621:                        buf = (uchar dosfar *) & scsiq_buf;
        !          6622:                        for (i = 0; i < sizeof (ASC_SCSI_REQ_Q); i++) {
        !          6623:                                *buf++ = 0x00;
        !          6624:                        }
        !          6625: 
        !          6626:                        scsiq->r1.status = (uchar) QS_READY;
        !          6627:                        scsiq->r2.cdb_len = 6;
        !          6628:                        scsiq->r2.tag_code = M2_QTAG_MSG_SIMPLE;
        !          6629:                        scsiq->r1.target_id = target_id;
        !          6630: 
        !          6631:                        scsiq->r2.target_ix = ASC_TIDLUN_TO_IX(tid_no, 0);
        !          6632:                        scsiq->cdbptr = (uchar dosfar *) scsiq->cdb;
        !          6633: 
        !          6634:                        scsiq->r1.cntl = QC_NO_CALLBACK | QC_MSG_OUT | QC_URGENT;
        !          6635:                        AscWriteLramByte(asc_dvc->iop_base, ASCV_MSGOUT_BEG,
        !          6636:                                                         M1_BUS_DVC_RESET);
        !          6637: 
        !          6638:                        asc_dvc->unit_not_ready &= ~target_id;
        !          6639: 
        !          6640:                        asc_dvc->sdtr_done |= target_id;
        !          6641: 
        !          6642:                        if (AscExeScsiQueue(asc_dvc, (ASC_SCSI_Q dosfar *) scsiq)
        !          6643:                                == 1) {
        !          6644:                                asc_dvc->unit_not_ready = target_id;
        !          6645:                                DvcSleepMilliSecond(1000);
        !          6646:                                _AscWaitQDone(iop_base, (ASC_SCSI_Q dosfar *) scsiq);
        !          6647:                                if (AscStopQueueExe(iop_base) == 1) {
        !          6648: 
        !          6649:                                        AscCleanUpDiscQueue(iop_base);
        !          6650:                                        AscStartQueueExe(iop_base);
        !          6651:                                        if (asc_dvc->pci_fix_asyn_xfer & target_id) {
        !          6652: 
        !          6653:                                                AscSetRunChipSynRegAtID(iop_base, tid_no,
        !          6654:                                                                                         ASYN_SDTR_DATA_FIX_PCI_REV_AB);
        !          6655:                                        }
        !          6656:                                        AscWaitTixISRDone(asc_dvc, target_ix);
        !          6657:                                }
        !          6658:                        } else {
        !          6659: 
        !          6660:                                sta = 0;
        !          6661:                        }
        !          6662: 
        !          6663:                        asc_dvc->sdtr_done &= ~target_id;
        !          6664:                } else {
        !          6665:                        sta = ERR;
        !          6666:                        AscStartQueueExe(iop_base);
        !          6667:                }
        !          6668:        }
        !          6669:        asc_dvc->unit_not_ready = saved_unit_not_ready;
        !          6670:        return (sta);
        !          6671: }
        !          6672: 
        !          6673: int
        !          6674: AscResetSB(
        !          6675:                          ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          6676: )
        !          6677: {
        !          6678:        int                 sta;
        !          6679:        int                 i;
        !          6680:        PortAddr            iop_base;
        !          6681: 
        !          6682:        iop_base = asc_dvc->iop_base;
        !          6683:        asc_dvc->unit_not_ready = 0xFF;
        !          6684:        sta = TRUE;
        !          6685:        AscWaitISRDone(asc_dvc);
        !          6686:        AscStopQueueExe(iop_base);
        !          6687: 
        !          6688:        asc_dvc->sdtr_done = 0;
        !          6689:        AscResetChipAndScsiBus(iop_base);
        !          6690: 
        !          6691:        DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
        !          6692: 
        !          6693: #if CC_SCAM
        !          6694:        if (!(asc_dvc->dvc_cntl & ASC_CNTL_NO_SCAM)) {
        !          6695:                AscSCAM(asc_dvc);
        !          6696:        }
        !          6697: #endif
        !          6698:        AscReInitLram(asc_dvc);
        !          6699: 
        !          6700:        for (i = 0; i <= ASC_MAX_TID; i++) {
        !          6701:                asc_dvc->cur_dvc_qng[i] = 0;
        !          6702:                if (asc_dvc->pci_fix_asyn_xfer & (0x01 << i)) {
        !          6703: 
        !          6704:                        AscSetChipSynRegAtID(iop_base, i, ASYN_SDTR_DATA_FIX_PCI_REV_AB);
        !          6705:                }
        !          6706:        }
        !          6707: 
        !          6708:        asc_dvc->err_code = 0;
        !          6709: 
        !          6710:        AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
        !          6711:        if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
        !          6712:                sta = ERR;
        !          6713:        }
        !          6714:        if (AscStartChip(iop_base) == 0) {
        !          6715:                sta = ERR;
        !          6716:        }
        !          6717:        AscStartQueueExe(iop_base);
        !          6718:        asc_dvc->unit_not_ready = 0;
        !          6719:        asc_dvc->queue_full_or_busy = 0;
        !          6720:        return (sta);
        !          6721: }
        !          6722: 
        !          6723: int
        !          6724: AscSetRunChipSynRegAtID(
        !          6725:                                                   PortAddr iop_base,
        !          6726:                                                   uchar tid_no,
        !          6727:                                                   uchar sdtr_data
        !          6728: )
        !          6729: {
        !          6730:        int                 sta = FALSE;
        !          6731: 
        !          6732:        if (AscHostReqRiscHalt(iop_base)) {
        !          6733:                sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
        !          6734: 
        !          6735:                AscStartChip(iop_base);
        !          6736:                return (sta);
        !          6737:        }
        !          6738:        return (sta);
        !          6739: }
        !          6740: 
        !          6741: int
        !          6742: AscSetChipSynRegAtID(
        !          6743:                                                PortAddr iop_base,
        !          6744:                                                uchar id,
        !          6745:                                                uchar sdtr_data
        !          6746: )
        !          6747: {
        !          6748:        AscSetBank(iop_base, 1);
        !          6749:        AscWriteChipScsiID(iop_base, id);
        !          6750:        if (AscReadChipScsiID(iop_base) != (0x01 << id)) {
        !          6751:                return (FALSE);
        !          6752:        }
        !          6753:        AscSetBank(iop_base, 0);
        !          6754:        AscWriteChipSyn(iop_base, sdtr_data);
        !          6755:        if (AscReadChipSyn(iop_base) != sdtr_data) {
        !          6756:                return (FALSE);
        !          6757:        }
        !          6758:        return (TRUE);
        !          6759: }
        !          6760: 
        !          6761: int
        !          6762: AscReInitLram(
        !          6763:                                 ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          6764: )
        !          6765: {
        !          6766:        AscInitLram(asc_dvc);
        !          6767:        AscInitQLinkVar(asc_dvc);
        !          6768:        return (0);
        !          6769: }
        !          6770: 
        !          6771: ushort
        !          6772: AscInitLram(
        !          6773:                           ASC_DVC_VAR asc_ptr_type * asc_dvc)
        !          6774: {
        !          6775:        uchar               i;
        !          6776:        ushort              s_addr;
        !          6777:        PortAddr            iop_base;
        !          6778:        ushort              warn_code;
        !          6779: 
        !          6780:        iop_base = asc_dvc->iop_base;
        !          6781:        warn_code = 0;
        !          6782: 
        !          6783:        AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
        !          6784:                           (ushort) (((int) (asc_dvc->max_total_qng + 2 + 1) * 64) >> 1)
        !          6785:          );
        !          6786: 
        !          6787:        i = ASC_MIN_ACTIVE_QNO;
        !          6788:        s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
        !          6789: 
        !          6790:        AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
        !          6791:                                         (uchar) (i + 1));
        !          6792:        AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
        !          6793:                                         (uchar) (asc_dvc->max_total_qng));
        !          6794:        AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
        !          6795:                                         (uchar) i);
        !          6796:        i++;
        !          6797:        s_addr += ASC_QBLK_SIZE;
        !          6798:        for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
        !          6799:                AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
        !          6800:                                                 (uchar) (i + 1));
        !          6801:                AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
        !          6802:                                                 (uchar) (i - 1));
        !          6803:                AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
        !          6804:                                                 (uchar) i);
        !          6805:        }
        !          6806: 
        !          6807:        AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
        !          6808:                                         (uchar) ASC_QLINK_END);
        !          6809:        AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
        !          6810:                                         (uchar) (asc_dvc->max_total_qng - 1));
        !          6811:        AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
        !          6812:                                         (uchar) asc_dvc->max_total_qng);
        !          6813:        i++;
        !          6814:        s_addr += ASC_QBLK_SIZE;
        !          6815: 
        !          6816:        for (; i <= (uchar) (asc_dvc->max_total_qng + 3);
        !          6817:                 i++, s_addr += ASC_QBLK_SIZE) {
        !          6818: 
        !          6819:                AscWriteLramByte(iop_base,
        !          6820:                                                 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_FWD), i);
        !          6821:                AscWriteLramByte(iop_base,
        !          6822:                                                 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_BWD), i);
        !          6823:                AscWriteLramByte(iop_base,
        !          6824:                                                 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_QNO), i);
        !          6825:        }
        !          6826: 
        !          6827:        return (warn_code);
        !          6828: }
        !          6829: 
        !          6830: ushort
        !          6831: AscInitQLinkVar(
        !          6832:                                   ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          6833: )
        !          6834: {
        !          6835:        PortAddr            iop_base;
        !          6836:        int                 i;
        !          6837:        ushort              lram_addr;
        !          6838: 
        !          6839:        iop_base = asc_dvc->iop_base;
        !          6840:        AscPutRiscVarFreeQHead(iop_base, 1);
        !          6841:        AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
        !          6842: 
        !          6843:        AscPutVarFreeQHead(iop_base, 1);
        !          6844:        AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
        !          6845: 
        !          6846:        AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
        !          6847:                                         (uchar) ((int) asc_dvc->max_total_qng + 1));
        !          6848:        AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
        !          6849:                                         (uchar) ((int) asc_dvc->max_total_qng + 2));
        !          6850: 
        !          6851:        AscWriteLramByte(iop_base, (ushort) ASCV_TOTAL_READY_Q_B,
        !          6852:                                         asc_dvc->max_total_qng);
        !          6853: 
        !          6854:        AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
        !          6855:        AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
        !          6856:        AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
        !          6857:        AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
        !          6858:        AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
        !          6859: 
        !          6860:        AscWriteLramByte(iop_base, (ushort) ASCV_CDBCNT_B, 0);
        !          6861: 
        !          6862:        lram_addr = ASC_QADR_BEG;
        !          6863:        for (i = 0; i < 32; i++, lram_addr += 2) {
        !          6864:                AscWriteLramWord(iop_base, lram_addr, 0);
        !          6865:        }
        !          6866: 
        !          6867:        return (0);
        !          6868: }
        !          6869: 
        !          6870: int
        !          6871: AscSetLibErrorCode(
        !          6872:                                          ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          6873:                                          ushort err_code
        !          6874: )
        !          6875: {
        !          6876:        if (asc_dvc->err_code == 0) {
        !          6877: 
        !          6878:                asc_dvc->err_code = err_code;
        !          6879:                AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
        !          6880:                                                 err_code);
        !          6881:        }
        !          6882:        return (err_code);
        !          6883: }
        !          6884: 
        !          6885: int
        !          6886: _AscWaitQDone(
        !          6887:                                 PortAddr iop_base,
        !          6888:                                 ASC_SCSI_Q dosfar * scsiq
        !          6889: )
        !          6890: {
        !          6891:        ushort              q_addr;
        !          6892:        uchar               q_status;
        !          6893:        int                 count = 0;
        !          6894: 
        !          6895:        while (scsiq->q1.q_no == 0) ;
        !          6896:        q_addr = ASC_QNO_TO_QADDR(scsiq->q1.q_no);
        !          6897: 
        !          6898:        do {
        !          6899:                q_status = AscReadLramByte(iop_base, q_addr + ASC_SCSIQ_B_STATUS);
        !          6900:                DvcSleepMilliSecond(100L);
        !          6901:                if (count++ > 30) {
        !          6902:                        return (0);
        !          6903:                }
        !          6904:        } while ((q_status & QS_READY) != 0);
        !          6905:        return (1);
        !          6906: }
        !          6907: 
        !          6908: uchar               _sdtr_period_tbl_[ASC_SYN_XFER_NO] =
        !          6909: {
        !          6910:        SYN_XFER_NS_0,
        !          6911:        SYN_XFER_NS_1,
        !          6912:        SYN_XFER_NS_2,
        !          6913:        SYN_XFER_NS_3,
        !          6914:        SYN_XFER_NS_4,
        !          6915:        SYN_XFER_NS_5,
        !          6916:        SYN_XFER_NS_6,
        !          6917:        SYN_XFER_NS_7};
        !          6918: 
        !          6919: uchar
        !          6920: AscMsgOutSDTR(
        !          6921:                                 PortAddr iop_base,
        !          6922:                                 uchar sdtr_period,
        !          6923:                                 uchar sdtr_offset
        !          6924: )
        !          6925: {
        !          6926:        SDTR_XMSG           sdtr_buf;
        !          6927:        uchar               sdtr_period_index;
        !          6928: 
        !          6929:        sdtr_buf.msg_type = MS_EXTEND;
        !          6930:        sdtr_buf.msg_len = MS_SDTR_LEN;
        !          6931:        sdtr_buf.msg_req = MS_SDTR_CODE;
        !          6932:        sdtr_buf.xfer_period = sdtr_period;
        !          6933:        sdtr_offset &= ASC_SYN_MAX_OFFSET;
        !          6934:        sdtr_buf.req_ack_offset = sdtr_offset;
        !          6935:        AscMemWordCopyToLram(iop_base, ASCV_MSGOUT_BEG,
        !          6936:                                                 (ushort dosfar *) & sdtr_buf, SYN_XMSG_WLEN);
        !          6937:        if ((sdtr_period_index = AscGetSynPeriodIndex(sdtr_period)) <=
        !          6938:                ASC_MAX_SDTR_PERIOD_INDEX) {
        !          6939:                return ((sdtr_period_index << 4) | sdtr_offset);
        !          6940:        } else {
        !          6941: 
        !          6942:                return (0);
        !          6943:        }
        !          6944: }
        !          6945: 
        !          6946: uchar
        !          6947: AscCalSDTRData(
        !          6948:                                  uchar sdtr_period,
        !          6949:                                  uchar syn_offset
        !          6950: )
        !          6951: {
        !          6952:        uchar               byte;
        !          6953:        uchar               sdtr_period_ix;
        !          6954: 
        !          6955:        sdtr_period_ix = AscGetSynPeriodIndex(sdtr_period);
        !          6956:        if ((sdtr_period_ix > ASC_MAX_SDTR_PERIOD_INDEX) ||
        !          6957:                (sdtr_period_ix > ASC_SDTR_PERIOD_IX_MIN)) {
        !          6958:                return (0xFF);
        !          6959:        }
        !          6960:        byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
        !          6961:        return (byte);
        !          6962: }
        !          6963: 
        !          6964: void
        !          6965: AscSetChipSDTR(
        !          6966:                                  PortAddr iop_base,
        !          6967:                                  uchar sdtr_data,
        !          6968:                                  uchar tid_no
        !          6969: )
        !          6970: {
        !          6971: 
        !          6972:        AscWriteChipSyn(iop_base, sdtr_data);
        !          6973:        AscWriteLramByte(iop_base,
        !          6974:                                   (ushort) ((ushort) ASCV_SDTR_DONE_BEG + (ushort) tid_no),
        !          6975:                                         sdtr_data);
        !          6976:        return;
        !          6977: }
        !          6978: 
        !          6979: uchar
        !          6980: AscGetSynPeriodIndex(
        !          6981:                                                uchar syn_time
        !          6982: )
        !          6983: {
        !          6984:        if ((syn_time >= SYN_XFER_NS_0) && (syn_time <= SYN_XFER_NS_7)) {
        !          6985:                if (syn_time <= SYN_XFER_NS_6) {
        !          6986:                        if (syn_time <= SYN_XFER_NS_5) {
        !          6987:                                if (syn_time <= SYN_XFER_NS_4) {
        !          6988:                                        if (syn_time <= SYN_XFER_NS_3) {
        !          6989:                                                if (syn_time <= SYN_XFER_NS_2) {
        !          6990:                                                        if (syn_time <= SYN_XFER_NS_1) {
        !          6991:                                                                if (syn_time <= SYN_XFER_NS_0) {
        !          6992:                                                                        return (0);
        !          6993:                                                                } else
        !          6994:                                                                        return (1);
        !          6995:                                                        } else {
        !          6996:                                                                return (2);
        !          6997:                                                        }
        !          6998:                                                } else {
        !          6999:                                                        return (3);
        !          7000:                                                }
        !          7001:                                        } else {
        !          7002:                                                return (4);
        !          7003:                                        }
        !          7004:                                } else {
        !          7005:                                        return (5);
        !          7006:                                }
        !          7007:                        } else {
        !          7008:                                return (6);
        !          7009:                        }
        !          7010:                } else {
        !          7011:                        return (7);
        !          7012:                }
        !          7013:        } else {
        !          7014: 
        !          7015:                return (8);
        !          7016:        }
        !          7017: }
        !          7018: 
        !          7019: uchar
        !          7020: AscAllocFreeQueue(
        !          7021:                                         PortAddr iop_base,
        !          7022:                                         uchar free_q_head
        !          7023: )
        !          7024: {
        !          7025:        ushort              q_addr;
        !          7026:        uchar               next_qp;
        !          7027:        uchar               q_status;
        !          7028: 
        !          7029:        q_addr = ASC_QNO_TO_QADDR(free_q_head);
        !          7030:        q_status = (uchar) AscReadLramByte(iop_base,
        !          7031:                                                                        (ushort) (q_addr + ASC_SCSIQ_B_STATUS));
        !          7032:        next_qp = AscReadLramByte(iop_base,
        !          7033:                                                          (ushort) (q_addr + ASC_SCSIQ_B_FWD));
        !          7034:        if (((q_status & QS_READY) == 0) &&
        !          7035:                (next_qp != ASC_QLINK_END)) {
        !          7036:                return (next_qp);
        !          7037:        }
        !          7038:        return (ASC_QLINK_END);
        !          7039: }
        !          7040: 
        !          7041: uchar
        !          7042: AscAllocMultipleFreeQueue(
        !          7043:                                                         PortAddr iop_base,
        !          7044:                                                         uchar free_q_head,
        !          7045:                                                         uchar n_free_q
        !          7046: )
        !          7047: {
        !          7048:        uchar               i;
        !          7049: 
        !          7050:        for (i = 0; i < n_free_q; i++) {
        !          7051:                if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
        !          7052:                        == ASC_QLINK_END) {
        !          7053:                        return (ASC_QLINK_END);
        !          7054:                }
        !          7055:        }
        !          7056:        return (free_q_head);
        !          7057: }
        !          7058: 
        !          7059: int
        !          7060: AscRiscHaltedAbortSRB(
        !          7061:                                                 ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          7062:                                                 ulong srb_ptr
        !          7063: )
        !          7064: {
        !          7065:        PortAddr            iop_base;
        !          7066:        ushort              q_addr;
        !          7067:        uchar               q_no;
        !          7068:        ASC_QDONE_INFO      scsiq_buf;
        !          7069:        ASC_QDONE_INFO dosfar *scsiq;
        !          7070:        ASC_ISR_CALLBACK    asc_isr_callback;
        !          7071:        int                 last_int_level;
        !          7072: 
        !          7073:        iop_base = asc_dvc->iop_base;
        !          7074:        asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
        !          7075:        last_int_level = DvcEnterCritical();
        !          7076:        scsiq = (ASC_QDONE_INFO dosfar *) & scsiq_buf;
        !          7077: 
        !          7078: #if CC_LINK_BUSY_Q
        !          7079:        _AscAbortSrbBusyQueue(asc_dvc, scsiq, srb_ptr);
        !          7080: #endif
        !          7081: 
        !          7082:        for (q_no = ASC_MIN_ACTIVE_QNO; q_no <= asc_dvc->max_total_qng;
        !          7083:                 q_no++) {
        !          7084:                q_addr = ASC_QNO_TO_QADDR(q_no);
        !          7085:                scsiq->d2.srb_ptr = AscReadLramDWord(iop_base,
        !          7086:                                                   (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR));
        !          7087:                if (scsiq->d2.srb_ptr == srb_ptr) {
        !          7088:                        _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count);
        !          7089:                        if (((scsiq->q_status & QS_READY) != 0) &&
        !          7090:                                ((scsiq->q_status & QS_ABORTED) == 0) &&
        !          7091:                                ((scsiq->cntl & QCSG_SG_XFER_LIST) == 0)) {
        !          7092: 
        !          7093:                                scsiq->q_status |= QS_ABORTED;
        !          7094:                                scsiq->d3.done_stat = QD_ABORTED_BY_HOST;
        !          7095:                                AscWriteLramDWord(iop_base,
        !          7096:                                                        (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR),
        !          7097:                                                                  0L);
        !          7098:                                AscWriteLramByte(iop_base,
        !          7099:                                                        (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
        !          7100:                                                                 scsiq->q_status);
        !          7101:                                (*asc_isr_callback) (asc_dvc, scsiq);
        !          7102:                                return (1);
        !          7103:                        }
        !          7104:                }
        !          7105:        }
        !          7106:        DvcLeaveCritical(last_int_level);
        !          7107:        return (0);
        !          7108: }
        !          7109: 
        !          7110: int
        !          7111: AscRiscHaltedAbortTIX(
        !          7112:                                                 ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          7113:                                                 uchar target_ix
        !          7114: )
        !          7115: {
        !          7116:        PortAddr            iop_base;
        !          7117:        ushort              q_addr;
        !          7118:        uchar               q_no;
        !          7119:        ASC_QDONE_INFO      scsiq_buf;
        !          7120:        ASC_QDONE_INFO dosfar *scsiq;
        !          7121:        ASC_ISR_CALLBACK    asc_isr_callback;
        !          7122:        int                 last_int_level;
        !          7123: 
        !          7124: #if CC_LINK_BUSY_Q
        !          7125:        uchar               tid_no;
        !          7126: 
        !          7127: #endif
        !          7128: 
        !          7129:        iop_base = asc_dvc->iop_base;
        !          7130:        asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
        !          7131:        last_int_level = DvcEnterCritical();
        !          7132:        scsiq = (ASC_QDONE_INFO dosfar *) & scsiq_buf;
        !          7133: 
        !          7134: #if CC_LINK_BUSY_Q
        !          7135: 
        !          7136:        tid_no = ASC_TIX_TO_TID(target_ix);
        !          7137:        _AscAbortTidBusyQueue(asc_dvc, scsiq, tid_no);
        !          7138: 
        !          7139: #endif
        !          7140: 
        !          7141:        for (q_no = ASC_MIN_ACTIVE_QNO; q_no <= asc_dvc->max_total_qng;
        !          7142:                 q_no++) {
        !          7143:                q_addr = ASC_QNO_TO_QADDR(q_no);
        !          7144:                _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count);
        !          7145:                if (((scsiq->q_status & QS_READY) != 0) &&
        !          7146:                        ((scsiq->q_status & QS_ABORTED) == 0) &&
        !          7147:                        ((scsiq->cntl & QCSG_SG_XFER_LIST) == 0)) {
        !          7148:                        if (scsiq->d2.target_ix == target_ix) {
        !          7149:                                scsiq->q_status |= QS_ABORTED;
        !          7150:                                scsiq->d3.done_stat = QD_ABORTED_BY_HOST;
        !          7151: 
        !          7152:                                AscWriteLramDWord(iop_base,
        !          7153:                                                        (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR),
        !          7154:                                                                  0L);
        !          7155: 
        !          7156:                                AscWriteLramByte(iop_base,
        !          7157:                                                        (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
        !          7158:                                                                 scsiq->q_status);
        !          7159:                                (*asc_isr_callback) (asc_dvc, scsiq);
        !          7160:                        }
        !          7161:                }
        !          7162:        }
        !          7163:        DvcLeaveCritical(last_int_level);
        !          7164:        return (1);
        !          7165: }
        !          7166: 
        !          7167: #if CC_LINK_BUSY_Q
        !          7168: 
        !          7169: #endif
        !          7170: 
        !          7171: int
        !          7172: AscHostReqRiscHalt(
        !          7173:                                          PortAddr iop_base
        !          7174: )
        !          7175: {
        !          7176:        int                 count = 0;
        !          7177:        int                 sta = 0;
        !          7178:        uchar               saved_stop_code;
        !          7179: 
        !          7180:        if (AscIsChipHalted(iop_base))
        !          7181:                return (1);
        !          7182:        saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
        !          7183: 
        !          7184:        AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
        !          7185:                                         ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP
        !          7186:          );
        !          7187:        do {
        !          7188:                if (AscIsChipHalted(iop_base)) {
        !          7189:                        sta = 1;
        !          7190:                        break;
        !          7191:                }
        !          7192:                DvcSleepMilliSecond(100);
        !          7193:        } while (count++ < 20);
        !          7194: 
        !          7195:        AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
        !          7196:        return (sta);
        !          7197: }
        !          7198: 
        !          7199: int
        !          7200: AscStopQueueExe(
        !          7201:                                   PortAddr iop_base
        !          7202: )
        !          7203: {
        !          7204:        int                 count;
        !          7205: 
        !          7206:        count = 0;
        !          7207:        if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
        !          7208:                AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
        !          7209:                                                 ASC_STOP_REQ_RISC_STOP);
        !          7210:                do {
        !          7211:                        if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
        !          7212:                                ASC_STOP_ACK_RISC_STOP) {
        !          7213:                                return (1);
        !          7214:                        }
        !          7215:                        DvcSleepMilliSecond(100);
        !          7216:                } while (count++ < 20);
        !          7217:        }
        !          7218:        return (0);
        !          7219: }
        !          7220: 
        !          7221: int
        !          7222: AscStartQueueExe(
        !          7223:                                        PortAddr iop_base
        !          7224: )
        !          7225: {
        !          7226:        if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
        !          7227:                AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
        !          7228:        }
        !          7229:        return (1);
        !          7230: }
        !          7231: 
        !          7232: int
        !          7233: AscCleanUpBusyQueue(
        !          7234:                                           PortAddr iop_base
        !          7235: )
        !          7236: {
        !          7237:        int                 count;
        !          7238:        uchar               stop_code;
        !          7239: 
        !          7240:        count = 0;
        !          7241:        if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
        !          7242:                AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
        !          7243:                                                 ASC_STOP_CLEAN_UP_BUSY_Q);
        !          7244:                do {
        !          7245:                        stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
        !          7246:                        if ((stop_code & ASC_STOP_CLEAN_UP_BUSY_Q) == 0)
        !          7247:                                break;
        !          7248:                        DvcSleepMilliSecond(100);
        !          7249:                } while (count++ < 20);
        !          7250:        }
        !          7251:        return (1);
        !          7252: }
        !          7253: 
        !          7254: int
        !          7255: AscCleanUpDiscQueue(
        !          7256:                                           PortAddr iop_base
        !          7257: )
        !          7258: {
        !          7259:        int                 count;
        !          7260:        uchar               stop_code;
        !          7261: 
        !          7262:        count = 0;
        !          7263:        if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
        !          7264:                AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
        !          7265:                                                 ASC_STOP_CLEAN_UP_DISC_Q);
        !          7266:                do {
        !          7267:                        stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
        !          7268:                        if ((stop_code & ASC_STOP_CLEAN_UP_DISC_Q) == 0)
        !          7269:                                break;
        !          7270:                        DvcSleepMilliSecond(100);
        !          7271:                } while (count++ < 20);
        !          7272:        }
        !          7273:        return (1);
        !          7274: }
        !          7275: 
        !          7276: int
        !          7277: AscWaitTixISRDone(
        !          7278:                                         ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          7279:                                         uchar target_ix
        !          7280: )
        !          7281: {
        !          7282:        uchar               cur_req;
        !          7283:        uchar               tid_no;
        !          7284: 
        !          7285:        tid_no = ASC_TIX_TO_TID(target_ix);
        !          7286:        while (TRUE) {
        !          7287:                if ((cur_req = asc_dvc->cur_dvc_qng[tid_no]) == 0) {
        !          7288:                        break;
        !          7289:                }
        !          7290:                DvcSleepMilliSecond(1000L);
        !          7291:                if (asc_dvc->cur_dvc_qng[tid_no] == cur_req) {
        !          7292:                        break;
        !          7293:                }
        !          7294:        }
        !          7295:        return (1);
        !          7296: }
        !          7297: 
        !          7298: int
        !          7299: AscWaitISRDone(
        !          7300:                                  ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          7301: )
        !          7302: {
        !          7303:        int                 tid;
        !          7304: 
        !          7305:        for (tid = 0; tid <= ASC_MAX_TID; tid++) {
        !          7306:                AscWaitTixISRDone(asc_dvc, ASC_TID_TO_TIX(tid));
        !          7307:        }
        !          7308:        return (1);
        !          7309: }
        !          7310: 
        !          7311: ulong
        !          7312: AscGetOnePhyAddr(
        !          7313:                                        ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          7314:                                        uchar dosfar * buf_addr,
        !          7315:                                        ulong buf_size
        !          7316: )
        !          7317: {
        !          7318:        ASC_MIN_SG_HEAD     sg_head;
        !          7319: 
        !          7320:        sg_head.entry_cnt = ASC_MIN_SG_LIST;
        !          7321:        if (DvcGetSGList(asc_dvc, (uchar dosfar *) buf_addr,
        !          7322:                                  buf_size, (ASC_SG_HEAD dosfar *) & sg_head) != buf_size) {
        !          7323:                return (0L);
        !          7324:        }
        !          7325:        if (sg_head.entry_cnt > 1) {
        !          7326:                return (0L);
        !          7327:        }
        !          7328:        return (sg_head.sg_list[0].addr);
        !          7329: }
        !          7330: 
        !          7331: ulong
        !          7332: AscGetEisaProductID(
        !          7333:                                           PortAddr iop_base
        !          7334: )
        !          7335: {
        !          7336:        PortAddr            eisa_iop;
        !          7337:        ushort              product_id_high, product_id_low;
        !          7338:        ulong               product_id;
        !          7339: 
        !          7340:        eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK;
        !          7341:        product_id_low = inpw(eisa_iop);
        !          7342:        product_id_high = inpw(eisa_iop + 2);
        !          7343:        product_id = ((ulong) product_id_high << 16) | (ulong) product_id_low;
        !          7344:        return (product_id);
        !          7345: }
        !          7346: 
        !          7347: PortAddr
        !          7348: AscSearchIOPortAddrEISA(
        !          7349:                                                   PortAddr iop_base
        !          7350: )
        !          7351: {
        !          7352:        ulong               eisa_product_id;
        !          7353: 
        !          7354:        if (iop_base == 0) {
        !          7355:                iop_base = ASC_EISA_MIN_IOP_ADDR;
        !          7356:        } else {
        !          7357:                if (iop_base == ASC_EISA_MAX_IOP_ADDR)
        !          7358:                        return (0);
        !          7359:                if ((iop_base & 0x0050) == 0x0050) {
        !          7360:                        iop_base += ASC_EISA_BIG_IOP_GAP;
        !          7361:                } else {
        !          7362:                        iop_base += ASC_EISA_SMALL_IOP_GAP;
        !          7363:                }
        !          7364:        }
        !          7365:        while (iop_base <= ASC_EISA_MAX_IOP_ADDR) {
        !          7366: 
        !          7367:                eisa_product_id = AscGetEisaProductID(iop_base);
        !          7368:                if ((eisa_product_id == ASC_EISA_ID_740) ||
        !          7369:                        (eisa_product_id == ASC_EISA_ID_750)) {
        !          7370:                        if (AscFindSignature(iop_base)) {
        !          7371: 
        !          7372:                                inpw(iop_base + 4);
        !          7373:                                return (iop_base);
        !          7374:                        }
        !          7375:                }
        !          7376:                if (iop_base == ASC_EISA_MAX_IOP_ADDR)
        !          7377:                        return (0);
        !          7378:                if ((iop_base & 0x0050) == 0x0050) {
        !          7379:                        iop_base += ASC_EISA_BIG_IOP_GAP;
        !          7380:                } else {
        !          7381:                        iop_base += ASC_EISA_SMALL_IOP_GAP;
        !          7382:                }
        !          7383:        }
        !          7384:        return (0);
        !          7385: }
        !          7386: 
        !          7387: int
        !          7388: AscStartChip(
        !          7389:                                PortAddr iop_base
        !          7390: )
        !          7391: {
        !          7392:        AscSetChipControl(iop_base, 0);
        !          7393:        if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
        !          7394:                return (0);
        !          7395:        }
        !          7396:        return (1);
        !          7397: }
        !          7398: 
        !          7399: int
        !          7400: AscStopChip(
        !          7401:                           PortAddr iop_base
        !          7402: )
        !          7403: {
        !          7404:        uchar               cc_val;
        !          7405: 
        !          7406:        cc_val = AscGetChipControl(iop_base) & (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
        !          7407:        AscSetChipControl(iop_base, (uchar) (cc_val | CC_HALT));
        !          7408:        AscSetChipIH(iop_base, INS_HALT);
        !          7409:        AscSetChipIH(iop_base, INS_RFLAG_WTM);
        !          7410:        if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
        !          7411:                return (0);
        !          7412:        }
        !          7413:        return (1);
        !          7414: }
        !          7415: 
        !          7416: int
        !          7417: AscIsChipHalted(
        !          7418:                                   PortAddr iop_base
        !          7419: )
        !          7420: {
        !          7421: 
        !          7422:        if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
        !          7423:                if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
        !          7424:                        return (1);
        !          7425:                }
        !          7426:        }
        !          7427:        return (0);
        !          7428: }
        !          7429: 
        !          7430: void
        !          7431: AscSetChipIH(
        !          7432:                                PortAddr iop_base,
        !          7433:                                ushort ins_code
        !          7434: )
        !          7435: {
        !          7436:        AscSetBank(iop_base, 1);
        !          7437:        AscWriteChipIH(iop_base, ins_code);
        !          7438:        AscSetBank(iop_base, 0);
        !          7439:        return;
        !          7440: }
        !          7441: 
        !          7442: void
        !          7443: AscAckInterrupt(
        !          7444:                                   PortAddr iop_base
        !          7445: )
        !          7446: {
        !          7447: 
        !          7448:        uchar               host_flag;
        !          7449:        uchar               risc_flag;
        !          7450:        ushort              loop;
        !          7451: 
        !          7452:        loop = 0;
        !          7453:        do {
        !          7454:                risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
        !          7455:                if (loop++ > 0x7FFF) {
        !          7456:                        break;
        !          7457:                }
        !          7458:        } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
        !          7459: 
        !          7460:        host_flag = AscReadLramByte(iop_base, ASCV_HOST_FLAG_B);
        !          7461:        AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
        !          7462:                                         (uchar) (host_flag | ASC_HOST_FLAG_ACK_INT));
        !          7463: 
        !          7464:        AscSetChipStatus(iop_base, CIW_INT_ACK);
        !          7465:        loop = 0;
        !          7466:        while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
        !          7467: 
        !          7468:                AscSetChipStatus(iop_base, CIW_INT_ACK);
        !          7469:                if (loop++ > 3) {
        !          7470:                        break;
        !          7471:                }
        !          7472:        }
        !          7473: 
        !          7474:        AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
        !          7475:        return;
        !          7476: }
        !          7477: 
        !          7478: void
        !          7479: AscDisableInterrupt(
        !          7480:                                           PortAddr iop_base
        !          7481: )
        !          7482: {
        !          7483:        ushort              cfg;
        !          7484: 
        !          7485:        cfg = AscGetChipCfgLsw(iop_base);
        !          7486:        AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
        !          7487:        return;
        !          7488: }
        !          7489: 
        !          7490: void
        !          7491: AscEnableInterrupt(
        !          7492:                                          PortAddr iop_base
        !          7493: )
        !          7494: {
        !          7495:        ushort              cfg;
        !          7496: 
        !          7497:        cfg = AscGetChipCfgLsw(iop_base);
        !          7498:        AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
        !          7499:        return;
        !          7500: }
        !          7501: 
        !          7502: void
        !          7503: AscSetBank(
        !          7504:                          PortAddr iop_base,
        !          7505:                          uchar bank
        !          7506: )
        !          7507: {
        !          7508:        uchar               val;
        !          7509: 
        !          7510:        val = AscGetChipControl(iop_base) &
        !          7511:          (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET | CC_CHIP_RESET));
        !          7512:        if (bank == 1) {
        !          7513:                val |= CC_BANK_ONE;
        !          7514:        } else if (bank == 2) {
        !          7515:                val |= CC_DIAG | CC_BANK_ONE;
        !          7516:        } else {
        !          7517:                val &= ~CC_BANK_ONE;
        !          7518:        }
        !          7519:        AscSetChipControl(iop_base, val);
        !          7520:        return;
        !          7521: }
        !          7522: 
        !          7523: int
        !          7524: AscResetChipAndScsiBus(
        !          7525:                                                  PortAddr iop_base
        !          7526: )
        !          7527: {
        !          7528:        AscStopChip(iop_base);
        !          7529:        AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
        !          7530:        DvcSleepMilliSecond(200);
        !          7531: 
        !          7532:        AscSetChipIH(iop_base, INS_RFLAG_WTM);
        !          7533:        AscSetChipIH(iop_base, INS_HALT);
        !          7534: 
        !          7535:        AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
        !          7536:        AscSetChipControl(iop_base, CC_HALT);
        !          7537:        DvcSleepMilliSecond(200);
        !          7538:        return (AscIsChipHalted(iop_base));
        !          7539: }
        !          7540: 
        !          7541: ushort
        !          7542: AscGetIsaDmaChannel(
        !          7543:                                           PortAddr iop_base
        !          7544: )
        !          7545: {
        !          7546:        ushort              channel;
        !          7547: 
        !          7548:        channel = AscGetChipCfgLsw(iop_base) & 0x0003;
        !          7549:        if (channel == 0x03)
        !          7550:                return (0);
        !          7551:        else if (channel == 0x00)
        !          7552:                return (7);
        !          7553:        return (channel + 4);
        !          7554: }
        !          7555: 
        !          7556: ushort
        !          7557: AscSetIsaDmaChannel(
        !          7558:                                           PortAddr iop_base,
        !          7559:                                           ushort dma_channel
        !          7560: )
        !          7561: {
        !          7562:        ushort              cfg_lsw;
        !          7563:        uchar               value;
        !          7564: 
        !          7565:        if ((dma_channel >= 5) && (dma_channel <= 7)) {
        !          7566: 
        !          7567:                if (dma_channel == 7)
        !          7568:                        value = 0x00;
        !          7569:                else
        !          7570:                        value = dma_channel - 4;
        !          7571:                cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
        !          7572:                cfg_lsw |= value;
        !          7573:                AscSetChipCfgLsw(iop_base, cfg_lsw);
        !          7574:                return (AscGetIsaDmaChannel(iop_base));
        !          7575:        }
        !          7576:        return (0);
        !          7577: }
        !          7578: 
        !          7579: uchar
        !          7580: AscSetIsaDmaSpeed(
        !          7581:                                         PortAddr iop_base,
        !          7582:                                         uchar speed_value
        !          7583: )
        !          7584: {
        !          7585:        speed_value &= 0x07;
        !          7586:        AscSetBank(iop_base, 1);
        !          7587:        AscSetChipDmaSpeed(iop_base, speed_value);
        !          7588:        AscSetBank(iop_base, 0);
        !          7589:        return (AscGetIsaDmaSpeed(iop_base));
        !          7590: }
        !          7591: 
        !          7592: uchar
        !          7593: AscGetIsaDmaSpeed(
        !          7594:                                         PortAddr iop_base
        !          7595: )
        !          7596: {
        !          7597:        uchar               speed_value;
        !          7598: 
        !          7599:        AscSetBank(iop_base, 1);
        !          7600:        speed_value = AscGetChipDmaSpeed(iop_base);
        !          7601:        speed_value &= 0x07;
        !          7602:        AscSetBank(iop_base, 0);
        !          7603:        return (speed_value);
        !          7604: }
        !          7605: 
        !          7606: ulong
        !          7607: AscGetMaxDmaCount(
        !          7608:                                         ushort bus_type
        !          7609: )
        !          7610: {
        !          7611:        if (bus_type & ASC_IS_ISA)
        !          7612:                return (ASC_MAX_ISA_DMA_COUNT);
        !          7613:        else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
        !          7614:                return (ASC_MAX_VL_DMA_COUNT);
        !          7615:        return (ASC_MAX_PCI_DMA_COUNT);
        !          7616: }
        !          7617: 
        !          7618: ushort
        !          7619: AscInitGetConfig(
        !          7620:                                        ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          7621: )
        !          7622: {
        !          7623:        ushort              warn_code;
        !          7624: 
        !          7625:        warn_code = 0;
        !          7626:        asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
        !          7627:        if (asc_dvc->err_code != 0)
        !          7628:                return (UW_ERR);
        !          7629:        if (AscFindSignature(asc_dvc->iop_base)) {
        !          7630:                warn_code |= AscInitAscDvcVar(asc_dvc);
        !          7631:                warn_code |= AscInitFromEEP(asc_dvc);
        !          7632:                asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
        !          7633: 
        !          7634:                if (asc_dvc->scsi_reset_wait > 10)
        !          7635:                        asc_dvc->scsi_reset_wait = 10;
        !          7636: 
        !          7637:        } else {
        !          7638:                asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
        !          7639:        }
        !          7640:        return (warn_code);
        !          7641: }
        !          7642: 
        !          7643: ushort
        !          7644: AscInitSetConfig(
        !          7645:                                        ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          7646: )
        !          7647: {
        !          7648:        ushort              warn_code;
        !          7649: 
        !          7650:        warn_code = 0;
        !          7651:        asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
        !          7652:        if (asc_dvc->err_code != 0)
        !          7653:                return (UW_ERR);
        !          7654:        if (AscFindSignature(asc_dvc->iop_base)) {
        !          7655:                warn_code |= AscInitFromAscDvcVar(asc_dvc);
        !          7656:                asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
        !          7657:        } else {
        !          7658:                asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
        !          7659:        }
        !          7660:        return (warn_code);
        !          7661: }
        !          7662: 
        !          7663: ushort
        !          7664: AscInitAsc1000Driver(
        !          7665:                                                ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          7666: )
        !          7667: {
        !          7668:        ushort              warn_code;
        !          7669:        PortAddr            iop_base;
        !          7670: 
        !          7671:        extern ushort       _mcode_size;
        !          7672:        extern ulong        _mcode_chksum;
        !          7673:        extern uchar        _mcode_buf[];
        !          7674: 
        !          7675:        ASC_DBG(3, "AscInitAsc1000Driver: begin\n");
        !          7676:        iop_base = asc_dvc->iop_base;
        !          7677:        warn_code = 0;
        !          7678: 
        !          7679:        if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
        !          7680:                !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
        !          7681: 
        !          7682:                ASC_DBG(3, "AscInitAsc1000Driver: AscResetChipAndScsiBus()\n");
        !          7683:                AscResetChipAndScsiBus(iop_base);
        !          7684:                DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
        !          7685:        }
        !          7686:        asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
        !          7687:        if (asc_dvc->err_code != 0)
        !          7688:                return (UW_ERR);
        !          7689:        ASC_DBG(3, "AscInitAsc1000Driver: AscFindSignature()\n");
        !          7690:        if (!AscFindSignature(asc_dvc->iop_base)) {
        !          7691:                asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
        !          7692:                return (warn_code);
        !          7693:        }
        !          7694:        ASC_DBG(3, "AscInitAsc1000Driver: AscDisableInterrupt()\n");
        !          7695:        AscDisableInterrupt(iop_base);
        !          7696: 
        !          7697:        ASC_DBG(3, "AscInitAsc1000Driver: AscInitLram()\n");
        !          7698:        warn_code |= AscInitLram(asc_dvc);
        !          7699:        if (asc_dvc->err_code != 0)
        !          7700:                return (UW_ERR);
        !          7701:        ASC_DBG(3, "AscInitAsc1000Driver: AscLoadMicroCode()\n");
        !          7702:        if (AscLoadMicroCode(iop_base, 0, (ushort dosfar *) _mcode_buf,
        !          7703:                                                 _mcode_size) != _mcode_chksum) {
        !          7704:                asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
        !          7705:                return (warn_code);
        !          7706:        }
        !          7707:        ASC_DBG(3, "AscInitAsc1000Driver: AscInitMicroCodeVar()\n");
        !          7708:        warn_code |= AscInitMicroCodeVar(asc_dvc);
        !          7709:        asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
        !          7710:        ASC_DBG(3, "AscInitAsc1000Driver: AscEnableInterrupt()\n");
        !          7711:        AscEnableInterrupt(iop_base);
        !          7712:        return (warn_code);
        !          7713: }
        !          7714: 
        !          7715: ushort
        !          7716: AscInitAscDvcVar(
        !          7717:                                        ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          7718: )
        !          7719: {
        !          7720:        int                 i;
        !          7721:        PortAddr            iop_base;
        !          7722:        ushort              warn_code;
        !          7723: 
        !          7724:        iop_base = asc_dvc->iop_base;
        !          7725:        warn_code = 0;
        !          7726:        asc_dvc->err_code = 0;
        !          7727: 
        !          7728:        if ((asc_dvc->bus_type &
        !          7729:                 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
        !          7730:                asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
        !          7731:        }
        !          7732: #if CC_LINK_BUSY_Q
        !          7733:        for (i = 0; i <= ASC_MAX_TID; i++) {
        !          7734:                asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q dosfar *) 0L;
        !          7735:                asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q dosfar *) 0L;
        !          7736:        }
        !          7737: #endif
        !          7738: 
        !          7739:        asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
        !          7740:        asc_dvc->bug_fix_cntl = 0;
        !          7741:        asc_dvc->pci_fix_asyn_xfer = 0;
        !          7742:        asc_dvc->init_sdtr = 0;
        !          7743:        asc_dvc->sdtr_done = 0;
        !          7744:        asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
        !          7745:        asc_dvc->cur_total_qng = 0;
        !          7746:        asc_dvc->is_in_int = 0;
        !          7747:        asc_dvc->scsi_reset_wait = 3;
        !          7748:        asc_dvc->in_critical_cnt = 0;
        !          7749: 
        !          7750:        asc_dvc->last_q_shortage = 0;
        !          7751:        asc_dvc->use_tagged_qng = 0;
        !          7752:        asc_dvc->cfg->can_tagged_qng = 0;
        !          7753:        asc_dvc->no_scam = 0;
        !          7754:        asc_dvc->irq_no = 10;
        !          7755:        asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
        !          7756:        asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
        !          7757:        asc_dvc->cfg->cmd_qng_enabled = ASC_SCSI_WIDTH_BIT_SET;
        !          7758:        asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
        !          7759:        asc_dvc->cfg->chip_version = AscGetChipVersion(iop_base,
        !          7760:                                                                                                   asc_dvc->bus_type);
        !          7761:        if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
        !          7762: 
        !          7763:                AscPutChipIFC(iop_base, IFC_INIT_DEFAULT);
        !          7764:                asc_dvc->bus_type = ASC_IS_ISAPNP;
        !          7765:        }
        !          7766:        asc_dvc->unit_not_ready = 0;
        !          7767:        asc_dvc->queue_full_or_busy = 0;
        !          7768: 
        !          7769:        if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
        !          7770:                asc_dvc->cfg->isa_dma_channel = (uchar) AscGetIsaDmaChannel(iop_base);
        !          7771:                asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
        !          7772:        }
        !          7773:        asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
        !          7774:        asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
        !          7775:          ASC_LIB_VERSION_MINOR;
        !          7776:        asc_dvc->int_count = 0L;
        !          7777:        asc_dvc->req_count = 0L;
        !          7778:        asc_dvc->busy_count = 0L;
        !          7779:        asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
        !          7780: 
        !          7781:        for (i = 0; i <= ASC_MAX_TID; i++) {
        !          7782:                asc_dvc->cfg->sdtr_data[i] =
        !          7783:                  (uchar) (ASC_DEF_SDTR_OFFSET | (ASC_DEF_SDTR_INDEX << 4));
        !          7784:                asc_dvc->cur_dvc_qng[i] = 0;
        !          7785:                asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
        !          7786:                asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q dosfar *) 0L;
        !          7787:                asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q dosfar *) 0L;
        !          7788:        }
        !          7789:        return (warn_code);
        !          7790: }
        !          7791: 
        !          7792: ushort
        !          7793: AscInitFromAscDvcVar(
        !          7794:                                                ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          7795: )
        !          7796: {
        !          7797:        PortAddr            iop_base;
        !          7798:        ushort              cfg_msw;
        !          7799:        ushort              warn_code;
        !          7800: 
        !          7801:        iop_base = asc_dvc->iop_base;
        !          7802:        warn_code = 0;
        !          7803: 
        !          7804:        cfg_msw = AscGetChipCfgMsw(iop_base);
        !          7805: 
        !          7806:        if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
        !          7807:                cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
        !          7808:                warn_code |= ASC_WARN_CFG_MSW_RECOVER;
        !          7809:                AscSetChipCfgMsw(iop_base, cfg_msw);
        !          7810:        }
        !          7811:        if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
        !          7812:                warn_code |= ASC_WARN_AUTO_CONFIG;
        !          7813: 
        !          7814:        }
        !          7815:        if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
        !          7816:                asc_dvc->cfg->cmd_qng_enabled) {
        !          7817:                asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
        !          7818:                warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
        !          7819:        }
        !          7820:        if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
        !          7821: 
        !          7822:                if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
        !          7823:                        != asc_dvc->irq_no) {
        !          7824:                        asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
        !          7825:                }
        !          7826:        }
        !          7827:        if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
        !          7828:                asc_dvc->cfg->chip_scsi_id) {
        !          7829:                asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
        !          7830:        }
        !          7831:        if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
        !          7832:                AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
        !          7833:                AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
        !          7834:        }
        !          7835:        return (warn_code);
        !          7836: }
        !          7837: 
        !          7838: ushort
        !          7839: AscInitFromEEP(
        !          7840:                                  ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          7841: )
        !          7842: {
        !          7843:        ASCEEP_CONFIG       eep_config_buf;
        !          7844:        ASCEEP_CONFIG dosfar *eep_config;
        !          7845:        PortAddr            iop_base;
        !          7846:        ushort              chksum;
        !          7847:        ushort              warn_code;
        !          7848:        ushort              cfg_msw, cfg_lsw;
        !          7849:        uchar               i;
        !          7850: 
        !          7851:        iop_base = asc_dvc->iop_base;
        !          7852:        warn_code = 0;
        !          7853: 
        !          7854:        AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
        !          7855: 
        !          7856:        AscStopQueueExe(iop_base);
        !          7857:        if ((AscStopChip(iop_base) == FALSE) ||
        !          7858:                (AscGetChipScsiCtrl(iop_base) != 0)) {
        !          7859:                asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
        !          7860:                AscResetChipAndScsiBus(iop_base);
        !          7861:                DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
        !          7862:        }
        !          7863:        if (AscIsChipHalted(iop_base) == FALSE) {
        !          7864:                asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
        !          7865:                return (warn_code);
        !          7866:        }
        !          7867:        AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
        !          7868:        if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
        !          7869:                asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
        !          7870:                return (warn_code);
        !          7871:        }
        !          7872:        eep_config = (ASCEEP_CONFIG dosfar *) & eep_config_buf;
        !          7873: 
        !          7874:        cfg_msw = AscGetChipCfgMsw(iop_base);
        !          7875:        cfg_lsw = AscGetChipCfgLsw(iop_base);
        !          7876: 
        !          7877:        if (asc_dvc->bus_type & ASC_IS_PCI) {
        !          7878: #if CC_DISABLE_PCI_PARITY_INT
        !          7879:                cfg_msw &= 0xFFC0;
        !          7880:                AscSetChipCfgMsw(iop_base, cfg_msw);
        !          7881: #endif
        !          7882:                if (asc_dvc->cfg->pci_device_id == ASC_PCI_DEVICE_ID_REV_A) {
        !          7883:                        asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ADD_ONE_BYTE;
        !          7884:                }
        !          7885:        }
        !          7886:        if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
        !          7887:                cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
        !          7888:                warn_code |= ASC_WARN_CFG_MSW_RECOVER;
        !          7889:                AscSetChipCfgMsw(iop_base, cfg_msw);
        !          7890:        }
        !          7891:        chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
        !          7892: 
        !          7893:        eep_config->cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
        !          7894: 
        !          7895:        if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
        !          7896:                warn_code |= ASC_WARN_AUTO_CONFIG;
        !          7897: 
        !          7898:                if (asc_dvc->cfg->chip_version == 3) {
        !          7899: 
        !          7900:                        if (eep_config->cfg_lsw != cfg_lsw) {
        !          7901:                                warn_code |= ASC_WARN_EEPROM_RECOVER;
        !          7902:                                eep_config->cfg_lsw = AscGetChipCfgLsw(iop_base);
        !          7903:                        }
        !          7904:                        if (eep_config->cfg_msw != cfg_msw) {
        !          7905:                                warn_code |= ASC_WARN_EEPROM_RECOVER;
        !          7906:                                eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
        !          7907:                        }
        !          7908:                }
        !          7909:        }
        !          7910:        eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
        !          7911:        if (chksum != eep_config->chksum) {
        !          7912:                warn_code |= ASC_WARN_EEPROM_CHKSUM;
        !          7913:        }
        !          7914:        asc_dvc->init_sdtr = eep_config->init_sdtr;
        !          7915:        asc_dvc->cfg->disc_enable = eep_config->disc_enable;
        !          7916: 
        !          7917:        asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
        !          7918:        asc_dvc->cfg->isa_dma_speed = eep_config->isa_dma_speed;
        !          7919:        asc_dvc->start_motor = eep_config->start_motor;
        !          7920:        asc_dvc->dvc_cntl = eep_config->cntl;
        !          7921:        asc_dvc->no_scam = eep_config->no_scam;
        !          7922: 
        !          7923:        if ((asc_dvc->bus_type & ASC_IS_PCI) &&
        !          7924:                !(asc_dvc->dvc_cntl & ASC_CNTL_NO_PCI_FIX_ASYN_XFER)) {
        !          7925:                if ((asc_dvc->cfg->pci_device_id == ASC_PCI_DEVICE_ID_REV_A) ||
        !          7926:                        (asc_dvc->cfg->pci_device_id == ASC_PCI_DEVICE_ID_REV_B)) {
        !          7927:                        asc_dvc->pci_fix_asyn_xfer = ASC_ALL_DEVICE_BIT_SET;
        !          7928:                }
        !          7929:        } else if (asc_dvc->bus_type & ASC_IS_ISAPNP) {
        !          7930: 
        !          7931:                if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
        !          7932:                        == ASC_CHIP_VER_ASYN_BUG) {
        !          7933:                        asc_dvc->pci_fix_asyn_xfer = ASC_ALL_DEVICE_BIT_SET;
        !          7934:                }
        !          7935:        }
        !          7936:        if (!AscTestExternalLram(asc_dvc)) {
        !          7937:                if (asc_dvc->bus_type & ASC_IS_PCI) {
        !          7938:                        eep_config->cfg_msw |= 0x0800;
        !          7939:                        cfg_msw |= 0x0800;
        !          7940:                        AscSetChipCfgMsw(iop_base, cfg_msw);
        !          7941:                        eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
        !          7942:                        eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
        !          7943:                }
        !          7944:        } else {
        !          7945: #if CC_TEST_RW_LRAM
        !          7946:                asc_dvc->err_code |= AscTestLramEndian(iop_base);
        !          7947: #endif
        !          7948:        }
        !          7949:        if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
        !          7950:                eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
        !          7951:        }
        !          7952:        if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
        !          7953:                eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
        !          7954:        }
        !          7955:        if (eep_config->max_tag_qng > eep_config->max_total_qng) {
        !          7956:                eep_config->max_tag_qng = eep_config->max_total_qng;
        !          7957:        }
        !          7958:        if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
        !          7959:                eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
        !          7960:        }
        !          7961:        asc_dvc->max_total_qng = eep_config->max_total_qng;
        !          7962: 
        !          7963:        if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
        !          7964:                eep_config->use_cmd_qng) {
        !          7965:                eep_config->disc_enable = eep_config->use_cmd_qng;
        !          7966:                warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
        !          7967:        }
        !          7968:        asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
        !          7969:        eep_config->chip_scsi_id &= ASC_MAX_TID;
        !          7970:        asc_dvc->cfg->chip_scsi_id = eep_config->chip_scsi_id;
        !          7971: 
        !          7972:        for (i = 0; i <= ASC_MAX_TID; i++) {
        !          7973:                asc_dvc->cfg->sdtr_data[i] = eep_config->sdtr_data[i];
        !          7974:                asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
        !          7975:        }
        !          7976: 
        !          7977:        eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
        !          7978:        if (AscSetEEPConfig(iop_base, eep_config, asc_dvc->bus_type) != 0) {
        !          7979:                asc_dvc->err_code |= ASC_IERR_WRITE_EEPROM;
        !          7980:        }
        !          7981:        return (warn_code);
        !          7982: }
        !          7983: 
        !          7984: ushort
        !          7985: AscInitMicroCodeVar(
        !          7986:                                           ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          7987: )
        !          7988: {
        !          7989:        int                 i;
        !          7990:        ushort              warn_code;
        !          7991:        PortAddr            iop_base;
        !          7992:        ulong               phy_addr;
        !          7993: 
        !          7994:        iop_base = asc_dvc->iop_base;
        !          7995:        warn_code = 0;
        !          7996:        for (i = 0; i <= ASC_MAX_TID; i++) {
        !          7997:                AscWriteLramByte(iop_base, (ushort) (ASCV_SDTR_DATA_BEG + i),
        !          7998:                                                 asc_dvc->cfg->sdtr_data[i]);
        !          7999:        }
        !          8000: 
        !          8001:        AscInitQLinkVar(asc_dvc);
        !          8002: 
        !          8003:        AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
        !          8004:                                         asc_dvc->cfg->disc_enable);
        !          8005:        AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
        !          8006:                                         ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
        !          8007:        if ((phy_addr = AscGetOnePhyAddr(asc_dvc,
        !          8008:                                                                 (uchar dosfar *) asc_dvc->cfg->overrun_buf,
        !          8009:                                                                         ASC_OVERRUN_BSIZE)) == 0L) {
        !          8010:                asc_dvc->err_code |= ASC_IERR_GET_PHY_ADDR;
        !          8011:        } else {
        !          8012: 
        !          8013:                phy_addr = (phy_addr & 0xFFFFFFF8UL) + 8;
        !          8014:                AscWriteLramDWord(iop_base, ASCV_OVERRUN_PADDR_D, phy_addr);
        !          8015:                AscWriteLramDWord(iop_base, ASCV_OVERRUN_BSIZE_D,
        !          8016:                                                  ASC_OVERRUN_BSIZE - 8);
        !          8017:        }
        !          8018: 
        !          8019:        asc_dvc->cfg->mcode_date = AscReadLramWord(iop_base,
        !          8020:                                                                                           (ushort) ASCV_MC_DATE_W);
        !          8021:        asc_dvc->cfg->mcode_version = AscReadLramWord(iop_base,
        !          8022:                                                                                                  (ushort) ASCV_MC_VER_W);
        !          8023:        AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
        !          8024:        if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
        !          8025:                asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
        !          8026:                return (warn_code);
        !          8027:        }
        !          8028:        if (AscStartChip(iop_base) != 1) {
        !          8029:                asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
        !          8030:                return (warn_code);
        !          8031:        }
        !          8032:        return (warn_code);
        !          8033: }
        !          8034: 
        !          8035: void                dosfar
        !          8036: AscInitPollIsrCallBack(
        !          8037:                                                  ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          8038:                                                  ASC_QDONE_INFO dosfar * scsi_done_q
        !          8039: )
        !          8040: {
        !          8041:        ASC_SCSI_REQ_Q dosfar *scsiq_req;
        !          8042:        ASC_ISR_CALLBACK    asc_isr_callback;
        !          8043:        uchar               cp_sen_len;
        !          8044:        uchar               i;
        !          8045: 
        !          8046:        if ((scsi_done_q->d2.flag & ASC_FLAG_SCSIQ_REQ) != 0) {
        !          8047:                scsiq_req = (ASC_SCSI_REQ_Q dosfar *) scsi_done_q->d2.srb_ptr;
        !          8048:                ASC_DBG2(3, "AscInitPollIsrCallBack: done_stat %x, host_stat %x\n",
        !          8049:                                 scsiq_req->r3.done_stat, scsiq_req->r3.host_stat);
        !          8050:                scsiq_req->r3.done_stat = scsi_done_q->d3.done_stat;
        !          8051:                scsiq_req->r3.host_stat = scsi_done_q->d3.host_stat;
        !          8052:                scsiq_req->r3.scsi_stat = scsi_done_q->d3.scsi_stat;
        !          8053:                scsiq_req->r3.scsi_msg = scsi_done_q->d3.scsi_msg;
        !          8054:                if ((scsi_done_q->d3.scsi_stat == SS_CHK_CONDITION) &&
        !          8055:                        (scsi_done_q->d3.host_stat == 0)) {
        !          8056:                        cp_sen_len = (uchar) ASC_MIN_SENSE_LEN;
        !          8057:                        if (scsiq_req->r1.sense_len < ASC_MIN_SENSE_LEN) {
        !          8058:                                cp_sen_len = (uchar) scsiq_req->r1.sense_len;
        !          8059:                        }
        !          8060:                        for (i = 0; i < cp_sen_len; i++) {
        !          8061:                                scsiq_req->sense[i] = scsiq_req->sense_ptr[i];
        !          8062:                        }
        !          8063:                }
        !          8064:        } else {
        !          8065:                ASC_DBG1(3, "AscInitPollIsrCallBack: isr_callback %x\n",
        !          8066:                                 (unsigned) asc_dvc->isr_callback);
        !          8067:                if (asc_dvc->isr_callback != 0) {
        !          8068:                        asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
        !          8069:                        (*asc_isr_callback) (asc_dvc, scsi_done_q);
        !          8070:                }
        !          8071:        }
        !          8072:        return;
        !          8073: }
        !          8074: 
        !          8075: int
        !          8076: AscTestExternalLram(
        !          8077:                                           ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          8078: )
        !          8079: {
        !          8080:        PortAddr            iop_base;
        !          8081:        ushort              q_addr;
        !          8082:        ushort              saved_word;
        !          8083:        int                 sta;
        !          8084: 
        !          8085:        iop_base = asc_dvc->iop_base;
        !          8086:        sta = 0;
        !          8087: 
        !          8088:        q_addr = ASC_QNO_TO_QADDR(241);
        !          8089:        saved_word = AscReadLramWord(iop_base, q_addr);
        !          8090:        if (AscVerWriteLramWord(iop_base, q_addr, 0x55AA) == 0) {
        !          8091:                sta = 1;
        !          8092:                AscWriteLramWord(iop_base, q_addr, saved_word);
        !          8093:        }
        !          8094:        return (sta);
        !          8095: }
        !          8096: 
        !          8097: #if CC_TEST_LRAM_ENDIAN
        !          8098: 
        !          8099: #endif
        !          8100: 
        !          8101: int
        !          8102: AscWriteEEPCmdReg(
        !          8103:                                         PortAddr iop_base,
        !          8104:                                         uchar cmd_reg
        !          8105: )
        !          8106: {
        !          8107:        uchar               read_back;
        !          8108:        int                 retry;
        !          8109: 
        !          8110:        retry = 0;
        !          8111:        while (TRUE) {
        !          8112:                AscSetChipEEPCmd(iop_base, cmd_reg);
        !          8113:                DvcSleepMilliSecond(1);
        !          8114:                read_back = AscGetChipEEPCmd(iop_base);
        !          8115:                if (read_back == cmd_reg) {
        !          8116:                        return (1);
        !          8117:                }
        !          8118:                if (retry++ > ASC_EEP_MAX_RETRY) {
        !          8119:                        return (0);
        !          8120:                }
        !          8121:        }
        !          8122: }
        !          8123: 
        !          8124: int
        !          8125: AscWriteEEPDataReg(
        !          8126:                                          PortAddr iop_base,
        !          8127:                                          ushort data_reg
        !          8128: )
        !          8129: {
        !          8130:        ushort              read_back;
        !          8131:        int                 retry;
        !          8132: 
        !          8133:        retry = 0;
        !          8134:        while (TRUE) {
        !          8135:                AscSetChipEEPData(iop_base, data_reg);
        !          8136:                DvcSleepMilliSecond(1);
        !          8137:                read_back = AscGetChipEEPData(iop_base);
        !          8138:                if (read_back == data_reg) {
        !          8139:                        return (1);
        !          8140:                }
        !          8141:                if (retry++ > ASC_EEP_MAX_RETRY) {
        !          8142:                        return (0);
        !          8143:                }
        !          8144:        }
        !          8145: }
        !          8146: 
        !          8147: void
        !          8148: AscWaitEEPRead(
        !          8149:                                  void
        !          8150: )
        !          8151: {
        !          8152:        DvcSleepMilliSecond(1);
        !          8153:        return;
        !          8154: }
        !          8155: 
        !          8156: void
        !          8157: AscWaitEEPWrite(
        !          8158:                                   void
        !          8159: )
        !          8160: {
        !          8161:        DvcSleepMilliSecond(20);
        !          8162:        return;
        !          8163: }
        !          8164: 
        !          8165: ushort
        !          8166: AscReadEEPWord(
        !          8167:                                  PortAddr iop_base,
        !          8168:                                  uchar addr
        !          8169: )
        !          8170: {
        !          8171:        ushort              read_wval;
        !          8172:        uchar               cmd_reg;
        !          8173: 
        !          8174:        AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
        !          8175:        AscWaitEEPRead();
        !          8176:        cmd_reg = addr | ASC_EEP_CMD_READ;
        !          8177:        AscWriteEEPCmdReg(iop_base, cmd_reg);
        !          8178:        AscWaitEEPRead();
        !          8179:        read_wval = AscGetChipEEPData(iop_base);
        !          8180:        AscWaitEEPRead();
        !          8181:        return (read_wval);
        !          8182: }
        !          8183: 
        !          8184: ushort
        !          8185: AscWriteEEPWord(
        !          8186:                                   PortAddr iop_base,
        !          8187:                                   uchar addr,
        !          8188:                                   ushort word_val
        !          8189: )
        !          8190: {
        !          8191:        ushort              read_wval;
        !          8192: 
        !          8193:        read_wval = AscReadEEPWord(iop_base, addr);
        !          8194:        if (read_wval != word_val) {
        !          8195:                AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
        !          8196:                AscWaitEEPRead();
        !          8197: 
        !          8198:                AscWriteEEPDataReg(iop_base, word_val);
        !          8199:                AscWaitEEPRead();
        !          8200: 
        !          8201:                AscWriteEEPCmdReg(iop_base,
        !          8202:                                                  (uchar) ((uchar) ASC_EEP_CMD_WRITE | addr));
        !          8203:                AscWaitEEPWrite();
        !          8204: 
        !          8205:                AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
        !          8206:                AscWaitEEPRead();
        !          8207:                return (AscReadEEPWord(iop_base, addr));
        !          8208:        }
        !          8209:        return (read_wval);
        !          8210: }
        !          8211: 
        !          8212: ushort
        !          8213: AscGetEEPConfig(
        !          8214:                                   PortAddr iop_base,
        !          8215:                                   ASCEEP_CONFIG dosfar * cfg_buf, ushort bus_type
        !          8216: )
        !          8217: {
        !          8218:        ushort              wval;
        !          8219:        ushort              sum;
        !          8220:        ushort dosfar      *wbuf;
        !          8221:        int                 cfg_beg;
        !          8222:        int                 cfg_end;
        !          8223:        int                 s_addr;
        !          8224:        int                 isa_pnp_wsize;
        !          8225: 
        !          8226:        wbuf = (ushort dosfar *) cfg_buf;
        !          8227:        sum = 0;
        !          8228: 
        !          8229:        isa_pnp_wsize = 0;
        !          8230:        for (s_addr = 0; s_addr < (2 + isa_pnp_wsize); s_addr++, wbuf++) {
        !          8231:                wval = AscReadEEPWord(iop_base, (uchar) s_addr);
        !          8232:                sum += wval;
        !          8233:                *wbuf = wval;
        !          8234:        }
        !          8235: 
        !          8236:        if (bus_type & ASC_IS_VL) {
        !          8237:                cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
        !          8238:                cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
        !          8239:        } else {
        !          8240:                cfg_beg = ASC_EEP_DVC_CFG_BEG;
        !          8241:                cfg_end = ASC_EEP_MAX_DVC_ADDR;
        !          8242:        }
        !          8243: 
        !          8244:        for (s_addr = cfg_beg; s_addr <= (cfg_end - 1);
        !          8245:                 s_addr++, wbuf++) {
        !          8246:                wval = AscReadEEPWord(iop_base, (uchar) s_addr);
        !          8247:                sum += wval;
        !          8248:                *wbuf = wval;
        !          8249:        }
        !          8250:        *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
        !          8251:        return (sum);
        !          8252: }
        !          8253: 
        !          8254: int
        !          8255: AscSetEEPConfigOnce(
        !          8256:                                           PortAddr iop_base,
        !          8257:                                           ASCEEP_CONFIG dosfar * cfg_buf, ushort bus_type
        !          8258: )
        !          8259: {
        !          8260:        int                 n_error;
        !          8261:        ushort dosfar      *wbuf;
        !          8262:        ushort              sum;
        !          8263:        int                 s_addr;
        !          8264:        int                 cfg_beg;
        !          8265:        int                 cfg_end;
        !          8266: 
        !          8267:        wbuf = (ushort dosfar *) cfg_buf;
        !          8268:        n_error = 0;
        !          8269:        sum = 0;
        !          8270:        for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
        !          8271:                sum += *wbuf;
        !          8272:                if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
        !          8273:                        n_error++;
        !          8274:                }
        !          8275:        }
        !          8276:        if (bus_type & ASC_IS_VL) {
        !          8277:                cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
        !          8278:                cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
        !          8279:        } else {
        !          8280:                cfg_beg = ASC_EEP_DVC_CFG_BEG;
        !          8281:                cfg_end = ASC_EEP_MAX_DVC_ADDR;
        !          8282:        }
        !          8283:        for (s_addr = cfg_beg; s_addr <= (cfg_end - 1);
        !          8284:                 s_addr++, wbuf++) {
        !          8285:                sum += *wbuf;
        !          8286:                if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
        !          8287:                        n_error++;
        !          8288:                }
        !          8289:        }
        !          8290:        *wbuf = sum;
        !          8291:        if (sum != AscWriteEEPWord(iop_base, (uchar) s_addr, sum)) {
        !          8292:                n_error++;
        !          8293:        }
        !          8294:        wbuf = (ushort dosfar *) cfg_buf;
        !          8295:        for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
        !          8296:                if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
        !          8297:                        n_error++;
        !          8298:                }
        !          8299:        }
        !          8300:        for (s_addr = cfg_beg; s_addr <= cfg_end;
        !          8301:                 s_addr++, wbuf++) {
        !          8302:                if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
        !          8303:                        n_error++;
        !          8304:                }
        !          8305:        }
        !          8306:        return (n_error);
        !          8307: }
        !          8308: 
        !          8309: int
        !          8310: AscSetEEPConfig(
        !          8311:                                   PortAddr iop_base,
        !          8312:                                   ASCEEP_CONFIG dosfar * cfg_buf, ushort bus_type
        !          8313: )
        !          8314: {
        !          8315:        int                 retry;
        !          8316:        int                 n_error;
        !          8317: 
        !          8318:        retry = 0;
        !          8319:        while (TRUE) {
        !          8320:                if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
        !          8321:                                                                                   bus_type)) == 0) {
        !          8322:                        break;
        !          8323:                }
        !          8324:                if (++retry > ASC_EEP_MAX_RETRY) {
        !          8325:                        break;
        !          8326:                }
        !          8327:        }
        !          8328:        return (n_error);
        !          8329: }
        !          8330: 
        !          8331: int
        !          8332: AscInitPollBegin(
        !          8333:                                        ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          8334: )
        !          8335: {
        !          8336:        PortAddr            iop_base;
        !          8337: 
        !          8338:        iop_base = asc_dvc->iop_base;
        !          8339: 
        !          8340: #if CC_INIT_INQ_DISPLAY
        !          8341:        DvcDisplayString((uchar dosfar *) "\r\n");
        !          8342: #endif
        !          8343: 
        !          8344:        AscDisableInterrupt(iop_base);
        !          8345: 
        !          8346:        asc_dvc->init_state |= ASC_INIT_STATE_BEG_INQUIRY;
        !          8347: 
        !          8348:        AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B, 0x00);
        !          8349:        asc_dvc->use_tagged_qng = 0;
        !          8350:        asc_dvc->cfg->can_tagged_qng = 0;
        !          8351:        asc_dvc->saved_ptr2func = (ulong) asc_dvc->isr_callback;
        !          8352:        asc_dvc->isr_callback = ASC_GET_PTR2FUNC(AscInitPollIsrCallBack);
        !          8353:        return (0);
        !          8354: }
        !          8355: 
        !          8356: int
        !          8357: AscInitPollEnd(
        !          8358:                                  ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          8359: )
        !          8360: {
        !          8361:        PortAddr            iop_base;
        !          8362:        int                 i;
        !          8363: 
        !          8364:        iop_base = asc_dvc->iop_base;
        !          8365:        asc_dvc->isr_callback = (Ptr2Func) asc_dvc->saved_ptr2func;
        !          8366:        AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
        !          8367:                                         asc_dvc->cfg->disc_enable);
        !          8368:        AscWriteLramByte(iop_base, ASCV_USE_TAGGED_QNG_B,
        !          8369:                                         asc_dvc->use_tagged_qng);
        !          8370:        AscWriteLramByte(iop_base, ASCV_CAN_TAGGED_QNG_B,
        !          8371:                                         asc_dvc->cfg->can_tagged_qng);
        !          8372: 
        !          8373:        for (i = 0; i <= ASC_MAX_TID; i++) {
        !          8374:                AscWriteLramByte(iop_base,
        !          8375:                                          (ushort) ((ushort) ASCV_MAX_DVC_QNG_BEG + (ushort) i),
        !          8376:                                                 asc_dvc->max_dvc_qng[i]);
        !          8377:        }
        !          8378: 
        !          8379:        AscEnableInterrupt(iop_base);
        !          8380: 
        !          8381: #if CC_INIT_INQ_DISPLAY
        !          8382:        DvcDisplayString((uchar dosfar *) "\r\n");
        !          8383: #endif
        !          8384:        asc_dvc->init_state |= ASC_INIT_STATE_END_INQUIRY;
        !          8385: 
        !          8386:        return (0);
        !          8387: }
        !          8388: 
        !          8389: int                 _asc_wait_slow_device_ = FALSE;
        !          8390: 
        !          8391: int
        !          8392: AscInitPollTarget(
        !          8393:                                         ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          8394:                                         ASC_SCSI_REQ_Q dosfar * scsiq,
        !          8395:                                         ASC_SCSI_INQUIRY dosfar * inq,
        !          8396:                                         ASC_CAP_INFO dosfar * cap_info
        !          8397: )
        !          8398: {
        !          8399:        uchar               tid_no, lun;
        !          8400:        uchar               dvc_type;
        !          8401:        ASC_SCSI_BIT_ID_TYPE tid_bits;
        !          8402:        int                 dvc_found;
        !          8403:        int                 support_read_cap;
        !          8404:        int                 tmp_disable_init_sdtr;
        !          8405:        ulong               phy_addr;
        !          8406: 
        !          8407:        dvc_found = 0;
        !          8408:        tmp_disable_init_sdtr = FALSE;
        !          8409:        tid_bits = scsiq->r1.target_id;
        !          8410:        lun = scsiq->r1.target_lun;
        !          8411:        tid_no = ASC_TIX_TO_TID(scsiq->r2.target_ix);
        !          8412:        if ((phy_addr = AscGetOnePhyAddr(asc_dvc,
        !          8413:                                                                         (uchar dosfar *) scsiq->sense_ptr,
        !          8414:                                                                         (ulong) scsiq->r1.sense_len)) == 0L) {
        !          8415:                return (ERR);
        !          8416:        }
        !          8417:        scsiq->r1.sense_addr = phy_addr;
        !          8418:        if (((asc_dvc->init_sdtr & tid_bits) != 0) &&
        !          8419:                ((asc_dvc->sdtr_done & tid_bits) == 0)) {
        !          8420: 
        !          8421:                asc_dvc->init_sdtr &= ~tid_bits;
        !          8422:                tmp_disable_init_sdtr = TRUE;
        !          8423:        }
        !          8424:        ASC_DBG(3, "AscInitPollTarget: PollScsiInquiry()\n");
        !          8425:        if (PollScsiInquiry(asc_dvc, scsiq, (uchar dosfar *) inq,
        !          8426:                                                sizeof (ASC_SCSI_INQUIRY)) == 1) {
        !          8427:                dvc_found = 1;
        !          8428:                support_read_cap = TRUE;
        !          8429:                dvc_type = inq->byte0.peri_dvc_type;
        !          8430:                if (dvc_type != SCSI_TYPE_UNKNOWN) {
        !          8431:                        if ((dvc_type != SCSI_TYPE_DASD) &&
        !          8432:                                (dvc_type != SCSI_TYPE_WORM) &&
        !          8433:                                (dvc_type != SCSI_TYPE_CDROM) &&
        !          8434:                                (dvc_type != SCSI_TYPE_OPTMEM)) {
        !          8435:                                asc_dvc->start_motor &= ~tid_bits;
        !          8436:                                support_read_cap = FALSE;
        !          8437:                        }
        !          8438:                        if ((dvc_type != SCSI_TYPE_DASD) ||
        !          8439:                                inq->byte1.rmb) {
        !          8440: 
        !          8441:                                if (!_asc_wait_slow_device_) {
        !          8442:                                        DvcSleepMilliSecond(3000 - ((int) tid_no * 250));
        !          8443:                                        _asc_wait_slow_device_ = TRUE;
        !          8444:                                }
        !          8445:                        }
        !          8446: #if CC_INIT_INQ_DISPLAY
        !          8447:                        AscDispInquiry(tid_no, lun, inq);
        !          8448: #endif
        !          8449: 
        !          8450:                        if (lun == 0) {
        !          8451: 
        !          8452:                                if ((inq->byte3.rsp_data_fmt >= 2) ||
        !          8453:                                        (inq->byte2.ansi_apr_ver >= 2)) {
        !          8454: 
        !          8455:                                        if (inq->byte7.CmdQue) {
        !          8456:                                                asc_dvc->cfg->can_tagged_qng |= tid_bits;
        !          8457:                                                if (asc_dvc->cfg->cmd_qng_enabled & tid_bits) {
        !          8458:                                                        asc_dvc->use_tagged_qng |= tid_bits;
        !          8459:                                                        asc_dvc->max_dvc_qng[tid_no] =
        !          8460:                                                          asc_dvc->cfg->max_tag_qng[tid_no];
        !          8461:                                                }
        !          8462:                                        }
        !          8463:                                        if (!inq->byte7.Sync) {
        !          8464: 
        !          8465:                                                asc_dvc->init_sdtr &= ~tid_bits;
        !          8466:                                                asc_dvc->sdtr_done &= ~tid_bits;
        !          8467:                                        } else if (tmp_disable_init_sdtr) {
        !          8468: 
        !          8469:                                                asc_dvc->init_sdtr |= tid_bits;
        !          8470:                                        }
        !          8471:                                } else {
        !          8472: 
        !          8473:                                        asc_dvc->init_sdtr &= ~tid_bits;
        !          8474:                                        asc_dvc->sdtr_done &= ~tid_bits;
        !          8475:                                        asc_dvc->use_tagged_qng &= ~tid_bits;
        !          8476:                                }
        !          8477:                        }
        !          8478:                        if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
        !          8479:                                if (!(asc_dvc->init_sdtr & tid_bits)) {
        !          8480: 
        !          8481:                                        AscSetRunChipSynRegAtID(asc_dvc->iop_base, tid_no,
        !          8482:                                                                                        ASYN_SDTR_DATA_FIX_PCI_REV_AB);
        !          8483:                                }
        !          8484:                        }
        !          8485:                        ASC_DBG(3, "AscInitPollTarget: InitTestUnitReady()\n");
        !          8486:                        if (InitTestUnitReady(asc_dvc, scsiq) != 1) {
        !          8487: 
        !          8488:                        } else {
        !          8489:                                if ((cap_info != 0L) && support_read_cap) {
        !          8490:                                        ASC_DBG(3, "AscInitPollTarget: PollScsiReadCapacity()\n");
        !          8491:                                        if (PollScsiReadCapacity(asc_dvc, scsiq,
        !          8492:                                                                                         cap_info) != 1) {
        !          8493:                                                cap_info->lba = 0L;
        !          8494:                                                cap_info->blk_size = 0x0000;
        !          8495:                                        } else {
        !          8496: 
        !          8497:                                        }
        !          8498:                                }
        !          8499:                        }
        !          8500:                } else {
        !          8501:                        asc_dvc->start_motor &= ~tid_bits;
        !          8502:                }
        !          8503:        } else {
        !          8504: 
        !          8505:        }
        !          8506:        return (dvc_found);
        !          8507: }
        !          8508: 
        !          8509: int
        !          8510: PollQueueDone(
        !          8511:                                 ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          8512:                                 ASC_SCSI_REQ_Q dosfar * scsiq,
        !          8513:                                 int timeout_sec
        !          8514: )
        !          8515: {
        !          8516:        int                 status;
        !          8517:        int                 retry;
        !          8518: 
        !          8519:        retry = 0;
        !          8520:        do {
        !          8521:                ASC_DBG(3, "PollQueueDone: AscExeScsiQueue()\n");
        !          8522:                if ((status = AscExeScsiQueue(asc_dvc,
        !          8523:                                                                          (ASC_SCSI_Q dosfar *) scsiq)) == 1) {
        !          8524:                        ASC_DBG(3, "PollQueueDone: AscPollQDone()\n");
        !          8525:                        if ((status = AscPollQDone(asc_dvc, scsiq,
        !          8526:                                                                           timeout_sec)) != 1) {
        !          8527:                                ASC_DBG1(3, "PollQueueDone: AscPollQDone() status %x\n", status);
        !          8528:                                if (status == 0x80) {
        !          8529:                                        if (retry++ > ASC_MAX_INIT_BUSY_RETRY) {
        !          8530:                                                break;
        !          8531:                                        }
        !          8532:                                        scsiq->r3.done_stat = 0;
        !          8533:                                        scsiq->r3.host_stat = 0;
        !          8534:                                        scsiq->r3.scsi_stat = 0;
        !          8535:                                        scsiq->r3.scsi_msg = 0;
        !          8536:                                        DvcSleepMilliSecond(100);
        !          8537:                                        continue;
        !          8538:                                }
        !          8539:                                scsiq->r3.done_stat = 0;
        !          8540:                                scsiq->r3.host_stat = 0;
        !          8541:                                scsiq->r3.scsi_stat = 0;
        !          8542:                                scsiq->r3.scsi_msg = 0;
        !          8543:                                ASC_DBG1(3, "PollQueueDone: AscAbortSRB() scsiq %x\n",
        !          8544:                                                 (unsigned) scsiq);
        !          8545: 
        !          8546:                                AscAbortSRB(asc_dvc, (ulong) scsiq);
        !          8547:                        }
        !          8548:                        ASC_DBG1(3, "PollQueueDone: done_stat %x\n", scsiq->r3.done_stat);
        !          8549:                        return (scsiq->r3.done_stat);
        !          8550:                }
        !          8551:        } while ((status == 0) || (status == 0x80));
        !          8552:        ASC_DBG(3, "PollQueueDone: done_stat QD_WITH_ERROR\n");
        !          8553:        return (scsiq->r3.done_stat = QD_WITH_ERROR);
        !          8554: }
        !          8555: 
        !          8556: int
        !          8557: PollScsiInquiry(
        !          8558:                                   ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          8559:                                   ASC_SCSI_REQ_Q dosfar * scsiq,
        !          8560:                                   uchar dosfar * buf,
        !          8561:                                   int buf_len
        !          8562: )
        !          8563: {
        !          8564:        if (AscScsiInquiry(asc_dvc, scsiq, buf, buf_len) == ERR) {
        !          8565:                return (scsiq->r3.done_stat = QD_WITH_ERROR);
        !          8566:        }
        !          8567:        return (PollQueueDone(asc_dvc, (ASC_SCSI_REQ_Q dosfar *) scsiq, 4));
        !          8568: }
        !          8569: 
        !          8570: int
        !          8571: PollScsiReadCapacity(
        !          8572:                                                ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          8573:                                                ASC_SCSI_REQ_Q dosfar * scsiq,
        !          8574:                                                ASC_CAP_INFO dosfar * cap_info
        !          8575: )
        !          8576: {
        !          8577:        ASC_CAP_INFO        scsi_cap_info;
        !          8578:        int                 status;
        !          8579: 
        !          8580:        if (AscScsiReadCapacity(asc_dvc, scsiq,
        !          8581:                                                        (uchar dosfar *) & scsi_cap_info) == ERR) {
        !          8582:                return (scsiq->r3.done_stat = QD_WITH_ERROR);
        !          8583:        }
        !          8584:        status = PollQueueDone(asc_dvc, (ASC_SCSI_REQ_Q dosfar *) scsiq, 8);
        !          8585:        if (status == 1) {
        !          8586: #if CC_LITTLE_ENDIAN_HOST
        !          8587:                cap_info->lba = (ulong) * swapfarbuf4((uchar dosfar *) & scsi_cap_info.lba);
        !          8588:                cap_info->blk_size = (ulong) * swapfarbuf4((uchar dosfar *) & scsi_cap_info.blk_size);
        !          8589: #else
        !          8590:                cap_info->lba = scsi_cap_info.lba;
        !          8591:                cap_info->blk_size = scsi_cap_info.blk_size;
        !          8592: #endif
        !          8593:                return (scsiq->r3.done_stat);
        !          8594:        }
        !          8595:        return (scsiq->r3.done_stat = QD_WITH_ERROR);
        !          8596: }
        !          8597: 
        !          8598: ulong dosfar       *
        !          8599: swapfarbuf4(
        !          8600:                           uchar dosfar * buf
        !          8601: )
        !          8602: {
        !          8603:        uchar               tmp;
        !          8604: 
        !          8605:        tmp = buf[3];
        !          8606:        buf[3] = buf[0];
        !          8607:        buf[0] = tmp;
        !          8608: 
        !          8609:        tmp = buf[1];
        !          8610:        buf[1] = buf[2];
        !          8611:        buf[2] = tmp;
        !          8612: 
        !          8613:        return ((ulong dosfar *) buf);
        !          8614: }
        !          8615: 
        !          8616: int
        !          8617: PollScsiTestUnitReady(
        !          8618:                                                 ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          8619:                                                 ASC_SCSI_REQ_Q dosfar * scsiq
        !          8620: )
        !          8621: {
        !          8622:        if (AscScsiTestUnitReady(asc_dvc, scsiq) == ERR) {
        !          8623:                return (scsiq->r3.done_stat = QD_WITH_ERROR);
        !          8624:        }
        !          8625:        return (PollQueueDone(asc_dvc, (ASC_SCSI_REQ_Q dosfar *) scsiq, 12));
        !          8626: }
        !          8627: 
        !          8628: int
        !          8629: PollScsiStartUnit(
        !          8630:                                         ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          8631:                                         ASC_SCSI_REQ_Q dosfar * scsiq
        !          8632: )
        !          8633: {
        !          8634:        if (AscScsiStartStopUnit(asc_dvc, scsiq, 1) == ERR) {
        !          8635:                return (scsiq->r3.done_stat = QD_WITH_ERROR);
        !          8636:        }
        !          8637:        return (PollQueueDone(asc_dvc, (ASC_SCSI_REQ_Q dosfar *) scsiq, 40));
        !          8638: }
        !          8639: 
        !          8640: int
        !          8641: InitTestUnitReady(
        !          8642:                                         ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          8643:                                         ASC_SCSI_REQ_Q dosfar * scsiq
        !          8644: )
        !          8645: {
        !          8646:        ASC_SCSI_BIT_ID_TYPE tid_bits;
        !          8647:        int                 retry;
        !          8648:        ASC_REQ_SENSE dosfar *sen;
        !          8649: 
        !          8650:        retry = 0;
        !          8651:        tid_bits = scsiq->r1.target_id;
        !          8652:        while (retry++ < 2) {
        !          8653:                ASC_DBG(3, "InitTestUnitReady: PollScsiTestUnitReady()\n");
        !          8654:                PollScsiTestUnitReady(asc_dvc, scsiq);
        !          8655:                ASC_DBG1(3, "InitTestUnitReady: done_stat %x\n", scsiq->r3.done_stat);
        !          8656:                if (scsiq->r3.done_stat == 0x01) {
        !          8657:                        return (1);
        !          8658:                } else if (scsiq->r3.done_stat == QD_WITH_ERROR) {
        !          8659:                        DvcSleepMilliSecond(100);
        !          8660: 
        !          8661:                        sen = (ASC_REQ_SENSE dosfar *) scsiq->sense_ptr;
        !          8662: 
        !          8663:                        if ((scsiq->r3.scsi_stat == SS_CHK_CONDITION) &&
        !          8664:                                ((sen->err_code & 0x70) != 0)) {
        !          8665: 
        !          8666:                                if (sen->sense_key == SCSI_SENKEY_NOT_READY) {
        !          8667: 
        !          8668:                                        if (asc_dvc->start_motor & tid_bits) {
        !          8669:                                                if (PollScsiStartUnit(asc_dvc, scsiq) == 1) {
        !          8670:                                                        retry = 0;
        !          8671:                                                        continue;
        !          8672:                                                } else {
        !          8673:                                                        asc_dvc->start_motor &= ~tid_bits;
        !          8674:                                                        break;
        !          8675:                                                }
        !          8676:                                        } else {
        !          8677:                                                DvcSleepMilliSecond(100);
        !          8678:                                        }
        !          8679:                                } else if (sen->sense_key == SCSI_SENKEY_ATTENSION) {
        !          8680:                                        DvcSleepMilliSecond(100);
        !          8681:                                } else {
        !          8682:                                        break;
        !          8683:                                }
        !          8684:                        } else {
        !          8685:                                break;
        !          8686:                        }
        !          8687:                } else if (scsiq->r3.done_stat == QD_ABORTED_BY_HOST) {
        !          8688:                        break;
        !          8689:                } else {
        !          8690:                        break;
        !          8691:                }
        !          8692:        }
        !          8693:        return (0);
        !          8694: }
        !          8695: 
        !          8696: #if CC_INIT_INQ_DISPLAY
        !          8697: 
        !          8698: #endif
        !          8699: 
        !          8700: int
        !          8701: AscPollQDone(
        !          8702:                                ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          8703:                                ASC_SCSI_REQ_Q dosfar * scsiq,
        !          8704:                                int timeout_sec
        !          8705: )
        !          8706: {
        !          8707:        int                 loop, loop_end;
        !          8708:        int                 sta;
        !          8709:        PortAddr            iop_base;
        !          8710: 
        !          8711:        iop_base = asc_dvc->iop_base;
        !          8712:        loop = 0;
        !          8713:        loop_end = timeout_sec * 100;
        !          8714:        sta = 1;
        !          8715: 
        !          8716:        while (TRUE) {
        !          8717:                ASC_DBG4(3,
        !          8718:                 "AscPollQDone: loop %d, err_code %x, done_stat %x, scsi_stat %x\n",
        !          8719:                 loop, asc_dvc->err_code, scsiq->r3.done_stat, scsiq->r3.scsi_stat);
        !          8720:                if (asc_dvc->err_code != 0) {
        !          8721:                        scsiq->r3.done_stat = QD_WITH_ERROR;
        !          8722:                        sta = ERR;
        !          8723:                        break;
        !          8724:                }
        !          8725:                if (scsiq->r3.done_stat != QD_IN_PROGRESS) {
        !          8726:                        if ((scsiq->r3.done_stat == QD_WITH_ERROR) &&
        !          8727:                                (scsiq->r3.scsi_stat == SS_TARGET_BUSY)) {
        !          8728:                                sta = 0x80;
        !          8729:                                break;
        !          8730:                        }
        !          8731:                        break;
        !          8732:                }
        !          8733:                DvcSleepMilliSecond(10);
        !          8734:                if (loop++ > loop_end) {
        !          8735:                        sta = 0;
        !          8736:                        break;
        !          8737:                }
        !          8738:                if (AscIsChipHalted(iop_base)) {
        !          8739:                        AscISR(asc_dvc);
        !          8740:                        loop = 0;
        !          8741:                } else {
        !          8742:                        ASC_DBG(3, "AscPollQDone: AscIsIntPending()\n");
        !          8743:                        if (AscIsIntPending(iop_base)) {
        !          8744:                                ASC_DBG(3, "AscPollQDone: AscISR()\n");
        !          8745:                                AscISR(asc_dvc);
        !          8746:                        }
        !          8747:                }
        !          8748:        }
        !          8749:        ASC_DBG1(3, "AscPollQDone: sta %x\n", sta);
        !          8750:        return (sta);
        !          8751: }
        !          8752: 
        !          8753: uchar
        !          8754: AscReadLramByte(
        !          8755:                                   PortAddr iop_base,
        !          8756:                                   ushort addr
        !          8757: )
        !          8758: {
        !          8759:        uchar               byte_data;
        !          8760:        ushort              word_data;
        !          8761: 
        !          8762:        if (isodd_word(addr)) {
        !          8763:                AscSetChipLramAddr(iop_base, addr - 1);
        !          8764:                word_data = AscGetChipLramData(iop_base);
        !          8765: 
        !          8766: #if CC_LITTLE_ENDIAN_HOST
        !          8767:                byte_data = (uchar) ((word_data >> 8) & 0xFF);
        !          8768: #else
        !          8769:                byte_data = (uchar) (word_data & 0xFF);
        !          8770: #endif
        !          8771: 
        !          8772:        } else {
        !          8773:                AscSetChipLramAddr(iop_base, addr);
        !          8774:                word_data = AscGetChipLramData(iop_base);
        !          8775: 
        !          8776: #if CC_LITTLE_ENDIAN_HOST
        !          8777:                byte_data = (uchar) (word_data & 0xFF);
        !          8778: #else
        !          8779:                byte_data = (uchar) ((word_data >> 8) & 0xFF);
        !          8780: #endif
        !          8781: 
        !          8782:        }
        !          8783:        return (byte_data);
        !          8784: }
        !          8785: 
        !          8786: ushort
        !          8787: AscReadLramWord(
        !          8788:                                   PortAddr iop_base,
        !          8789:                                   ushort addr
        !          8790: )
        !          8791: {
        !          8792:        ushort              word_data;
        !          8793: 
        !          8794:        AscSetChipLramAddr(iop_base, addr);
        !          8795:        word_data = AscGetChipLramData(iop_base);
        !          8796:        return (word_data);
        !          8797: }
        !          8798: 
        !          8799: ulong
        !          8800: AscReadLramDWord(
        !          8801:                                        PortAddr iop_base,
        !          8802:                                        ushort addr
        !          8803: )
        !          8804: {
        !          8805:        ushort              val_low, val_high;
        !          8806:        ulong               dword_data;
        !          8807: 
        !          8808:        AscSetChipLramAddr(iop_base, addr);
        !          8809: 
        !          8810: #if CC_LITTLE_ENDIAN_HOST
        !          8811:        val_low = AscGetChipLramData(iop_base);
        !          8812: 
        !          8813:        val_high = AscGetChipLramData(iop_base);
        !          8814: #else
        !          8815:        val_high = AscGetChipLramData(iop_base);
        !          8816:        val_low = AscGetChipLramData(iop_base);
        !          8817: #endif
        !          8818: 
        !          8819:        dword_data = ((ulong) val_high << 16) | (ulong) val_low;
        !          8820:        return (dword_data);
        !          8821: }
        !          8822: 
        !          8823: void
        !          8824: AscWriteLramWord(
        !          8825:                                        PortAddr iop_base,
        !          8826:                                        ushort addr,
        !          8827:                                        ushort word_val
        !          8828: )
        !          8829: {
        !          8830:        AscSetChipLramAddr(iop_base, addr);
        !          8831:        AscPutChipLramData(iop_base, word_val);
        !          8832:        return;
        !          8833: }
        !          8834: 
        !          8835: void
        !          8836: AscWriteLramDWord(
        !          8837:                                         PortAddr iop_base,
        !          8838:                                         ushort addr,
        !          8839:                                         ulong dword_val
        !          8840: )
        !          8841: {
        !          8842:        ushort              word_val;
        !          8843: 
        !          8844:        AscSetChipLramAddr(iop_base, addr);
        !          8845: 
        !          8846: #if CC_LITTLE_ENDIAN_HOST
        !          8847:        word_val = (ushort) dword_val;
        !          8848:        AscPutChipLramData(iop_base, word_val);
        !          8849:        word_val = (ushort) (dword_val >> 16);
        !          8850:        AscPutChipLramData(iop_base, word_val);
        !          8851: #else
        !          8852:        word_val = (ushort) (dword_val >> 16);
        !          8853:        AscPutChipLramData(iop_base, word_val);
        !          8854:        word_val = (ushort) dword_val;
        !          8855:        AscPutChipLramData(iop_base, word_val);
        !          8856: #endif
        !          8857:        return;
        !          8858: }
        !          8859: 
        !          8860: void
        !          8861: AscWriteLramByte(
        !          8862:                                        PortAddr iop_base,
        !          8863:                                        ushort addr,
        !          8864:                                        uchar byte_val
        !          8865: )
        !          8866: {
        !          8867:        ushort              word_data;
        !          8868: 
        !          8869:        if (isodd_word(addr)) {
        !          8870:                addr--;
        !          8871:                word_data = AscReadLramWord(iop_base, addr);
        !          8872:                word_data &= 0x00FF;
        !          8873:                word_data |= (((ushort) byte_val << 8) & 0xFF00);
        !          8874:        } else {
        !          8875:                word_data = AscReadLramWord(iop_base, addr);
        !          8876:                word_data &= 0xFF00;
        !          8877:                word_data |= ((ushort) byte_val & 0x00FF);
        !          8878:        }
        !          8879:        AscWriteLramWord(iop_base, addr, word_data);
        !          8880:        return;
        !          8881: }
        !          8882: 
        !          8883: int
        !          8884: AscVerWriteLramWord(
        !          8885:                                           PortAddr iop_base,
        !          8886:                                           ushort addr,
        !          8887:                                           ushort word_val
        !          8888: )
        !          8889: {
        !          8890:        int                 sta;
        !          8891: 
        !          8892:        sta = 0;
        !          8893:        AscSetChipLramAddr(iop_base, addr);
        !          8894:        AscPutChipLramData(iop_base, word_val);
        !          8895:        AscSetChipLramAddr(iop_base, addr);
        !          8896:        if (word_val != AscGetChipLramData(iop_base)) {
        !          8897:                sta = ERR;
        !          8898:        }
        !          8899:        return (sta);
        !          8900: }
        !          8901: 
        !          8902: void
        !          8903: AscMemWordCopyToLram(
        !          8904:                                                PortAddr iop_base,
        !          8905:                                                ushort s_addr,
        !          8906:                                                ushort dosfar * s_buffer,
        !          8907:                                                int words
        !          8908: )
        !          8909: {
        !          8910:        AscSetChipLramAddr(iop_base, s_addr);
        !          8911:        DvcOutPortWords(iop_base + IOP_RAM_DATA, s_buffer, words);
        !          8912:        return;
        !          8913: }
        !          8914: 
        !          8915: void
        !          8916: AscMemDWordCopyToLram(
        !          8917:                                                 PortAddr iop_base,
        !          8918:                                                 ushort s_addr,
        !          8919:                                                 ulong dosfar * s_buffer,
        !          8920:                                                 int dwords
        !          8921: )
        !          8922: {
        !          8923:        AscSetChipLramAddr(iop_base, s_addr);
        !          8924:        DvcOutPortDWords(iop_base + IOP_RAM_DATA, s_buffer, dwords);
        !          8925:        return;
        !          8926: }
        !          8927: 
        !          8928: void
        !          8929: AscMemWordCopyFromLram(
        !          8930:                                                  PortAddr iop_base,
        !          8931:                                                  ushort s_addr,
        !          8932:                                                  ushort dosfar * d_buffer,
        !          8933:                                                  int words
        !          8934: )
        !          8935: {
        !          8936:        AscSetChipLramAddr(iop_base, s_addr);
        !          8937:        DvcInPortWords(iop_base + IOP_RAM_DATA, d_buffer, words);
        !          8938:        return;
        !          8939: }
        !          8940: 
        !          8941: ulong
        !          8942: AscMemSumLramWord(
        !          8943:                                         PortAddr iop_base,
        !          8944:                                         ushort s_addr,
        !          8945:                                         rint words
        !          8946: )
        !          8947: {
        !          8948:        ulong               sum;
        !          8949:        int                 i;
        !          8950: 
        !          8951:        sum = 0L;
        !          8952:        for (i = 0; i < words; i++, s_addr += 2) {
        !          8953:                sum += AscReadLramWord(iop_base, s_addr);
        !          8954:        }
        !          8955:        return (sum);
        !          8956: }
        !          8957: 
        !          8958: void
        !          8959: AscMemWordSetLram(
        !          8960:                                         PortAddr iop_base,
        !          8961:                                         ushort s_addr,
        !          8962:                                         ushort set_wval,
        !          8963:                                         rint words
        !          8964: )
        !          8965: {
        !          8966:        rint                i;
        !          8967: 
        !          8968:        AscSetChipLramAddr(iop_base, s_addr);
        !          8969:        for (i = 0; i < words; i++) {
        !          8970:                AscPutChipLramData(iop_base, set_wval);
        !          8971:        }
        !          8972:        return;
        !          8973: }
        !          8974: 
        !          8975: int
        !          8976: AscScsiInquiry(
        !          8977:                                  ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          8978:                                  ASC_SCSI_REQ_Q dosfar * scsiq,
        !          8979:                                  uchar dosfar * buf, int buf_len
        !          8980: )
        !          8981: {
        !          8982:        if (AscScsiSetupCmdQ(asc_dvc, scsiq, buf,
        !          8983:                                                 (ulong) buf_len) == ERR) {
        !          8984:                return (scsiq->r3.done_stat = QD_WITH_ERROR);
        !          8985:        }
        !          8986:        scsiq->cdb[0] = (uchar) SCSICMD_Inquiry;
        !          8987:        scsiq->cdb[1] = scsiq->r1.target_lun << 5;
        !          8988:        scsiq->cdb[2] = 0;
        !          8989:        scsiq->cdb[3] = 0;
        !          8990:        scsiq->cdb[4] = buf_len;
        !          8991:        scsiq->cdb[5] = 0;
        !          8992:        scsiq->r2.cdb_len = 6;
        !          8993:        return (0);
        !          8994: }
        !          8995: 
        !          8996: int
        !          8997: AscScsiReadCapacity(
        !          8998:                                           ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          8999:                                           ASC_SCSI_REQ_Q dosfar * scsiq,
        !          9000:                                           uchar dosfar * info
        !          9001: )
        !          9002: {
        !          9003:        if (AscScsiSetupCmdQ(asc_dvc, scsiq, info, 8L) == ERR) {
        !          9004:                return (scsiq->r3.done_stat = QD_WITH_ERROR);
        !          9005:        }
        !          9006:        scsiq->cdb[0] = (uchar) SCSICMD_ReadCapacity;
        !          9007:        scsiq->cdb[1] = scsiq->r1.target_lun << 5;
        !          9008:        scsiq->cdb[2] = 0;
        !          9009:        scsiq->cdb[3] = 0;
        !          9010:        scsiq->cdb[4] = 0;
        !          9011:        scsiq->cdb[5] = 0;
        !          9012:        scsiq->cdb[6] = 0;
        !          9013:        scsiq->cdb[7] = 0;
        !          9014:        scsiq->cdb[8] = 0;
        !          9015:        scsiq->cdb[9] = 0;
        !          9016:        scsiq->r2.cdb_len = 10;
        !          9017:        return (0);
        !          9018: }
        !          9019: 
        !          9020: int
        !          9021: AscScsiTestUnitReady(
        !          9022:                                                ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          9023:                                                ASC_SCSI_REQ_Q dosfar * scsiq
        !          9024: )
        !          9025: {
        !          9026:        if (AscScsiSetupCmdQ(asc_dvc, scsiq, FNULLPTR,
        !          9027:                                                 (ulong) 0L) == ERR) {
        !          9028:                return (scsiq->r3.done_stat = QD_WITH_ERROR);
        !          9029:        }
        !          9030:        scsiq->r1.cntl = (uchar) ASC_SCSIDIR_NODATA;
        !          9031:        scsiq->cdb[0] = (uchar) SCSICMD_TestUnitReady;
        !          9032:        scsiq->cdb[1] = scsiq->r1.target_lun << 5;
        !          9033:        scsiq->cdb[2] = 0;
        !          9034:        scsiq->cdb[3] = 0;
        !          9035:        scsiq->cdb[4] = 0;
        !          9036:        scsiq->cdb[5] = 0;
        !          9037:        scsiq->r2.cdb_len = 6;
        !          9038:        return (0);
        !          9039: }
        !          9040: 
        !          9041: int
        !          9042: AscScsiStartStopUnit(
        !          9043:                                                ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          9044:                                                ASC_SCSI_REQ_Q dosfar * scsiq,
        !          9045:                                                uchar op_mode
        !          9046: )
        !          9047: {
        !          9048:        if (AscScsiSetupCmdQ(asc_dvc, scsiq, FNULLPTR, (ulong) 0L) == ERR) {
        !          9049:                return (scsiq->r3.done_stat = QD_WITH_ERROR);
        !          9050:        }
        !          9051:        scsiq->r1.cntl = (uchar) ASC_SCSIDIR_NODATA;
        !          9052:        scsiq->cdb[0] = (uchar) SCSICMD_StartStopUnit;
        !          9053:        scsiq->cdb[1] = scsiq->r1.target_lun << 5;
        !          9054:        scsiq->cdb[2] = 0;
        !          9055:        scsiq->cdb[3] = 0;
        !          9056:        scsiq->cdb[4] = op_mode;
        !          9057: 
        !          9058:        scsiq->cdb[5] = 0;
        !          9059:        scsiq->r2.cdb_len = 6;
        !          9060:        return (0);
        !          9061: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.