Annotation of Gnu-Mach/i386/i386at/gpl/linux/scsi/advansys.c, revision 1.1.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.