Annotation of Gnu-Mach/linux/src/drivers/scsi/advansys.c, revision 1.1

1.1     ! root        1: /* $Id: advansys.c,v 1.1 1999/04/26 05:54:04 tb Exp $ */
        !             2: #define ASC_VERSION "3.1E"    /* AdvanSys Driver Version */
        !             3: 
        !             4: /*
        !             5:  * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
        !             6:  * 
        !             7:  * Copyright (c) 1995-1998 Advanced System Products, Inc.
        !             8:  * All Rights Reserved.
        !             9:  *
        !            10:  * Redistribution and use in source and binary forms, with or without
        !            11:  * modification, are permitted provided that redistributions of source
        !            12:  * code retain the above copyright notice and this comment without
        !            13:  * modification.
        !            14:  *
        !            15:  * There is an AdvanSys Linux WWW page at:
        !            16:  *  http://www.advansys.com/linux.html
        !            17:  *
        !            18:  * The latest version of the AdvanSys driver is available at:
        !            19:  *  ftp://ftp.advansys.com/pub/linux/linux.tgz
        !            20:  *
        !            21:  * Please send questions, comments, bug reports to:
        !            22:  *  [email protected] (Bob Frey)
        !            23:  */
        !            24: 
        !            25: /*
        !            26: 
        !            27:   Documentation for the AdvanSys Driver
        !            28: 
        !            29:   A. Linux Kernel Testing
        !            30:   B. Adapters Supported by this Driver
        !            31:   C. Linux v1.2.X - Directions for Adding the AdvanSys Driver
        !            32:   D. Linux v1.3.1 - v1.3.57 - Directions for Adding the AdvanSys Driver
        !            33:   E. Linux v1.3.58 and Newer - Upgrading the AdvanSys Driver
        !            34:   F. Source Comments
        !            35:   G. Driver Compile Time Options and Debugging
        !            36:   H. Driver LILO Option
        !            37:   I. Release History
        !            38:   J. Known Problems or Issues
        !            39:   K. Credits
        !            40:   L. AdvanSys Contact Information
        !            41: 
        !            42:   A. Linux Kernel Testing
        !            43: 
        !            44:      This driver has been tested in the following Linux kernels: v1.2.13,
        !            45:      v1.3.57, v2.0.33, v2.1.77. These kernel versions are major releases
        !            46:      of Linux or the latest Linux kernel versions available when this version
        !            47:      of the driver was released. The driver should also work in earlier
        !            48:      versions of the Linux kernel. Beginning with v1.3.58 the AdvanSys driver
        !            49:      is included with all Linux kernels. Please refer to sections C, D, and
        !            50:      E for instructions on adding or upgrading the AdvanSys driver.
        !            51: 
        !            52:   B. Adapters Supported by this Driver
        !            53:  
        !            54:      AdvanSys (Advanced System Products, Inc.) manufactures the following
        !            55:      RISC-based, Bus-Mastering, Fast (10 Mhz) and Ultra (20 Mhz) Narrow
        !            56:      (8-bit transfer) SCSI Host Adapters for the ISA, EISA, VL, and PCI
        !            57:      buses and RISC-based, Bus-Mastering, Ultra (20 Mhz) Wide (16-bit
        !            58:      transfer) SCSI Host Adapters for the PCI bus.
        !            59:      
        !            60:      The CDB counts below indicate the number of SCSI CDB (Command
        !            61:      Descriptor Block) requests that can be stored in the RISC chip
        !            62:      cache and board LRAM. A CDB is a single SCSI command. The driver
        !            63:      detect routine will display the number of CDBs available for each
        !            64:      adapter detected. The number of CDBs used by the driver can be
        !            65:      lowered in the BIOS by changing the 'Host Queue Size' adapter setting.
        !            66: 
        !            67:      Connectivity Products:
        !            68:         ABP510/5150 - Bus-Master ISA (240 CDB) (Footnote 1)
        !            69:         ABP5140 - Bus-Master ISA PnP (16 CDB) (Footnote 1, 3)
        !            70:         ABP5142 - Bus-Master ISA PnP with floppy (16 CDB) (Footnote 4)
        !            71:         ABP920 - Bus-Master PCI (16 CDB)
        !            72:         ABP930 - Bus-Master PCI (16 CDB) (Footnote 5)
        !            73:         ABP930U - Bus-Master PCI Ultra (16 CDB)
        !            74:         ABP930UA - Bus-Master PCI Ultra (16 CDB)
        !            75:         ABP960 - Bus-Master PCI MAC/PC (16 CDB) (Footnote 2)
        !            76:         ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB) (Footnote 2)
        !            77:      
        !            78:      Single Channel Products:
        !            79:         ABP542 - Bus-Master ISA with floppy (240 CDB)
        !            80:         ABP742 - Bus-Master EISA (240 CDB)
        !            81:         ABP842 - Bus-Master VL (240 CDB)
        !            82:         ABP940 - Bus-Master PCI (240 CDB)
        !            83:         ABP940U - Bus-Master PCI Ultra (240 CDB)
        !            84:         ABP970 - Bus-Master PCI MAC/PC (240 CDB)
        !            85:         ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB)
        !            86:         ABP940UW - Bus-Master PCI Ultra-Wide (240 CDB)
        !            87:      
        !            88:      Multi Channel Products:
        !            89:         ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel)
        !            90:         ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel)
        !            91:         ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel)
        !            92:         ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel)
        !            93:         ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel)
        !            94:      
        !            95:      Footnotes:
        !            96:        1. This board has been shipped by HP with the 4020i CD-R drive.
        !            97:           The board has no BIOS so it cannot control a boot device, but
        !            98:           it can control any secondary SCSI device.
        !            99:        2. This board has been sold by Iomega as a Jaz Jet PCI adapter.
        !           100:        3. This board has been sold by SIIG as the i540 SpeedMaster.
        !           101:        4. This board has been sold by SIIG as the i542 SpeedMaster.
        !           102:        5. This board has been sold by SIIG as the Fast SCSI Pro PCI.
        !           103: 
        !           104:   C. Linux v1.2.X - Directions for Adding the AdvanSys Driver
        !           105: 
        !           106:      These directions apply to v1.2.13. For versions that follow v1.2.13.
        !           107:      but precede v1.3.57 some of the changes for Linux v1.3.X listed
        !           108:      below may need to be modified or included. A patch is available
        !           109:      for v1.2.13 from the AdvanSys WWW and FTP sites.
        !           110:  
        !           111:      There are two source files: advansys.h and advansys.c. Copy
        !           112:      both of these files to the directory /usr/src/linux/drivers/scsi.
        !           113:     
        !           114:      1. Add the following line to /usr/src/linux/arch/i386/config.in
        !           115:         after "comment 'SCSI low-level drivers'":
        !           116:     
        !           117:           bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y
        !           118:     
        !           119:      2. Add the following lines to /usr/src/linux/drivers/scsi/hosts.c
        !           120:         after "#include "hosts.h"":
        !           121:     
        !           122:           #ifdef CONFIG_SCSI_ADVANSYS
        !           123:           #include "advansys.h"
        !           124:           #endif
        !           125:     
        !           126:         and after "static Scsi_Host_Template builtin_scsi_hosts[] =":
        !           127:     
        !           128:           #ifdef CONFIG_SCSI_ADVANSYS
        !           129:           ADVANSYS,
        !           130:           #endif
        !           131:     
        !           132:      3. Add the following lines to /usr/src/linux/drivers/scsi/Makefile:
        !           133:     
        !           134:           ifdef CONFIG_SCSI_ADVANSYS
        !           135:           SCSI_SRCS := $(SCSI_SRCS) advansys.c
        !           136:           SCSI_OBJS := $(SCSI_OBJS) advansys.o
        !           137:           else
        !           138:           SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o
        !           139:           endif
        !           140: 
        !           141:      4. (Optional) If you would like to enable the LILO command line
        !           142:         and /etc/lilo.conf 'advansys' option, make the following changes.
        !           143:         This option can be used to disable I/O port scanning or to limit
        !           144:         I/O port scanning to specific addresses. Refer to the 'Driver
        !           145:         LILO Option' section below. Add the following lines to
        !           146:         /usr/src/linux/init/main.c in the prototype section:
        !           147: 
        !           148:           extern void advansys_setup(char *str, int *ints);
        !           149: 
        !           150:         and add the following lines to the bootsetups[] array.
        !           151: 
        !           152:           #ifdef CONFIG_SCSI_ADVANSYS
        !           153:              { "advansys=", advansys_setup },
        !           154:           #endif
        !           155: 
        !           156:      5. If you have the HP 4020i CD-R driver and Linux v1.2.X you should
        !           157:         add a fix to the CD-ROM target driver. This fix will allow
        !           158:         you to mount CDs with the iso9660 file system. Linux v1.3.X
        !           159:         already has this fix. In the file /usr/src/linux/drivers/scsi/sr.c
        !           160:         and function get_sectorsize() after the line:
        !           161: 
        !           162:         if(scsi_CDs[i].sector_size == 0) scsi_CDs[i].sector_size = 2048;
        !           163: 
        !           164:         add the following line:
        !           165: 
        !           166:         if(scsi_CDs[i].sector_size == 2340) scsi_CDs[i].sector_size = 2048;
        !           167: 
        !           168:      6. In the directory /usr/src/linux run 'make config' to configure
        !           169:         the AdvanSys driver, then run 'make vmlinux' or 'make zlilo' to
        !           170:         make the kernel. If the AdvanSys driver is not configured, then
        !           171:         a loadable module can be built by running 'make modules' and
        !           172:         'make modules_install'. Use 'insmod' and 'rmmod' to install
        !           173:         and remove advansys.o.
        !           174:  
        !           175:   D. Linux v1.3.1 - v1.3.57 - Directions for Adding the AdvanSys Driver
        !           176: 
        !           177:      These directions apply to v1.3.57. For versions that precede v1.3.57
        !           178:      some of these changes may need to be modified or eliminated. A patch
        !           179:      is available for v1.3.57 from the AdvanSys WWW and FTP sites.
        !           180:      Beginning with v1.3.58 this driver is included with the Linux
        !           181:      distribution eliminating the need for making any changes.
        !           182: 
        !           183:      There are two source files: advansys.h and advansys.c. Copy
        !           184:      both of these files to the directory /usr/src/linux/drivers/scsi.
        !           185:    
        !           186:      1. Add the following line to /usr/src/linux/drivers/scsi/Config.in
        !           187:         after "comment 'SCSI low-level drivers'":
        !           188:    
        !           189:           dep_tristate 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS $CONFIG_SCSI
        !           190:    
        !           191:      2. Add the following lines to /usr/src/linux/drivers/scsi/hosts.c
        !           192:         after "#include "hosts.h"":
        !           193:    
        !           194:           #ifdef CONFIG_SCSI_ADVANSYS
        !           195:           #include "advansys.h"
        !           196:           #endif
        !           197:    
        !           198:         and after "static Scsi_Host_Template builtin_scsi_hosts[] =":
        !           199:    
        !           200:           #ifdef CONFIG_SCSI_ADVANSYS
        !           201:           ADVANSYS,
        !           202:           #endif
        !           203:    
        !           204:      3. Add the following lines to /usr/src/linux/drivers/scsi/Makefile:
        !           205:    
        !           206:           ifeq ($(CONFIG_SCSI_ADVANSYS),y)
        !           207:           L_OBJS += advansys.o
        !           208:           else
        !           209:             ifeq ($(CONFIG_SCSI_ADVANSYS),m)
        !           210:             M_OBJS += advansys.o
        !           211:             endif
        !           212:           endif
        !           213:    
        !           214:      4. Add the following line to /usr/src/linux/include/linux/proc_fs.h
        !           215:         in the enum scsi_directory_inos array:
        !           216:    
        !           217:           PROC_SCSI_ADVANSYS,
        !           218:    
        !           219:      5. (Optional) If you would like to enable the LILO command line
        !           220:         and /etc/lilo.conf 'advansys' option, make the following changes.
        !           221:         This option can be used to disable I/O port scanning or to limit
        !           222:         I/O port scanning to specific addresses. Refer to the 'Driver
        !           223:         LILO Option' section below. Add the following lines to
        !           224:         /usr/src/linux/init/main.c in the prototype section:
        !           225:    
        !           226:           extern void advansys_setup(char *str, int *ints);
        !           227:    
        !           228:         and add the following lines to the bootsetups[] array.
        !           229:    
        !           230:           #ifdef CONFIG_SCSI_ADVANSYS
        !           231:              { "advansys=", advansys_setup },
        !           232:           #endif
        !           233:    
        !           234:      6. In the directory /usr/src/linux run 'make config' to configure
        !           235:         the AdvanSys driver, then run 'make vmlinux' or 'make zlilo' to
        !           236:         make the kernel. If the AdvanSys driver is not configured, then
        !           237:         a loadable module can be built by running 'make modules' and
        !           238:         'make modules_install'. Use 'insmod' and 'rmmod' to install
        !           239:         and remove advansys.o.
        !           240: 
        !           241:   E. Linux v1.3.58 and Newer - Upgrading the AdvanSys Driver
        !           242: 
        !           243:      To upgrade the AdvanSys driver in a Linux v1.3.58 and newer
        !           244:      kernel, first check the version of the current driver. The
        !           245:      version is defined by the manifest constant ASC_VERSION at
        !           246:      the beginning of advansys.c. The new driver should have a
        !           247:      ASC_VERSION value greater than the current version. To install
        !           248:      the new driver rename advansys.c and advansys.h in the Linux
        !           249:      kernel source tree drivers/scsi directory to different names
        !           250:      or save them to a different directory in case you want to revert
        !           251:      to the old version of the driver. After the old driver is saved
        !           252:      copy the new advansys.c and advansys.h to drivers/scsi, rebuild
        !           253:      the kernel, and install the new kernel. No other changes are needed.
        !           254: 
        !           255:   F. Source Comments
        !           256:  
        !           257:      1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'.
        !           258:  
        !           259:      2. This driver should be maintained in multiple files. But to make
        !           260:         it easier to include with Linux and to follow Linux conventions,
        !           261:         the whole driver is maintained in the source files advansys.h and
        !           262:         advansys.c. In this file logical sections of the driver begin with
        !           263:         a comment that contains '---'. The following are the logical sections
        !           264:         of the driver below.
        !           265:  
        !           266:            --- Linux Version
        !           267:            --- Linux Include Files 
        !           268:            --- Driver Options
        !           269:            --- Debugging Header
        !           270:            --- Asc Library Constants and Macros
        !           271:            --- Adv Library Constants and Macros
        !           272:            --- Driver Constants and Macros
        !           273:            --- Driver Structures
        !           274:            --- Driver Data
        !           275:            --- Driver Function Prototypes
        !           276:            --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
        !           277:            --- Loadable Driver Support
        !           278:            --- Miscellaneous Driver Functions
        !           279:            --- Functions Required by the Asc Library
        !           280:            --- Functions Required by the Adv Library
        !           281:            --- Tracing and Debugging Functions
        !           282:            --- Asc Library Functions
        !           283:            --- Adv Library Functions
        !           284:  
        !           285:      3. The string 'XXX' is used to flag code that needs to be re-written
        !           286:         or that contains a problem that needs to be addressed.
        !           287:  
        !           288:      4. I have stripped comments from and reformatted the source for the
        !           289:         Asc Library and Adv Library to reduce the size of this file. This
        !           290:         source can be found under the following headings. The Asc Library
        !           291:         is used to support Narrow Boards. The Adv Library is used to
        !           292:         support Wide Boards.
        !           293:  
        !           294:            --- Asc Library Constants and Macros
        !           295:            --- Adv Library Constants and Macros
        !           296:            --- Asc Library Functions
        !           297:            --- Adv Library Functions
        !           298:  
        !           299:   G. Driver Compile Time Options and Debugging
        !           300:  
        !           301:      In this source file the following constants can be defined. They are
        !           302:      defined in the source below. Both of these options are enabled by
        !           303:      default.
        !           304:  
        !           305:      1. ADVANSYS_ASSERT - Enable driver assertions (Def: Enabled)
        !           306: 
        !           307:         Enabling this option adds assertion logic statements to the
        !           308:         driver. If an assertion fails a message will be displayed to
        !           309:         the console, but the system will continue to operate. Any
        !           310:         assertions encountered should be reported to the person
        !           311:         responsible for the driver. Assertion statements may proactively
        !           312:         detect problems with the driver and facilitate fixing these
        !           313:         problems. Enabling assertions will add a small overhead to the
        !           314:         execution of the driver.
        !           315: 
        !           316:      2. ADVANSYS_DEBUG - Enable driver debugging (Def: Disabled)
        !           317: 
        !           318:         Enabling this option adds tracing functions to the driver and
        !           319:         the ability to set a driver tracing level at boot time. This
        !           320:         option will also export symbols not required outside the driver to
        !           321:         the kernel name space. This option is very useful for debugging
        !           322:         the driver, but it will add to the size of the driver execution
        !           323:         image and add overhead to the execution of the driver.
        !           324:  
        !           325:         The amount of debugging output can be controlled with the global
        !           326:         variable 'asc_dbglvl'. The higher the number the more output. By
        !           327:         default the debug level is 0.
        !           328:         
        !           329:         If the driver is loaded at boot time and the LILO Driver Option
        !           330:         is included in the system, the debug level can be changed by
        !           331:         specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The
        !           332:         first three hex digits of the pseudo I/O Port must be set to
        !           333:         'deb' and the fourth hex digit specifies the debug level: 0 - F.
        !           334:         The following command line will look for an adapter at 0x330
        !           335:         and set the debug level to 2.
        !           336: 
        !           337:            linux advansys=0x330,0,0,0,0xdeb2
        !           338: 
        !           339:         If the driver is built as a loadable module this variable can be
        !           340:         defined when the driver is loaded. The following insmod command
        !           341:         will set the debug level to one.
        !           342:   
        !           343:            insmod advansys.o asc_dbglvl=1
        !           344:  
        !           345:         Debugging Message Levels:
        !           346:            0: Errors Only
        !           347:            1: High-Level Tracing
        !           348:            2-N: Verbose Tracing
        !           349:  
        !           350:         I don't know the approved way for turning on printk()s to the
        !           351:         console. Here's a program I use to do this. Debug output is
        !           352:         logged in /var/adm/messages.
        !           353:  
        !           354:           main()
        !           355:           {
        !           356:                   syscall(103, 7, 0, 0);
        !           357:           }
        !           358:  
        !           359:         I found that increasing LOG_BUF_LEN to 40960 in kernel/printk.c
        !           360:         prevents most level 1 debug messages from being lost.
        !           361: 
        !           362:      3. ADVANSYS_STATS - Enable statistics (Def: Enabled >= v1.3.0)
        !           363:  
        !           364:         Enabling this option adds statistics collection and display
        !           365:         through /proc to the driver. The information is useful for
        !           366:         monitoring driver and device performance. It will add to the
        !           367:         size of the driver execution image and add minor overhead to
        !           368:         the execution of the driver.
        !           369: 
        !           370:         Statistics are maintained on a per adapter basis. Driver entry
        !           371:         point call counts and transfer size counts are maintained.
        !           372:         Statistics are only available for kernels greater than or equal
        !           373:         to v1.3.0 with the CONFIG_PROC_FS (/proc) file system configured.
        !           374: 
        !           375:         AdvanSys SCSI adapter files have the following path name format:
        !           376: 
        !           377:            /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
        !           378: 
        !           379:         This information can be displayed with cat. For example:
        !           380: 
        !           381:            cat /proc/scsi/advansys/0
        !           382: 
        !           383:         When ADVANSYS_STATS is not defined the AdvanSys /proc files only
        !           384:         contain adapter and device configuration information.
        !           385: 
        !           386:   H. Driver LILO Option
        !           387:  
        !           388:      If init/main.c is modified as described in the 'Directions for Adding
        !           389:      the AdvanSys Driver to Linux' section (B.4.) above, the driver will
        !           390:      recognize the 'advansys' LILO command line and /etc/lilo.conf option.
        !           391:      This option can be used to either disable I/O port scanning or to limit
        !           392:      scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and
        !           393:      PCI boards will still be searched for and detected. This option only
        !           394:      affects searching for ISA and VL boards.
        !           395: 
        !           396:      Examples:
        !           397:        1. Eliminate I/O port scanning:
        !           398:             boot: linux advansys=
        !           399:               or
        !           400:             boot: linux advansys=0x0
        !           401:        2. Limit I/O port scanning to one I/O port:
        !           402:             boot: linux advansys=0x110
        !           403:        3. Limit I/O port scanning to four I/O ports:
        !           404:             boot: linux advansys=0x110,0x210,0x230,0x330
        !           405: 
        !           406:      For a loadable module the same effect can be achieved by setting
        !           407:      the 'asc_iopflag' variable and 'asc_ioport' array when loading
        !           408:      the driver, e.g.
        !           409: 
        !           410:            insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330
        !           411: 
        !           412:      If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_IOPORT_PROBE + 1)
        !           413:      I/O Port may be added to specify the driver debug level. Refer to
        !           414:      the 'Driver Compile Time Options and Debugging' section above for
        !           415:      more information.
        !           416: 
        !           417:   I. Release History
        !           418: 
        !           419:      BETA-1.0 (12/23/95): 
        !           420:          First Release
        !           421: 
        !           422:      BETA-1.1 (12/28/95):
        !           423:          1. Prevent advansys_detect() from being called twice.
        !           424:          2. Add LILO 0xdeb[0-f] option to set 'asc_dbglvl'.
        !           425: 
        !           426:      1.2 (1/12/96):
        !           427:          1. Prevent re-entrancy in the interrupt handler which
        !           428:             resulted in the driver hanging Linux.
        !           429:          2. Fix problem that prevented ABP-940 cards from being
        !           430:             recognized on some PCI motherboards.
        !           431:          3. Add support for the ABP-5140 PnP ISA card.
        !           432:          4. Fix check condition return status.
        !           433:          5. Add conditionally compiled code for Linux v1.3.X.
        !           434: 
        !           435:      1.3 (2/23/96):
        !           436:          1. Fix problem in advansys_biosparam() that resulted in the
        !           437:             wrong drive geometry being returned for drives > 1GB with
        !           438:             extended translation enabled.
        !           439:          2. Add additional tracing during device initialization.
        !           440:          3. Change code that only applies to ISA PnP adapter.
        !           441:          4. Eliminate 'make dep' warning.
        !           442:          5. Try to fix problem with handling resets by increasing their
        !           443:             timeout value.
        !           444: 
        !           445:      1.4 (5/8/96):
        !           446:          1. Change definitions to eliminate conflicts with other subsystems.
        !           447:          2. Add versioning code for the shared interrupt changes.
        !           448:          3. Eliminate problem in asc_rmqueue() with iterating after removing
        !           449:             a request.
        !           450:          4. Remove reset request loop problem from the "Known Problems or
        !           451:             Issues" section. This problem was isolated and fixed in the
        !           452:             mid-level SCSI driver.
        !           453:         
        !           454:      1.5 (8/8/96):
        !           455:          1. Add support for ABP-940U (PCI Ultra) adapter.
        !           456:          2. Add support for IRQ sharing by setting the SA_SHIRQ flag for
        !           457:             request_irq and supplying a dev_id pointer to both request_irq()
        !           458:             and free_irq().
        !           459:          3. In AscSearchIOPortAddr11() restore a call to check_region() which
        !           460:             should be used before I/O port probing.
        !           461:          4. Fix bug in asc_prt_hex() which resulted in the displaying
        !           462:             the wrong data.
        !           463:          5. Incorporate miscellaneous Asc Library bug fixes and new microcode.
        !           464:          6. Change driver versioning to be specific to each Linux sub-level.
        !           465:          7. Change statistics gathering to be per adapter instead of global
        !           466:             to the driver.
        !           467:          8. Add more information and statistics to the adapter /proc file:
        !           468:             /proc/scsi/advansys[0...].
        !           469:          9. Remove 'cmd_per_lun' from the "Known Problems or Issues" list.
        !           470:             This problem has been addressed with the SCSI mid-level changes
        !           471:             made in v1.3.89. The advansys_select_queue_depths() function
        !           472:             was added for the v1.3.89 changes.
        !           473: 
        !           474:      1.6 (9/10/96):
        !           475:          1. Incorporate miscellaneous Asc Library bug fixes and new microcode.
        !           476: 
        !           477:      1.7 (9/25/96):
        !           478:          1. Enable clustering and optimize the setting of the maximum number
        !           479:             of scatter gather elements for any particular board. Clustering
        !           480:             increases CPU utilization, but results in a relatively larger
        !           481:             increase in I/O throughput.
        !           482:          2. Improve the performance of the request queuing functions by
        !           483:             adding a last pointer to the queue structure.
        !           484:          3. Correct problems with reset and abort request handling that
        !           485:             could have hung or crashed Linux.
        !           486:          4. Add more information to the adapter /proc file:
        !           487:             /proc/scsi/advansys[0...].
        !           488:          5. Remove the request timeout issue form the driver issues list.
        !           489:          6. Miscellaneous documentation additions and changes.
        !           490: 
        !           491:      1.8 (10/4/96):
        !           492:          1. Make changes to handle the new v2.1.0 kernel memory mapping
        !           493:             in which a kernel virtual address may not be equivalent to its
        !           494:             bus or DMA memory address.
        !           495:          2. Change abort and reset request handling to make it yet even
        !           496:             more robust.
        !           497:          3. Try to mitigate request starvation by sending ordered requests
        !           498:             to heavily loaded, tag queuing enabled devices.
        !           499:          4. Maintain statistics on request response time.
        !           500:          5. Add request response time statistics and other information to
        !           501:             the adapter /proc file: /proc/scsi/advansys[0...].
        !           502: 
        !           503:      1.9 (10/21/96):
        !           504:          1. Add conditionally compiled code (ASC_QUEUE_FLOW_CONTROL) to
        !           505:             make use of mid-level SCSI driver device queue depth flow
        !           506:             control mechanism. This will eliminate aborts caused by a
        !           507:             device being unable to keep up with requests and eliminate
        !           508:             repeat busy or QUEUE FULL status returned by a device.
        !           509:          2. Incorporate miscellaneous Asc Library bug fixes.
        !           510:          3. To allow the driver to work in kernels with broken module
        !           511:             support set 'cmd_per_lun' if the driver is compiled as a
        !           512:             module. This change affects kernels v1.3.89 to present.
        !           513:          4. Remove PCI BIOS address from the driver banner. The PCI BIOS
        !           514:             is relocated by the motherboard BIOS and its new address can
        !           515:             not be determined by the driver.
        !           516:          5. Add mid-level SCSI queue depth information to the adapter
        !           517:             /proc file: /proc/scsi/advansys[0...].
        !           518: 
        !           519:      2.0 (11/14/96):
        !           520:          1. Change allocation of global structures used for device
        !           521:             initialization to guarantee they are in DMA-able memory.
        !           522:             Previously when the driver was loaded as a module these
        !           523:             structures might not have been in DMA-able memory, causing
        !           524:             device initialization to fail.
        !           525: 
        !           526:      2.1 (12/30/96):
        !           527:          1. In advansys_reset(), if the request is a synchronous reset
        !           528:             request, even if the request serial number has changed, then
        !           529:             complete the request.
        !           530:          2. Add Asc Library bug fixes including new microcode.
        !           531:          3. Clear inquiry buffer before using it.
        !           532:          4. Correct ifdef typo.
        !           533: 
        !           534:      2.2 (1/15/97):
        !           535:          1. Add Asc Library bug fixes including new microcode.
        !           536:          2. Add synchronous data transfer rate information to the
        !           537:             adapter /proc file: /proc/scsi/advansys[0...].
        !           538:          3. Change ADVANSYS_DEBUG to be disabled by default. This
        !           539:             will reduce the size of the driver image, eliminate execution
        !           540:             overhead, and remove unneeded symbols from the kernel symbol
        !           541:             space that were previously added by the driver.
        !           542:          4. Add new compile-time option ADVANSYS_ASSERT for assertion
        !           543:             code that used to be defined within ADVANSYS_DEBUG. This
        !           544:             option is enabled by default.
        !           545: 
        !           546:      2.8 (5/26/97):
        !           547:          1. Change version number to 2.8 to synchronize the Linux driver
        !           548:             version numbering with other AdvanSys drivers.
        !           549:          2. Reformat source files without tabs to present the same view
        !           550:             of the file to everyone regardless of the editor tab setting
        !           551:             being used.
        !           552:          3. Add Asc Library bug fixes.
        !           553: 
        !           554:      3.1A (1/8/98):
        !           555:          1. Change version number to 3.1 to indicate that support for
        !           556:             Ultra-Wide adapters (ABP-940UW) is included in this release.
        !           557:          2. Add Asc Library (Narrow Board) bug fixes.
        !           558:          3. Report an underrun condition with the host status byte set
        !           559:             to DID_UNDERRUN. Currently DID_UNDERRUN is defined to 0 which
        !           560:             causes the underrun condition to be ignored. When Linux defines
        !           561:             its own DID_UNDERRUN the constant defined in this file can be
        !           562:             removed.
        !           563:          4. Add patch to AscWaitTixISRDone().
        !           564:          5. Add support for up to 16 different AdvanSys host adapter SCSI
        !           565:             channels in one system. This allows four cards with four channels
        !           566:             to be used in one system.
        !           567: 
        !           568:      3.1B (1/9/98):
        !           569:          1. Handle that PCI register base addresses are not always page
        !           570:             aligned even though ioremap() requires that the address argument
        !           571:             be page aligned.
        !           572: 
        !           573:      3.1C (1/10/98):
        !           574:          1. Update latest BIOS version checked for from the /proc file.
        !           575:          2. Don't set microcode SDTR variable at initialization. Instead
        !           576:             wait until device capabilities have been detected from an Inquiry
        !           577:             command.
        !           578: 
        !           579:      3.1D (1/21/98):
        !           580:          1. Improve performance when the driver is compiled as module by
        !           581:             allowing up to 64 scatter-gather elements instead of 8.
        !           582: 
        !           583:      3.1E (5/1/98):
        !           584:          1. Set time delay in AscWaitTixISRDone() to 1000 ms.
        !           585:          2. Include SMP locking changes.
        !           586:          3. For v2.1.93 and newer kernels use CONFIG_PCI and new PCI BIOS
        !           587:             access functions.
        !           588:          4. Update board serial number printing.
        !           589:          5. Try allocating an IRQ both with and without the SA_INTERRUPT
        !           590:             flag set to allow IRQ sharing with drivers that do not set
        !           591:             the SA_INTERRUPT flag. Also display a more descriptive error
        !           592:             message if request_irq() fails.
        !           593:          5. Update to latest Asc and Adv Libraries.
        !           594: 
        !           595:   J. Known Problems or Issues
        !           596: 
        !           597:          1. Remove conditional constants (ASC_QUEUE_FLOW_CONTROL) around
        !           598:             the queue depth flow control code when mid-level SCSI changes
        !           599:             are included in Linux.
        !           600: 
        !           601:   K. Credits
        !           602: 
        !           603:      Nathan Hartwell <[email protected]> provided the directions and
        !           604:      basis for the Linux v1.3.X changes which were included in the
        !           605:      1.2 release.
        !           606: 
        !           607:      Thomas E Zerucha <[email protected]> pointed out a bug
        !           608:      in advansys_biosparam() which was fixed in the 1.3 release.
        !           609: 
        !           610:      Erik Ratcliffe <[email protected]> has done testing of the
        !           611:      AdvanSys driver in the Caldera releases.
        !           612: 
        !           613:      Rik van Riel <[email protected]> provided a patch to
        !           614:      AscWaitTixISRDone() which he found necessary to make the
        !           615:      driver work with a SCSI-1 disk.
        !           616: 
        !           617:      Mark Moran <[email protected]> has helped test Ultra-Wide
        !           618:      support in the 3.1A driver.
        !           619: 
        !           620:   L. AdvanSys Contact Information
        !           621:  
        !           622:      Mail:                   Advanced System Products, Inc.
        !           623:                              1150 Ringwood Court
        !           624:                              San Jose, CA 95131
        !           625:      Operator:               1-408-383-9400
        !           626:      FAX:                    1-408-383-9612
        !           627:      Tech Support:           1-800-525-7440/1-408-467-2930
        !           628:      BBS:                    1-408-383-9540 (14400,N,8,1)
        !           629:      Interactive FAX:        1-408-383-9753
        !           630:      Customer Direct Sales:  1-800-525-7443/1-408-383-5777
        !           631:      Tech Support E-Mail:    [email protected]
        !           632:      FTP Site:               ftp.advansys.com (login: anonymous)
        !           633:      Web Site:               http://www.advansys.com
        !           634: 
        !           635: */
        !           636: 
        !           637: 
        !           638: /*
        !           639:  * --- Linux Version
        !           640:  */
        !           641: 
        !           642: /* Convert Linux Version, Patch-level, Sub-level to LINUX_VERSION_CODE. */
        !           643: #define ASC_LINUX_VERSION(V, P, S)    (((V) * 65536) + ((P) * 256) + (S))
        !           644: 
        !           645: #ifndef LINUX_VERSION_CODE
        !           646: #include <linux/version.h>
        !           647: #endif /* LINUX_VERSION_CODE */
        !           648: 
        !           649: 
        !           650: /*
        !           651:  * --- Linux Include Files 
        !           652:  */
        !           653: 
        !           654: #include <linux/config.h>
        !           655: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
        !           656: #ifdef MODULE
        !           657: #include <linux/module.h>
        !           658: #endif /* MODULE */
        !           659: #endif /* version >= v1.3.0 */
        !           660: #include <linux/string.h>
        !           661: #include <linux/sched.h>
        !           662: #include <linux/kernel.h>
        !           663: #include <linux/head.h>
        !           664: #include <linux/types.h>
        !           665: #include <linux/ioport.h>
        !           666: #include <linux/delay.h>
        !           667: #include <linux/malloc.h>
        !           668: #include <linux/mm.h>
        !           669: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
        !           670: #include <linux/proc_fs.h>
        !           671: #endif /* version >= v1.3.0 */
        !           672: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,23)
        !           673: #include <linux/init.h>
        !           674: #endif /* version >= v2.1.23 */
        !           675: #include <asm/io.h>
        !           676: #include <asm/system.h>
        !           677: #include <asm/dma.h>
        !           678: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
        !           679: #include "../block/blk.h"
        !           680: #else /* version >= v1.3.0 */
        !           681: #include <linux/blk.h>
        !           682: #include <linux/stat.h>
        !           683: #endif /* version >= v1.3.0 */
        !           684: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,95)
        !           685: #include <asm/spinlock.h>
        !           686: #endif /* version >= 2.1.95 */
        !           687: #include "scsi.h"
        !           688: #include "hosts.h"
        !           689: #include "sd.h"
        !           690: #include "advansys.h"
        !           691: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,93)
        !           692: #ifdef CONFIG_PCI
        !           693: #include <linux/pci.h>
        !           694: #endif /* CONFIG_PCI */
        !           695: #else /* version < v2.1.93 */
        !           696: /*
        !           697:  * For earlier than v2.1.93 the driver has its own PCI configuration.
        !           698:  * If PCI is not needed in a kernel before v2.1.93 this define can be
        !           699:  * turned-off to make the driver object smaller.
        !           700:  */
        !           701: #define ASC_CONFIG_PCI
        !           702: #endif /* version < v2.1.93 */
        !           703: 
        !           704: /*
        !           705:  * If Linux eventually defines a DID_UNDERRUN, the constant here can be
        !           706:  * removed. The current value of zero for DID_UNDERRUN results in underrun
        !           707:  * conditions being ignored.
        !           708:  */
        !           709: #define DID_UNDERRUN 0
        !           710: 
        !           711: 
        !           712: /*
        !           713:  * --- Driver Options
        !           714:  */
        !           715: 
        !           716: /* Enable driver assertions. */
        !           717: #define ADVANSYS_ASSERT
        !           718: 
        !           719: /* Enable driver tracing. */
        !           720: /* #define ADVANSYS_DEBUG */
        !           721: 
        !           722: /*
        !           723:  * Because of no /proc to display them, statistics are disabled
        !           724:  * for versions prior to v1.3.0.
        !           725:  */
        !           726: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
        !           727: #undef ADVANSYS_STATS /* Disable statistics */
        !           728: #else /* version >= v1.3.0 */
        !           729: #define ADVANSYS_STATS /* Enable statistics. */
        !           730: #endif /* version >= v1.3.0 */
        !           731: 
        !           732: 
        !           733: /*
        !           734:  * --- Debugging Header
        !           735:  */
        !           736: 
        !           737: #ifdef ADVANSYS_DEBUG
        !           738: #define STATIC
        !           739: #else /* ADVANSYS_DEBUG */
        !           740: #define STATIC static
        !           741: #endif /* ADVANSYS_DEBUG */
        !           742: 
        !           743: 
        !           744: /*
        !           745:  * --- Asc Library Constants and Macros
        !           746:  */
        !           747: 
        !           748: #define ASC_LIB_VERSION_MAJOR  1
        !           749: #define ASC_LIB_VERSION_MINOR  22
        !           750: #define ASC_LIB_SERIAL_NUMBER  113
        !           751: 
        !           752: typedef unsigned char uchar;
        !           753: 
        !           754: #ifndef NULL
        !           755: #define NULL     (0)
        !           756: #endif
        !           757: #ifndef TRUE
        !           758: #define TRUE     (1)
        !           759: #endif
        !           760: #ifndef FALSE
        !           761: #define FALSE    (0)
        !           762: #endif
        !           763: #define  REG     register
        !           764: #define rchar    REG __s8
        !           765: #define rshort   REG __s16
        !           766: #define rint     REG __s32
        !           767: #define rlong    REG __s32
        !           768: #define ruchar   REG __u8
        !           769: #define rushort  REG __u16
        !           770: #define ruint    REG __u32
        !           771: #define rulong   REG __u32
        !           772: #define NULLPTR  (void *)0
        !           773: #define FNULLPTR (void *)0UL
        !           774: #define EOF      (-1)
        !           775: #define EOS      '\0'
        !           776: #define ERR      (-1)
        !           777: #define UB_ERR   (uchar)(0xFF)
        !           778: #define UW_ERR   (uint)(0xFFFF)
        !           779: #define UL_ERR   (ulong)(0xFFFFFFFFUL)
        !           780: #define iseven_word(val)  ((((uint)val) & (uint)0x0001) == 0)
        !           781: #define isodd_word(val)   ((((uint)val) & (uint)0x0001) != 0)
        !           782: #define toeven_word(val)  (((uint)val) & (uint)0xFFFE)
        !           783: #define biton(val, bits)   (((uint)(val >> bits) & (uint)0x0001) != 0)
        !           784: #define bitoff(val, bits)  (((uint)(val >> bits) & (uint)0x0001) == 0)
        !           785: #define lbiton(val, bits)  (((ulong)(val >> bits) & (ulong)0x00000001UL) != 0)
        !           786: #define lbitoff(val, bits) (((ulong)(val >> bits) & (ulong)0x00000001UL) == 0)
        !           787: #define  absh(val)    ((val) < 0 ? -(val) : (val))
        !           788: #define  swapbyte(ch)  ((((ch) << 4) | ((ch) >> 4)))
        !           789: #ifndef GBYTE
        !           790: #define GBYTE       (0x40000000UL)
        !           791: #endif
        !           792: #ifndef MBYTE
        !           793: #define MBYTE       (0x100000UL)
        !           794: #endif
        !           795: #ifndef KBYTE
        !           796: #define KBYTE       (0x400)
        !           797: #endif
        !           798: #define HI_BYTE(x) (*((__u8 *)(&x)+1))
        !           799: #define LO_BYTE(x) (*((__u8 *)&x))
        !           800: #define HI_WORD(x) (*((__u16 *)(&x)+1))
        !           801: #define LO_WORD(x) (*((__u16 *)&x))
        !           802: #ifndef MAKEWORD
        !           803: #define MAKEWORD(lo, hi)    ((__u16) (((__u16) lo) | ((__u16) hi << 8)))
        !           804: #endif
        !           805: #ifndef MAKELONG
        !           806: #define MAKELONG(lo, hi)    ((__u32) (((__u32) lo) | ((__u32) hi << 16)))
        !           807: #endif
        !           808: #define SwapWords(dWord)        ((__u32) ((dWord >> 16) | (dWord << 16)))
        !           809: #define SwapBytes(word)         ((__u16) ((word >> 8) | (word << 8)))
        !           810: #define BigToLittle(dWord) ((__u32) (SwapWords(MAKELONG(SwapBytes(LO_WORD(dWord)), SwapBytes(HI_WORD(dWord))))))
        !           811: #define LittleToBig(dWord)      BigToLittle(dWord)
        !           812: #define AscPCIConfigVendorIDRegister      0x0000
        !           813: #define AscPCIConfigDeviceIDRegister      0x0002
        !           814: #define AscPCIConfigCommandRegister       0x0004
        !           815: #define AscPCIConfigStatusRegister        0x0006
        !           816: #define AscPCIConfigRevisionIDRegister    0x0008
        !           817: #define AscPCIConfigCacheSize             0x000C
        !           818: #define AscPCIConfigLatencyTimer          0x000D
        !           819: #define AscPCIIOBaseRegister              0x0010
        !           820: #define AscPCICmdRegBits_IOMemBusMaster   0x0007
        !           821: #define ASC_PCI_ID2BUS(id)    ((id) & 0xFF)
        !           822: #define ASC_PCI_ID2DEV(id)    (((id) >> 11) & 0x1F)
        !           823: #define ASC_PCI_ID2FUNC(id)   (((id) >> 8) & 0x7)
        !           824: #define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF))
        !           825: #define ASC_PCI_VENDORID                  0x10CD
        !           826: #define ASC_PCI_DEVICEID_1200A            0x1100
        !           827: #define ASC_PCI_DEVICEID_1200B            0x1200
        !           828: #define ASC_PCI_DEVICEID_ULTRA            0x1300 
        !           829: #define ASC_PCI_REVISION_3150             0x02
        !           830: #define ASC_PCI_REVISION_3050             0x03
        !           831: 
        !           832: #define  ASC_DVCLIB_CALL_DONE     (1)
        !           833: #define  ASC_DVCLIB_CALL_FAILED   (0)
        !           834: #define  ASC_DVCLIB_CALL_ERROR    (-1)
        !           835: 
        !           836: #define PortAddr            unsigned short    /* port address size  */
        !           837: #define Ptr2Func            ulong
        !           838: #define inp(port)           inb(port)
        !           839: #define inpw(port)          inw(port)
        !           840: #define inpl(port)          inl(port)
        !           841: #define outp(port, byte)    outb((byte), (port))
        !           842: #define outpw(port, word)   outw((word), (port))
        !           843: #define outpl(port, long)   outl((long), (port))
        !           844: #define ASC_MAX_SG_QUEUE    7
        !           845: #define ASC_MAX_SG_LIST     SG_ALL
        !           846: 
        !           847: #define ASC_CS_TYPE  unsigned short
        !           848: #ifndef asc_ptr_type
        !           849: #define asc_ptr_type
        !           850: #endif
        !           851: 
        !           852: #ifndef ASC_GET_PTR2FUNC
        !           853: #define ASC_GET_PTR2FUNC(fun)  (Ptr2Func)(fun)
        !           854: #endif
        !           855: #define FLIP_BYTE_NIBBLE(x)    (((x<<4)& 0xFF) | (x>>4))
        !           856: #define ASC_IS_ISA          (0x0001)
        !           857: #define ASC_IS_ISAPNP       (0x0081)
        !           858: #define ASC_IS_EISA         (0x0002)
        !           859: #define ASC_IS_PCI          (0x0004)
        !           860: #define ASC_IS_PCI_ULTRA    (0x0104)
        !           861: #define ASC_IS_PCMCIA       (0x0008)
        !           862: #define ASC_IS_MCA          (0x0020)
        !           863: #define ASC_IS_VL           (0x0040)
        !           864: #define ASC_ISA_PNP_PORT_ADDR  (0x279)
        !           865: #define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
        !           866: #define ASC_IS_WIDESCSI_16  (0x0100)
        !           867: #define ASC_IS_WIDESCSI_32  (0x0200)
        !           868: #define ASC_IS_BIG_ENDIAN   (0x8000)
        !           869: #define ASC_CHIP_MIN_VER_VL      (0x01)
        !           870: #define ASC_CHIP_MAX_VER_VL      (0x07)
        !           871: #define ASC_CHIP_MIN_VER_PCI     (0x09)
        !           872: #define ASC_CHIP_MAX_VER_PCI     (0x0F)
        !           873: #define ASC_CHIP_VER_PCI_BIT     (0x08)
        !           874: #define ASC_CHIP_MIN_VER_ISA     (0x11)
        !           875: #define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
        !           876: #define ASC_CHIP_MAX_VER_ISA     (0x27)
        !           877: #define ASC_CHIP_VER_ISA_BIT     (0x30)
        !           878: #define ASC_CHIP_VER_ISAPNP_BIT  (0x20)
        !           879: #define ASC_CHIP_VER_ASYN_BUG    (0x21)
        !           880: #define ASC_CHIP_VER_PCI             0x08
        !           881: #define ASC_CHIP_VER_PCI_ULTRA_3150  (ASC_CHIP_VER_PCI | 0x02)
        !           882: #define ASC_CHIP_VER_PCI_ULTRA_3050  (ASC_CHIP_VER_PCI | 0x03)
        !           883: #define ASC_CHIP_MIN_VER_EISA (0x41)
        !           884: #define ASC_CHIP_MAX_VER_EISA (0x47)
        !           885: #define ASC_CHIP_VER_EISA_BIT (0x40)
        !           886: #define ASC_CHIP_LATEST_VER_EISA   ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
        !           887: #define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER   0x21
        !           888: #define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER   0x0A
        !           889: #define ASC_MAX_VL_DMA_ADDR     (0x07FFFFFFL)
        !           890: #define ASC_MAX_VL_DMA_COUNT    (0x07FFFFFFL)
        !           891: #define ASC_MAX_PCI_DMA_ADDR    (0xFFFFFFFFL)
        !           892: #define ASC_MAX_PCI_DMA_COUNT   (0xFFFFFFFFL)
        !           893: #define ASC_MAX_ISA_DMA_ADDR    (0x00FFFFFFL)
        !           894: #define ASC_MAX_ISA_DMA_COUNT   (0x00FFFFFFL)
        !           895: #define ASC_MAX_EISA_DMA_ADDR   (0x07FFFFFFL)
        !           896: #define ASC_MAX_EISA_DMA_COUNT  (0x07FFFFFFL)
        !           897: #ifndef inpw_noswap
        !           898: #define inpw_noswap(port)         inpw(port)
        !           899: #endif
        !           900: #ifndef outpw_noswap
        !           901: #define outpw_noswap(port, data)  outpw(port, data)
        !           902: #endif
        !           903: #define ASC_SCSI_ID_BITS  3
        !           904: #define ASC_SCSI_TIX_TYPE     uchar
        !           905: #define ASC_ALL_DEVICE_BIT_SET  0xFF
        !           906: #ifdef ASC_WIDESCSI_16
        !           907: #undef  ASC_SCSI_ID_BITS
        !           908: #define ASC_SCSI_ID_BITS  4
        !           909: #define ASC_ALL_DEVICE_BIT_SET  0xFFFF
        !           910: #endif
        !           911: #ifdef ASC_WIDESCSI_32
        !           912: #undef  ASC_SCSI_ID_BITS
        !           913: #define ASC_SCSI_ID_BITS  5
        !           914: #define ASC_ALL_DEVICE_BIT_SET  0xFFFFFFFFL
        !           915: #endif
        !           916: #if ASC_SCSI_ID_BITS == 3
        !           917: #define ASC_SCSI_BIT_ID_TYPE  uchar
        !           918: #define ASC_MAX_TID       7
        !           919: #define ASC_MAX_LUN       7
        !           920: #define ASC_SCSI_WIDTH_BIT_SET  0xFF
        !           921: #elif ASC_SCSI_ID_BITS == 4
        !           922: #define ASC_SCSI_BIT_ID_TYPE   ushort
        !           923: #define ASC_MAX_TID         15
        !           924: #define ASC_MAX_LUN         7
        !           925: #define ASC_SCSI_WIDTH_BIT_SET  0xFFFF
        !           926: #elif ASC_SCSI_ID_BITS == 5
        !           927: #define ASC_SCSI_BIT_ID_TYPE    ulong
        !           928: #define ASC_MAX_TID         31
        !           929: #define ASC_MAX_LUN         7
        !           930: #define ASC_SCSI_WIDTH_BIT_SET  0xFFFFFFFF
        !           931: #else
        !           932: #error  ASC_SCSI_ID_BITS definition is wrong
        !           933: #endif
        !           934: #define ASC_MAX_SENSE_LEN   32
        !           935: #define ASC_MIN_SENSE_LEN   14
        !           936: #define ASC_MAX_CDB_LEN     12
        !           937: #define ASC_SCSI_RESET_HOLD_TIME_US  60
        !           938: #define SCSICMD_TestUnitReady     0x00
        !           939: #define SCSICMD_Rewind            0x01
        !           940: #define SCSICMD_Rezero            0x01
        !           941: #define SCSICMD_RequestSense      0x03
        !           942: #define SCSICMD_Format            0x04
        !           943: #define SCSICMD_FormatUnit        0x04
        !           944: #define SCSICMD_Read6             0x08
        !           945: #define SCSICMD_Write6            0x0A
        !           946: #define SCSICMD_Seek6             0x0B
        !           947: #define SCSICMD_Inquiry           0x12
        !           948: #define SCSICMD_Verify6           0x13
        !           949: #define SCSICMD_ModeSelect6       0x15
        !           950: #define SCSICMD_ModeSense6        0x1A
        !           951: #define SCSICMD_StartStopUnit     0x1B
        !           952: #define SCSICMD_LoadUnloadTape    0x1B
        !           953: #define SCSICMD_ReadCapacity      0x25
        !           954: #define SCSICMD_Read10            0x28
        !           955: #define SCSICMD_Write10           0x2A
        !           956: #define SCSICMD_Seek10            0x2B
        !           957: #define SCSICMD_Erase10           0x2C
        !           958: #define SCSICMD_WriteAndVerify10  0x2E
        !           959: #define SCSICMD_Verify10          0x2F
        !           960: #define SCSICMD_WriteBuffer       0x3B
        !           961: #define SCSICMD_ReadBuffer        0x3C
        !           962: #define SCSICMD_ReadLong          0x3E
        !           963: #define SCSICMD_WriteLong         0x3F
        !           964: #define SCSICMD_ReadTOC           0x43
        !           965: #define SCSICMD_ReadHeader        0x44
        !           966: #define SCSICMD_ModeSelect10      0x55
        !           967: #define SCSICMD_ModeSense10       0x5A
        !           968: #define SCSI_TYPE_DASD     0x00
        !           969: #define SCSI_TYPE_SASD     0x01
        !           970: #define SCSI_TYPE_PRN      0x02
        !           971: #define SCSI_TYPE_PROC     0x03
        !           972: #define SCSI_TYPE_WORM     0x04
        !           973: #define SCSI_TYPE_CDROM    0x05
        !           974: #define SCSI_TYPE_SCANNER  0x06
        !           975: #define SCSI_TYPE_OPTMEM   0x07
        !           976: #define SCSI_TYPE_MED_CHG  0x08
        !           977: #define SCSI_TYPE_COMM     0x09
        !           978: #define SCSI_TYPE_UNKNOWN  0x1F
        !           979: #define SCSI_TYPE_NO_DVC   0xFF
        !           980: #define ASC_SCSIDIR_NOCHK    0x00
        !           981: #define ASC_SCSIDIR_T2H      0x08
        !           982: #define ASC_SCSIDIR_H2T      0x10
        !           983: #define ASC_SCSIDIR_NODATA   0x18
        !           984: #define SCSI_SENKEY_NO_SENSE      0x00
        !           985: #define SCSI_SENKEY_UNDEFINED     0x01
        !           986: #define SCSI_SENKEY_NOT_READY     0x02
        !           987: #define SCSI_SENKEY_MEDIUM_ERR    0x03
        !           988: #define SCSI_SENKEY_HW_ERR        0x04
        !           989: #define SCSI_SENKEY_ILLEGAL       0x05
        !           990: #define SCSI_SENKEY_ATTENTION     0x06
        !           991: #define SCSI_SENKEY_PROTECTED     0x07
        !           992: #define SCSI_SENKEY_BLANK         0x08
        !           993: #define SCSI_SENKEY_V_UNIQUE      0x09
        !           994: #define SCSI_SENKEY_CPY_ABORT     0x0A
        !           995: #define SCSI_SENKEY_ABORT         0x0B
        !           996: #define SCSI_SENKEY_EQUAL         0x0C
        !           997: #define SCSI_SENKEY_VOL_OVERFLOW  0x0D
        !           998: #define SCSI_SENKEY_MISCOMP       0x0E
        !           999: #define SCSI_SENKEY_RESERVED      0x0F
        !          1000: #define SCSI_ASC_NOMEDIA          0x3A
        !          1001: #define ASC_SRB_HOST(x)  ((uchar)((uchar)(x) >> 4))
        !          1002: #define ASC_SRB_TID(x)   ((uchar)((uchar)(x) & (uchar)0x0F))
        !          1003: #define ASC_SRB_LUN(x)   ((uchar)((uint)(x) >> 13))
        !          1004: #define PUT_CDB1(x)   ((uchar)((uint)(x) >> 8))
        !          1005: #define SS_GOOD              0x00
        !          1006: #define SS_CHK_CONDITION     0x02
        !          1007: #define SS_CONDITION_MET     0x04
        !          1008: #define SS_TARGET_BUSY       0x08
        !          1009: #define SS_INTERMID          0x10
        !          1010: #define SS_INTERMID_COND_MET 0x14
        !          1011: #define SS_RSERV_CONFLICT    0x18
        !          1012: #define SS_CMD_TERMINATED    0x22
        !          1013: #define SS_QUEUE_FULL        0x28
        !          1014: #define MS_CMD_DONE    0x00
        !          1015: #define MS_EXTEND      0x01
        !          1016: #define MS_SDTR_LEN    0x03
        !          1017: #define MS_SDTR_CODE   0x01
        !          1018: #define MS_WDTR_LEN    0x02
        !          1019: #define MS_WDTR_CODE   0x03
        !          1020: #define MS_MDP_LEN    0x05
        !          1021: #define MS_MDP_CODE   0x00
        !          1022: #define M1_SAVE_DATA_PTR        0x02
        !          1023: #define M1_RESTORE_PTRS         0x03
        !          1024: #define M1_DISCONNECT           0x04
        !          1025: #define M1_INIT_DETECTED_ERR    0x05
        !          1026: #define M1_ABORT                0x06
        !          1027: #define M1_MSG_REJECT           0x07
        !          1028: #define M1_NO_OP                0x08
        !          1029: #define M1_MSG_PARITY_ERR       0x09
        !          1030: #define M1_LINK_CMD_DONE        0x0A
        !          1031: #define M1_LINK_CMD_DONE_WFLAG  0x0B
        !          1032: #define M1_BUS_DVC_RESET        0x0C
        !          1033: #define M1_ABORT_TAG            0x0D
        !          1034: #define M1_CLR_QUEUE            0x0E
        !          1035: #define M1_INIT_RECOVERY        0x0F
        !          1036: #define M1_RELEASE_RECOVERY     0x10
        !          1037: #define M1_KILL_IO_PROC         0x11
        !          1038: #define M2_QTAG_MSG_SIMPLE      0x20
        !          1039: #define M2_QTAG_MSG_HEAD        0x21
        !          1040: #define M2_QTAG_MSG_ORDERED     0x22
        !          1041: #define M2_IGNORE_WIDE_RESIDUE  0x23
        !          1042: 
        !          1043: typedef struct {
        !          1044:     uchar               peri_dvc_type:5;
        !          1045:     uchar               peri_qualifier:3;
        !          1046: } ASC_SCSI_INQ0;
        !          1047: 
        !          1048: typedef struct {
        !          1049:     uchar               dvc_type_modifier:7;
        !          1050:     uchar               rmb:1;
        !          1051: } ASC_SCSI_INQ1;
        !          1052: 
        !          1053: typedef struct {
        !          1054:     uchar               ansi_apr_ver:3;
        !          1055:     uchar               ecma_ver:3;
        !          1056:     uchar               iso_ver:2;
        !          1057: } ASC_SCSI_INQ2;
        !          1058: 
        !          1059: typedef struct {
        !          1060:     uchar               rsp_data_fmt:4;
        !          1061:     uchar               res:2;
        !          1062:     uchar               TemIOP:1;
        !          1063:     uchar               aenc:1;
        !          1064: } ASC_SCSI_INQ3;
        !          1065: 
        !          1066: typedef struct {
        !          1067:     uchar               StfRe:1;
        !          1068:     uchar               CmdQue:1;
        !          1069:     uchar               Reserved:1;
        !          1070:     uchar               Linked:1;
        !          1071:     uchar               Sync:1;
        !          1072:     uchar               WBus16:1;
        !          1073:     uchar               WBus32:1;
        !          1074:     uchar               RelAdr:1;
        !          1075: } ASC_SCSI_INQ7;
        !          1076: 
        !          1077: typedef struct {
        !          1078:     ASC_SCSI_INQ0       byte0;
        !          1079:     ASC_SCSI_INQ1       byte1;
        !          1080:     ASC_SCSI_INQ2       byte2;
        !          1081:     ASC_SCSI_INQ3       byte3;
        !          1082:     uchar               add_len;
        !          1083:     uchar               res1;
        !          1084:     uchar               res2;
        !          1085:     ASC_SCSI_INQ7       byte7;
        !          1086:     uchar               vendor_id[8];
        !          1087:     uchar               product_id[16];
        !          1088:     uchar               product_rev_level[4];
        !          1089: } ASC_SCSI_INQUIRY;
        !          1090: 
        !          1091: typedef struct asc_req_sense {
        !          1092:     uchar               err_code:7;
        !          1093:     uchar               info_valid:1;
        !          1094:     uchar               segment_no;
        !          1095:     uchar               sense_key:4;
        !          1096:     uchar               reserved_bit:1;
        !          1097:     uchar               sense_ILI:1;
        !          1098:     uchar               sense_EOM:1;
        !          1099:     uchar               file_mark:1;
        !          1100:     uchar               info1[4];
        !          1101:     uchar               add_sense_len;
        !          1102:     uchar               cmd_sp_info[4];
        !          1103:     uchar               asc;
        !          1104:     uchar               ascq;
        !          1105:     uchar               fruc;
        !          1106:     uchar               sks_byte0:7;
        !          1107:     uchar               sks_valid:1;
        !          1108:     uchar               sks_bytes[2];
        !          1109:     uchar               notused[2];
        !          1110:     uchar               ex_sense_code;
        !          1111:     uchar               info2[4];
        !          1112: } ASC_REQ_SENSE;
        !          1113: 
        !          1114: #define ASC_SG_LIST_PER_Q   7
        !          1115: #define QS_FREE        0x00
        !          1116: #define QS_READY       0x01
        !          1117: #define QS_DISC1       0x02
        !          1118: #define QS_DISC2       0x04
        !          1119: #define QS_BUSY        0x08
        !          1120: #define QS_ABORTED     0x40
        !          1121: #define QS_DONE        0x80
        !          1122: #define QC_NO_CALLBACK   0x01
        !          1123: #define QC_SG_SWAP_QUEUE 0x02
        !          1124: #define QC_SG_HEAD       0x04
        !          1125: #define QC_DATA_IN       0x08
        !          1126: #define QC_DATA_OUT      0x10
        !          1127: #define QC_URGENT        0x20
        !          1128: #define QC_MSG_OUT       0x40
        !          1129: #define QC_REQ_SENSE     0x80
        !          1130: #define QCSG_SG_XFER_LIST  0x02
        !          1131: #define QCSG_SG_XFER_MORE  0x04
        !          1132: #define QCSG_SG_XFER_END   0x08
        !          1133: #define QD_IN_PROGRESS       0x00
        !          1134: #define QD_NO_ERROR          0x01
        !          1135: #define QD_ABORTED_BY_HOST   0x02
        !          1136: #define QD_WITH_ERROR        0x04
        !          1137: #define QD_INVALID_REQUEST   0x80
        !          1138: #define QD_INVALID_HOST_NUM  0x81
        !          1139: #define QD_INVALID_DEVICE    0x82
        !          1140: #define QD_ERR_INTERNAL      0xFF
        !          1141: #define QHSTA_NO_ERROR               0x00
        !          1142: #define QHSTA_M_SEL_TIMEOUT          0x11
        !          1143: #define QHSTA_M_DATA_OVER_RUN        0x12
        !          1144: #define QHSTA_M_DATA_UNDER_RUN       0x12
        !          1145: #define QHSTA_M_UNEXPECTED_BUS_FREE  0x13
        !          1146: #define QHSTA_M_BAD_BUS_PHASE_SEQ    0x14
        !          1147: #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
        !          1148: #define QHSTA_D_ASC_DVC_ERROR_CODE_SET  0x22
        !          1149: #define QHSTA_D_HOST_ABORT_FAILED       0x23
        !          1150: #define QHSTA_D_EXE_SCSI_Q_FAILED       0x24
        !          1151: #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
        !          1152: #define QHSTA_D_ASPI_NO_BUF_POOL        0x26
        !          1153: #define QHSTA_M_WTM_TIMEOUT         0x41
        !          1154: #define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
        !          1155: #define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
        !          1156: #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
        !          1157: #define QHSTA_M_TARGET_STATUS_BUSY  0x45
        !          1158: #define QHSTA_M_BAD_TAG_CODE        0x46
        !          1159: #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY  0x47
        !          1160: #define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
        !          1161: #define QHSTA_D_LRAM_CMP_ERROR        0x81
        !          1162: #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
        !          1163: #define ASC_FLAG_SCSIQ_REQ        0x01
        !          1164: #define ASC_FLAG_BIOS_SCSIQ_REQ   0x02
        !          1165: #define ASC_FLAG_BIOS_ASYNC_IO    0x04
        !          1166: #define ASC_FLAG_SRB_LINEAR_ADDR  0x08
        !          1167: #define ASC_FLAG_WIN16            0x10
        !          1168: #define ASC_FLAG_WIN32            0x20
        !          1169: #define ASC_FLAG_ISA_OVER_16MB    0x40
        !          1170: #define ASC_FLAG_DOS_VM_CALLBACK  0x80
        !          1171: #define ASC_TAG_FLAG_EXTRA_BYTES               0x10
        !          1172: #define ASC_TAG_FLAG_DISABLE_DISCONNECT        0x04
        !          1173: #define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX  0x08
        !          1174: #define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
        !          1175: #define ASC_SCSIQ_CPY_BEG              4
        !          1176: #define ASC_SCSIQ_SGHD_CPY_BEG         2
        !          1177: #define ASC_SCSIQ_B_FWD                0
        !          1178: #define ASC_SCSIQ_B_BWD                1
        !          1179: #define ASC_SCSIQ_B_STATUS             2
        !          1180: #define ASC_SCSIQ_B_QNO                3
        !          1181: #define ASC_SCSIQ_B_CNTL               4
        !          1182: #define ASC_SCSIQ_B_SG_QUEUE_CNT       5
        !          1183: #define ASC_SCSIQ_D_DATA_ADDR          8
        !          1184: #define ASC_SCSIQ_D_DATA_CNT          12
        !          1185: #define ASC_SCSIQ_B_SENSE_LEN         20
        !          1186: #define ASC_SCSIQ_DONE_INFO_BEG       22
        !          1187: #define ASC_SCSIQ_D_SRBPTR            22
        !          1188: #define ASC_SCSIQ_B_TARGET_IX         26
        !          1189: #define ASC_SCSIQ_B_CDB_LEN           28
        !          1190: #define ASC_SCSIQ_B_TAG_CODE          29
        !          1191: #define ASC_SCSIQ_W_VM_ID             30
        !          1192: #define ASC_SCSIQ_DONE_STATUS         32
        !          1193: #define ASC_SCSIQ_HOST_STATUS         33
        !          1194: #define ASC_SCSIQ_SCSI_STATUS         34
        !          1195: #define ASC_SCSIQ_CDB_BEG             36
        !          1196: #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
        !          1197: #define ASC_SCSIQ_DW_REMAIN_XFER_CNT  60
        !          1198: #define ASC_SCSIQ_B_SG_WK_QP          49
        !          1199: #define ASC_SCSIQ_B_SG_WK_IX          50
        !          1200: #define ASC_SCSIQ_W_REQ_COUNT         52
        !          1201: #define ASC_SCSIQ_B_LIST_CNT          6
        !          1202: #define ASC_SCSIQ_B_CUR_LIST_CNT      7
        !          1203: #define ASC_SGQ_B_SG_CNTL             4
        !          1204: #define ASC_SGQ_B_SG_HEAD_QP          5
        !          1205: #define ASC_SGQ_B_SG_LIST_CNT         6
        !          1206: #define ASC_SGQ_B_SG_CUR_LIST_CNT     7
        !          1207: #define ASC_SGQ_LIST_BEG              8
        !          1208: #define ASC_DEF_SCSI1_QNG    4
        !          1209: #define ASC_MAX_SCSI1_QNG    4
        !          1210: #define ASC_DEF_SCSI2_QNG    16
        !          1211: #define ASC_MAX_SCSI2_QNG    32
        !          1212: #define ASC_TAG_CODE_MASK    0x23
        !          1213: #define ASC_STOP_REQ_RISC_STOP      0x01
        !          1214: #define ASC_STOP_ACK_RISC_STOP      0x03
        !          1215: #define ASC_STOP_CLEAN_UP_BUSY_Q    0x10
        !          1216: #define ASC_STOP_CLEAN_UP_DISC_Q    0x20
        !          1217: #define ASC_STOP_HOST_REQ_RISC_HALT 0x40
        !          1218: #define ASC_TIDLUN_TO_IX(tid, lun)  (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
        !          1219: #define ASC_TID_TO_TARGET_ID(tid)   (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
        !          1220: #define ASC_TIX_TO_TARGET_ID(tix)   (0x01 << ((tix) & ASC_MAX_TID))
        !          1221: #define ASC_TIX_TO_TID(tix)         ((tix) & ASC_MAX_TID)
        !          1222: #define ASC_TID_TO_TIX(tid)         ((tid) & ASC_MAX_TID)
        !          1223: #define ASC_TIX_TO_LUN(tix)         (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
        !          1224: #define ASC_QNO_TO_QADDR(q_no)      ((ASC_QADR_BEG)+((int)(q_no) << 6))
        !          1225: 
        !          1226: typedef struct asc_scisq_1 {
        !          1227:     uchar               status;
        !          1228:     uchar               q_no;
        !          1229:     uchar               cntl;
        !          1230:     uchar               sg_queue_cnt;
        !          1231:     uchar               target_id;
        !          1232:     uchar               target_lun;
        !          1233:     ulong               data_addr;
        !          1234:     ulong               data_cnt;
        !          1235:     ulong               sense_addr;
        !          1236:     uchar               sense_len;
        !          1237:     uchar               extra_bytes;
        !          1238: } ASC_SCSIQ_1;
        !          1239: 
        !          1240: typedef struct asc_scisq_2 {
        !          1241:     ulong               srb_ptr;
        !          1242:     uchar               target_ix;
        !          1243:     uchar               flag;
        !          1244:     uchar               cdb_len;
        !          1245:     uchar               tag_code;
        !          1246:     ushort              vm_id;
        !          1247: } ASC_SCSIQ_2;
        !          1248: 
        !          1249: typedef struct asc_scsiq_3 {
        !          1250:     uchar               done_stat;
        !          1251:     uchar               host_stat;
        !          1252:     uchar               scsi_stat;
        !          1253:     uchar               scsi_msg;
        !          1254: } ASC_SCSIQ_3;
        !          1255: 
        !          1256: typedef struct asc_scsiq_4 {
        !          1257:     uchar               cdb[ASC_MAX_CDB_LEN];
        !          1258:     uchar               y_first_sg_list_qp;
        !          1259:     uchar               y_working_sg_qp;
        !          1260:     uchar               y_working_sg_ix;
        !          1261:     uchar               y_res;
        !          1262:     ushort              x_req_count;
        !          1263:     ushort              x_reconnect_rtn;
        !          1264:     ulong               x_saved_data_addr;
        !          1265:     ulong               x_saved_data_cnt;
        !          1266: } ASC_SCSIQ_4;
        !          1267: 
        !          1268: typedef struct asc_q_done_info {
        !          1269:     ASC_SCSIQ_2         d2;
        !          1270:     ASC_SCSIQ_3         d3;
        !          1271:     uchar               q_status;
        !          1272:     uchar               q_no;
        !          1273:     uchar               cntl;
        !          1274:     uchar               sense_len;
        !          1275:     uchar               extra_bytes;
        !          1276:     uchar               res;
        !          1277:     ulong               remain_bytes;
        !          1278: } ASC_QDONE_INFO;
        !          1279: 
        !          1280: typedef struct asc_sg_list {
        !          1281:     ulong               addr;
        !          1282:     ulong               bytes;
        !          1283: } ASC_SG_LIST;
        !          1284: 
        !          1285: typedef struct asc_sg_head {
        !          1286:     ushort              entry_cnt;
        !          1287:     ushort              queue_cnt;
        !          1288:     ushort              entry_to_copy;
        !          1289:     ushort              res;
        !          1290:     ASC_SG_LIST         sg_list[ASC_MAX_SG_LIST];
        !          1291: } ASC_SG_HEAD;
        !          1292: 
        !          1293: #define ASC_MIN_SG_LIST   2
        !          1294: 
        !          1295: typedef struct asc_min_sg_head {
        !          1296:     ushort              entry_cnt;
        !          1297:     ushort              queue_cnt;
        !          1298:     ushort              entry_to_copy;
        !          1299:     ushort              res;
        !          1300:     ASC_SG_LIST         sg_list[ASC_MIN_SG_LIST];
        !          1301: } ASC_MIN_SG_HEAD;
        !          1302: 
        !          1303: #define QCX_SORT        (0x0001)
        !          1304: #define QCX_COALEASE    (0x0002)
        !          1305: 
        !          1306: typedef struct asc_scsi_q {
        !          1307:     ASC_SCSIQ_1         q1;
        !          1308:     ASC_SCSIQ_2         q2;
        !          1309:     uchar               *cdbptr;
        !          1310:     ASC_SG_HEAD         *sg_head;
        !          1311: } ASC_SCSI_Q;
        !          1312: 
        !          1313: typedef struct asc_scsi_req_q {
        !          1314:     ASC_SCSIQ_1         r1;
        !          1315:     ASC_SCSIQ_2         r2;
        !          1316:     uchar       *cdbptr;
        !          1317:     ASC_SG_HEAD *sg_head;
        !          1318:     uchar               *sense_ptr;
        !          1319:     ASC_SCSIQ_3         r3;
        !          1320:     uchar               cdb[ASC_MAX_CDB_LEN];
        !          1321:     uchar               sense[ASC_MIN_SENSE_LEN];
        !          1322: } ASC_SCSI_REQ_Q;
        !          1323: 
        !          1324: typedef struct asc_scsi_bios_req_q {
        !          1325:     ASC_SCSIQ_1         r1;
        !          1326:     ASC_SCSIQ_2         r2;
        !          1327:     uchar               *cdbptr;
        !          1328:     ASC_SG_HEAD         *sg_head;
        !          1329:     uchar               *sense_ptr;
        !          1330:     ASC_SCSIQ_3         r3;
        !          1331:     uchar               cdb[ASC_MAX_CDB_LEN];
        !          1332:     uchar               sense[ASC_MIN_SENSE_LEN];
        !          1333: } ASC_SCSI_BIOS_REQ_Q;
        !          1334: 
        !          1335: typedef struct asc_risc_q {
        !          1336:     uchar               fwd;
        !          1337:     uchar               bwd;
        !          1338:     ASC_SCSIQ_1         i1;
        !          1339:     ASC_SCSIQ_2         i2;
        !          1340:     ASC_SCSIQ_3         i3;
        !          1341:     ASC_SCSIQ_4         i4;
        !          1342: } ASC_RISC_Q;
        !          1343: 
        !          1344: typedef struct asc_sg_list_q {
        !          1345:     uchar               seq_no;
        !          1346:     uchar               q_no;
        !          1347:     uchar               cntl;
        !          1348:     uchar               sg_head_qp;
        !          1349:     uchar               sg_list_cnt;
        !          1350:     uchar               sg_cur_list_cnt;
        !          1351: } ASC_SG_LIST_Q;
        !          1352: 
        !          1353: typedef struct asc_risc_sg_list_q {
        !          1354:     uchar               fwd;
        !          1355:     uchar               bwd;
        !          1356:     ASC_SG_LIST_Q       sg;
        !          1357:     ASC_SG_LIST         sg_list[7];
        !          1358: } ASC_RISC_SG_LIST_Q;
        !          1359: 
        !          1360: #define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP  0x1000000UL
        !          1361: #define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP  1024
        !          1362: #define ASCQ_ERR_NO_ERROR             0
        !          1363: #define ASCQ_ERR_IO_NOT_FOUND         1
        !          1364: #define ASCQ_ERR_LOCAL_MEM            2
        !          1365: #define ASCQ_ERR_CHKSUM               3
        !          1366: #define ASCQ_ERR_START_CHIP           4
        !          1367: #define ASCQ_ERR_INT_TARGET_ID        5
        !          1368: #define ASCQ_ERR_INT_LOCAL_MEM        6
        !          1369: #define ASCQ_ERR_HALT_RISC            7
        !          1370: #define ASCQ_ERR_GET_ASPI_ENTRY       8
        !          1371: #define ASCQ_ERR_CLOSE_ASPI           9
        !          1372: #define ASCQ_ERR_HOST_INQUIRY         0x0A
        !          1373: #define ASCQ_ERR_SAVED_SRB_BAD        0x0B
        !          1374: #define ASCQ_ERR_QCNTL_SG_LIST        0x0C
        !          1375: #define ASCQ_ERR_Q_STATUS             0x0D
        !          1376: #define ASCQ_ERR_WR_SCSIQ             0x0E
        !          1377: #define ASCQ_ERR_PC_ADDR              0x0F
        !          1378: #define ASCQ_ERR_SYN_OFFSET           0x10
        !          1379: #define ASCQ_ERR_SYN_XFER_TIME        0x11
        !          1380: #define ASCQ_ERR_LOCK_DMA             0x12
        !          1381: #define ASCQ_ERR_UNLOCK_DMA           0x13
        !          1382: #define ASCQ_ERR_VDS_CHK_INSTALL      0x14
        !          1383: #define ASCQ_ERR_MICRO_CODE_HALT      0x15
        !          1384: #define ASCQ_ERR_SET_LRAM_ADDR        0x16
        !          1385: #define ASCQ_ERR_CUR_QNG              0x17
        !          1386: #define ASCQ_ERR_SG_Q_LINKS           0x18
        !          1387: #define ASCQ_ERR_SCSIQ_PTR            0x19
        !          1388: #define ASCQ_ERR_ISR_RE_ENTRY         0x1A
        !          1389: #define ASCQ_ERR_CRITICAL_RE_ENTRY    0x1B
        !          1390: #define ASCQ_ERR_ISR_ON_CRITICAL      0x1C
        !          1391: #define ASCQ_ERR_SG_LIST_ODD_ADDRESS  0x1D
        !          1392: #define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
        !          1393: #define ASCQ_ERR_SCSIQ_NULL_PTR       0x1F
        !          1394: #define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR   0x20
        !          1395: #define ASCQ_ERR_GET_NUM_OF_FREE_Q    0x21
        !          1396: #define ASCQ_ERR_SEND_SCSI_Q          0x22
        !          1397: #define ASCQ_ERR_HOST_REQ_RISC_HALT   0x23
        !          1398: #define ASCQ_ERR_RESET_SDTR           0x24
        !          1399: #define ASC_WARN_NO_ERROR             0x0000
        !          1400: #define ASC_WARN_IO_PORT_ROTATE       0x0001
        !          1401: #define ASC_WARN_EEPROM_CHKSUM        0x0002
        !          1402: #define ASC_WARN_IRQ_MODIFIED         0x0004
        !          1403: #define ASC_WARN_AUTO_CONFIG          0x0008
        !          1404: #define ASC_WARN_CMD_QNG_CONFLICT     0x0010
        !          1405: #define ASC_WARN_EEPROM_RECOVER       0x0020
        !          1406: #define ASC_WARN_CFG_MSW_RECOVER      0x0040
        !          1407: #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
        !          1408: #define ASC_IERR_WRITE_EEPROM         0x0001
        !          1409: #define ASC_IERR_MCODE_CHKSUM         0x0002
        !          1410: #define ASC_IERR_SET_PC_ADDR          0x0004
        !          1411: #define ASC_IERR_START_STOP_CHIP      0x0008
        !          1412: #define ASC_IERR_IRQ_NO               0x0010
        !          1413: #define ASC_IERR_SET_IRQ_NO           0x0020
        !          1414: #define ASC_IERR_CHIP_VERSION         0x0040
        !          1415: #define ASC_IERR_SET_SCSI_ID          0x0080
        !          1416: #define ASC_IERR_GET_PHY_ADDR         0x0100
        !          1417: #define ASC_IERR_BAD_SIGNATURE        0x0200
        !          1418: #define ASC_IERR_NO_BUS_TYPE          0x0400
        !          1419: #define ASC_IERR_SCAM                 0x0800
        !          1420: #define ASC_IERR_SET_SDTR             0x1000
        !          1421: #define ASC_IERR_RW_LRAM              0x8000
        !          1422: #define ASC_DEF_IRQ_NO  10
        !          1423: #define ASC_MAX_IRQ_NO  15
        !          1424: #define ASC_MIN_IRQ_NO  10
        !          1425: #define ASC_MIN_REMAIN_Q        (0x02)
        !          1426: #define ASC_DEF_MAX_TOTAL_QNG   (0xF0)
        !          1427: #define ASC_MIN_TAG_Q_PER_DVC   (0x04)
        !          1428: #define ASC_DEF_TAG_Q_PER_DVC   (0x04)
        !          1429: #define ASC_MIN_FREE_Q        ASC_MIN_REMAIN_Q
        !          1430: #define ASC_MIN_TOTAL_QNG     ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
        !          1431: #define ASC_MAX_TOTAL_QNG 240
        !          1432: #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
        !          1433: #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG   8
        !          1434: #define ASC_MAX_PCI_INRAM_TOTAL_QNG  20
        !          1435: #define ASC_MAX_INRAM_TAG_QNG   16
        !          1436: #define ASC_IOADR_TABLE_MAX_IX  11
        !          1437: #define ASC_IOADR_GAP   0x10
        !          1438: #define ASC_SEARCH_IOP_GAP 0x10
        !          1439: #define ASC_MIN_IOP_ADDR   (PortAddr)0x0100
        !          1440: #define ASC_MAX_IOP_ADDR   (PortAddr)0x3F0
        !          1441: #define ASC_IOADR_1     (PortAddr)0x0110
        !          1442: #define ASC_IOADR_2     (PortAddr)0x0130
        !          1443: #define ASC_IOADR_3     (PortAddr)0x0150
        !          1444: #define ASC_IOADR_4     (PortAddr)0x0190
        !          1445: #define ASC_IOADR_5     (PortAddr)0x0210
        !          1446: #define ASC_IOADR_6     (PortAddr)0x0230
        !          1447: #define ASC_IOADR_7     (PortAddr)0x0250
        !          1448: #define ASC_IOADR_8     (PortAddr)0x0330
        !          1449: #define ASC_IOADR_DEF   ASC_IOADR_8
        !          1450: #define ASC_LIB_SCSIQ_WK_SP        256
        !          1451: #define ASC_MAX_SYN_XFER_NO        16
        !          1452: #define ASC_SYN_MAX_OFFSET         0x0F
        !          1453: #define ASC_DEF_SDTR_OFFSET        0x0F
        !          1454: #define ASC_DEF_SDTR_INDEX         0x00
        !          1455: #define ASC_SDTR_ULTRA_PCI_10MB_INDEX  0x02
        !          1456: #define SYN_XFER_NS_0  25
        !          1457: #define SYN_XFER_NS_1  30
        !          1458: #define SYN_XFER_NS_2  35
        !          1459: #define SYN_XFER_NS_3  40
        !          1460: #define SYN_XFER_NS_4  50
        !          1461: #define SYN_XFER_NS_5  60
        !          1462: #define SYN_XFER_NS_6  70
        !          1463: #define SYN_XFER_NS_7  85
        !          1464: #define SYN_ULTRA_XFER_NS_0    12
        !          1465: #define SYN_ULTRA_XFER_NS_1    19
        !          1466: #define SYN_ULTRA_XFER_NS_2    25
        !          1467: #define SYN_ULTRA_XFER_NS_3    32
        !          1468: #define SYN_ULTRA_XFER_NS_4    38
        !          1469: #define SYN_ULTRA_XFER_NS_5    44
        !          1470: #define SYN_ULTRA_XFER_NS_6    50
        !          1471: #define SYN_ULTRA_XFER_NS_7    57
        !          1472: #define SYN_ULTRA_XFER_NS_8    63
        !          1473: #define SYN_ULTRA_XFER_NS_9    69
        !          1474: #define SYN_ULTRA_XFER_NS_10   75
        !          1475: #define SYN_ULTRA_XFER_NS_11   82
        !          1476: #define SYN_ULTRA_XFER_NS_12   88
        !          1477: #define SYN_ULTRA_XFER_NS_13   94
        !          1478: #define SYN_ULTRA_XFER_NS_14  100
        !          1479: #define SYN_ULTRA_XFER_NS_15  107
        !          1480: 
        !          1481: typedef struct ext_msg {
        !          1482:     uchar               msg_type;
        !          1483:     uchar               msg_len;
        !          1484:     uchar               msg_req;
        !          1485:     union {
        !          1486:         struct {
        !          1487:             uchar               sdtr_xfer_period;
        !          1488:             uchar               sdtr_req_ack_offset;
        !          1489:         } sdtr;
        !          1490:         struct {
        !          1491:             uchar               wdtr_width;
        !          1492:         } wdtr;
        !          1493:         struct {
        !          1494:             uchar               mdp_b3;
        !          1495:             uchar               mdp_b2;
        !          1496:             uchar               mdp_b1;
        !          1497:             uchar               mdp_b0;
        !          1498:         } mdp;
        !          1499:     } u_ext_msg;
        !          1500:     uchar               res;
        !          1501: } EXT_MSG;
        !          1502: 
        !          1503: #define xfer_period     u_ext_msg.sdtr.sdtr_xfer_period
        !          1504: #define req_ack_offset  u_ext_msg.sdtr.sdtr_req_ack_offset
        !          1505: #define wdtr_width      u_ext_msg.wdtr.wdtr_width
        !          1506: #define mdp_b3          u_ext_msg.mdp_b3
        !          1507: #define mdp_b2          u_ext_msg.mdp_b2
        !          1508: #define mdp_b1          u_ext_msg.mdp_b1
        !          1509: #define mdp_b0          u_ext_msg.mdp_b0
        !          1510: 
        !          1511: typedef struct asc_dvc_cfg {
        !          1512:     ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
        !          1513:     ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
        !          1514:     ASC_SCSI_BIT_ID_TYPE disc_enable;
        !          1515:     ASC_SCSI_BIT_ID_TYPE sdtr_enable;
        !          1516:     uchar               chip_scsi_id:4;
        !          1517:     uchar               isa_dma_speed:4;
        !          1518:     uchar               isa_dma_channel;
        !          1519:     uchar               chip_version;
        !          1520:     ushort              pci_device_id;
        !          1521:     ushort              lib_serial_no;
        !          1522:     ushort              lib_version;
        !          1523:     ushort              mcode_date;
        !          1524:     ushort              mcode_version;
        !          1525:     uchar               max_tag_qng[ASC_MAX_TID + 1];
        !          1526:     uchar               *overrun_buf;
        !          1527:     uchar               sdtr_period_offset[ASC_MAX_TID + 1];
        !          1528:     ushort              pci_slot_info;
        !          1529:     uchar               adapter_info[6];
        !          1530: } ASC_DVC_CFG;
        !          1531: 
        !          1532: #define ASC_DEF_DVC_CNTL       0xFFFF
        !          1533: #define ASC_DEF_CHIP_SCSI_ID   7
        !          1534: #define ASC_DEF_ISA_DMA_SPEED  4
        !          1535: #define ASC_INIT_STATE_NULL          0x0000
        !          1536: #define ASC_INIT_STATE_BEG_GET_CFG   0x0001
        !          1537: #define ASC_INIT_STATE_END_GET_CFG   0x0002
        !          1538: #define ASC_INIT_STATE_BEG_SET_CFG   0x0004
        !          1539: #define ASC_INIT_STATE_END_SET_CFG   0x0008
        !          1540: #define ASC_INIT_STATE_BEG_LOAD_MC   0x0010
        !          1541: #define ASC_INIT_STATE_END_LOAD_MC   0x0020
        !          1542: #define ASC_INIT_STATE_BEG_INQUIRY   0x0040
        !          1543: #define ASC_INIT_STATE_END_INQUIRY   0x0080
        !          1544: #define ASC_INIT_RESET_SCSI_DONE     0x0100
        !          1545: #define ASC_INIT_STATE_WITHOUT_EEP   0x8000
        !          1546: #define ASC_PCI_DEVICE_ID_REV_A      0x1100
        !          1547: #define ASC_PCI_DEVICE_ID_REV_B      0x1200
        !          1548: #define ASC_BUG_FIX_IF_NOT_DWB       0x0001
        !          1549: #define ASC_BUG_FIX_ASYN_USE_SYN     0x0002
        !          1550: #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
        !          1551: #define ASC_MIN_TAGGED_CMD  7
        !          1552: #define ASC_MAX_SCSI_RESET_WAIT      30
        !          1553: 
        !          1554: typedef struct asc_dvc_var {
        !          1555:     PortAddr            iop_base;
        !          1556:     ushort              err_code;
        !          1557:     ushort              dvc_cntl;
        !          1558:     ushort              bug_fix_cntl;
        !          1559:     ushort              bus_type;
        !          1560:     Ptr2Func            isr_callback;
        !          1561:     Ptr2Func            exe_callback;
        !          1562:     ASC_SCSI_BIT_ID_TYPE init_sdtr;
        !          1563:     ASC_SCSI_BIT_ID_TYPE sdtr_done;
        !          1564:     ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
        !          1565:     ASC_SCSI_BIT_ID_TYPE unit_not_ready;
        !          1566:     ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
        !          1567:     ASC_SCSI_BIT_ID_TYPE start_motor;
        !          1568:     uchar               scsi_reset_wait;
        !          1569:     uchar               chip_no;
        !          1570:     char                is_in_int;
        !          1571:     uchar               max_total_qng;
        !          1572:     uchar               cur_total_qng;
        !          1573:     uchar               in_critical_cnt;
        !          1574:     uchar               irq_no;
        !          1575:     uchar               last_q_shortage;
        !          1576:     ushort              init_state;
        !          1577:     uchar               cur_dvc_qng[ASC_MAX_TID + 1];
        !          1578:     uchar               max_dvc_qng[ASC_MAX_TID + 1];
        !          1579:     ASC_SCSI_Q  *scsiq_busy_head[ASC_MAX_TID + 1];
        !          1580:     ASC_SCSI_Q  *scsiq_busy_tail[ASC_MAX_TID + 1];
        !          1581:     uchar               sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
        !          1582:     ASC_DVC_CFG *cfg;
        !          1583:     Ptr2Func            saved_ptr2func;
        !          1584:     ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
        !          1585:     char                redo_scam;
        !          1586:     ushort              res2;
        !          1587:     uchar               dos_int13_table[ASC_MAX_TID + 1];
        !          1588:     ulong               max_dma_count;
        !          1589:     ASC_SCSI_BIT_ID_TYPE no_scam;
        !          1590:     ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
        !          1591:     uchar               max_sdtr_index;
        !          1592:     uchar               host_init_sdtr_index;
        !          1593:     ulong               drv_ptr;
        !          1594:     ulong               uc_break;
        !          1595:     ulong               res7;
        !          1596:     ulong               res8;
        !          1597: } ASC_DVC_VAR;
        !          1598: 
        !          1599: typedef int (* ASC_ISR_CALLBACK) (ASC_DVC_VAR asc_ptr_type *, ASC_QDONE_INFO *);
        !          1600: typedef int (* ASC_EXE_CALLBACK) (ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q *);
        !          1601: 
        !          1602: typedef struct asc_dvc_inq_info {
        !          1603:     uchar               type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
        !          1604: } ASC_DVC_INQ_INFO;
        !          1605: 
        !          1606: typedef struct asc_cap_info {
        !          1607:     ulong               lba;
        !          1608:     ulong               blk_size;
        !          1609: } ASC_CAP_INFO;
        !          1610: 
        !          1611: typedef struct asc_cap_info_array {
        !          1612:     ASC_CAP_INFO        cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
        !          1613: } ASC_CAP_INFO_ARRAY;
        !          1614: 
        !          1615: #define ASC_MCNTL_NO_SEL_TIMEOUT  (ushort)0x0001
        !          1616: #define ASC_MCNTL_NULL_TARGET     (ushort)0x0002
        !          1617: #define ASC_CNTL_INITIATOR         (ushort)0x0001
        !          1618: #define ASC_CNTL_BIOS_GT_1GB       (ushort)0x0002
        !          1619: #define ASC_CNTL_BIOS_GT_2_DISK    (ushort)0x0004
        !          1620: #define ASC_CNTL_BIOS_REMOVABLE    (ushort)0x0008
        !          1621: #define ASC_CNTL_NO_SCAM           (ushort)0x0010
        !          1622: #define ASC_CNTL_INT_MULTI_Q       (ushort)0x0080
        !          1623: #define ASC_CNTL_NO_LUN_SUPPORT    (ushort)0x0040
        !          1624: #define ASC_CNTL_NO_VERIFY_COPY    (ushort)0x0100
        !          1625: #define ASC_CNTL_RESET_SCSI        (ushort)0x0200
        !          1626: #define ASC_CNTL_INIT_INQUIRY      (ushort)0x0400
        !          1627: #define ASC_CNTL_INIT_VERBOSE      (ushort)0x0800
        !          1628: #define ASC_CNTL_SCSI_PARITY       (ushort)0x1000
        !          1629: #define ASC_CNTL_BURST_MODE        (ushort)0x2000
        !          1630: #define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
        !          1631: #define ASC_EEP_DVC_CFG_BEG_VL    2
        !          1632: #define ASC_EEP_MAX_DVC_ADDR_VL   15
        !          1633: #define ASC_EEP_DVC_CFG_BEG      32
        !          1634: #define ASC_EEP_MAX_DVC_ADDR     45
        !          1635: #define ASC_EEP_DEFINED_WORDS    10
        !          1636: #define ASC_EEP_MAX_ADDR         63
        !          1637: #define ASC_EEP_RES_WORDS         0
        !          1638: #define ASC_EEP_MAX_RETRY        20
        !          1639: #define ASC_MAX_INIT_BUSY_RETRY   8
        !          1640: #define ASC_EEP_ISA_PNP_WSIZE    16
        !          1641: 
        !          1642: typedef struct asceep_config {
        !          1643:     ushort              cfg_lsw;
        !          1644:     ushort              cfg_msw;
        !          1645:     uchar               init_sdtr;
        !          1646:     uchar               disc_enable;
        !          1647:     uchar               use_cmd_qng;
        !          1648:     uchar               start_motor;
        !          1649:     uchar               max_total_qng;
        !          1650:     uchar               max_tag_qng;
        !          1651:     uchar               bios_scan;
        !          1652:     uchar               power_up_wait;
        !          1653:     uchar               no_scam;
        !          1654:     uchar               chip_scsi_id:4;
        !          1655:     uchar               isa_dma_speed:4;
        !          1656:     uchar               dos_int13_table[ASC_MAX_TID + 1];
        !          1657:     uchar               adapter_info[6];
        !          1658:     ushort              cntl;
        !          1659:     ushort              chksum;
        !          1660: } ASCEEP_CONFIG;
        !          1661: 
        !          1662: #define ASC_PCI_CFG_LSW_SCSI_PARITY  0x0800
        !          1663: #define ASC_PCI_CFG_LSW_BURST_MODE   0x0080
        !          1664: #define ASC_PCI_CFG_LSW_INTR_ABLE    0x0020
        !          1665: 
        !          1666: #define ASC_EEP_CMD_READ          0x80
        !          1667: #define ASC_EEP_CMD_WRITE         0x40
        !          1668: #define ASC_EEP_CMD_WRITE_ABLE    0x30
        !          1669: #define ASC_EEP_CMD_WRITE_DISABLE 0x00
        !          1670: #define ASC_OVERRUN_BSIZE  0x00000048UL
        !          1671: #define ASC_CTRL_BREAK_ONCE        0x0001
        !          1672: #define ASC_CTRL_BREAK_STAY_IDLE   0x0002
        !          1673: #define ASCV_MSGOUT_BEG         0x0000
        !          1674: #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
        !          1675: #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
        !          1676: #define ASCV_BREAK_SAVED_CODE   (ushort)0x0006
        !          1677: #define ASCV_MSGIN_BEG          (ASCV_MSGOUT_BEG+8)
        !          1678: #define ASCV_MSGIN_SDTR_PERIOD  (ASCV_MSGIN_BEG+3)
        !          1679: #define ASCV_MSGIN_SDTR_OFFSET  (ASCV_MSGIN_BEG+4)
        !          1680: #define ASCV_SDTR_DATA_BEG      (ASCV_MSGIN_BEG+8)
        !          1681: #define ASCV_SDTR_DONE_BEG      (ASCV_SDTR_DATA_BEG+8)
        !          1682: #define ASCV_MAX_DVC_QNG_BEG    (ushort)0x0020
        !          1683: #define ASCV_BREAK_ADDR           (ushort)0x0028
        !          1684: #define ASCV_BREAK_NOTIFY_COUNT   (ushort)0x002A
        !          1685: #define ASCV_BREAK_CONTROL        (ushort)0x002C
        !          1686: #define ASCV_BREAK_HIT_COUNT      (ushort)0x002E
        !          1687: 
        !          1688: #define ASCV_ASCDVC_ERR_CODE_W  (ushort)0x0030
        !          1689: #define ASCV_MCODE_CHKSUM_W   (ushort)0x0032
        !          1690: #define ASCV_MCODE_SIZE_W     (ushort)0x0034
        !          1691: #define ASCV_STOP_CODE_B      (ushort)0x0036
        !          1692: #define ASCV_DVC_ERR_CODE_B   (ushort)0x0037
        !          1693: #define ASCV_OVERRUN_PADDR_D  (ushort)0x0038
        !          1694: #define ASCV_OVERRUN_BSIZE_D  (ushort)0x003C
        !          1695: #define ASCV_HALTCODE_W       (ushort)0x0040
        !          1696: #define ASCV_CHKSUM_W         (ushort)0x0042
        !          1697: #define ASCV_MC_DATE_W        (ushort)0x0044
        !          1698: #define ASCV_MC_VER_W         (ushort)0x0046
        !          1699: #define ASCV_NEXTRDY_B        (ushort)0x0048
        !          1700: #define ASCV_DONENEXT_B       (ushort)0x0049
        !          1701: #define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
        !          1702: #define ASCV_SCSIBUSY_B       (ushort)0x004B
        !          1703: #define ASCV_Q_DONE_IN_PROGRESS_B  (ushort)0x004C
        !          1704: #define ASCV_CURCDB_B         (ushort)0x004D
        !          1705: #define ASCV_RCLUN_B          (ushort)0x004E
        !          1706: #define ASCV_BUSY_QHEAD_B     (ushort)0x004F
        !          1707: #define ASCV_DISC1_QHEAD_B    (ushort)0x0050
        !          1708: #define ASCV_DISC_ENABLE_B    (ushort)0x0052
        !          1709: #define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
        !          1710: #define ASCV_HOSTSCSI_ID_B    (ushort)0x0055
        !          1711: #define ASCV_MCODE_CNTL_B     (ushort)0x0056
        !          1712: #define ASCV_NULL_TARGET_B    (ushort)0x0057
        !          1713: #define ASCV_FREE_Q_HEAD_W    (ushort)0x0058
        !          1714: #define ASCV_DONE_Q_TAIL_W    (ushort)0x005A
        !          1715: #define ASCV_FREE_Q_HEAD_B    (ushort)(ASCV_FREE_Q_HEAD_W+1)
        !          1716: #define ASCV_DONE_Q_TAIL_B    (ushort)(ASCV_DONE_Q_TAIL_W+1)
        !          1717: #define ASCV_HOST_FLAG_B      (ushort)0x005D
        !          1718: #define ASCV_TOTAL_READY_Q_B  (ushort)0x0064
        !          1719: #define ASCV_VER_SERIAL_B     (ushort)0x0065
        !          1720: #define ASCV_HALTCODE_SAVED_W (ushort)0x0066
        !          1721: #define ASCV_WTM_FLAG_B       (ushort)0x0068
        !          1722: #define ASCV_RISC_FLAG_B      (ushort)0x006A
        !          1723: #define ASCV_REQ_SG_LIST_QP   (ushort)0x006B
        !          1724: #define ASC_HOST_FLAG_IN_ISR        0x01
        !          1725: #define ASC_HOST_FLAG_ACK_INT       0x02
        !          1726: #define ASC_RISC_FLAG_GEN_INT      0x01
        !          1727: #define ASC_RISC_FLAG_REQ_SG_LIST  0x02
        !          1728: #define IOP_CTRL         (0x0F)
        !          1729: #define IOP_STATUS       (0x0E)
        !          1730: #define IOP_INT_ACK      IOP_STATUS
        !          1731: #define IOP_REG_IFC      (0x0D)
        !          1732: #define IOP_SYN_OFFSET    (0x0B)
        !          1733: #define IOP_EXTRA_CONTROL (0x0D)
        !          1734: #define IOP_REG_PC        (0x0C)
        !          1735: #define IOP_RAM_ADDR      (0x0A)
        !          1736: #define IOP_RAM_DATA      (0x08)
        !          1737: #define IOP_EEP_DATA      (0x06)
        !          1738: #define IOP_EEP_CMD       (0x07)
        !          1739: #define IOP_VERSION       (0x03)
        !          1740: #define IOP_CONFIG_HIGH   (0x04)
        !          1741: #define IOP_CONFIG_LOW    (0x02)
        !          1742: #define IOP_SIG_BYTE      (0x01)
        !          1743: #define IOP_SIG_WORD      (0x00)
        !          1744: #define IOP_REG_DC1      (0x0E)
        !          1745: #define IOP_REG_DC0      (0x0C)
        !          1746: #define IOP_REG_SB       (0x0B)
        !          1747: #define IOP_REG_DA1      (0x0A)
        !          1748: #define IOP_REG_DA0      (0x08)
        !          1749: #define IOP_REG_SC       (0x09)
        !          1750: #define IOP_DMA_SPEED    (0x07)
        !          1751: #define IOP_REG_FLAG     (0x07)
        !          1752: #define IOP_FIFO_H       (0x06)
        !          1753: #define IOP_FIFO_L       (0x04)
        !          1754: #define IOP_REG_ID       (0x05)
        !          1755: #define IOP_REG_QP       (0x03)
        !          1756: #define IOP_REG_IH       (0x02)
        !          1757: #define IOP_REG_IX       (0x01)
        !          1758: #define IOP_REG_AX       (0x00)
        !          1759: #define IFC_REG_LOCK      (0x00)
        !          1760: #define IFC_REG_UNLOCK    (0x09)
        !          1761: #define IFC_WR_EN_FILTER  (0x10)
        !          1762: #define IFC_RD_NO_EEPROM  (0x10)
        !          1763: #define IFC_SLEW_RATE     (0x20)
        !          1764: #define IFC_ACT_NEG       (0x40)
        !          1765: #define IFC_INP_FILTER    (0x80)
        !          1766: #define IFC_INIT_DEFAULT  (IFC_ACT_NEG | IFC_REG_UNLOCK)
        !          1767: #define SC_SEL   (uchar)(0x80)
        !          1768: #define SC_BSY   (uchar)(0x40)
        !          1769: #define SC_ACK   (uchar)(0x20)
        !          1770: #define SC_REQ   (uchar)(0x10)
        !          1771: #define SC_ATN   (uchar)(0x08)
        !          1772: #define SC_IO    (uchar)(0x04)
        !          1773: #define SC_CD    (uchar)(0x02)
        !          1774: #define SC_MSG   (uchar)(0x01)
        !          1775: #define SEC_SCSI_CTL         (uchar)(0x80)
        !          1776: #define SEC_ACTIVE_NEGATE    (uchar)(0x40)
        !          1777: #define SEC_SLEW_RATE        (uchar)(0x20)
        !          1778: #define SEC_ENABLE_FILTER    (uchar)(0x10)
        !          1779: #define ASC_HALT_EXTMSG_IN     (ushort)0x8000
        !          1780: #define ASC_HALT_CHK_CONDITION (ushort)0x8100
        !          1781: #define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
        !          1782: #define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX  (ushort)0x8300
        !          1783: #define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX   (ushort)0x8400
        !          1784: #define ASC_HALT_SDTR_REJECTED (ushort)0x4000
        !          1785: #define ASC_MAX_QNO        0xF8
        !          1786: #define ASC_DATA_SEC_BEG   (ushort)0x0080
        !          1787: #define ASC_DATA_SEC_END   (ushort)0x0080
        !          1788: #define ASC_CODE_SEC_BEG   (ushort)0x0080
        !          1789: #define ASC_CODE_SEC_END   (ushort)0x0080
        !          1790: #define ASC_QADR_BEG       (0x4000)
        !          1791: #define ASC_QADR_USED      (ushort)(ASC_MAX_QNO * 64)
        !          1792: #define ASC_QADR_END       (ushort)0x7FFF
        !          1793: #define ASC_QLAST_ADR      (ushort)0x7FC0
        !          1794: #define ASC_QBLK_SIZE      0x40
        !          1795: #define ASC_BIOS_DATA_QBEG 0xF8
        !          1796: #define ASC_MIN_ACTIVE_QNO 0x01
        !          1797: #define ASC_QLINK_END      0xFF
        !          1798: #define ASC_EEPROM_WORDS   0x10
        !          1799: #define ASC_MAX_MGS_LEN    0x10
        !          1800: #define ASC_BIOS_ADDR_DEF  0xDC00
        !          1801: #define ASC_BIOS_SIZE      0x3800
        !          1802: #define ASC_BIOS_RAM_OFF   0x3800
        !          1803: #define ASC_BIOS_RAM_SIZE  0x800
        !          1804: #define ASC_BIOS_MIN_ADDR  0xC000
        !          1805: #define ASC_BIOS_MAX_ADDR  0xEC00
        !          1806: #define ASC_BIOS_BANK_SIZE 0x0400
        !          1807: #define ASC_MCODE_START_ADDR  0x0080
        !          1808: #define ASC_CFG0_HOST_INT_ON    0x0020
        !          1809: #define ASC_CFG0_BIOS_ON        0x0040
        !          1810: #define ASC_CFG0_VERA_BURST_ON  0x0080
        !          1811: #define ASC_CFG0_SCSI_PARITY_ON 0x0800
        !          1812: #define ASC_CFG1_SCSI_TARGET_ON 0x0080
        !          1813: #define ASC_CFG1_LRAM_8BITS_ON  0x0800
        !          1814: #define ASC_CFG_MSW_CLR_MASK    0x3080
        !          1815: #define CSW_TEST1             (ASC_CS_TYPE)0x8000
        !          1816: #define CSW_AUTO_CONFIG       (ASC_CS_TYPE)0x4000
        !          1817: #define CSW_RESERVED1         (ASC_CS_TYPE)0x2000
        !          1818: #define CSW_IRQ_WRITTEN       (ASC_CS_TYPE)0x1000
        !          1819: #define CSW_33MHZ_SELECTED    (ASC_CS_TYPE)0x0800
        !          1820: #define CSW_TEST2             (ASC_CS_TYPE)0x0400
        !          1821: #define CSW_TEST3             (ASC_CS_TYPE)0x0200
        !          1822: #define CSW_RESERVED2         (ASC_CS_TYPE)0x0100
        !          1823: #define CSW_DMA_DONE          (ASC_CS_TYPE)0x0080
        !          1824: #define CSW_FIFO_RDY          (ASC_CS_TYPE)0x0040
        !          1825: #define CSW_EEP_READ_DONE     (ASC_CS_TYPE)0x0020
        !          1826: #define CSW_HALTED            (ASC_CS_TYPE)0x0010
        !          1827: #define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
        !          1828: #define CSW_PARITY_ERR        (ASC_CS_TYPE)0x0004
        !          1829: #define CSW_SCSI_RESET_LATCH  (ASC_CS_TYPE)0x0002
        !          1830: #define CSW_INT_PENDING       (ASC_CS_TYPE)0x0001
        !          1831: #define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
        !          1832: #define CIW_INT_ACK      (ASC_CS_TYPE)0x0100
        !          1833: #define CIW_TEST1        (ASC_CS_TYPE)0x0200
        !          1834: #define CIW_TEST2        (ASC_CS_TYPE)0x0400
        !          1835: #define CIW_SEL_33MHZ    (ASC_CS_TYPE)0x0800
        !          1836: #define CIW_IRQ_ACT      (ASC_CS_TYPE)0x1000
        !          1837: #define CC_CHIP_RESET   (uchar)0x80
        !          1838: #define CC_SCSI_RESET   (uchar)0x40
        !          1839: #define CC_HALT         (uchar)0x20
        !          1840: #define CC_SINGLE_STEP  (uchar)0x10
        !          1841: #define CC_DMA_ABLE     (uchar)0x08
        !          1842: #define CC_TEST         (uchar)0x04
        !          1843: #define CC_BANK_ONE     (uchar)0x02
        !          1844: #define CC_DIAG         (uchar)0x01
        !          1845: #define ASC_1000_ID0W      0x04C1
        !          1846: #define ASC_1000_ID0W_FIX  0x00C1
        !          1847: #define ASC_1000_ID1B      0x25
        !          1848: #define ASC_EISA_BIG_IOP_GAP   (0x1C30-0x0C50)
        !          1849: #define ASC_EISA_SMALL_IOP_GAP (0x0020)
        !          1850: #define ASC_EISA_MIN_IOP_ADDR  (0x0C30)
        !          1851: #define ASC_EISA_MAX_IOP_ADDR  (0xFC50)
        !          1852: #define ASC_EISA_REV_IOP_MASK  (0x0C83)
        !          1853: #define ASC_EISA_PID_IOP_MASK  (0x0C80)
        !          1854: #define ASC_EISA_CFG_IOP_MASK  (0x0C86)
        !          1855: #define ASC_GET_EISA_SLOT(iop)  (PortAddr)((iop) & 0xF000)
        !          1856: #define ASC_EISA_ID_740    0x01745004UL
        !          1857: #define ASC_EISA_ID_750    0x01755004UL
        !          1858: #define INS_HALTINT        (ushort)0x6281
        !          1859: #define INS_HALT           (ushort)0x6280
        !          1860: #define INS_SINT           (ushort)0x6200
        !          1861: #define INS_RFLAG_WTM      (ushort)0x7380
        !          1862: #define ASC_MC_SAVE_CODE_WSIZE  0x500
        !          1863: #define ASC_MC_SAVE_DATA_WSIZE  0x40
        !          1864: 
        !          1865: typedef struct asc_mc_saved {
        !          1866:     ushort              data[ASC_MC_SAVE_DATA_WSIZE];
        !          1867:     ushort              code[ASC_MC_SAVE_CODE_WSIZE];
        !          1868: } ASC_MC_SAVED;
        !          1869: 
        !          1870: #define AscGetQDoneInProgress(port)         AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
        !          1871: #define AscPutQDoneInProgress(port, val)    AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
        !          1872: #define AscGetVarFreeQHead(port)            AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
        !          1873: #define AscGetVarDoneQTail(port)            AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
        !          1874: #define AscPutVarFreeQHead(port, val)       AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
        !          1875: #define AscPutVarDoneQTail(port, val)       AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
        !          1876: #define AscGetRiscVarFreeQHead(port)        AscReadLramByte((port), ASCV_NEXTRDY_B)
        !          1877: #define AscGetRiscVarDoneQTail(port)        AscReadLramByte((port), ASCV_DONENEXT_B)
        !          1878: #define AscPutRiscVarFreeQHead(port, val)   AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
        !          1879: #define AscPutRiscVarDoneQTail(port, val)   AscWriteLramByte((port), ASCV_DONENEXT_B, val)
        !          1880: #define AscPutMCodeSDTRDoneAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data)) ;
        !          1881: #define AscGetMCodeSDTRDoneAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id)) ;
        !          1882: #define AscPutMCodeInitSDTRAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data) ;
        !          1883: #define AscGetMCodeInitSDTRAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id)) ;
        !          1884: #define AscSynIndexToPeriod(index)        (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
        !          1885: #define AscGetChipSignatureByte(port)     (uchar)inp((port)+IOP_SIG_BYTE)
        !          1886: #define AscGetChipSignatureWord(port)     (ushort)inpw((port)+IOP_SIG_WORD)
        !          1887: #define AscGetChipVerNo(port)             (uchar)inp((port)+IOP_VERSION)
        !          1888: #define AscGetChipCfgLsw(port)            (ushort)inpw((port)+IOP_CONFIG_LOW)
        !          1889: #define AscGetChipCfgMsw(port)            (ushort)inpw((port)+IOP_CONFIG_HIGH)
        !          1890: #define AscSetChipCfgLsw(port, data)      outpw((port)+IOP_CONFIG_LOW, data)
        !          1891: #define AscSetChipCfgMsw(port, data)      outpw((port)+IOP_CONFIG_HIGH, data)
        !          1892: #define AscGetChipEEPCmd(port)            (uchar)inp((port)+IOP_EEP_CMD)
        !          1893: #define AscSetChipEEPCmd(port, data)      outp((port)+IOP_EEP_CMD, data)
        !          1894: #define AscGetChipEEPData(port)           (ushort)inpw((port)+IOP_EEP_DATA)
        !          1895: #define AscSetChipEEPData(port, data)     outpw((port)+IOP_EEP_DATA, data)
        !          1896: #define AscGetChipLramAddr(port)          (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
        !          1897: #define AscSetChipLramAddr(port, addr)    outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
        !          1898: #define AscGetChipLramData(port)          (ushort)inpw((port)+IOP_RAM_DATA)
        !          1899: #define AscSetChipLramData(port, data)    outpw((port)+IOP_RAM_DATA, data)
        !          1900: #define AscGetChipLramDataNoSwap(port)         (ushort)inpw_noswap((port)+IOP_RAM_DATA)
        !          1901: #define AscSetChipLramDataNoSwap(port, data)   outpw_noswap((port)+IOP_RAM_DATA, data)
        !          1902: #define AscGetChipIFC(port)               (uchar)inp((port)+IOP_REG_IFC)
        !          1903: #define AscSetChipIFC(port, data)          outp((port)+IOP_REG_IFC, data)
        !          1904: #define AscGetChipStatus(port)            (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
        !          1905: #define AscSetChipStatus(port, cs_val)    outpw((port)+IOP_STATUS, cs_val)
        !          1906: #define AscGetChipControl(port)           (uchar)inp((port)+IOP_CTRL)
        !          1907: #define AscSetChipControl(port, cc_val)   outp((port)+IOP_CTRL, cc_val)
        !          1908: #define AscGetChipSyn(port)               (uchar)inp((port)+IOP_SYN_OFFSET)
        !          1909: #define AscSetChipSyn(port, data)         outp((port)+IOP_SYN_OFFSET, data)
        !          1910: #define AscSetPCAddr(port, data)          outpw((port)+IOP_REG_PC, data)
        !          1911: #define AscGetPCAddr(port)                (ushort)inpw((port)+IOP_REG_PC)
        !          1912: #define AscIsIntPending(port)             (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
        !          1913: #define AscGetChipScsiID(port)            ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
        !          1914: #define AscGetExtraControl(port)          (uchar)inp((port)+IOP_EXTRA_CONTROL)
        !          1915: #define AscSetExtraControl(port, data)    outp((port)+IOP_EXTRA_CONTROL, data)
        !          1916: #define AscReadChipAX(port)               (ushort)inpw((port)+IOP_REG_AX)
        !          1917: #define AscWriteChipAX(port, data)        outpw((port)+IOP_REG_AX, data)
        !          1918: #define AscReadChipIX(port)               (uchar)inp((port)+IOP_REG_IX)
        !          1919: #define AscWriteChipIX(port, data)        outp((port)+IOP_REG_IX, data)
        !          1920: #define AscReadChipIH(port)               (ushort)inpw((port)+IOP_REG_IH)
        !          1921: #define AscWriteChipIH(port, data)        outpw((port)+IOP_REG_IH, data)
        !          1922: #define AscReadChipQP(port)               (uchar)inp((port)+IOP_REG_QP)
        !          1923: #define AscWriteChipQP(port, data)        outp((port)+IOP_REG_QP, data)
        !          1924: #define AscReadChipFIFO_L(port)           (ushort)inpw((port)+IOP_REG_FIFO_L)
        !          1925: #define AscWriteChipFIFO_L(port, data)    outpw((port)+IOP_REG_FIFO_L, data)
        !          1926: #define AscReadChipFIFO_H(port)           (ushort)inpw((port)+IOP_REG_FIFO_H)
        !          1927: #define AscWriteChipFIFO_H(port, data)    outpw((port)+IOP_REG_FIFO_H, data)
        !          1928: #define AscReadChipDmaSpeed(port)         (uchar)inp((port)+IOP_DMA_SPEED)
        !          1929: #define AscWriteChipDmaSpeed(port, data)  outp((port)+IOP_DMA_SPEED, data)
        !          1930: #define AscReadChipDA0(port)              (ushort)inpw((port)+IOP_REG_DA0)
        !          1931: #define AscWriteChipDA0(port)             outpw((port)+IOP_REG_DA0, data)
        !          1932: #define AscReadChipDA1(port)              (ushort)inpw((port)+IOP_REG_DA1)
        !          1933: #define AscWriteChipDA1(port)             outpw((port)+IOP_REG_DA1, data)
        !          1934: #define AscReadChipDC0(port)              (ushort)inpw((port)+IOP_REG_DC0)
        !          1935: #define AscWriteChipDC0(port)             outpw((port)+IOP_REG_DC0, data)
        !          1936: #define AscReadChipDC1(port)              (ushort)inpw((port)+IOP_REG_DC1)
        !          1937: #define AscWriteChipDC1(port)             outpw((port)+IOP_REG_DC1, data)
        !          1938: #define AscReadChipDvcID(port)            (uchar)inp((port)+IOP_REG_ID)
        !          1939: #define AscWriteChipDvcID(port, data)     outp((port)+IOP_REG_ID, data)
        !          1940: 
        !          1941: STATIC int       AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
        !          1942: STATIC int       AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
        !          1943: STATIC void      AscWaitEEPRead(void);
        !          1944: STATIC void      AscWaitEEPWrite(void);
        !          1945: STATIC ushort    AscReadEEPWord(PortAddr, uchar);
        !          1946: STATIC ushort    AscWriteEEPWord(PortAddr, uchar, ushort);
        !          1947: STATIC ushort    AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
        !          1948: STATIC int       AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
        !          1949: STATIC int       AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
        !          1950: STATIC int       AscStartChip(PortAddr);
        !          1951: STATIC int       AscStopChip(PortAddr);
        !          1952: STATIC void      AscSetChipIH(PortAddr, ushort);
        !          1953: STATIC int       AscIsChipHalted(PortAddr);
        !          1954: STATIC void      AscAckInterrupt(PortAddr);
        !          1955: STATIC void      AscDisableInterrupt(PortAddr);
        !          1956: STATIC void      AscEnableInterrupt(PortAddr);
        !          1957: STATIC void      AscSetBank(PortAddr, uchar);
        !          1958: STATIC int       AscResetChipAndScsiBus(ASC_DVC_VAR *);
        !          1959: STATIC ushort    AscGetIsaDmaChannel(PortAddr);
        !          1960: STATIC ushort    AscSetIsaDmaChannel(PortAddr, ushort);
        !          1961: STATIC uchar     AscSetIsaDmaSpeed(PortAddr, uchar);
        !          1962: STATIC uchar     AscGetIsaDmaSpeed(PortAddr);
        !          1963: STATIC uchar     AscReadLramByte(PortAddr, ushort);
        !          1964: STATIC ushort    AscReadLramWord(PortAddr, ushort);
        !          1965: STATIC ulong     AscReadLramDWord(PortAddr, ushort);
        !          1966: STATIC void      AscWriteLramWord(PortAddr, ushort, ushort);
        !          1967: STATIC void      AscWriteLramDWord(PortAddr, ushort, ulong);
        !          1968: STATIC void      AscWriteLramByte(PortAddr, ushort, uchar);
        !          1969: STATIC ulong     AscMemSumLramWord(PortAddr, ushort, rint);
        !          1970: STATIC void      AscMemWordSetLram(PortAddr, ushort, ushort, rint);
        !          1971: STATIC void      AscMemWordCopyToLram(PortAddr, ushort, ushort *, int);
        !          1972: STATIC void      AscMemDWordCopyToLram(PortAddr, ushort, ulong *, int);
        !          1973: STATIC void      AscMemWordCopyFromLram(PortAddr, ushort, ushort *, int);
        !          1974: STATIC ushort    AscInitAscDvcVar(ASC_DVC_VAR asc_ptr_type *);
        !          1975: STATIC ushort    AscInitFromEEP(ASC_DVC_VAR asc_ptr_type *);
        !          1976: STATIC ushort    AscInitFromAscDvcVar(ASC_DVC_VAR asc_ptr_type *);
        !          1977: STATIC ushort    AscInitMicroCodeVar(ASC_DVC_VAR asc_ptr_type * asc_dvc);
        !          1978: STATIC int       AscTestExternalLram(ASC_DVC_VAR asc_ptr_type *);
        !          1979: STATIC uchar     AscMsgOutSDTR(ASC_DVC_VAR asc_ptr_type *, uchar, uchar);
        !          1980: STATIC uchar     AscCalSDTRData(ASC_DVC_VAR asc_ptr_type *, uchar, uchar);
        !          1981: STATIC void      AscSetChipSDTR(PortAddr, uchar, uchar);
        !          1982: STATIC uchar     AscGetSynPeriodIndex(ASC_DVC_VAR asc_ptr_type *, ruchar);
        !          1983: STATIC uchar     AscAllocFreeQueue(PortAddr, uchar);
        !          1984: STATIC uchar     AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
        !          1985: STATIC int       AscRiscHaltedAbortSRB(ASC_DVC_VAR asc_ptr_type *, ulong);
        !          1986: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
        !          1987: STATIC int       AscRiscHaltedAbortTIX(ASC_DVC_VAR asc_ptr_type *, uchar);
        !          1988: #endif /* version >= v1.3.89 */
        !          1989: STATIC int       AscHostReqRiscHalt(PortAddr);
        !          1990: STATIC int       AscStopQueueExe(PortAddr);
        !          1991: STATIC int       AscStartQueueExe(PortAddr);
        !          1992: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
        !          1993: STATIC int       AscCleanUpDiscQueue(PortAddr);
        !          1994: #endif /* version >= v1.3.89 */
        !          1995: STATIC int       AscCleanUpBusyQueue(PortAddr);
        !          1996: STATIC int       AscWaitTixISRDone(ASC_DVC_VAR asc_ptr_type *, uchar);
        !          1997: STATIC int       AscWaitISRDone(ASC_DVC_VAR asc_ptr_type *);
        !          1998: STATIC ulong     AscGetOnePhyAddr(ASC_DVC_VAR asc_ptr_type *, uchar *,
        !          1999:                     ulong);
        !          2000: STATIC int       AscSendScsiQueue(ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          2001:                     ASC_SCSI_Q * scsiq,
        !          2002:                     uchar n_q_required);
        !          2003: STATIC int       AscPutReadyQueue(ASC_DVC_VAR asc_ptr_type *,
        !          2004:                     ASC_SCSI_Q *, uchar);
        !          2005: STATIC int       AscPutReadySgListQueue(ASC_DVC_VAR asc_ptr_type *,
        !          2006:                     ASC_SCSI_Q *, uchar);
        !          2007: STATIC int       AscSetChipSynRegAtID(PortAddr, uchar, uchar);
        !          2008: STATIC int       AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
        !          2009: STATIC ushort    AscInitLram(ASC_DVC_VAR asc_ptr_type *);
        !          2010: STATIC int       AscReInitLram(ASC_DVC_VAR asc_ptr_type *);
        !          2011: STATIC ushort    AscInitQLinkVar(ASC_DVC_VAR asc_ptr_type *);
        !          2012: STATIC int       AscSetLibErrorCode(ASC_DVC_VAR asc_ptr_type *, ushort);
        !          2013: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
        !          2014: STATIC int       _AscWaitQDone(PortAddr, ASC_SCSI_Q *);
        !          2015: #endif /* version >= v1.3.89 */
        !          2016: STATIC int       AscIsrChipHalted(ASC_DVC_VAR asc_ptr_type *);
        !          2017: STATIC uchar     _AscCopyLramScsiDoneQ(PortAddr, ushort,
        !          2018:                     ASC_QDONE_INFO *, ulong);
        !          2019: STATIC int       AscIsrQDone(ASC_DVC_VAR asc_ptr_type *);
        !          2020: STATIC int       AscCompareString(uchar *, uchar *, int);
        !          2021: STATIC ushort    AscGetEisaChipCfg(PortAddr);
        !          2022: STATIC ulong     AscGetEisaProductID(PortAddr);
        !          2023: STATIC PortAddr  AscSearchIOPortAddrEISA(PortAddr);
        !          2024: STATIC uchar     AscGetChipScsiCtrl(PortAddr);
        !          2025: STATIC uchar     AscSetChipScsiID(PortAddr, uchar);
        !          2026: STATIC uchar     AscGetChipVersion(PortAddr, ushort);
        !          2027: STATIC ushort    AscGetChipBusType(PortAddr);
        !          2028: STATIC ulong     AscLoadMicroCode(PortAddr, ushort, ushort *, ushort);
        !          2029: STATIC int       AscFindSignature(PortAddr);
        !          2030: STATIC PortAddr  AscSearchIOPortAddr11(PortAddr);
        !          2031: STATIC void      AscToggleIRQAct(PortAddr);
        !          2032: STATIC void      AscSetISAPNPWaitForKey(void);
        !          2033: STATIC uchar     AscGetChipIRQ(PortAddr, ushort);
        !          2034: STATIC uchar     AscSetChipIRQ(PortAddr, uchar, ushort);
        !          2035: STATIC ushort    AscGetChipBiosAddress(PortAddr, ushort);
        !          2036: STATIC int       DvcEnterCritical(void);
        !          2037: STATIC void      DvcLeaveCritical(int);
        !          2038: STATIC void      DvcInPortWords(PortAddr, ushort *, int);
        !          2039: STATIC void      DvcOutPortWords(PortAddr, ushort *, int);
        !          2040: STATIC void      DvcOutPortDWords(PortAddr, ulong *, int);
        !          2041: STATIC uchar     DvcReadPCIConfigByte(ASC_DVC_VAR asc_ptr_type *, ushort);
        !          2042: STATIC void      DvcWritePCIConfigByte(ASC_DVC_VAR asc_ptr_type *,
        !          2043:                     ushort, uchar);
        !          2044: STATIC ushort      AscGetChipBiosAddress(PortAddr, ushort);
        !          2045: STATIC void      DvcSleepMilliSecond(ulong);
        !          2046: STATIC void      DvcDelayNanoSecond(ASC_DVC_VAR asc_ptr_type *, ulong);
        !          2047: STATIC ulong     DvcGetSGList(ASC_DVC_VAR asc_ptr_type *, uchar *,
        !          2048:                     ulong, ASC_SG_HEAD *);
        !          2049: STATIC void      DvcPutScsiQ(PortAddr, ushort, ushort *, int);
        !          2050: STATIC void      DvcGetQinfo(PortAddr, ushort, ushort *, int);
        !          2051: STATIC PortAddr  AscSearchIOPortAddr(PortAddr, ushort);
        !          2052: STATIC ushort    AscInitGetConfig(ASC_DVC_VAR asc_ptr_type *);
        !          2053: STATIC ushort    AscInitSetConfig(ASC_DVC_VAR asc_ptr_type *);
        !          2054: STATIC ushort    AscInitAsc1000Driver(ASC_DVC_VAR asc_ptr_type *);
        !          2055: STATIC void      AscAsyncFix(ASC_DVC_VAR asc_ptr_type *, uchar,
        !          2056:                     ASC_SCSI_INQUIRY *);
        !          2057: STATIC int       AscTagQueuingSafe(ASC_SCSI_INQUIRY *);
        !          2058: STATIC void      AscInquiryHandling(ASC_DVC_VAR asc_ptr_type *,
        !          2059:                     uchar, ASC_SCSI_INQUIRY *);
        !          2060: STATIC int       AscExeScsiQueue(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q *);
        !          2061: STATIC int       AscISR(ASC_DVC_VAR asc_ptr_type *);
        !          2062: STATIC uint      AscGetNumOfFreeQueue(ASC_DVC_VAR asc_ptr_type *, uchar,
        !          2063:                     uchar);
        !          2064: STATIC int       AscSgListToQueue(int);
        !          2065: STATIC int       AscAbortSRB(ASC_DVC_VAR asc_ptr_type *, ulong);
        !          2066: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
        !          2067: STATIC int       AscResetDevice(ASC_DVC_VAR asc_ptr_type *, uchar);
        !          2068: #endif /* version >= v1.3.89 */
        !          2069: STATIC int       AscResetSB(ASC_DVC_VAR asc_ptr_type *);
        !          2070: STATIC void      AscEnableIsaDma(uchar);
        !          2071: STATIC ulong     AscGetMaxDmaCount(ushort);
        !          2072: 
        !          2073: 
        !          2074: /*
        !          2075:  * --- Adv Library Constants and Macros
        !          2076:  */
        !          2077: 
        !          2078: #define ADV_LIB_VERSION_MAJOR  3
        !          2079: #define ADV_LIB_VERSION_MINOR  45
        !          2080: 
        !          2081: /* d_os_dep.h */
        !          2082: #define ADV_OS_LINUX
        !          2083: 
        !          2084: /*
        !          2085:  * Define Adv Library required special types.
        !          2086:  */
        !          2087: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
        !          2088: #define AdvPortAddr  unsigned short     /* I/O Port address size */
        !          2089: #else /* version >= v1,3,0 */
        !          2090: #define AdvPortAddr  unsigned long      /* Virtual memory address size */
        !          2091: #endif /* version >= v1,3,0 */
        !          2092: 
        !          2093: /*
        !          2094:  * Define Adv Library required memory access macros.
        !          2095:  */
        !          2096: #define ADV_MEM_READB(addr) readb(addr)
        !          2097: #define ADV_MEM_READW(addr) readw(addr)
        !          2098: #define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
        !          2099: #define ADV_MEM_WRITEW(addr, word) writew(word, addr)
        !          2100: 
        !          2101: /*
        !          2102:  * The I/O memory mapping function names changed in 2.1.X.
        !          2103:  */
        !          2104: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,0)
        !          2105: #define ioremap vremap
        !          2106: #define iounmap vfree
        !          2107: #endif /* version < v2.1.0 */
        !          2108: 
        !          2109: /*
        !          2110:  * Define total number of simultaneous maximum element scatter-gather
        !          2111:  * requests, i.e. ADV_TOT_SG_LIST * ADV_MAX_SG_LIST is the total number
        !          2112:  * of simultaneous scatter-gather elements supported per wide adapter.
        !          2113:  */
        !          2114: #define ADV_TOT_SG_LIST         64
        !          2115: 
        !          2116: /*
        !          2117:  * Define Adv Library required per request scatter-gather element limit.
        !          2118:  */
        !          2119: #define ADV_MAX_SG_LIST         64
        !          2120: 
        !          2121: /*
        !          2122:  * Scatter-Gather Definitions per request.
        !          2123:  *
        !          2124:  * Because SG block memory is allocated in virtual memory but is
        !          2125:  * referenced by the microcode as physical memory, we need to do
        !          2126:  * calculations to insure there will be enough physically contiguous
        !          2127:  * memory to support ADV_MAX_SG_LIST SG entries.
        !          2128:  */
        !          2129: 
        !          2130: /* Number of SG blocks needed. */
        !          2131: #define ADV_NUM_SG_BLOCK \
        !          2132:      ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
        !          2133: 
        !          2134: /* Total contiguous memory needed for SG blocks. */
        !          2135: #define ADV_SG_TOTAL_MEM_SIZE \
        !          2136:     (sizeof(ADV_SG_BLOCK) *  ADV_NUM_SG_BLOCK)
        !          2137: 
        !          2138: #define ASC_PAGE_SIZE PAGE_SIZE
        !          2139: 
        !          2140: /*
        !          2141:  * Number of page crossings possible for the total contiguous virtual memory
        !          2142:  * needed for SG blocks.
        !          2143:  *
        !          2144:  * We need to allocate this many additional SG blocks in virtual memory to
        !          2145:  * insure there will be space for ADV_NUM_SG_BLOCK physically contiguous
        !          2146:  * scatter-gather blocks.
        !          2147:  */
        !          2148: #define ADV_NUM_PAGE_CROSSING \
        !          2149:     ((ADV_SG_TOTAL_MEM_SIZE + (ASC_PAGE_SIZE - 1))/ASC_PAGE_SIZE)
        !          2150: 
        !          2151: /*
        !          2152:  * Define Adv Library Assertion Macro.
        !          2153:  */
        !          2154: 
        !          2155: #define ADV_ASSERT(a) ASC_ASSERT(a)
        !          2156: 
        !          2157: /* a_condor.h */
        !          2158: #define ADV_PCI_VENDOR_ID               0x10CD
        !          2159: #define ADV_PCI_DEVICE_ID_REV_A         0x2300
        !          2160: 
        !          2161: #define ASC_EEP_DVC_CFG_BEGIN           (0x00)
        !          2162: #define ASC_EEP_DVC_CFG_END             (0x15)
        !          2163: #define ASC_EEP_DVC_CTL_BEGIN           (0x16)  /* location of OEM name */
        !          2164: #define ASC_EEP_MAX_WORD_ADDR           (0x1E)
        !          2165: 
        !          2166: #define ASC_EEP_DELAY_MS                100
        !          2167: 
        !          2168: /*
        !          2169:  * EEPROM bits reference by the RISC after initialization.
        !          2170:  */
        !          2171: #define ADV_EEPROM_BIG_ENDIAN          0x8000   /* EEPROM Bit 15 */
        !          2172: #define ADV_EEPROM_BIOS_ENABLE         0x4000   /* EEPROM Bit 14 */
        !          2173: #define ADV_EEPROM_TERM_POL            0x2000   /* EEPROM Bit 13 */
        !          2174: 
        !          2175: /*
        !          2176:  * EEPROM configuration format
        !          2177:  *
        !          2178:  * Field naming convention: 
        !          2179:  *
        !          2180:  *  *_enable indicates the field enables or disables the feature. The
        !          2181:  *  value is never reset.
        !          2182:  *
        !          2183:  *  *_able indicates both whether a feature should be enabled or disabled
        !          2184:  *  and whether a device isi capable of the feature. At initialization
        !          2185:  *  this field may be set, but later if a device is found to be incapable
        !          2186:  *  of the feature, the field is cleared.
        !          2187:  *
        !          2188:  * Default values are maintained in a_init.c in the structure
        !          2189:  * Default_EEPROM_Config.
        !          2190:  */
        !          2191: typedef struct adveep_config
        !          2192: {                              
        !          2193:                                 /* Word Offset, Description */
        !          2194: 
        !          2195:   ushort cfg_lsw;               /* 00 power up initialization */
        !          2196:                                 /*  bit 13 set - Term Polarity Control */
        !          2197:                                 /*  bit 14 set - BIOS Enable */
        !          2198:                                 /*  bit 15 set - Big Endian Mode */
        !          2199:   ushort cfg_msw;               /* 01 unused      */
        !          2200:   ushort disc_enable;           /* 02 disconnect enable */         
        !          2201:   ushort wdtr_able;             /* 03 Wide DTR able */
        !          2202:   ushort sdtr_able;             /* 04 Synchronous DTR able */
        !          2203:   ushort start_motor;           /* 05 send start up motor */      
        !          2204:   ushort tagqng_able;           /* 06 tag queuing able */
        !          2205:   ushort bios_scan;             /* 07 BIOS device control */   
        !          2206:   ushort scam_tolerant;         /* 08 no scam */  
        !          2207:  
        !          2208:   uchar  adapter_scsi_id;       /* 09 Host Adapter ID */
        !          2209:   uchar  bios_boot_delay;       /*    power up wait */
        !          2210:  
        !          2211:   uchar  scsi_reset_delay;      /* 10 reset delay */
        !          2212:   uchar  bios_id_lun;           /*    first boot device scsi id & lun */
        !          2213:                                 /*    high nibble is lun */  
        !          2214:                                 /*    low nibble is scsi id */
        !          2215: 
        !          2216:   uchar  termination;           /* 11 0 - automatic */
        !          2217:                                 /*    1 - low off / high off */
        !          2218:                                 /*    2 - low off / high on */
        !          2219:                                 /*    3 - low on  / high on */
        !          2220:                                 /*    There is no low on  / high off */
        !          2221: 
        !          2222:   uchar  reserved1;             /*    reserved byte (not used) */                                  
        !          2223: 
        !          2224:   ushort bios_ctrl;             /* 12 BIOS control bits */
        !          2225:                                 /*  bit 0  set: BIOS don't act as initiator. */
        !          2226:                                 /*  bit 1  set: BIOS > 1 GB support */
        !          2227:                                 /*  bit 2  set: BIOS > 2 Disk Support */
        !          2228:                                 /*  bit 3  set: BIOS don't support removables */
        !          2229:                                 /*  bit 4  set: BIOS support bootable CD */
        !          2230:                                 /*  bit 5  set: */
        !          2231:                                 /*  bit 6  set: BIOS support multiple LUNs */
        !          2232:                                 /*  bit 7  set: BIOS display of message */
        !          2233:                                 /*  bit 8  set: */
        !          2234:                                 /*  bit 9  set: Reset SCSI bus during init. */
        !          2235:                                 /*  bit 10 set: */
        !          2236:                                 /*  bit 11 set: No verbose initialization. */
        !          2237:                                 /*  bit 12 set: SCSI parity enabled */
        !          2238:                                 /*  bit 13 set: */
        !          2239:                                 /*  bit 14 set: */
        !          2240:                                 /*  bit 15 set: */
        !          2241:   ushort  ultra_able;           /* 13 ULTRA speed able */ 
        !          2242:   ushort  reserved2;            /* 14 reserved */
        !          2243:   uchar   max_host_qng;         /* 15 maximum host queuing */
        !          2244:   uchar   max_dvc_qng;          /*    maximum per device queuing */
        !          2245:   ushort  dvc_cntl;             /* 16 control bit for driver */
        !          2246:   ushort  bug_fix;              /* 17 control bit for bug fix */
        !          2247:   ushort  serial_number_word1;  /* 18 Board serial number word 1 */  
        !          2248:   ushort  serial_number_word2;  /* 19 Board serial number word 2 */  
        !          2249:   ushort  serial_number_word3;  /* 20 Board serial number word 3 */
        !          2250:   ushort  check_sum;            /* 21 EEP check sum */
        !          2251:   uchar   oem_name[16];         /* 22 OEM name */
        !          2252:   ushort  dvc_err_code;         /* 30 last device driver error code */
        !          2253:   ushort  adv_err_code;         /* 31 last uc and Adv Lib error code */
        !          2254:   ushort  adv_err_addr;         /* 32 last uc error address */
        !          2255:   ushort  saved_dvc_err_code;   /* 33 saved last dev. driver error code   */
        !          2256:   ushort  saved_adv_err_code;   /* 34 saved last uc and Adv Lib error code */
        !          2257:   ushort  saved_adv_err_addr;   /* 35 saved last uc error address         */  
        !          2258:   ushort  num_of_err;           /* 36 number of error */
        !          2259: } ADVEEP_CONFIG; 
        !          2260: 
        !          2261: /*
        !          2262:  * EEPROM Commands
        !          2263:  */
        !          2264: #define ASC_EEP_CMD_DONE             0x0200
        !          2265: #define ASC_EEP_CMD_DONE_ERR         0x0001
        !          2266: 
        !          2267: /* cfg_word */
        !          2268: #define EEP_CFG_WORD_BIG_ENDIAN      0x8000
        !          2269: 
        !          2270: /* bios_ctrl */
        !          2271: #define BIOS_CTRL_BIOS               0x0001
        !          2272: #define BIOS_CTRL_EXTENDED_XLAT      0x0002
        !          2273: #define BIOS_CTRL_GT_2_DISK          0x0004
        !          2274: #define BIOS_CTRL_BIOS_REMOVABLE     0x0008
        !          2275: #define BIOS_CTRL_BOOTABLE_CD        0x0010
        !          2276: #define BIOS_CTRL_MULTIPLE_LUN       0x0040
        !          2277: #define BIOS_CTRL_DISPLAY_MSG        0x0080
        !          2278: #define BIOS_CTRL_NO_SCAM            0x0100
        !          2279: #define BIOS_CTRL_RESET_SCSI_BUS     0x0200
        !          2280: #define BIOS_CTRL_INIT_VERBOSE       0x0800
        !          2281: #define BIOS_CTRL_SCSI_PARITY        0x1000
        !          2282: 
        !          2283: /*
        !          2284:  * ASC 3550 Internal Memory Size - 8KB
        !          2285:  */
        !          2286: #define ADV_CONDOR_MEMSIZE   0x2000     /* 8 KB Internal Memory */
        !          2287: 
        !          2288: /*
        !          2289:  * ASC 3550 I/O Length - 64 bytes
        !          2290:  */
        !          2291: #define ADV_CONDOR_IOLEN     0x40       /* I/O Port Range in bytes */
        !          2292: 
        !          2293: /*
        !          2294:  * Byte I/O register address from base of 'iop_base'.
        !          2295:  */
        !          2296: #define IOPB_INTR_STATUS_REG    0x00
        !          2297: #define IOPB_CHIP_ID_1          0x01
        !          2298: #define IOPB_INTR_ENABLES       0x02
        !          2299: #define IOPB_CHIP_TYPE_REV      0x03
        !          2300: #define IOPB_RES_ADDR_4         0x04
        !          2301: #define IOPB_RES_ADDR_5         0x05
        !          2302: #define IOPB_RAM_DATA           0x06
        !          2303: #define IOPB_RES_ADDR_7         0x07
        !          2304: #define IOPB_FLAG_REG           0x08
        !          2305: #define IOPB_RES_ADDR_9         0x09
        !          2306: #define IOPB_RISC_CSR           0x0A
        !          2307: #define IOPB_RES_ADDR_B         0x0B
        !          2308: #define IOPB_RES_ADDR_C         0x0C
        !          2309: #define IOPB_RES_ADDR_D         0x0D
        !          2310: #define IOPB_RES_ADDR_E         0x0E
        !          2311: #define IOPB_RES_ADDR_F         0x0F
        !          2312: #define IOPB_MEM_CFG            0x10
        !          2313: #define IOPB_RES_ADDR_11        0x11
        !          2314: #define IOPB_RES_ADDR_12        0x12
        !          2315: #define IOPB_RES_ADDR_13        0x13
        !          2316: #define IOPB_FLASH_PAGE         0x14
        !          2317: #define IOPB_RES_ADDR_15        0x15
        !          2318: #define IOPB_RES_ADDR_16        0x16
        !          2319: #define IOPB_RES_ADDR_17        0x17
        !          2320: #define IOPB_FLASH_DATA         0x18
        !          2321: #define IOPB_RES_ADDR_19        0x19
        !          2322: #define IOPB_RES_ADDR_1A        0x1A
        !          2323: #define IOPB_RES_ADDR_1B        0x1B
        !          2324: #define IOPB_RES_ADDR_1C        0x1C
        !          2325: #define IOPB_RES_ADDR_1D        0x1D
        !          2326: #define IOPB_RES_ADDR_1E        0x1E
        !          2327: #define IOPB_RES_ADDR_1F        0x1F
        !          2328: #define IOPB_DMA_CFG0           0x20
        !          2329: #define IOPB_DMA_CFG1           0x21
        !          2330: #define IOPB_TICKLE             0x22
        !          2331: #define IOPB_DMA_REG_WR         0x23
        !          2332: #define IOPB_SDMA_STATUS        0x24
        !          2333: #define IOPB_SCSI_BYTE_CNT      0x25
        !          2334: #define IOPB_HOST_BYTE_CNT      0x26
        !          2335: #define IOPB_BYTE_LEFT_TO_XFER  0x27
        !          2336: #define IOPB_BYTE_TO_XFER_0     0x28
        !          2337: #define IOPB_BYTE_TO_XFER_1     0x29
        !          2338: #define IOPB_BYTE_TO_XFER_2     0x2A
        !          2339: #define IOPB_BYTE_TO_XFER_3     0x2B
        !          2340: #define IOPB_ACC_GRP            0x2C
        !          2341: #define IOPB_RES_ADDR_2D        0x2D
        !          2342: #define IOPB_DEV_ID             0x2E
        !          2343: #define IOPB_RES_ADDR_2F        0x2F
        !          2344: #define IOPB_SCSI_DATA          0x30
        !          2345: #define IOPB_RES_ADDR_31        0x31
        !          2346: #define IOPB_RES_ADDR_32        0x32
        !          2347: #define IOPB_SCSI_DATA_HSHK     0x33
        !          2348: #define IOPB_SCSI_CTRL          0x34
        !          2349: #define IOPB_RES_ADDR_35        0x35
        !          2350: #define IOPB_RES_ADDR_36        0x36
        !          2351: #define IOPB_RES_ADDR_37        0x37
        !          2352: #define IOPB_RES_ADDR_38        0x38
        !          2353: #define IOPB_RES_ADDR_39        0x39
        !          2354: #define IOPB_RES_ADDR_3A        0x3A
        !          2355: #define IOPB_RES_ADDR_3B        0x3B
        !          2356: #define IOPB_RFIFO_CNT          0x3C
        !          2357: #define IOPB_RES_ADDR_3D        0x3D
        !          2358: #define IOPB_RES_ADDR_3E        0x3E
        !          2359: #define IOPB_RES_ADDR_3F        0x3F
        !          2360: 
        !          2361: /*
        !          2362:  * Word I/O register address from base of 'iop_base'.
        !          2363:  */
        !          2364: #define IOPW_CHIP_ID_0          0x00  /* CID0  */
        !          2365: #define IOPW_CTRL_REG           0x02  /* CC    */
        !          2366: #define IOPW_RAM_ADDR           0x04  /* LA    */
        !          2367: #define IOPW_RAM_DATA           0x06  /* LD    */
        !          2368: #define IOPW_RES_ADDR_08        0x08
        !          2369: #define IOPW_RISC_CSR           0x0A  /* CSR   */
        !          2370: #define IOPW_SCSI_CFG0          0x0C  /* CFG0  */
        !          2371: #define IOPW_SCSI_CFG1          0x0E  /* CFG1  */
        !          2372: #define IOPW_RES_ADDR_10        0x10
        !          2373: #define IOPW_SEL_MASK           0x12  /* SM    */
        !          2374: #define IOPW_RES_ADDR_14        0x14
        !          2375: #define IOPW_FLASH_ADDR         0x16  /* FA    */
        !          2376: #define IOPW_RES_ADDR_18        0x18
        !          2377: #define IOPW_EE_CMD             0x1A  /* EC    */
        !          2378: #define IOPW_EE_DATA            0x1C  /* ED    */
        !          2379: #define IOPW_SFIFO_CNT          0x1E  /* SFC   */
        !          2380: #define IOPW_RES_ADDR_20        0x20
        !          2381: #define IOPW_Q_BASE             0x22  /* QB    */
        !          2382: #define IOPW_QP                 0x24  /* QP    */
        !          2383: #define IOPW_IX                 0x26  /* IX    */
        !          2384: #define IOPW_SP                 0x28  /* SP    */
        !          2385: #define IOPW_PC                 0x2A  /* PC    */
        !          2386: #define IOPW_RES_ADDR_2C        0x2C
        !          2387: #define IOPW_RES_ADDR_2E        0x2E
        !          2388: #define IOPW_SCSI_DATA          0x30  /* SD    */
        !          2389: #define IOPW_SCSI_DATA_HSHK     0x32  /* SDH   */
        !          2390: #define IOPW_SCSI_CTRL          0x34  /* SC    */
        !          2391: #define IOPW_HSHK_CFG           0x36  /* HCFG  */
        !          2392: #define IOPW_SXFR_STATUS        0x36  /* SXS   */
        !          2393: #define IOPW_SXFR_CNTL          0x38  /* SXL   */
        !          2394: #define IOPW_SXFR_CNTH          0x3A  /* SXH   */
        !          2395: #define IOPW_RES_ADDR_3C        0x3C
        !          2396: #define IOPW_RFIFO_DATA         0x3E  /* RFD   */
        !          2397: 
        !          2398: /*
        !          2399:  * Doubleword I/O register address from base of 'iop_base'.
        !          2400:  */
        !          2401: #define IOPDW_RES_ADDR_0         0x00
        !          2402: #define IOPDW_RAM_DATA           0x04
        !          2403: #define IOPDW_RES_ADDR_8         0x08
        !          2404: #define IOPDW_RES_ADDR_C         0x0C
        !          2405: #define IOPDW_RES_ADDR_10        0x10
        !          2406: #define IOPDW_RES_ADDR_14        0x14
        !          2407: #define IOPDW_RES_ADDR_18        0x18
        !          2408: #define IOPDW_RES_ADDR_1C        0x1C
        !          2409: #define IOPDW_SDMA_ADDR0         0x20
        !          2410: #define IOPDW_SDMA_ADDR1         0x24
        !          2411: #define IOPDW_SDMA_COUNT         0x28
        !          2412: #define IOPDW_SDMA_ERROR         0x2C
        !          2413: #define IOPDW_RDMA_ADDR0         0x30
        !          2414: #define IOPDW_RDMA_ADDR1         0x34
        !          2415: #define IOPDW_RDMA_COUNT         0x38
        !          2416: #define IOPDW_RDMA_ERROR         0x3C
        !          2417: 
        !          2418: #define ADV_CHIP_ID_BYTE         0x25
        !          2419: #define ADV_CHIP_ID_WORD         0x04C1
        !          2420: 
        !          2421: #define ADV_SC_SCSI_BUS_RESET    0x2000
        !          2422: 
        !          2423: #define ADV_INTR_ENABLE_HOST_INTR                   0x01
        !          2424: #define ADV_INTR_ENABLE_SEL_INTR                    0x02
        !          2425: #define ADV_INTR_ENABLE_DPR_INTR                    0x04
        !          2426: #define ADV_INTR_ENABLE_RTA_INTR                    0x08
        !          2427: #define ADV_INTR_ENABLE_RMA_INTR                    0x10
        !          2428: #define ADV_INTR_ENABLE_RST_INTR                    0x20
        !          2429: #define ADV_INTR_ENABLE_DPE_INTR                    0x40
        !          2430: #define ADV_INTR_ENABLE_GLOBAL_INTR                 0x80
        !          2431: 
        !          2432: #define ADV_INTR_STATUS_INTRA            0x01
        !          2433: #define ADV_INTR_STATUS_INTRB            0x02
        !          2434: #define ADV_INTR_STATUS_INTRC            0x04
        !          2435: 
        !          2436: #define ADV_RISC_CSR_STOP           (0x0000)
        !          2437: #define ADV_RISC_TEST_COND          (0x2000)
        !          2438: #define ADV_RISC_CSR_RUN            (0x4000)
        !          2439: #define ADV_RISC_CSR_SINGLE_STEP    (0x8000)
        !          2440: 
        !          2441: #define ADV_CTRL_REG_HOST_INTR      0x0100
        !          2442: #define ADV_CTRL_REG_SEL_INTR       0x0200
        !          2443: #define ADV_CTRL_REG_DPR_INTR       0x0400
        !          2444: #define ADV_CTRL_REG_RTA_INTR       0x0800
        !          2445: #define ADV_CTRL_REG_RMA_INTR       0x1000
        !          2446: #define ADV_CTRL_REG_RES_BIT14      0x2000
        !          2447: #define ADV_CTRL_REG_DPE_INTR       0x4000
        !          2448: #define ADV_CTRL_REG_POWER_DONE     0x8000
        !          2449: #define ADV_CTRL_REG_ANY_INTR       0xFF00
        !          2450: 
        !          2451: #define ADV_CTRL_REG_CMD_RESET             0x00C6
        !          2452: #define ADV_CTRL_REG_CMD_WR_IO_REG         0x00C5
        !          2453: #define ADV_CTRL_REG_CMD_RD_IO_REG         0x00C4
        !          2454: #define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE  0x00C3
        !          2455: #define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE  0x00C2
        !          2456: 
        !          2457: #define ADV_SCSI_CTRL_RSTOUT        0x2000
        !          2458: 
        !          2459: #define AdvIsIntPending(port)  \
        !          2460:     (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
        !          2461: 
        !          2462: /*
        !          2463:  * SCSI_CFG0 Register bit definitions
        !          2464:  */
        !          2465: #define TIMER_MODEAB    0xC000  /* Watchdog, Second, and Select. Timer Ctrl. */
        !          2466: #define PARITY_EN       0x2000  /* Enable SCSI Parity Error detection */
        !          2467: #define EVEN_PARITY     0x1000  /* Select Even Parity */
        !          2468: #define WD_LONG         0x0800  /* Watchdog Interval, 1: 57 min, 0: 13 sec */
        !          2469: #define QUEUE_128       0x0400  /* Queue Size, 1: 128 byte, 0: 64 byte */
        !          2470: #define PRIM_MODE       0x0100  /* Primitive SCSI mode */
        !          2471: #define SCAM_EN         0x0080  /* Enable SCAM selection */
        !          2472: #define SEL_TMO_LONG    0x0040  /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
        !          2473: #define CFRM_ID         0x0020  /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
        !          2474: #define OUR_ID_EN       0x0010  /* Enable OUR_ID bits */
        !          2475: #define OUR_ID          0x000F  /* SCSI ID */
        !          2476: 
        !          2477: /*
        !          2478:  * SCSI_CFG1 Register bit definitions
        !          2479:  */
        !          2480: #define BIG_ENDIAN      0x8000  /* Enable Big Endian Mode MIO:15, EEP:15 */
        !          2481: #define TERM_POL        0x2000  /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
        !          2482: #define SLEW_RATE       0x1000  /* SCSI output buffer slew rate */
        !          2483: #define FILTER_SEL      0x0C00  /* Filter Period Selection */
        !          2484: #define  FLTR_DISABLE    0x0000  /* Input Filtering Disabled */
        !          2485: #define  FLTR_11_TO_20NS 0x0800  /* Input Filtering 11ns to 20ns */          
        !          2486: #define  FLTR_21_TO_39NS 0x0C00  /* Input Filtering 21ns to 39ns */          
        !          2487: #define ACTIVE_DBL      0x0200  /* Disable Active Negation */
        !          2488: #define DIFF_MODE       0x0100  /* SCSI differential Mode (Read-Only) */
        !          2489: #define DIFF_SENSE      0x0080  /* 1: No SE cables, 0: SE cable (Read-Only) */
        !          2490: #define TERM_CTL_SEL    0x0040  /* Enable TERM_CTL_H and TERM_CTL_L */
        !          2491: #define TERM_CTL        0x0030  /* External SCSI Termination Bits */
        !          2492: #define  TERM_CTL_H      0x0020  /* Enable External SCSI Upper Termination */
        !          2493: #define  TERM_CTL_L      0x0010  /* Enable External SCSI Lower Termination */
        !          2494: #define CABLE_DETECT    0x000F  /* External SCSI Cable Connection Status */
        !          2495: 
        !          2496: #define CABLE_ILLEGAL_A 0x7
        !          2497:     /* x 0 0 0  | on  on | Illegal (all 3 connectors are used) */
        !          2498: 
        !          2499: #define CABLE_ILLEGAL_B 0xB
        !          2500:     /* 0 x 0 0  | on  on | Illegal (all 3 connectors are used) */
        !          2501: 
        !          2502: /*
        !          2503:    The following table details the SCSI_CFG1 Termination Polarity,
        !          2504:    Termination Control and Cable Detect bits.
        !          2505: 
        !          2506:    Cable Detect | Termination
        !          2507:    Bit 3 2 1 0  | 5   4  | Notes
        !          2508:    _____________|________|____________________
        !          2509:        1 1 1 0  | on  on | Internal wide only
        !          2510:        1 1 0 1  | on  on | Internal narrow only
        !          2511:        1 0 1 1  | on  on | External narrow only
        !          2512:        0 x 1 1  | on  on | External wide only
        !          2513:        1 1 0 0  | on  off| Internal wide and internal narrow
        !          2514:        1 0 1 0  | on  off| Internal wide and external narrow
        !          2515:        0 x 1 0  | off off| Internal wide and external wide
        !          2516:        1 0 0 1  | on  off| Internal narrow and external narrow
        !          2517:        0 x 0 1  | on  off| Internal narrow and external wide
        !          2518:        1 1 1 1  | on  on | No devices are attached
        !          2519:        x 0 0 0  | on  on | Illegal (all 3 connectors are used)
        !          2520:        0 x 0 0  | on  on | Illegal (all 3 connectors are used)
        !          2521:   
        !          2522:        x means don't-care (either '0' or '1')
        !          2523:   
        !          2524:        If term_pol (bit 13) is '0' (active-low terminator enable), then:
        !          2525:            'on' is '0' and 'off' is '1'.
        !          2526:   
        !          2527:        If term_pol bit is '1' (meaning active-hi terminator enable), then:
        !          2528:            'on' is '1' and 'off' is '0'.
        !          2529:  */
        !          2530: 
        !          2531: /*
        !          2532:  * MEM_CFG Register bit definitions
        !          2533:  */
        !          2534: #define BIOS_EN         0x40    /* BIOS Enable MIO:14,EEP:14 */
        !          2535: #define FAST_EE_CLK     0x20    /* Diagnostic Bit */
        !          2536: #define RAM_SZ          0x1C    /* Specify size of RAM to RISC */
        !          2537: #define  RAM_SZ_2KB      0x00    /* 2 KB */
        !          2538: #define  RAM_SZ_4KB      0x04    /* 4 KB */
        !          2539: #define  RAM_SZ_8KB      0x08    /* 8 KB */
        !          2540: #define  RAM_SZ_16KB     0x0C    /* 16 KB */
        !          2541: #define  RAM_SZ_32KB     0x10    /* 32 KB */
        !          2542: #define  RAM_SZ_64KB     0x14    /* 64 KB */
        !          2543: 
        !          2544: /*
        !          2545:  * DMA_CFG0 Register bit definitions
        !          2546:  *
        !          2547:  * This register is only accessible to the host.
        !          2548:  */
        !          2549: #define BC_THRESH_ENB   0x80    /* PCI DMA Start Conditions */
        !          2550: #define FIFO_THRESH     0x70    /* PCI DMA FIFO Threshold */
        !          2551: #define  FIFO_THRESH_16B  0x00   /* 16 bytes */
        !          2552: #define  FIFO_THRESH_32B  0x20   /* 32 bytes */
        !          2553: #define  FIFO_THRESH_48B  0x30   /* 48 bytes */
        !          2554: #define  FIFO_THRESH_64B  0x40   /* 64 bytes */
        !          2555: #define  FIFO_THRESH_80B  0x50   /* 80 bytes (default) */
        !          2556: #define  FIFO_THRESH_96B  0x60   /* 96 bytes */
        !          2557: #define  FIFO_THRESH_112B 0x70   /* 112 bytes */
        !          2558: #define START_CTL       0x0C    /* DMA start conditions */
        !          2559: #define  START_CTL_TH    0x00    /* Wait threshold level (default) */
        !          2560: #define  START_CTL_ID    0x04    /* Wait SDMA/SBUS idle */
        !          2561: #define  START_CTL_THID  0x08    /* Wait threshold and SDMA/SBUS idle */
        !          2562: #define  START_CTL_EMFU  0x0C    /* Wait SDMA FIFO empty/full */
        !          2563: #define READ_CMD        0x03    /* Memory Read Method */
        !          2564: #define  READ_CMD_MR     0x00    /* Memory Read */
        !          2565: #define  READ_CMD_MRL    0x02    /* Memory Read Long */
        !          2566: #define  READ_CMD_MRM    0x03    /* Memory Read Multiple (default) */
        !          2567: 
        !          2568: /* a_advlib.h */
        !          2569: 
        !          2570: /*
        !          2571:  * Adv Library Status Definitions
        !          2572:  */
        !          2573: #define ADV_TRUE        1
        !          2574: #define ADV_FALSE       0
        !          2575: #define ADV_NOERROR     1
        !          2576: #define ADV_SUCCESS     1
        !          2577: #define ADV_BUSY        0
        !          2578: #define ADV_ERROR       (-1)
        !          2579: 
        !          2580: 
        !          2581: /*
        !          2582:  * ASC_DVC_VAR 'warn_code' values
        !          2583:  */
        !          2584: #define ASC_WARN_EEPROM_CHKSUM          0x0002 /* EEP check sum error */
        !          2585: #define ASC_WARN_EEPROM_TERMINATION     0x0004 /* EEP termination bad field */
        !          2586: #define ASC_WARN_SET_PCI_CONFIG_SPACE   0x0080 /* PCI config space set error */
        !          2587: #define ASC_WARN_ERROR                  0xFFFF /* ADV_ERROR return */
        !          2588: 
        !          2589: #define ADV_MAX_TID                     15 /* max. target identifier */
        !          2590: #define ADV_MAX_LUN                     7  /* max. logical unit number */
        !          2591: 
        !          2592: 
        !          2593: /*
        !          2594:  * AscInitGetConfig() and AscInitAsc1000Driver() Definitions
        !          2595:  *
        !          2596:  * Error code values are set in ASC_DVC_VAR 'err_code'.
        !          2597:  */
        !          2598: #define ASC_IERR_WRITE_EEPROM       0x0001 /* write EEPROM error */
        !          2599: #define ASC_IERR_MCODE_CHKSUM       0x0002 /* micro code check sum error */
        !          2600: #define ASC_IERR_START_STOP_CHIP    0x0008 /* start/stop chip failed */
        !          2601: #define ASC_IERR_CHIP_VERSION       0x0040 /* wrong chip version */
        !          2602: #define ASC_IERR_SET_SCSI_ID        0x0080 /* set SCSI ID failed */
        !          2603: #define ASC_IERR_BAD_SIGNATURE      0x0200 /* signature not found */
        !          2604: #define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
        !          2605: #define ASC_IERR_SINGLE_END_DEVICE  0x0800 /* Single-end used w/differential */
        !          2606: #define ASC_IERR_REVERSED_CABLE     0x1000 /* Narrow flat cable reversed */
        !          2607: #define ASC_IERR_RW_LRAM            0x8000 /* read/write local RAM error */
        !          2608: 
        !          2609: /*
        !          2610:  * Fixed locations of microcode operating variables.
        !          2611:  */
        !          2612: #define ASC_MC_CODE_BEGIN_ADDR          0x0028 /* microcode start address */
        !          2613: #define ASC_MC_CODE_END_ADDR            0x002A /* microcode end address */
        !          2614: #define ASC_MC_CODE_CHK_SUM             0x002C /* microcode code checksum */
        !          2615: #define ASC_MC_STACK_BEGIN              0x002E /* microcode stack begin */
        !          2616: #define ASC_MC_STACK_END                0x0030 /* microcode stack end */
        !          2617: #define ASC_MC_VERSION_DATE             0x0038 /* microcode version */
        !          2618: #define ASC_MC_VERSION_NUM              0x003A /* microcode number */
        !          2619: #define ASCV_VER_SERIAL_W               0x003C /* used in dos_init */
        !          2620: #define ASC_MC_BIOSMEM                  0x0040 /* BIOS RISC Memory Start */
        !          2621: #define ASC_MC_BIOSLEN                  0x0050 /* BIOS RISC Memory Length */
        !          2622: #define ASC_MC_HALTCODE                 0x0094 /* microcode halt code */
        !          2623: #define ASC_MC_CALLERPC                 0x0096 /* microcode halt caller PC */
        !          2624: #define ASC_MC_ADAPTER_SCSI_ID          0x0098 /* one ID byte + reserved */
        !          2625: #define ASC_MC_ULTRA_ABLE               0x009C
        !          2626: #define ASC_MC_SDTR_ABLE                0x009E
        !          2627: #define ASC_MC_TAGQNG_ABLE              0x00A0
        !          2628: #define ASC_MC_DISC_ENABLE              0x00A2
        !          2629: #define ASC_MC_IDLE_CMD                 0x00A6
        !          2630: #define ASC_MC_IDLE_PARA_STAT           0x00A8
        !          2631: #define ASC_MC_DEFAULT_SCSI_CFG0        0x00AC
        !          2632: #define ASC_MC_DEFAULT_SCSI_CFG1        0x00AE
        !          2633: #define ASC_MC_DEFAULT_MEM_CFG          0x00B0
        !          2634: #define ASC_MC_DEFAULT_SEL_MASK         0x00B2
        !          2635: #define ASC_MC_RISC_NEXT_READY          0x00B4
        !          2636: #define ASC_MC_RISC_NEXT_DONE           0x00B5
        !          2637: #define ASC_MC_SDTR_DONE                0x00B6
        !          2638: #define ASC_MC_NUMBER_OF_QUEUED_CMD     0x00C0
        !          2639: #define ASC_MC_NUMBER_OF_MAX_CMD        0x00D0
        !          2640: #define ASC_MC_DEVICE_HSHK_CFG_TABLE    0x0100
        !          2641: #define ASC_MC_WDTR_ABLE                0x0120 /* Wide Transfer TID bitmask. */
        !          2642: #define ASC_MC_CONTROL_FLAG             0x0122 /* Microcode control flag. */
        !          2643: #define ASC_MC_WDTR_DONE                0x0124
        !          2644: #define ASC_MC_HOST_NEXT_READY          0x0128 /* Host Next Ready RQL Entry. */
        !          2645: #define ASC_MC_HOST_NEXT_DONE           0x0129 /* Host Next Done RQL Entry. */
        !          2646: 
        !          2647: /*
        !          2648:  * BIOS LRAM variable absolute offsets.
        !          2649:  */
        !          2650: #define BIOS_CODESEG    0x54
        !          2651: #define BIOS_CODELEN    0x56
        !          2652: #define BIOS_SIGNATURE  0x58
        !          2653: #define BIOS_VERSION    0x5A
        !          2654: #define BIOS_SIGNATURE  0x58
        !          2655: 
        !          2656: /*
        !          2657:  * Microcode Control Flags
        !          2658:  *
        !          2659:  * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
        !          2660:  * and handled by the microcode.
        !          2661:  */
        !          2662: #define CONTROL_FLAG_IGNORE_PERR        0x0001 /* Ignore DMA Parity Errors */
        !          2663: 
        !          2664: /*
        !          2665:  * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
        !          2666:  */
        !          2667: #define HSHK_CFG_WIDE_XFR       0x8000
        !          2668: #define HSHK_CFG_RATE           0x0F00
        !          2669: #define HSHK_CFG_OFFSET         0x001F
        !          2670: 
        !          2671: /*
        !          2672:  * LRAM RISC Queue Lists (LRAM addresses 0x1200 - 0x19FF)
        !          2673:  *
        !          2674:  * Each of the 255 Adv Library/Microcode RISC queue lists or mailboxes 
        !          2675:  * starting at LRAM address 0x1200 is 8 bytes and has the following
        !          2676:  * structure. Only 253 of these are actually used for command queues.
        !          2677:  */
        !          2678: 
        !          2679: #define ASC_MC_RISC_Q_LIST_BASE         0x1200
        !          2680: #define ASC_MC_RISC_Q_LIST_SIZE         0x0008
        !          2681: #define ASC_MC_RISC_Q_TOTAL_CNT         0x00FF /* Num. queue slots in LRAM. */
        !          2682: #define ASC_MC_RISC_Q_FIRST             0x0001
        !          2683: #define ASC_MC_RISC_Q_LAST              0x00FF
        !          2684: 
        !          2685: #define ASC_DEF_MAX_HOST_QNG    0xFD /* Max. number of host commands (253) */
        !          2686: #define ASC_DEF_MIN_HOST_QNG    0x10 /* Min. number of host commands (16) */
        !          2687: #define ASC_DEF_MAX_DVC_QNG     0x3F /* Max. number commands per device (63) */
        !          2688: #define ASC_DEF_MIN_DVC_QNG     0x04 /* Min. number commands per device (4) */
        !          2689: 
        !          2690: /* RISC Queue List structure - 8 bytes */
        !          2691: #define RQL_FWD     0     /* forward pointer (1 byte) */
        !          2692: #define RQL_BWD     1     /* backward pointer (1 byte) */
        !          2693: #define RQL_STATE   2     /* state byte - free, ready, done, aborted (1 byte) */
        !          2694: #define RQL_TID     3     /* request target id (1 byte) */
        !          2695: #define RQL_PHYADDR 4     /* request physical pointer (4 bytes) */
        !          2696:      
        !          2697: /* RISC Queue List state values */
        !          2698: #define ASC_MC_QS_FREE                  0x00
        !          2699: #define ASC_MC_QS_READY                 0x01
        !          2700: #define ASC_MC_QS_DONE                  0x40
        !          2701: #define ASC_MC_QS_ABORTED               0x80
        !          2702: 
        !          2703: /* RISC Queue List pointer values */
        !          2704: #define ASC_MC_NULL_Q                   0x00            /* NULL_Q == 0   */
        !          2705: #define ASC_MC_BIOS_Q                   0xFF            /* BIOS_Q = 255  */
        !          2706: 
        !          2707: /* ASC_SCSI_REQ_Q 'cntl' field values */
        !          2708: #define ASC_MC_QC_START_MOTOR           0x02     /* Issue start motor. */
        !          2709: #define ASC_MC_QC_NO_OVERRUN            0x04     /* Don't report overrun. */
        !          2710: #define ASC_MC_QC_FIRST_DMA             0x08     /* Internal microcode flag. */
        !          2711: #define ASC_MC_QC_ABORTED               0x10     /* Request aborted by host. */
        !          2712: #define ASC_MC_QC_REQ_SENSE             0x20     /* Auto-Request Sense. */
        !          2713: #define ASC_MC_QC_DOS_REQ               0x80     /* Request issued by DOS. */
        !          2714: 
        !          2715: 
        !          2716: /*
        !          2717:  * ASC_SCSI_REQ_Q 'a_flag' definitions
        !          2718:  *
        !          2719:  * The Adv Library should limit use to the lower nibble (4 bits) of
        !          2720:  * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
        !          2721:  */
        !          2722: #define ADV_POLL_REQUEST                0x01   /* poll for request completion */
        !          2723: #define ADV_SCSIQ_DONE                  0x02   /* request done */
        !          2724: 
        !          2725: /*
        !          2726:  * Adapter temporary configuration structure
        !          2727:  *
        !          2728:  * This structure can be discarded after initialization. Don't add
        !          2729:  * fields here needed after initialization.
        !          2730:  *
        !          2731:  * Field naming convention: 
        !          2732:  *
        !          2733:  *  *_enable indicates the field enables or disables a feature. The
        !          2734:  *  value of the field is never reset.
        !          2735:  */
        !          2736: typedef struct adv_dvc_cfg {
        !          2737:   ushort disc_enable;       /* enable disconnection */
        !          2738:   uchar  chip_version;      /* chip version */
        !          2739:   uchar  termination;       /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
        !          2740:   ushort pci_device_id;     /* PCI device code number */
        !          2741:   ushort lib_version;       /* Adv Library version number */
        !          2742:   ushort control_flag;      /* Microcode Control Flag */
        !          2743:   ushort mcode_date;        /* Microcode date */
        !          2744:   ushort mcode_version;     /* Microcode version */
        !          2745:   ushort pci_slot_info;     /* high byte device/function number */
        !          2746:                             /* bits 7-3 device num., bits 2-0 function num. */
        !          2747:                             /* low byte bus num. */
        !          2748:   ushort bios_boot_wait;    /* BIOS boot time delay */
        !          2749:   ushort serial1;           /* EEPROM serial number word 1 */
        !          2750:   ushort serial2;           /* EEPROM serial number word 2 */
        !          2751:   ushort serial3;           /* EEPROM serial number word 3 */
        !          2752: } ADV_DVC_CFG; 
        !          2753: 
        !          2754: /*
        !          2755:  * Adapter operation variable structure.
        !          2756:  *
        !          2757:  * One structure is required per host adapter.
        !          2758:  *
        !          2759:  * Field naming convention: 
        !          2760:  *
        !          2761:  *  *_able indicates both whether a feature should be enabled or disabled
        !          2762:  *  and whether a device isi capable of the feature. At initialization
        !          2763:  *  this field may be set, but later if a device is found to be incapable
        !          2764:  *  of the feature, the field is cleared.
        !          2765:  */
        !          2766: typedef struct adv_dvc_var {
        !          2767:   AdvPortAddr iop_base;   /* I/O port address */
        !          2768:   ushort err_code;        /* fatal error code */
        !          2769:   ushort bios_ctrl;       /* BIOS control word, EEPROM word 12 */
        !          2770:   Ptr2Func isr_callback;  /* pointer to function, called in AdvISR() */
        !          2771:   Ptr2Func sbreset_callback;  /* pointer to function, called in AdvISR() */
        !          2772:   ushort wdtr_able;       /* try WDTR for a device */
        !          2773:   ushort sdtr_able;       /* try SDTR for a device */
        !          2774:   ushort ultra_able;      /* try SDTR Ultra speed for a device */
        !          2775:   ushort tagqng_able;     /* try tagged queuing with a device */
        !          2776:   uchar  max_dvc_qng;     /* maximum number of tagged commands per device */
        !          2777:   ushort start_motor;     /* start motor command allowed */
        !          2778:   uchar  scsi_reset_wait; /* delay in seconds after scsi bus reset */
        !          2779:   uchar  chip_no;         /* should be assigned by caller */
        !          2780:   uchar  max_host_qng;    /* maximum number of Q'ed command allowed */
        !          2781:   uchar  cur_host_qng;    /* total number of queue command */
        !          2782:   uchar  irq_no;          /* IRQ number */
        !          2783:   ushort no_scam;         /* scam_tolerant of EEPROM */
        !          2784:   ushort idle_cmd_done;   /* microcode idle command done set by AdvISR() */
        !          2785:   ulong  drv_ptr;         /* driver pointer to private structure */
        !          2786:   uchar  chip_scsi_id;    /* chip SCSI target ID */
        !          2787:  /*
        !          2788:   * Note: The following fields will not be used after initialization. The
        !          2789:   * driver may discard the buffer after initialization is done.
        !          2790:   */
        !          2791:   ADV_DVC_CFG *cfg; /* temporary configuration structure  */
        !          2792: } ADV_DVC_VAR; 
        !          2793: 
        !          2794: #define NO_OF_SG_PER_BLOCK              15
        !          2795: 
        !          2796: typedef struct asc_sg_block {
        !          2797:     uchar reserved1; 
        !          2798:     uchar reserved2; 
        !          2799:     uchar first_entry_no;             /* starting entry number */
        !          2800:     uchar last_entry_no;              /* last entry number */
        !          2801:     struct asc_sg_block *sg_ptr; /* links to the next sg block */
        !          2802:     struct  {
        !          2803:         ulong sg_addr;                /* SG element address */
        !          2804:         ulong sg_count;               /* SG element count */
        !          2805:     } sg_list[NO_OF_SG_PER_BLOCK];
        !          2806: } ADV_SG_BLOCK;
        !          2807: 
        !          2808: /*
        !          2809:  * ASC_SCSI_REQ_Q - microcode request structure
        !          2810:  *
        !          2811:  * All fields in this structure up to byte 60 are used by the microcode.
        !          2812:  * The microcode makes assumptions about the size and ordering of fields
        !          2813:  * in this structure. Do not change the structure definition here without
        !          2814:  * coordinating the change with the microcode.
        !          2815:  */
        !          2816: typedef struct adv_scsi_req_q {
        !          2817:     uchar       cntl;           /* Ucode flags and state (ASC_MC_QC_*). */
        !          2818:     uchar       sg_entry_cnt;   /* SG element count. Zero for no SG. */
        !          2819:     uchar       target_id;      /* Device target identifier. */
        !          2820:     uchar       target_lun;     /* Device target logical unit number. */
        !          2821:     ulong       data_addr;      /* Data buffer physical address. */
        !          2822:     ulong       data_cnt;       /* Data count. Ucode sets to residual. */
        !          2823:     ulong       sense_addr;     /* Sense buffer physical address. */
        !          2824:     ulong       srb_ptr;        /* Driver request pointer. */
        !          2825:     uchar       a_flag;         /* Adv Library flag field. */
        !          2826:     uchar       sense_len;      /* Auto-sense length. Ucode sets to residual. */
        !          2827:     uchar       cdb_len;        /* SCSI CDB length. */
        !          2828:     uchar       tag_code;       /* SCSI-2 Tag Queue Code: 00, 20-22. */
        !          2829:     uchar       done_status;    /* Completion status. */
        !          2830:     uchar       scsi_status;    /* SCSI status byte. */
        !          2831:     uchar       host_status;    /* Ucode host status. */
        !          2832:     uchar       ux_sg_ix;       /* Ucode working SG variable. */
        !          2833:     uchar       cdb[12];        /* SCSI command block. */
        !          2834:     ulong       sg_real_addr;   /* SG list physical address. */
        !          2835:     struct adv_scsi_req_q *free_scsiq_link;
        !          2836:     ulong       ux_wk_data_cnt; /* Saved data count at disconnection. */
        !          2837:     struct adv_scsi_req_q *scsiq_ptr;
        !          2838:     ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
        !          2839:     /*
        !          2840:      * End of microcode structure - 60 bytes. The rest of the structure
        !          2841:      * is used by the Adv Library and ignored by the microcode.
        !          2842:      */
        !          2843:     ulong       vsense_addr;    /* Sense buffer virtual address. */
        !          2844:     ulong       vdata_addr;     /* Data buffer virtual address. */
        !          2845:     uchar       orig_sense_len; /* Original length of sense buffer. */
        !          2846: } ADV_SCSI_REQ_Q; /* BIOS - 70 bytes, DOS - 76 bytes, W95, WNT - 69 bytes */
        !          2847: 
        !          2848: /*
        !          2849:  * Microcode idle loop commands
        !          2850:  */
        !          2851: #define IDLE_CMD_COMPLETED           0
        !          2852: #define IDLE_CMD_STOP_CHIP           0x0001
        !          2853: #define IDLE_CMD_STOP_CHIP_SEND_INT  0x0002
        !          2854: #define IDLE_CMD_SEND_INT            0x0004
        !          2855: #define IDLE_CMD_ABORT               0x0008
        !          2856: #define IDLE_CMD_DEVICE_RESET        0x0010
        !          2857: #define IDLE_CMD_SCSI_RESET          0x0020
        !          2858: 
        !          2859: /*
        !          2860:  * AdvSendIdleCmd() flag definitions.
        !          2861:  */
        !          2862: #define ADV_NOWAIT     0x01
        !          2863: 
        !          2864: /*
        !          2865:  * Wait loop time out values.
        !          2866:  */
        !          2867: #define SCSI_WAIT_10_SEC             10         /* 10 seconds */
        !          2868: #define SCSI_MS_PER_SEC              1000       /* milliseconds per second */
        !          2869: 
        !          2870: /*
        !          2871:  * Device drivers must define the following functions.
        !          2872:  */
        !          2873: STATIC int   DvcEnterCritical(void);
        !          2874: STATIC void  DvcLeaveCritical(int);
        !          2875: STATIC void  DvcSleepMilliSecond(ulong);
        !          2876: STATIC uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort);
        !          2877: STATIC void  DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar);
        !          2878: STATIC ulong DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
        !          2879:                 uchar *, long *, int);
        !          2880: STATIC void  DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
        !          2881: 
        !          2882: /*
        !          2883:  * Adv Library functions available to drivers.
        !          2884:  */
        !          2885: STATIC int     AdvExeScsiQueue(ADV_DVC_VAR *,
        !          2886:                          ADV_SCSI_REQ_Q *);
        !          2887: STATIC int     AdvISR(ADV_DVC_VAR *);
        !          2888: STATIC int     AdvInitGetConfig(ADV_DVC_VAR *);
        !          2889: STATIC int     AdvInitAsc3550Driver(ADV_DVC_VAR *);
        !          2890: STATIC int     AdvResetSB(ADV_DVC_VAR *);
        !          2891: 
        !          2892: /*
        !          2893:  * Internal Adv Library functions.
        !          2894:  */
        !          2895: STATIC int    AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ulong, int);
        !          2896: STATIC void   AdvResetChip(ADV_DVC_VAR *);
        !          2897: STATIC int    AdvSendScsiCmd(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
        !          2898: STATIC void   AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
        !          2899: STATIC int    AdvInitFromEEP(ADV_DVC_VAR *);
        !          2900: STATIC ushort AdvGetEEPConfig(AdvPortAddr, ADVEEP_CONFIG *);
        !          2901: STATIC void   AdvSetEEPConfig(AdvPortAddr, ADVEEP_CONFIG *);
        !          2902: STATIC void   AdvWaitEEPCmd(AdvPortAddr);
        !          2903: STATIC ushort AdvReadEEPWord(AdvPortAddr, int);
        !          2904: STATIC void   AdvResetSCSIBus(ADV_DVC_VAR *);
        !          2905: 
        !          2906: /*
        !          2907:  * PCI Bus Definitions
        !          2908:  */
        !          2909: #define AscPCICmdRegBits_BusMastering     0x0007
        !          2910: #define AscPCICmdRegBits_ParErrRespCtrl   0x0040
        !          2911: 
        !          2912: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
        !          2913: 
        !          2914: /* Read byte from a register. */
        !          2915: #define AdvReadByteRegister(iop_base, reg_off) \
        !          2916:      (inp((iop_base) + (reg_off)))
        !          2917: 
        !          2918: /* Write byte to a register. */
        !          2919: #define AdvWriteByteRegister(iop_base, reg_off, byte) \
        !          2920:      (outp((iop_base) + (reg_off), (byte)))
        !          2921: 
        !          2922: /* Read word (2 bytes) from a register. */
        !          2923: #define AdvReadWordRegister(iop_base, reg_off) \
        !          2924:      (inpw((iop_base) + (reg_off)))
        !          2925: 
        !          2926: /* Write word (2 bytes) to a register. */
        !          2927: #define AdvWriteWordRegister(iop_base, reg_off, word) \
        !          2928:      (outpw((iop_base) + (reg_off), (word)))
        !          2929: 
        !          2930: /* Read byte from LRAM. */
        !          2931: #define AdvReadByteLram(iop_base, addr, byte) \
        !          2932: do { \
        !          2933:     outpw((iop_base) + IOPW_RAM_ADDR, (addr)); \
        !          2934:     (byte) = inp((iop_base) + IOPB_RAM_DATA); \
        !          2935: } while (0)
        !          2936: 
        !          2937: /* Write byte to LRAM. */
        !          2938: #define AdvWriteByteLram(iop_base, addr, byte) \
        !          2939:     (outpw((iop_base) + IOPW_RAM_ADDR, (addr)), \
        !          2940:      outp((iop_base) + IOPB_RAM_DATA, (byte)))
        !          2941: 
        !          2942: /* Read word (2 bytes) from LRAM. */
        !          2943: #define AdvReadWordLram(iop_base, addr, word) \
        !          2944: do { \
        !          2945:     outpw((iop_base) + IOPW_RAM_ADDR, (addr));  \
        !          2946:     (word) = inpw((iop_base) + IOPW_RAM_DATA); \
        !          2947: } while (0)
        !          2948: 
        !          2949: /* Write word (2 bytes) to LRAM. */
        !          2950: #define AdvWriteWordLram(iop_base, addr, word) \
        !          2951:     (outpw((iop_base) + IOPW_RAM_ADDR, (addr)), \
        !          2952:      outpw((iop_base) + IOPW_RAM_DATA, (word)))
        !          2953: 
        !          2954: /* Write double word (4 bytes) to LRAM */
        !          2955: /* Because of unspecified C language ordering don't use auto-increment. */
        !          2956: #define AdvWriteDWordLram(iop_base, addr, dword) \
        !          2957:     ((outpw((iop_base) + IOPW_RAM_ADDR, (addr)), \
        !          2958:       outpw((iop_base) + IOPW_RAM_DATA, (ushort) ((dword) & 0xFFFF))), \
        !          2959:      (outpw((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
        !          2960:       outpw((iop_base) + IOPW_RAM_DATA, (ushort) ((dword >> 16) & 0xFFFF))))
        !          2961: 
        !          2962: /* Read word (2 bytes) from LRAM assuming that the address is already set. */
        !          2963: #define AdvReadWordAutoIncLram(iop_base) \
        !          2964:      (inpw((iop_base) + IOPW_RAM_DATA))
        !          2965: 
        !          2966: /* Write word (2 bytes) to LRAM assuming that the address is already set. */
        !          2967: #define AdvWriteWordAutoIncLram(iop_base, word) \
        !          2968:      (outpw((iop_base) + IOPW_RAM_DATA, (word)))
        !          2969: 
        !          2970: #else /* version >= v1,3,0 */
        !          2971: 
        !          2972: /* Read byte from a register. */
        !          2973: #define AdvReadByteRegister(iop_base, reg_off) \
        !          2974:      (ADV_MEM_READB((iop_base) + (reg_off)))
        !          2975: 
        !          2976: /* Write byte to a register. */
        !          2977: #define AdvWriteByteRegister(iop_base, reg_off, byte) \
        !          2978:      (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
        !          2979: 
        !          2980: /* Read word (2 bytes) from a register. */
        !          2981: #define AdvReadWordRegister(iop_base, reg_off) \
        !          2982:      (ADV_MEM_READW((iop_base) + (reg_off)))
        !          2983: 
        !          2984: /* Write word (2 bytes) to a register. */
        !          2985: #define AdvWriteWordRegister(iop_base, reg_off, word) \
        !          2986:      (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
        !          2987: 
        !          2988: /* Read byte from LRAM. */
        !          2989: #define AdvReadByteLram(iop_base, addr, byte) \
        !          2990: do { \
        !          2991:     ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
        !          2992:     (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
        !          2993: } while (0)
        !          2994: 
        !          2995: /* Write byte to LRAM. */
        !          2996: #define AdvWriteByteLram(iop_base, addr, byte) \
        !          2997:     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
        !          2998:      ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
        !          2999: 
        !          3000: /* Read word (2 bytes) from LRAM. */
        !          3001: #define AdvReadWordLram(iop_base, addr, word) \
        !          3002: do { \
        !          3003:     ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
        !          3004:     (word) = ADV_MEM_READW((iop_base) + IOPW_RAM_DATA); \
        !          3005: } while (0)
        !          3006: 
        !          3007: /* Write word (2 bytes) to LRAM. */
        !          3008: #define AdvWriteWordLram(iop_base, addr, word) \
        !          3009:     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
        !          3010:      ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
        !          3011: 
        !          3012: /* Write double word (4 bytes) to LRAM */
        !          3013: /* Because of unspecified C language ordering don't use auto-increment. */
        !          3014: #define AdvWriteDWordLram(iop_base, addr, dword) \
        !          3015:     ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
        !          3016:       ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
        !          3017:                      (ushort) ((dword) & 0xFFFF))), \
        !          3018:      (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
        !          3019:       ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
        !          3020:                      (ushort) ((dword >> 16) & 0xFFFF))))
        !          3021: 
        !          3022: /* Read word (2 bytes) from LRAM assuming that the address is already set. */
        !          3023: #define AdvReadWordAutoIncLram(iop_base) \
        !          3024:      (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
        !          3025: 
        !          3026: /* Write word (2 bytes) to LRAM assuming that the address is already set. */
        !          3027: #define AdvWriteWordAutoIncLram(iop_base, word) \
        !          3028:      (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
        !          3029: 
        !          3030: #endif /* version >= v1,3,0 */
        !          3031: 
        !          3032: /*
        !          3033:  * Define macro to check for Condor signature.
        !          3034:  *
        !          3035:  * Evaluate to ADV_TRUE if a Condor chip is found the specified port
        !          3036:  * address 'iop_base'. Otherwise evalue to ADV_FALSE.
        !          3037:  */
        !          3038: #define AdvFindSignature(iop_base) \
        !          3039:     (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
        !          3040:     ADV_CHIP_ID_BYTE) && \
        !          3041:      (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
        !          3042:     ADV_CHIP_ID_WORD)) ?  ADV_TRUE : ADV_FALSE)
        !          3043: 
        !          3044: /*
        !          3045:  * Define macro to Return the version number of the chip at 'iop_base'.
        !          3046:  *
        !          3047:  * The second parameter 'bus_type' is currently unused.
        !          3048:  */
        !          3049: #define AdvGetChipVersion(iop_base, bus_type) \
        !          3050:     AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
        !          3051: 
        !          3052: /*
        !          3053:  * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
        !          3054:  * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
        !          3055:  * 
        !          3056:  * If the request has not yet been sent to the device it will simply be
        !          3057:  * aborted from RISC memory. If the request is disconnected it will be
        !          3058:  * aborted on reselection by sending an Abort Message to the target ID.
        !          3059:  *
        !          3060:  * Return value:
        !          3061:  *      ADV_TRUE(1) - Queue was successfully aborted.
        !          3062:  *      ADV_FALSE(0) - Queue was not found on the active queue list.
        !          3063:  */
        !          3064: #define AdvAbortSRB(asc_dvc, srb_ptr) \
        !          3065:     AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
        !          3066:                 (ulong) (srb_ptr), 0)
        !          3067: 
        !          3068: /*
        !          3069:  * Send a Bus Device Reset Message to the specified target ID.
        !          3070:  *
        !          3071:  * All outstanding commands will be purged if sending the
        !          3072:  * Bus Device Reset Message is successful.
        !          3073:  *
        !          3074:  * Return Value:
        !          3075:  *      ADV_TRUE(1) - All requests on the target are purged.
        !          3076:  *      ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
        !          3077:  *                     are not purged.
        !          3078:  */
        !          3079: #define AdvResetDevice(asc_dvc, target_id) \
        !          3080:         AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
        !          3081:                     (ulong) (target_id), 0)
        !          3082: 
        !          3083: /*
        !          3084:  * SCSI Wide Type definition.
        !          3085:  */
        !          3086: #define ADV_SCSI_BIT_ID_TYPE   ushort
        !          3087: 
        !          3088: /*
        !          3089:  * AdvInitScsiTarget() 'cntl_flag' options.
        !          3090:  */
        !          3091: #define ADV_SCAN_LUN           0x01
        !          3092: #define ADV_CAPINFO_NOLUN      0x02
        !          3093: 
        !          3094: /*
        !          3095:  * Convert target id to target id bit mask.
        !          3096:  */
        !          3097: #define ADV_TID_TO_TIDMASK(tid)   (0x01 << ((tid) & ADV_MAX_TID))
        !          3098: 
        !          3099: /*
        !          3100:  * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
        !          3101:  */
        !          3102: 
        !          3103: #define QD_NO_STATUS         0x00       /* Request not completed yet. */
        !          3104: #define QD_NO_ERROR          0x01
        !          3105: #define QD_ABORTED_BY_HOST   0x02
        !          3106: #define QD_WITH_ERROR        0x04
        !          3107: 
        !          3108: #define QHSTA_NO_ERROR              0x00
        !          3109: #define QHSTA_M_SEL_TIMEOUT         0x11
        !          3110: #define QHSTA_M_DATA_OVER_RUN       0x12
        !          3111: #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
        !          3112: #define QHSTA_M_QUEUE_ABORTED       0x15
        !          3113: #define QHSTA_M_SXFR_SDMA_ERR       0x16 /* SXFR_STATUS SCSI DMA Error */
        !          3114: #define QHSTA_M_SXFR_SXFR_PERR      0x17 /* SXFR_STATUS SCSI Bus Parity Error */
        !          3115: #define QHSTA_M_RDMA_PERR           0x18 /* RISC PCI DMA parity error */
        !          3116: #define QHSTA_M_SXFR_OFF_UFLW       0x19 /* SXFR_STATUS Offset Underflow */
        !          3117: #define QHSTA_M_SXFR_OFF_OFLW       0x20 /* SXFR_STATUS Offset Overflow */
        !          3118: #define QHSTA_M_SXFR_WD_TMO         0x21 /* SXFR_STATUS Watchdog Timeout */
        !          3119: #define QHSTA_M_SXFR_DESELECTED     0x22 /* SXFR_STATUS Deselected */
        !          3120: /* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
        !          3121: #define QHSTA_M_SXFR_XFR_OFLW       0x12 /* SXFR_STATUS Transfer Overflow */
        !          3122: #define QHSTA_M_SXFR_XFR_PH_ERR     0x24 /* SXFR_STATUS Transfer Phase Error */
        !          3123: #define QHSTA_M_SXFR_UNKNOWN_ERROR  0x25 /* SXFR_STATUS Unknown Error */
        !          3124: #define QHSTA_M_WTM_TIMEOUT         0x41
        !          3125: #define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
        !          3126: #define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
        !          3127: #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
        !          3128: #define QHSTA_M_INVALID_DEVICE      0x45 /* Bad target ID */
        !          3129: 
        !          3130: typedef int (* ADV_ISR_CALLBACK)
        !          3131:     (ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
        !          3132: 
        !          3133: typedef int (* ADV_SBRESET_CALLBACK)
        !          3134:     (ADV_DVC_VAR *);
        !          3135: 
        !          3136: /*
        !          3137:  * Default EEPROM Configuration structure defined in a_init.c.
        !          3138:  */
        !          3139: extern ADVEEP_CONFIG Default_EEPROM_Config;
        !          3140: 
        !          3141: /*
        !          3142:  * DvcGetPhyAddr() flag arguments
        !          3143:  */
        !          3144: #define ADV_IS_SCSIQ_FLAG       0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
        !          3145: #define ADV_ASCGETSGLIST_VADDR  0x02 /* 'addr' is AscGetSGList() virtual addr */
        !          3146: #define ADV_IS_SENSE_FLAG       0x04 /* 'addr' is sense virtual pointer */
        !          3147: #define ADV_IS_DATA_FLAG        0x08 /* 'addr' is data virtual pointer */
        !          3148: #define ADV_IS_SGLIST_FLAG      0x10 /* 'addr' is sglist virtual pointer */
        !          3149: 
        !          3150: /* Return the address that is aligned at the next doubleword >= to 'addr'. */
        !          3151: #define ADV_DWALIGN(addr)       (((ulong) (addr) + 0x3) & ~0x3)
        !          3152: 
        !          3153: /*
        !          3154:  * Total contiguous memory needed for driver SG blocks.
        !          3155:  *
        !          3156:  * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
        !          3157:  * number of scatter-gather elements the driver supports in a
        !          3158:  * single request.
        !          3159:  */
        !          3160: 
        !          3161: #ifndef ADV_MAX_SG_LIST
        !          3162: Forced Error: Driver must define ADV_MAX_SG_LIST.
        !          3163: #endif /* ADV_MAX_SG_LIST */
        !          3164: 
        !          3165: #define ADV_SG_LIST_MAX_BYTE_SIZE \
        !          3166:          (sizeof(ADV_SG_BLOCK) * \
        !          3167:           ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
        !          3168: 
        !          3169: /*
        !          3170:  * A driver may optionally define the assertion macro ADV_ASSERT() in
        !          3171:  * its d_os_dep.h file. If the macro has not already been defined,
        !          3172:  * then define the macro to a no-op.
        !          3173:  */
        !          3174: #ifndef ADV_ASSERT
        !          3175: #define ADV_ASSERT(a)
        !          3176: #endif /* ADV_ASSERT */
        !          3177: 
        !          3178: 
        !          3179: /*
        !          3180:  * --- Driver Constants and Macros
        !          3181:  */
        !          3182: 
        !          3183: #define ASC_NUM_BOARD_SUPPORTED 16
        !          3184: #define ASC_NUM_IOPORT_PROBE    4
        !          3185: #define ASC_NUM_BUS             4
        !          3186: 
        !          3187: /* Reference Scsi_Host hostdata */
        !          3188: #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
        !          3189: 
        !          3190: /* asc_board_t flags */
        !          3191: #define ASC_HOST_IN_RESET       0x01
        !          3192: #define ASC_HOST_IN_ABORT       0x02
        !          3193: #define ASC_IS_WIDE_BOARD       0x04    /* AdvanSys Wide Board */
        !          3194: #define ASC_SELECT_QUEUE_DEPTHS 0x08
        !          3195: 
        !          3196: #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
        !          3197: #define ASC_WIDE_BOARD(boardp)   ((boardp)->flags & ASC_IS_WIDE_BOARD)
        !          3198: 
        !          3199: #define NO_ISA_DMA              0xff        /* No ISA DMA Channel Used */
        !          3200: 
        !          3201: /*
        !          3202:  * If the Linux kernel version supports freeing initialization code
        !          3203:  * and data after loading, define macros for this purpose. These macros
        !          3204:  * are not used when the driver is built as a module, cf. linux/init.h.
        !          3205:  */
        !          3206: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,23)
        !          3207: #define ASC_INITFUNC(func)      func
        !          3208: #define ASC_INITDATA
        !          3209: #define ASC_INIT
        !          3210: #else /* version >= v2.1.23 */
        !          3211: #define ASC_INITFUNC(func)      __initfunc(func)
        !          3212: #define ASC_INITDATA            __initdata
        !          3213: #define ASC_INIT                __init
        !          3214: #endif /* version >= v2.1.23 */
        !          3215: 
        !          3216: #define ASC_INFO_SIZE           128            /* advansys_info() line size */
        !          3217: 
        !          3218: /* /proc/scsi/advansys/[0...] related definitions */
        !          3219: #define ASC_PRTBUF_SIZE         2048
        !          3220: #define ASC_PRTLINE_SIZE        160
        !          3221: 
        !          3222: #define ASC_PRT_NEXT() \
        !          3223:     if (cp) { \
        !          3224:         totlen += len; \
        !          3225:         leftlen -= len; \
        !          3226:         if (leftlen == 0) { \
        !          3227:             return totlen; \
        !          3228:         } \
        !          3229:         cp += len; \
        !          3230:     }
        !          3231: 
        !          3232: #define ASC_MIN(a, b) (((a) < (b)) ? (a) : (b))
        !          3233: 
        !          3234: /* Asc Library return codes */
        !          3235: #define ASC_TRUE        1
        !          3236: #define ASC_FALSE       0
        !          3237: #define ASC_NOERROR     1
        !          3238: #define ASC_BUSY        0
        !          3239: #define ASC_ERROR       (-1)
        !          3240: 
        !          3241: /* Scsi_Cmnd function return codes */
        !          3242: #define STATUS_BYTE(byte)   (byte)
        !          3243: #define MSG_BYTE(byte)      ((byte) << 8)
        !          3244: #define HOST_BYTE(byte)     ((byte) << 16)
        !          3245: #define DRIVER_BYTE(byte)   ((byte) << 24)
        !          3246: 
        !          3247: /*
        !          3248:  * The following definitions and macros are OS independent interfaces to
        !          3249:  * the queue functions:
        !          3250:  *  REQ - SCSI request structure
        !          3251:  *  REQP - pointer to SCSI request structure
        !          3252:  *  REQPTID(reqp) - reqp's target id
        !          3253:  *  REQPNEXT(reqp) - reqp's next pointer
        !          3254:  *  REQPNEXTP(reqp) - pointer to reqp's next pointer
        !          3255:  *  REQPTIME(reqp) - reqp's time stamp value
        !          3256:  *  REQTIMESTAMP() - system time stamp value
        !          3257:  */
        !          3258: typedef Scsi_Cmnd            REQ, *REQP;
        !          3259: #define REQPNEXT(reqp)       ((REQP) ((reqp)->host_scribble))
        !          3260: #define REQPNEXTP(reqp)      ((REQP *) &((reqp)->host_scribble))
        !          3261: #define REQPTID(reqp)        ((reqp)->target)
        !          3262: #define REQPTIME(reqp)       ((reqp)->SCp.this_residual)
        !          3263: #define REQTIMESTAMP()       (jiffies)
        !          3264: 
        !          3265: #define REQTIMESTAT(function, ascq, reqp, tid) \
        !          3266: { \
        !          3267:     /*
        !          3268:      * If the request time stamp is less than the system time stamp, then \
        !          3269:      * maybe the system time stamp wrapped. Set the request time to zero.\
        !          3270:      */ \
        !          3271:     if (REQPTIME(reqp) <= REQTIMESTAMP()) { \
        !          3272:         REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \
        !          3273:     } else { \
        !          3274:         /* Indicate an error occurred with the assertion. */ \
        !          3275:         ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \
        !          3276:         REQPTIME(reqp) = 0; \
        !          3277:     } \
        !          3278:     /* Handle first minimum time case without external initialization. */ \
        !          3279:     if (((ascq)->q_tot_cnt[tid] == 1) ||  \
        !          3280:         (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \
        !          3281:             (ascq)->q_min_tim[tid] = REQPTIME(reqp); \
        !          3282:             ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
        !          3283:                 (function), (tid), (ascq)->q_min_tim[tid]); \
        !          3284:         } \
        !          3285:     if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \
        !          3286:         (ascq)->q_max_tim[tid] = REQPTIME(reqp); \
        !          3287:         ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
        !          3288:             (function), tid, (ascq)->q_max_tim[tid]); \
        !          3289:     } \
        !          3290:     (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \
        !          3291:     /* Reset the time stamp field. */ \
        !          3292:     REQPTIME(reqp) = 0; \
        !          3293: }
        !          3294: 
        !          3295: /* asc_enqueue() flags */
        !          3296: #define ASC_FRONT       1
        !          3297: #define ASC_BACK        2
        !          3298: 
        !          3299: /* asc_dequeue_list() argument */
        !          3300: #define ASC_TID_ALL        (-1)
        !          3301: 
        !          3302: /* Return non-zero, if the queue is empty. */
        !          3303: #define ASC_QUEUE_EMPTY(ascq)    ((ascq)->q_tidmask == 0)
        !          3304: 
        !          3305: /* PCI configuration declarations */
        !          3306: 
        !          3307: #define PCI_BASE_CLASS_PREDEFINED               0x00
        !          3308: #define PCI_BASE_CLASS_MASS_STORAGE             0x01
        !          3309: #define PCI_BASE_CLASS_NETWORK                  0x02
        !          3310: #define PCI_BASE_CLASS_DISPLAY                  0x03
        !          3311: #define PCI_BASE_CLASS_MULTIMEDIA               0x04
        !          3312: #define PCI_BASE_CLASS_MEMORY_CONTROLLER        0x05
        !          3313: #define PCI_BASE_CLASS_BRIDGE_DEVICE            0x06
        !          3314: 
        !          3315: /* MASS STORAGE */
        !          3316: #define PCI_SUB_CLASS_SCSI_CONTROLLER           0x00
        !          3317: #define PCI_SUB_CLASS_IDE_CONTROLLER            0x01
        !          3318: #define PCI_SUB_CLASS_FLOPPY_DISK_CONTROLLER    0x02
        !          3319: #define PCI_SUB_CLASS_IPI_BUS_CONTROLLER        0x03
        !          3320: #define PCI_SUB_CLASS_OTHER_MASS_CONTROLLER     0x80
        !          3321: 
        !          3322: /* NETWORK CONTROLLER */
        !          3323: #define PCI_SUB_CLASS_ETHERNET_CONTROLLER       0x00
        !          3324: #define PCI_SUB_CLASS_TOKEN_RING_CONTROLLER     0x01
        !          3325: #define PCI_SUB_CLASS_FDDI_CONTROLLER           0x02
        !          3326: #define PCI_SUB_CLASS_OTHER_NETWORK_CONTROLLER  0x80
        !          3327: 
        !          3328: /* DISPLAY CONTROLLER */
        !          3329: #define PCI_SUB_CLASS_VGA_CONTROLLER            0x00
        !          3330: #define PCI_SUB_CLASS_XGA_CONTROLLER            0x01
        !          3331: #define PCI_SUB_CLASS_OTHER_DISPLAY_CONTROLLER  0x80
        !          3332: 
        !          3333: /* MULTIMEDIA CONTROLLER */
        !          3334: #define PCI_SUB_CLASS_VIDEO_DEVICE              0x00
        !          3335: #define PCI_SUB_CLASS_AUDIO_DEVICE              0x01
        !          3336: #define PCI_SUB_CLASS_OTHER_MULTIMEDIA_DEVICE   0x80
        !          3337: 
        !          3338: /* MEMORY CONTROLLER */
        !          3339: #define PCI_SUB_CLASS_RAM_CONTROLLER            0x00
        !          3340: #define PCI_SUB_CLASS_FLASH_CONTROLLER          0x01
        !          3341: #define PCI_SUB_CLASS_OTHER_MEMORY_CONTROLLER   0x80
        !          3342: 
        !          3343: /* BRIDGE CONTROLLER */
        !          3344: #define PCI_SUB_CLASS_HOST_BRIDGE_CONTROLLER    0x00
        !          3345: #define PCI_SUB_CLASS_ISA_BRIDGE_CONTROLLER     0x01
        !          3346: #define PCI_SUB_CLASS_EISA_BRIDGE_CONTROLLER    0x02
        !          3347: #define PCI_SUB_CLASS_MC_BRIDGE_CONTROLLER      0x03
        !          3348: #define PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER    0x04
        !          3349: #define PCI_SUB_CLASS_PCMCIA_BRIDGE_CONTROLLER  0x05
        !          3350: #define PCI_SUB_CLASS_OTHER_BRIDGE_CONTROLLER   0x80
        !          3351: 
        !          3352: #define PCI_MAX_SLOT            0x1F
        !          3353: #define PCI_MAX_BUS             0xFF
        !          3354: #define PCI_IOADDRESS_MASK      0xFFFE
        !          3355: #define ASC_PCI_VENDORID        0x10CD
        !          3356: #define ASC_PCI_DEVICE_ID_CNT   4       /* PCI Device ID count. */
        !          3357: #define ASC_PCI_DEVICE_ID_1100  0x1100
        !          3358: #define ASC_PCI_DEVICE_ID_1200  0x1200
        !          3359: #define ASC_PCI_DEVICE_ID_1300  0x1300
        !          3360: #define ASC_PCI_DEVICE_ID_2300  0x2300
        !          3361: 
        !          3362: /* PCI IO Port Addresses to generate special cycle */
        !          3363: 
        !          3364: #define PCI_CONFIG_ADDRESS_MECH1          0x0CF8
        !          3365: #define PCI_CONFIG_DATA_MECH1             0x0CFC
        !          3366: 
        !          3367: #define PCI_CONFIG_FORWARD_REGISTER       0x0CFA    /* 0=type 0; 1=type 1; */
        !          3368: 
        !          3369: #define PCI_CONFIG_BUS_NUMBER_MASK        0x00FF0000
        !          3370: #define PCI_CONFIG_DEVICE_FUNCTION_MASK   0x0000FF00
        !          3371: #define PCI_CONFIG_REGISTER_NUMBER_MASK   0x000000F8
        !          3372: 
        !          3373: #define PCI_DEVICE_FOUND                0x0000
        !          3374: #define PCI_DEVICE_NOT_FOUND            0xffff
        !          3375: 
        !          3376: #define SUBCLASS_OFFSET         0x0A
        !          3377: #define CLASSCODE_OFFSET        0x0B
        !          3378: #define VENDORID_OFFSET         0x00
        !          3379: #define DEVICEID_OFFSET         0x02
        !          3380: 
        !          3381: #ifndef ADVANSYS_STATS
        !          3382: #define ASC_STATS(shp, counter)
        !          3383: #define ASC_STATS_ADD(shp, counter, count)
        !          3384: #else /* ADVANSYS_STATS */
        !          3385: #define ASC_STATS(shp, counter) \
        !          3386:     (ASC_BOARDP(shp)->asc_stats.counter++)
        !          3387: 
        !          3388: #define ASC_STATS_ADD(shp, counter, count) \
        !          3389:     (ASC_BOARDP(shp)->asc_stats.counter += (count))
        !          3390: #endif /* ADVANSYS_STATS */
        !          3391: 
        !          3392: #define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
        !          3393: 
        !          3394: /* If the result wraps when calculating tenths, return 0. */
        !          3395: #define ASC_TENTHS(num, den) \
        !          3396:     (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
        !          3397:     0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
        !          3398: 
        !          3399: /*
        !          3400:  * Display a message to the console.
        !          3401:  */
        !          3402: #define ASC_PRINT(s) \
        !          3403:     { \
        !          3404:         printk("advansys: "); \
        !          3405:         printk(s); \
        !          3406:     }
        !          3407: 
        !          3408: #define ASC_PRINT1(s, a1) \
        !          3409:     { \
        !          3410:         printk("advansys: "); \
        !          3411:         printk((s), (a1)); \
        !          3412:     }
        !          3413: 
        !          3414: #define ASC_PRINT2(s, a1, a2) \
        !          3415:     { \
        !          3416:         printk("advansys: "); \
        !          3417:         printk((s), (a1), (a2)); \
        !          3418:     }
        !          3419: 
        !          3420: #define ASC_PRINT3(s, a1, a2, a3) \
        !          3421:     { \
        !          3422:         printk("advansys: "); \
        !          3423:         printk((s), (a1), (a2), (a3)); \
        !          3424:     }
        !          3425: 
        !          3426: #define ASC_PRINT4(s, a1, a2, a3, a4) \
        !          3427:     { \
        !          3428:         printk("advansys: "); \
        !          3429:         printk((s), (a1), (a2), (a3), (a4)); \
        !          3430:     }
        !          3431: 
        !          3432: 
        !          3433: #ifndef ADVANSYS_DEBUG
        !          3434: 
        !          3435: #define ASC_DBG(lvl, s)
        !          3436: #define ASC_DBG1(lvl, s, a1)
        !          3437: #define ASC_DBG2(lvl, s, a1, a2)
        !          3438: #define ASC_DBG3(lvl, s, a1, a2, a3)
        !          3439: #define ASC_DBG4(lvl, s, a1, a2, a3, a4)
        !          3440: #define ASC_DBG_PRT_SCSI_HOST(lvl, s)
        !          3441: #define ASC_DBG_PRT_SCSI_CMND(lvl, s)
        !          3442: #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
        !          3443: #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
        !          3444: #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
        !          3445: #define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
        !          3446: #define ASC_DBG_PRT_HEX(lvl, name, start, length)
        !          3447: #define ASC_DBG_PRT_CDB(lvl, cdb, len)
        !          3448: #define ASC_DBG_PRT_SENSE(lvl, sense, len)
        !          3449: #define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
        !          3450: 
        !          3451: #else /* ADVANSYS_DEBUG */
        !          3452: 
        !          3453: /*
        !          3454:  * Debugging Message Levels:
        !          3455:  * 0: Errors Only
        !          3456:  * 1: High-Level Tracing
        !          3457:  * 2-N: Verbose Tracing
        !          3458:  */
        !          3459: 
        !          3460: #define ASC_DBG(lvl, s) \
        !          3461:     { \
        !          3462:         if (asc_dbglvl >= (lvl)) { \
        !          3463:             printk(s); \
        !          3464:         } \
        !          3465:     }
        !          3466: 
        !          3467: #define ASC_DBG1(lvl, s, a1) \
        !          3468:     { \
        !          3469:         if (asc_dbglvl >= (lvl)) { \
        !          3470:             printk((s), (a1)); \
        !          3471:         } \
        !          3472:     }
        !          3473: 
        !          3474: #define ASC_DBG2(lvl, s, a1, a2) \
        !          3475:     { \
        !          3476:         if (asc_dbglvl >= (lvl)) { \
        !          3477:             printk((s), (a1), (a2)); \
        !          3478:         } \
        !          3479:     }
        !          3480: 
        !          3481: #define ASC_DBG3(lvl, s, a1, a2, a3) \
        !          3482:     { \
        !          3483:         if (asc_dbglvl >= (lvl)) { \
        !          3484:             printk((s), (a1), (a2), (a3)); \
        !          3485:         } \
        !          3486:     }
        !          3487: 
        !          3488: #define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
        !          3489:     { \
        !          3490:         if (asc_dbglvl >= (lvl)) { \
        !          3491:             printk((s), (a1), (a2), (a3), (a4)); \
        !          3492:         } \
        !          3493:     }
        !          3494: 
        !          3495: #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
        !          3496:     { \
        !          3497:         if (asc_dbglvl >= (lvl)) { \
        !          3498:             asc_prt_scsi_host(s); \
        !          3499:         } \
        !          3500:     }
        !          3501: 
        !          3502: #define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
        !          3503:     { \
        !          3504:         if (asc_dbglvl >= (lvl)) { \
        !          3505:             asc_prt_scsi_cmnd(s); \
        !          3506:         } \
        !          3507:     }
        !          3508: 
        !          3509: #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
        !          3510:     { \
        !          3511:         if (asc_dbglvl >= (lvl)) { \
        !          3512:             asc_prt_asc_scsi_q(scsiqp); \
        !          3513:         } \
        !          3514:     }
        !          3515: 
        !          3516: #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
        !          3517:     { \
        !          3518:         if (asc_dbglvl >= (lvl)) { \
        !          3519:             asc_prt_asc_qdone_info(qdone); \
        !          3520:         } \
        !          3521:     }
        !          3522: 
        !          3523: #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
        !          3524:     { \
        !          3525:         if (asc_dbglvl >= (lvl)) { \
        !          3526:             asc_prt_adv_scsi_req_q(scsiqp); \
        !          3527:         } \
        !          3528:     }
        !          3529: 
        !          3530: #define ASC_DBG_PRT_HEX(lvl, name, start, length) \
        !          3531:     { \
        !          3532:         if (asc_dbglvl >= (lvl)) { \
        !          3533:             asc_prt_hex((name), (start), (length)); \
        !          3534:         } \
        !          3535:     }
        !          3536: 
        !          3537: #define ASC_DBG_PRT_CDB(lvl, cdb, len) \
        !          3538:         ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
        !          3539: 
        !          3540: #define ASC_DBG_PRT_SENSE(lvl, sense, len) \
        !          3541:         ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
        !          3542: 
        !          3543: #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
        !          3544:         ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
        !          3545: #endif /* ADVANSYS_DEBUG */
        !          3546: 
        !          3547: #ifndef ADVANSYS_ASSERT
        !          3548: #define ASC_ASSERT(a)
        !          3549: #else /* ADVANSYS_ASSERT */
        !          3550: 
        !          3551: #define ASC_ASSERT(a) \
        !          3552:     { \
        !          3553:         if (!(a)) { \
        !          3554:             printk("ASC_ASSERT() Failure: file %s, line %d\n", \
        !          3555:                 __FILE__, __LINE__); \
        !          3556:         } \
        !          3557:     }
        !          3558: 
        !          3559: #endif /* ADVANSYS_ASSERT */
        !          3560: 
        !          3561: 
        !          3562: /*
        !          3563:  * --- Driver Structures
        !          3564:  */
        !          3565: 
        !          3566: #ifdef ADVANSYS_STATS
        !          3567: 
        !          3568: /* Per board statistics structure */
        !          3569: struct asc_stats {
        !          3570:     /* Driver Entrypoint Statistics */
        !          3571:     ulong     command;         /* # calls to advansys_command() */
        !          3572:     ulong     queuecommand;    /* # calls to advansys_queuecommand() */
        !          3573:     ulong     abort;           /* # calls to advansys_abort() */
        !          3574:     ulong     reset;           /* # calls to advansys_reset() */
        !          3575:     ulong     biosparam;       /* # calls to advansys_biosparam() */
        !          3576:     ulong     interrupt;       /* # advansys_interrupt() calls */
        !          3577:     ulong     callback;        /* # calls to asc/adv_isr_callback() */
        !          3578:     ulong     done;            /* # calls to request's scsi_done function */
        !          3579:     ulong     build_error;     /* # asc/adv_build_req() ASC_ERROR returns. */
        !          3580:     ulong     adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
        !          3581:     ulong     adv_build_nosg;  /* # adv_build_req() adv_sgblk_t alloc. fail. */
        !          3582:     /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
        !          3583:     ulong     exe_noerror;     /* # ASC_NOERROR returns. */
        !          3584:     ulong     exe_busy;        /* # ASC_BUSY returns. */
        !          3585:     ulong     exe_error;       /* # ASC_ERROR returns. */
        !          3586:     ulong     exe_unknown;     /* # unknown returns. */
        !          3587:     /* Data Transfer Statistics */
        !          3588:     ulong     cont_cnt;        /* # non-scatter-gather I/O requests received */
        !          3589:     ulong     cont_xfer;       /* # contiguous transfer 512-bytes */
        !          3590:     ulong     sg_cnt;          /* # scatter-gather I/O requests received */
        !          3591:     ulong     sg_elem;         /* # scatter-gather elements */
        !          3592:     ulong     sg_xfer;         /* # scatter-gather transfer 512-bytes */
        !          3593: };
        !          3594: #endif /* ADVANSYS_STATS */
        !          3595: 
        !          3596: /*
        !          3597:  * Request queuing structure
        !          3598:  */
        !          3599: typedef struct asc_queue {
        !          3600:     ADV_SCSI_BIT_ID_TYPE  q_tidmask;                /* queue mask */
        !          3601:     REQP                  q_first[ADV_MAX_TID+1];   /* first queued request */
        !          3602:     REQP                  q_last[ADV_MAX_TID+1];    /* last queued request */
        !          3603: #ifdef ADVANSYS_STATS
        !          3604:     short                 q_cur_cnt[ADV_MAX_TID+1]; /* current queue count */
        !          3605:     short                 q_max_cnt[ADV_MAX_TID+1]; /* maximum queue count */
        !          3606:     ulong                 q_tot_cnt[ADV_MAX_TID+1]; /* total enqueue count */
        !          3607:     ulong                 q_tot_tim[ADV_MAX_TID+1]; /* total time queued */
        !          3608:     ushort                q_max_tim[ADV_MAX_TID+1]; /* maximum time queued */
        !          3609:     ushort                q_min_tim[ADV_MAX_TID+1]; /* minimum time queued */
        !          3610: #endif /* ADVANSYS_STATS */
        !          3611: } asc_queue_t;
        !          3612: 
        !          3613: /*
        !          3614:  * Adv Library Request Structures
        !          3615:  *
        !          3616:  * The following two se structures are used to process Wide Board requests.
        !          3617:  * One structure is needed for each command received from the Mid-Level SCSI
        !          3618:  * driver.
        !          3619:  *
        !          3620:  * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
        !          3621:  * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
        !          3622:  * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
        !          3623:  * Mid-Level SCSI request structure.
        !          3624:  *
        !          3625:  * The adv_sgblk_t structure is used to handle requests that include
        !          3626:  * scatter-gather elements.
        !          3627:  */
        !          3628: typedef struct adv_sgblk {
        !          3629:     ADV_SG_BLOCK        sg_block[ADV_NUM_SG_BLOCK + ADV_NUM_PAGE_CROSSING];
        !          3630:     uchar               align2[4];       /* Sgblock structure padding. */
        !          3631:     struct adv_sgblk    *next_sgblkp;    /* Next scatter-gather structure. */
        !          3632: } adv_sgblk_t;
        !          3633: 
        !          3634: typedef struct adv_req {
        !          3635:     ADV_SCSI_REQ_Q      scsi_req_q;   /* Adv Library request structure. */
        !          3636:     uchar               align1[4];    /* Request structure padding. */
        !          3637:     Scsi_Cmnd           *cmndp;       /* Mid-Level SCSI command pointer. */
        !          3638:     adv_sgblk_t         *sgblkp;      /* Adv Library scatter-gather pointer. */
        !          3639:     struct adv_req      *next_reqp;   /* Next Request Structure. */
        !          3640: } adv_req_t;
        !          3641: 
        !          3642: /*
        !          3643:  * Structure allocated for each board.
        !          3644:  *
        !          3645:  * This structure is allocated by scsi_register() at the end
        !          3646:  * of the 'Scsi_Host' structure starting at the 'hostdata'
        !          3647:  * field. It is guaranteed to be allocated from DMA-able memory.
        !          3648:  */
        !          3649: typedef struct asc_board {
        !          3650:     int                  id;                    /* Board Id */
        !          3651:     uint                 flags;                 /* Board flags */
        !          3652:     union {
        !          3653:         ASC_DVC_VAR      asc_dvc_var;           /* Narrow board */
        !          3654:         ADV_DVC_VAR      adv_dvc_var;           /* Wide board */
        !          3655:     } dvc_var;
        !          3656:     union {
        !          3657:         ASC_DVC_CFG      asc_dvc_cfg;           /* Narrow board */
        !          3658:         ADV_DVC_CFG      adv_dvc_cfg;           /* Wide board */
        !          3659:     } dvc_cfg;
        !          3660:     asc_queue_t          active;                /* Active command queue */
        !          3661:     asc_queue_t          waiting;               /* Waiting command queue */
        !          3662:     asc_queue_t          done;                  /* Done command queue */
        !          3663:     ADV_SCSI_BIT_ID_TYPE init_tidmask;          /* Target init./valid mask */
        !          3664:     Scsi_Device          *device[ADV_MAX_TID+1]; /* Mid-Level Scsi Device */
        !          3665:     ushort               reqcnt[ADV_MAX_TID+1]; /* Starvation request count */
        !          3666: #if ASC_QUEUE_FLOW_CONTROL
        !          3667:     ushort               nerrcnt[ADV_MAX_TID+1]; /* No error request count */
        !          3668: #endif /* ASC_QUEUE_FLOW_CONTROL */
        !          3669:     ADV_SCSI_BIT_ID_TYPE queue_full;            /* Queue full mask */
        !          3670:     ushort               queue_full_cnt[ADV_MAX_TID+1]; /* Queue full count */
        !          3671:     union {
        !          3672:         ASCEEP_CONFIG    asc_eep;               /* Narrow EEPROM config. */
        !          3673:         ADVEEP_CONFIG    adv_eep;               /* Wide EEPROM config. */
        !          3674:     } eep_config;
        !          3675:     ulong                last_reset;            /* Saved last reset time */
        !          3676: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
        !          3677:     /* /proc/scsi/advansys/[0...] */
        !          3678:     char                 *prtbuf;               /* Statistics Print Buffer */
        !          3679: #endif /* version >= v1.3.0 */
        !          3680: #ifdef ADVANSYS_STATS
        !          3681:     struct asc_stats     asc_stats;             /* Board statistics */
        !          3682: #endif /* ADVANSYS_STATS */
        !          3683:     /*
        !          3684:      * The following fields are used only for Narrow Boards.
        !          3685:      */
        !          3686:     /* The following three structures must be in DMA-able memory. */
        !          3687:     ASC_SCSI_REQ_Q       scsireqq;
        !          3688:     ASC_CAP_INFO         cap_info;
        !          3689:     ASC_SCSI_INQUIRY     inquiry;
        !          3690:     uchar                sdtr_data[ASC_MAX_TID+1]; /* SDTR information */
        !          3691:     /*
        !          3692:      * The following fields are used only for Wide Boards.
        !          3693:      */
        !          3694:     void                 *ioremap_addr;         /* I/O Memory remap address. */
        !          3695:     ushort               ioport;                /* I/O Port address. */
        !          3696:     adv_req_t            *orig_reqp;            /* adv_req_t memory block. */
        !          3697:     adv_req_t            *adv_reqp;             /* Request structures. */
        !          3698:     adv_sgblk_t          *orig_sgblkp;          /* adv_sgblk_t memory block. */
        !          3699:     adv_sgblk_t          *adv_sgblkp;           /* Scatter-gather structures. */
        !          3700:     ushort               bios_signature;        /* BIOS Signature. */
        !          3701:     ushort               bios_version;          /* BIOS Version. */
        !          3702:     ushort               bios_codeseg;          /* BIOS Code Segment. */
        !          3703:     ushort               bios_codelen;          /* BIOS Code Segment Length. */
        !          3704: } asc_board_t;
        !          3705: 
        !          3706: /*
        !          3707:  * PCI configuration structures
        !          3708:  */
        !          3709: typedef struct _PCI_DATA_
        !          3710: {
        !          3711:     uchar    type;
        !          3712:     uchar    bus;
        !          3713:     uchar    slot;
        !          3714:     uchar    func;
        !          3715:     uchar    offset;
        !          3716: } PCI_DATA;
        !          3717: 
        !          3718: typedef struct _PCI_DEVICE_
        !          3719: {
        !          3720:     ushort   vendorID;
        !          3721:     ushort   deviceID;
        !          3722:     ushort   slotNumber;
        !          3723:     ushort   slotFound;
        !          3724:     uchar    busNumber;
        !          3725:     uchar    maxBusNumber;
        !          3726:     uchar    devFunc;
        !          3727:     ushort   startSlot;
        !          3728:     ushort   endSlot;
        !          3729:     uchar    bridge;
        !          3730:     uchar    type;
        !          3731: } PCI_DEVICE;
        !          3732: 
        !          3733: typedef struct _PCI_CONFIG_SPACE_
        !          3734: {
        !          3735:     ushort   vendorID;
        !          3736:     ushort   deviceID;
        !          3737:     ushort   command;
        !          3738:     ushort   status;
        !          3739:     uchar    revision;
        !          3740:     uchar    classCode[3];
        !          3741:     uchar    cacheSize;
        !          3742:     uchar    latencyTimer;
        !          3743:     uchar    headerType;
        !          3744:     uchar    bist;
        !          3745:     ulong    baseAddress[6];
        !          3746:     ushort   reserved[4];
        !          3747:     ulong    optionRomAddr;
        !          3748:     ushort   reserved2[4];
        !          3749:     uchar    irqLine;
        !          3750:     uchar    irqPin;
        !          3751:     uchar    minGnt;
        !          3752:     uchar    maxLatency;
        !          3753: } PCI_CONFIG_SPACE;
        !          3754: 
        !          3755: 
        !          3756: /*
        !          3757:  * --- Driver Data
        !          3758:  */
        !          3759: 
        !          3760: /* Note: All driver global data should be initialized. */
        !          3761: 
        !          3762: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
        !          3763: struct proc_dir_entry proc_scsi_advansys =
        !          3764: {
        !          3765:     PROC_SCSI_ADVANSYS,              /* unsigned short low_ino */
        !          3766:     8,                               /* unsigned short namelen */
        !          3767:     "advansys",                      /* const char *name */
        !          3768:     S_IFDIR | S_IRUGO | S_IXUGO,     /* mode_t mode */
        !          3769:     2                                /* nlink_t nlink */
        !          3770: };
        !          3771: #endif /* version >= v1.3.0 */
        !          3772: 
        !          3773: /* Number of boards detected in system. */
        !          3774: STATIC int asc_board_count = 0;
        !          3775: STATIC struct Scsi_Host    *asc_host[ASC_NUM_BOARD_SUPPORTED] = { 0 };
        !          3776: 
        !          3777: /* Overrun buffer shared between all boards. */
        !          3778: STATIC uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
        !          3779: 
        !          3780: /*
        !          3781:  * Global structures required to issue a command.
        !          3782:  */
        !          3783: STATIC ASC_SCSI_Q asc_scsi_q = { { 0 } };
        !          3784: STATIC ASC_SG_HEAD asc_sg_head = { 0 };
        !          3785: 
        !          3786: /* List of supported bus types. */
        !          3787: STATIC ushort asc_bus[ASC_NUM_BUS] ASC_INITDATA = {
        !          3788:     ASC_IS_ISA,
        !          3789:     ASC_IS_VL,
        !          3790:     ASC_IS_EISA,
        !          3791:     ASC_IS_PCI,
        !          3792: };
        !          3793: 
        !          3794: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
        !          3795: #ifdef ASC_CONFIG_PCI
        !          3796: STATIC int pci_scan_method ASC_INITDATA = -1;
        !          3797: #endif /* ASC_CONFIG_PCI */
        !          3798: #endif /* version < v2.1.93 */
        !          3799: 
        !          3800: /*
        !          3801:  * Used with the LILO 'advansys' option to eliminate or
        !          3802:  * limit I/O port probing at boot time, cf. advansys_setup().
        !          3803:  */
        !          3804: STATIC int asc_iopflag = ASC_FALSE;
        !          3805: STATIC int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 };
        !          3806: 
        !          3807: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
        !          3808: /*
        !          3809:  * In kernels earlier than v1.3.0, kmalloc() does not work
        !          3810:  * during driver initialization. Therefore statically declare
        !          3811:  * 16 elements of each structure. v1.3.0 kernels will probably
        !          3812:  * not need any more than this number.
        !          3813:  */
        !          3814: uchar adv_req_buf[16 * sizeof(adv_req_t)] = { 0 };
        !          3815: uchar adv_sgblk_buf[16 * sizeof(adv_sgblk_t)] = { 0 };
        !          3816: #endif /* version >= v1,3,0 */
        !          3817: 
        !          3818: #ifdef ADVANSYS_DEBUG
        !          3819: STATIC char *
        !          3820: asc_bus_name[ASC_NUM_BUS] = {
        !          3821:     "ASC_IS_ISA",
        !          3822:     "ASC_IS_VL",
        !          3823:     "ASC_IS_EISA",
        !          3824:     "ASC_IS_PCI",
        !          3825: };
        !          3826: 
        !          3827: STATIC int          asc_dbglvl = 0;
        !          3828: #endif /* ADVANSYS_DEBUG */
        !          3829: 
        !          3830: /* Declaration for Asc Library internal data referenced by driver. */
        !          3831: STATIC PortAddr     _asc_def_iop_base[];
        !          3832: 
        !          3833: 
        !          3834: /*
        !          3835:  * --- Driver Function Prototypes
        !          3836:  *
        !          3837:  * advansys.h contains function prototypes for functions global to Linux.
        !          3838:  */
        !          3839: 
        !          3840: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
        !          3841: STATIC int          asc_proc_copy(off_t, off_t, char *, int , char *, int);
        !          3842: #endif /* version >= v1.3.0 */
        !          3843: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
        !          3844: STATIC void         advansys_interrupt(int, struct pt_regs *);
        !          3845: #else /* version >= v1.3.70 */
        !          3846: STATIC void         advansys_interrupt(int, void *, struct pt_regs *);
        !          3847: #endif /* version >= v1.3.70 */
        !          3848: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
        !          3849: STATIC void         advansys_select_queue_depths(struct Scsi_Host *,
        !          3850:                                                 Scsi_Device *);
        !          3851: #endif /* version >= v1.3.89 */
        !          3852: STATIC void       advansys_command_done(Scsi_Cmnd *);
        !          3853: STATIC void       asc_scsi_done_list(Scsi_Cmnd *);
        !          3854: STATIC int        asc_execute_scsi_cmnd(Scsi_Cmnd *);
        !          3855: STATIC int        asc_build_req(asc_board_t *, Scsi_Cmnd *);
        !          3856: STATIC int        adv_build_req(asc_board_t *, Scsi_Cmnd *, ADV_SCSI_REQ_Q **);
        !          3857: STATIC int        adv_get_sglist(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *, Scsi_Cmnd *);
        !          3858: STATIC void       asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
        !          3859: STATIC void       adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
        !          3860: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
        !          3861: #ifdef ASC_CONFIG_PCI
        !          3862: STATIC int        asc_srch_pci_dev(PCI_DEVICE *);
        !          3863: STATIC uchar      asc_scan_method(void);
        !          3864: STATIC int        asc_pci_find_dev(PCI_DEVICE *);
        !          3865: STATIC void       asc_get_pci_cfg(PCI_DEVICE *, PCI_CONFIG_SPACE *);
        !          3866: STATIC ushort     asc_get_cfg_word(PCI_DATA *);
        !          3867: STATIC uchar      asc_get_cfg_byte(PCI_DATA *);
        !          3868: STATIC void       asc_put_cfg_byte(PCI_DATA *, uchar);
        !          3869: #endif /* ASC_CONFIG_PCI */
        !          3870: #endif /* version < v2.1.93 */
        !          3871: STATIC void       asc_enqueue(asc_queue_t *, REQP, int);
        !          3872: STATIC REQP       asc_dequeue(asc_queue_t *, int);
        !          3873: STATIC REQP       asc_dequeue_list(asc_queue_t *, REQP *, int);
        !          3874: STATIC int        asc_rmqueue(asc_queue_t *, REQP);
        !          3875: STATIC int        asc_isqueued(asc_queue_t *, REQP);
        !          3876: STATIC void       asc_execute_queue(asc_queue_t *);
        !          3877: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
        !          3878: STATIC int        asc_prt_board_devices(struct Scsi_Host *, char *, int);
        !          3879: STATIC int        asc_prt_adv_bios(struct Scsi_Host *, char *, int);
        !          3880: STATIC int        asc_get_eeprom_string(ushort *serialnum, uchar *cp);
        !          3881: STATIC int        asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
        !          3882: STATIC int        asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
        !          3883: STATIC int        asc_prt_driver_conf(struct Scsi_Host *, char *, int);
        !          3884: STATIC int        asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
        !          3885: STATIC int        asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
        !          3886: STATIC int        asc_prt_line(char *, int, char *fmt, ...);
        !          3887: #endif /* version >= v1.3.0 */
        !          3888: 
        !          3889: /* Declaration for Asc Library internal functions reference by driver. */
        !          3890: STATIC int          AscFindSignature(PortAddr);
        !          3891: STATIC ushort       AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
        !          3892: 
        !          3893: #ifdef ADVANSYS_STATS
        !          3894: STATIC int          asc_prt_board_stats(struct Scsi_Host *, char *, int);
        !          3895: #endif /* ADVANSYS_STATS */
        !          3896: 
        !          3897: #ifdef ADVANSYS_DEBUG
        !          3898: STATIC void         asc_prt_scsi_host(struct Scsi_Host *);
        !          3899: STATIC void         asc_prt_scsi_cmnd(Scsi_Cmnd *);
        !          3900: STATIC void         asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
        !          3901: STATIC void         asc_prt_asc_dvc_var(ASC_DVC_VAR *);
        !          3902: STATIC void         asc_prt_asc_scsi_q(ASC_SCSI_Q *);
        !          3903: STATIC void         asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
        !          3904: STATIC void         asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
        !          3905: STATIC void         asc_prt_adv_dvc_var(ADV_DVC_VAR *);
        !          3906: STATIC void         asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
        !          3907: STATIC void         asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
        !          3908: STATIC void         asc_prt_hex(char *f, uchar *, int);
        !          3909: #endif /* ADVANSYS_DEBUG */
        !          3910: 
        !          3911: #ifdef ADVANSYS_ASSERT
        !          3912: STATIC int             interrupts_enabled(void);
        !          3913: #endif /* ADVANSYS_ASSERT */
        !          3914: 
        !          3915: 
        !          3916: /*
        !          3917:  * --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
        !          3918:  */
        !          3919: 
        !          3920: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
        !          3921: /*
        !          3922:  * advansys_proc_info() - /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
        !          3923:  *
        !          3924:  * *buffer: I/O buffer
        !          3925:  * **start: if inout == FALSE pointer into buffer where user read should start
        !          3926:  * offset: current offset into a /proc/scsi/advansys/[0...] file
        !          3927:  * length: length of buffer
        !          3928:  * hostno: Scsi_Host host_no
        !          3929:  * inout: TRUE - user is writing; FALSE - user is reading
        !          3930:  *
        !          3931:  * Return the number of bytes read from or written to a
        !          3932:  * /proc/scsi/advansys/[0...] file.
        !          3933:  *
        !          3934:  * Note: This function uses the per board buffer 'prtbuf' which is
        !          3935:  * allocated when the board is initialized in advansys_detect(). The
        !          3936:  * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
        !          3937:  * used to write to the buffer. The way asc_proc_copy() is written
        !          3938:  * if 'prtbuf' is too small it will not be overwritten. Instead the
        !          3939:  * user just won't get all the available statistics.
        !          3940:  */
        !          3941: int
        !          3942: advansys_proc_info(char *buffer, char **start, off_t offset, int length, 
        !          3943:                    int hostno, int inout)
        !          3944: {
        !          3945:     struct Scsi_Host    *shp;
        !          3946:     asc_board_t         *boardp;
        !          3947:     int                 i;
        !          3948:     char                *cp;
        !          3949:     int                 cplen;
        !          3950:     int                 cnt;
        !          3951:     int                 totcnt;
        !          3952:     int                 leftlen;
        !          3953:     char                *curbuf;
        !          3954:     off_t               advoffset;
        !          3955:     Scsi_Device         *scd;
        !          3956: 
        !          3957:     ASC_DBG(1, "advansys_proc_info: begin\n");
        !          3958: 
        !          3959:     /*
        !          3960:      * User write not supported.
        !          3961:      */
        !          3962:     if (inout == TRUE) {
        !          3963:         return(-ENOSYS);
        !          3964:     }
        !          3965: 
        !          3966:     /*
        !          3967:      * User read of /proc/scsi/advansys/[0...] file.
        !          3968:      */
        !          3969: 
        !          3970:     /* Find the specified board. */
        !          3971:     for (i = 0; i < asc_board_count; i++) {
        !          3972:         if (asc_host[i]->host_no == hostno) {
        !          3973:             break;
        !          3974:         }
        !          3975:     }
        !          3976:     if (i == asc_board_count) {
        !          3977:         return(-ENOENT);
        !          3978:     }
        !          3979: 
        !          3980:     shp = asc_host[i];
        !          3981:     boardp = ASC_BOARDP(shp);
        !          3982: 
        !          3983:     /* Copy read data starting at the beginning of the buffer. */
        !          3984:     *start = buffer;
        !          3985:     curbuf = buffer;
        !          3986:     advoffset = 0;
        !          3987:     totcnt = 0;
        !          3988:     leftlen = length;
        !          3989: 
        !          3990:     /*
        !          3991:      * Get board configuration information.
        !          3992:      *
        !          3993:      * advansys_info() returns the board string from its own static buffer.
        !          3994:      */
        !          3995:     cp = (char *) advansys_info(shp);
        !          3996:     strcat(cp, "\n");
        !          3997:     cplen = strlen(cp);
        !          3998:     /* Copy board information. */
        !          3999:     cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
        !          4000:     totcnt += cnt;
        !          4001:     leftlen -= cnt;
        !          4002:     if (leftlen == 0) {
        !          4003:         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
        !          4004:         return totcnt;
        !          4005:     }
        !          4006:     advoffset += cplen;
        !          4007:     curbuf += cnt;
        !          4008: 
        !          4009:     /*
        !          4010:      * Display Wide Board BIOS Information.
        !          4011:      */
        !          4012:     if (ASC_WIDE_BOARD(boardp)) {
        !          4013:         cp = boardp->prtbuf;
        !          4014:         cplen = asc_prt_adv_bios(shp, cp, ASC_PRTBUF_SIZE);
        !          4015:         ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
        !          4016:         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
        !          4017:         totcnt += cnt;
        !          4018:         leftlen -= cnt;
        !          4019:         if (leftlen == 0) {
        !          4020:             ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
        !          4021:             return totcnt;
        !          4022:         }
        !          4023:         advoffset += cplen;
        !          4024:         curbuf += cnt;
        !          4025:     }
        !          4026: 
        !          4027:     /*
        !          4028:      * Display driver information for each device attached to the board.
        !          4029:      */
        !          4030:     cp = boardp->prtbuf;
        !          4031:     cplen = asc_prt_board_devices(shp, cp, ASC_PRTBUF_SIZE);
        !          4032:     ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
        !          4033:     cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
        !          4034:     totcnt += cnt;
        !          4035:     leftlen -= cnt;
        !          4036:     if (leftlen == 0) {
        !          4037:         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
        !          4038:         return totcnt;
        !          4039:     }
        !          4040:     advoffset += cplen;
        !          4041:     curbuf += cnt;
        !          4042: 
        !          4043:     /*
        !          4044:      * Display target driver information for each device attached
        !          4045:      * to the board.
        !          4046:      */
        !          4047: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,75)
        !          4048:     for (scd = scsi_devices; scd; scd = scd->next)
        !          4049: #else /* version >= v2.1.75 */
        !          4050:     for (scd = shp->host_queue; scd; scd = scd->next)
        !          4051: #endif /* version >= v2.1.75 */
        !          4052:     {
        !          4053:         if (scd->host == shp) {
        !          4054:             cp = boardp->prtbuf;
        !          4055:             /*
        !          4056:              * Note: If proc_print_scsidevice() writes more than
        !          4057:              * ASC_PRTBUF_SIZE bytes, it will overrun 'prtbuf'.
        !          4058:              */
        !          4059:             proc_print_scsidevice(scd, cp, &cplen, 0);
        !          4060:             ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
        !          4061:             cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
        !          4062:             totcnt += cnt;
        !          4063:             leftlen -= cnt;
        !          4064:             if (leftlen == 0) {
        !          4065:                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
        !          4066:                 return totcnt;
        !          4067:             }
        !          4068:             advoffset += cplen;
        !          4069:             curbuf += cnt;
        !          4070:         }
        !          4071:     }
        !          4072:     
        !          4073:     /*
        !          4074:      * Display EEPROM configuration for the board.
        !          4075:      */
        !          4076:     cp = boardp->prtbuf;
        !          4077:     if (ASC_NARROW_BOARD(boardp)) {
        !          4078:         cplen = asc_prt_asc_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
        !          4079:     } else {
        !          4080:         cplen = asc_prt_adv_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
        !          4081:     }
        !          4082:     ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
        !          4083:     cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
        !          4084:     totcnt += cnt;
        !          4085:     leftlen -= cnt;
        !          4086:     if (leftlen == 0) {
        !          4087:         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
        !          4088:         return totcnt;
        !          4089:     }
        !          4090:     advoffset += cplen;
        !          4091:     curbuf += cnt;
        !          4092: 
        !          4093:     /*
        !          4094:      * Display driver configuration and information for the board.
        !          4095:      */
        !          4096:     cp = boardp->prtbuf;
        !          4097:     cplen = asc_prt_driver_conf(shp, cp, ASC_PRTBUF_SIZE);
        !          4098:     ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
        !          4099:     cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
        !          4100:     totcnt += cnt;
        !          4101:     leftlen -= cnt;
        !          4102:     if (leftlen == 0) {
        !          4103:         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
        !          4104:         return totcnt;
        !          4105:     }
        !          4106:     advoffset += cplen;
        !          4107:     curbuf += cnt;
        !          4108: 
        !          4109: #ifdef ADVANSYS_STATS
        !          4110:     /*
        !          4111:      * Display driver statistics for the board.
        !          4112:      */
        !          4113:     cp = boardp->prtbuf;
        !          4114:     cplen = asc_prt_board_stats(shp, cp, ASC_PRTBUF_SIZE);
        !          4115:     ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
        !          4116:     cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
        !          4117:     totcnt += cnt;
        !          4118:     leftlen -= cnt;
        !          4119:     if (leftlen == 0) {
        !          4120:         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
        !          4121:         return totcnt;
        !          4122:     }
        !          4123:     advoffset += cplen;
        !          4124:     curbuf += cnt;
        !          4125: #endif /* ADVANSYS_STATS */
        !          4126: 
        !          4127:     /*
        !          4128:      * Display Asc Library dynamic configuration information
        !          4129:      * for the board.
        !          4130:      */
        !          4131:     cp = boardp->prtbuf;
        !          4132:     if (ASC_NARROW_BOARD(boardp)) {
        !          4133:         cplen = asc_prt_asc_board_info(shp, cp, ASC_PRTBUF_SIZE);
        !          4134:     } else {
        !          4135:         cplen = asc_prt_adv_board_info(shp, cp, ASC_PRTBUF_SIZE);
        !          4136:     }
        !          4137:     ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
        !          4138:     cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
        !          4139:     totcnt += cnt;
        !          4140:     leftlen -= cnt;
        !          4141:     if (leftlen == 0) {
        !          4142:         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
        !          4143:         return totcnt;
        !          4144:     }
        !          4145:     advoffset += cplen;
        !          4146:     curbuf += cnt;
        !          4147: 
        !          4148:     ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
        !          4149: 
        !          4150:     return totcnt;
        !          4151: }
        !          4152: #endif /* version >= v1.3.0 */
        !          4153: 
        !          4154: /*
        !          4155:  * advansys_detect()
        !          4156:  *
        !          4157:  * Detect function for AdvanSys adapters.
        !          4158:  *
        !          4159:  * Argument is a pointer to the host driver's scsi_hosts entry.
        !          4160:  *
        !          4161:  * Return number of adapters found.
        !          4162:  *
        !          4163:  * Note: Because this function is called during system initialization
        !          4164:  * it must not call SCSI mid-level functions including scsi_malloc()
        !          4165:  * and scsi_free().
        !          4166:  */
        !          4167: ASC_INITFUNC(
        !          4168: int
        !          4169: advansys_detect(Scsi_Host_Template *tpnt)
        !          4170: )
        !          4171: {
        !          4172:     static int          detect_called = ASC_FALSE;
        !          4173:     int                 iop;
        !          4174:     int                 bus;
        !          4175:     struct Scsi_Host    *shp;
        !          4176:     asc_board_t         *boardp;
        !          4177:     ASC_DVC_VAR         *asc_dvc_varp = NULL;
        !          4178:     ADV_DVC_VAR         *adv_dvc_varp = NULL;
        !          4179:     int                 ioport = 0;
        !          4180:     int                 share_irq = FALSE;
        !          4181: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
        !          4182: #ifdef ASC_CONFIG_PCI
        !          4183:     PCI_DEVICE          pciDevice;
        !          4184:     PCI_CONFIG_SPACE    pciConfig;
        !          4185: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
        !          4186:     unsigned long       pci_memory_address;
        !          4187: #endif /* version >= v1,3,0 */
        !          4188: #endif /* ASC_CONFIG_PCI */
        !          4189: #else /* version >= v2.1.93 */ 
        !          4190: #ifdef CONFIG_PCI
        !          4191:     struct pci_dev      *pci_devp = NULL;
        !          4192:     int                 pci_device_id_cnt = 0;
        !          4193:     unsigned int        pci_device_id[ASC_PCI_DEVICE_ID_CNT] = {
        !          4194:                                     ASC_PCI_DEVICE_ID_1100,
        !          4195:                                     ASC_PCI_DEVICE_ID_1200,
        !          4196:                                     ASC_PCI_DEVICE_ID_1300,
        !          4197:                                     ASC_PCI_DEVICE_ID_2300
        !          4198:                         };
        !          4199:     unsigned long       pci_memory_address;
        !          4200: #endif /* CONFIG_PCI */
        !          4201: #endif /* version >= v2.1.93 */ 
        !          4202:     int                 warn_code, err_code;
        !          4203:     int                 ret;
        !          4204: 
        !          4205:     if (detect_called == ASC_FALSE) {
        !          4206:         detect_called = ASC_TRUE;
        !          4207:     } else {
        !          4208:         printk("AdvanSys SCSI: advansys_detect() multiple calls ignored\n");
        !          4209:         return 0;
        !          4210:     }
        !          4211: 
        !          4212:     ASC_DBG(1, "advansys_detect: begin\n");
        !          4213: 
        !          4214: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
        !          4215:     tpnt->proc_dir = &proc_scsi_advansys;
        !          4216: #endif /* version >= v1.3.0 */
        !          4217: 
        !          4218:     asc_board_count = 0;
        !          4219: 
        !          4220:     /*
        !          4221:      * If I/O port probing has been modified, then verify and
        !          4222:      * clean-up the 'asc_ioport' list.
        !          4223:      */
        !          4224:     if (asc_iopflag == ASC_TRUE) {
        !          4225:         for (ioport = 0; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
        !          4226:             ASC_DBG2(1, "advansys_detect: asc_ioport[%d] %x\n",
        !          4227:                 ioport, asc_ioport[ioport]);
        !          4228:             if (asc_ioport[ioport] != 0) {
        !          4229:                 for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX; iop++) {
        !          4230:                     if (_asc_def_iop_base[iop] == asc_ioport[ioport]) {
        !          4231:                         break;
        !          4232:                     }
        !          4233:                 }
        !          4234:                 if (iop == ASC_IOADR_TABLE_MAX_IX) {
        !          4235:                     printk(
        !          4236: "AdvanSys SCSI: specified I/O Port 0x%X is invalid\n",
        !          4237:                         asc_ioport[ioport]);
        !          4238:                     asc_ioport[ioport] = 0;
        !          4239:                 }
        !          4240:             }
        !          4241:         }
        !          4242:         ioport = 0;
        !          4243:     }
        !          4244: 
        !          4245: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
        !          4246: #ifdef ASC_CONFIG_PCI
        !          4247:     memset(&pciDevice, 0, sizeof(PCI_DEVICE));
        !          4248:     memset(&pciConfig, 0, sizeof(PCI_CONFIG_SPACE));
        !          4249:     pciDevice.maxBusNumber = PCI_MAX_BUS;
        !          4250:     pciDevice.endSlot = PCI_MAX_SLOT;
        !          4251: #endif /* ASC_CONFIG_PCI */
        !          4252: #endif /* version < v2.1.93 */ 
        !          4253: 
        !          4254:     for (bus = 0; bus < ASC_NUM_BUS; bus++) {
        !          4255: 
        !          4256:         ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n",
        !          4257:             bus, asc_bus_name[bus]);
        !          4258:         iop = 0;
        !          4259: 
        !          4260:         while (asc_board_count < ASC_NUM_BOARD_SUPPORTED) {
        !          4261: 
        !          4262:             ASC_DBG1(2, "advansys_detect: asc_board_count %d\n",
        !          4263:                 asc_board_count);
        !          4264: 
        !          4265:             switch (asc_bus[bus]) {
        !          4266:             case ASC_IS_ISA:
        !          4267:             case ASC_IS_VL:
        !          4268:                 if (asc_iopflag == ASC_FALSE) {
        !          4269:                     iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
        !          4270:                 } else {
        !          4271:                     /*
        !          4272:                      * ISA and VL I/O port scanning has either been
        !          4273:                      * eliminated or limited to selected ports on
        !          4274:                      * the LILO command line, /etc/lilo.conf, or
        !          4275:                      * by setting variables when the module was loaded.
        !          4276:                      */
        !          4277:                     ASC_DBG(1, "advansys_detect: I/O port scanning modified\n");
        !          4278:                 ioport_try_again:
        !          4279:                     iop = 0;
        !          4280:                     for (; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
        !          4281:                         if ((iop = asc_ioport[ioport]) != 0) {
        !          4282:                             break;
        !          4283:                         }
        !          4284:                     }
        !          4285:                     if (iop) {
        !          4286:                         ASC_DBG1(1, "advansys_detect: probing I/O port %x...\n",
        !          4287:                             iop);
        !          4288:                         if (check_region(iop, ASC_IOADR_GAP) != 0) {
        !          4289:                             printk(
        !          4290: "AdvanSys SCSI: specified I/O Port 0x%X is busy\n", iop);
        !          4291:                             /* Don't try this I/O port twice. */
        !          4292:                             asc_ioport[ioport] = 0;
        !          4293:                             goto ioport_try_again;
        !          4294:                         } else if (AscFindSignature(iop) == ASC_FALSE) {
        !          4295:                             printk(
        !          4296: "AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n", iop);
        !          4297:                             /* Don't try this I/O port twice. */
        !          4298:                             asc_ioport[ioport] = 0;
        !          4299:                             goto ioport_try_again;
        !          4300:                         } else {
        !          4301:                             /*
        !          4302:                              * If this isn't an ISA board, then it must be
        !          4303:                              * a VL board. If currently looking an ISA
        !          4304:                              * board is being looked for then try for
        !          4305:                              * another ISA board in 'asc_ioport'.
        !          4306:                              */
        !          4307:                             if (asc_bus[bus] == ASC_IS_ISA &&
        !          4308:                                 (AscGetChipVersion(iop, ASC_IS_ISA) &
        !          4309:                                  ASC_CHIP_VER_ISA_BIT) == 0) {
        !          4310:                                  /*
        !          4311:                                  * Don't clear 'asc_ioport[ioport]'. Try
        !          4312:                                  * this board again for VL. Increment
        !          4313:                                  * 'ioport' past this board.
        !          4314:                                  */
        !          4315:                                  ioport++;
        !          4316:                                  goto ioport_try_again;
        !          4317:                             }
        !          4318:                         }
        !          4319:                         /*
        !          4320:                          * This board appears good, don't try the I/O port
        !          4321:                          * again by clearing its value. Increment 'ioport'
        !          4322:                          * for the next iteration.
        !          4323:                          */
        !          4324:                         asc_ioport[ioport++] = 0;
        !          4325:                     }
        !          4326:                 }
        !          4327:                 break;
        !          4328: 
        !          4329:             case ASC_IS_EISA:
        !          4330:                 iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
        !          4331:                 break;
        !          4332: 
        !          4333: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
        !          4334: #ifdef ASC_CONFIG_PCI
        !          4335:             case ASC_IS_PCI:
        !          4336:                 if (asc_srch_pci_dev(&pciDevice) != PCI_DEVICE_FOUND) {
        !          4337:                     iop = 0;
        !          4338:                 } else {
        !          4339:                     ASC_DBG2(2,
        !          4340:                         "advansys_detect: slotFound %d, busNumber %d\n",
        !          4341:                         pciDevice.slotFound, pciDevice.busNumber);
        !          4342:                     asc_get_pci_cfg(&pciDevice, &pciConfig);
        !          4343:                     iop = pciConfig.baseAddress[0] & PCI_IOADDRESS_MASK;
        !          4344:                     ASC_DBG2(1,
        !          4345:                         "advansys_detect: vendorID %X, deviceID %X\n",
        !          4346:                         pciConfig.vendorID, pciConfig.deviceID);
        !          4347:                     ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n",
        !          4348:                         iop, pciConfig.irqLine);
        !          4349:                 }
        !          4350:                 break;
        !          4351: #endif /* ASC_CONFIG_PCI */
        !          4352: #else /* version >= v2.1.93 */ 
        !          4353: #ifdef CONFIG_PCI
        !          4354:             case ASC_IS_PCI:
        !          4355:                 while (pci_device_id_cnt < ASC_PCI_DEVICE_ID_CNT) {
        !          4356:                     if ((pci_devp = pci_find_device(ASC_PCI_VENDORID,
        !          4357:                          pci_device_id[pci_device_id_cnt], pci_devp)) == NULL) {
        !          4358:                         pci_device_id_cnt++;
        !          4359:                     } else {
        !          4360:                         break;
        !          4361:                     }
        !          4362:                 }
        !          4363:                 if (pci_devp == NULL) {
        !          4364:                     iop = 0;
        !          4365:                 } else {
        !          4366:                     ASC_DBG2(2,
        !          4367:                         "advansys_detect: devfn %d, bus number %d\n",
        !          4368:                         pci_devp->devfn, pci_devp->bus->number);
        !          4369:                     iop = pci_devp->base_address[0] & PCI_IOADDRESS_MASK;
        !          4370:                     ASC_DBG2(1,
        !          4371:                         "advansys_detect: vendorID %X, deviceID %X\n",
        !          4372:                         pci_devp->vendor, pci_devp->device);
        !          4373:                     ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n",
        !          4374:                         iop, pci_devp->irq);
        !          4375:                 }
        !          4376:                 break;
        !          4377: #endif /* CONFIG_PCI */
        !          4378: #endif /* version >= v2.1.93 */ 
        !          4379: 
        !          4380:             default:
        !          4381:                 ASC_PRINT1("advansys_detect: unknown bus type: %d\n",
        !          4382:                     asc_bus[bus]);
        !          4383:                 break;
        !          4384:             }
        !          4385:             ASC_DBG1(1, "advansys_detect: iop %x\n", iop);
        !          4386: 
        !          4387:             /*
        !          4388:              * Adapter not found, try next bus type.
        !          4389:              */
        !          4390:             if (iop == 0) {
        !          4391:                 break;
        !          4392:             }
        !          4393: 
        !          4394:             /*
        !          4395:              * Adapter found.
        !          4396:              *
        !          4397:              * Register the adapter, get its configuration, and
        !          4398:              * initialize it.
        !          4399:              */
        !          4400:             ASC_DBG(2, "advansys_detect: scsi_register()\n");
        !          4401:             shp = scsi_register(tpnt, sizeof(asc_board_t));
        !          4402: 
        !          4403:             /* Save a pointer to the Scsi_host of each board found. */
        !          4404:             asc_host[asc_board_count++] = shp;
        !          4405: 
        !          4406:             /* Initialize private per board data */
        !          4407:             boardp = ASC_BOARDP(shp);
        !          4408:             memset(boardp, 0, sizeof(asc_board_t));
        !          4409:             boardp->id = asc_board_count - 1;
        !          4410: 
        !          4411:             /*
        !          4412:              * Handle both narrow and wide boards.
        !          4413:              *
        !          4414:              * If a Wide board was detected, set the board structure
        !          4415:              * wide board flag. Set-up the board structure based on
        !          4416:              * the board type.
        !          4417:              */
        !          4418: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
        !          4419: #ifdef ASC_CONFIG_PCI
        !          4420:             if (asc_bus[bus] == ASC_IS_PCI &&
        !          4421:                  pciConfig.deviceID == ASC_PCI_DEVICE_ID_2300) {
        !          4422:                 boardp->flags |= ASC_IS_WIDE_BOARD;
        !          4423:             }
        !          4424: #endif /* ASC_CONFIG_PCI */
        !          4425: #else /* version >= v2.1.93 */ 
        !          4426: #ifdef CONFIG_PCI
        !          4427:             if (asc_bus[bus] == ASC_IS_PCI &&
        !          4428:                  pci_devp->device == ASC_PCI_DEVICE_ID_2300) {
        !          4429:                 boardp->flags |= ASC_IS_WIDE_BOARD;
        !          4430:             }
        !          4431: #endif /* CONFIG_PCI */
        !          4432: #endif /* version >= v2.1.93 */ 
        !          4433: 
        !          4434:             if (ASC_NARROW_BOARD(boardp)) {
        !          4435:                 ASC_DBG(1, "advansys_detect: narrow board\n");
        !          4436:                 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
        !          4437:                 asc_dvc_varp->bus_type = asc_bus[bus];
        !          4438:                 asc_dvc_varp->drv_ptr = (ulong) boardp;
        !          4439:                 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
        !          4440:                 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
        !          4441:                 asc_dvc_varp->iop_base = iop;
        !          4442:                 asc_dvc_varp->isr_callback = (Ptr2Func) asc_isr_callback;
        !          4443:             } else {
        !          4444:                 ASC_DBG(1, "advansys_detect: wide board\n");
        !          4445:                 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
        !          4446:                 adv_dvc_varp->drv_ptr = (ulong) boardp;
        !          4447:                 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
        !          4448:                 adv_dvc_varp->isr_callback = (Ptr2Func) adv_isr_callback;
        !          4449: 
        !          4450: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
        !          4451:                 adv_dvc_varp->iop_base = iop;
        !          4452: #else /* version >= v1,3,0 */
        !          4453:                 /*
        !          4454:                  * Map the board's registers into virtual memory for
        !          4455:                  * PCI slave access. Only memory accesses are used to
        !          4456:                  * access the board's registers.
        !          4457:                  *
        !          4458:                  * Note: The PCI register base address is not always
        !          4459:                  * page aligned, but the address passed to ioremap()
        !          4460:                  * must be page aligned. It is guaranteed that the
        !          4461:                  * PCI register base address will not cross a page
        !          4462:                  * boundary.
        !          4463:                  */
        !          4464: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
        !          4465: #ifdef ASC_CONFIG_PCI
        !          4466:                 pci_memory_address = pciConfig.baseAddress[1];
        !          4467:                 if ((boardp->ioremap_addr =
        !          4468:                     ioremap(pci_memory_address & PAGE_MASK,
        !          4469:                          PAGE_SIZE)) == 0) {
        !          4470:                    ASC_PRINT3(
        !          4471: "advansys_detect: board %d: ioremap(%lx, %d) returned NULL\n",
        !          4472:                    boardp->id, pci_memory_address, ADV_CONDOR_IOLEN);
        !          4473:                    scsi_unregister(shp);
        !          4474:                    asc_board_count--;
        !          4475:                    continue;
        !          4476:                 }
        !          4477:                 adv_dvc_varp->iop_base = (AdvPortAddr)
        !          4478:                     (boardp->ioremap_addr +
        !          4479:                      (pci_memory_address - (pci_memory_address & PAGE_MASK)));
        !          4480: #endif /* ASC_CONFIG_PCI */
        !          4481: #else /* version >= v2.1.93 */ 
        !          4482: #ifdef CONFIG_PCI
        !          4483:                 pci_memory_address = pci_devp->base_address[1];
        !          4484:                 if ((boardp->ioremap_addr =
        !          4485:                     ioremap(pci_memory_address & PAGE_MASK,
        !          4486:                          PAGE_SIZE)) == 0) {
        !          4487:                    ASC_PRINT3(
        !          4488: "advansys_detect: board %d: ioremap(%lx, %d) returned NULL\n",
        !          4489:                    boardp->id, pci_memory_address, ADV_CONDOR_IOLEN);
        !          4490:                    scsi_unregister(shp);
        !          4491:                    asc_board_count--;
        !          4492:                    continue;
        !          4493:                 }
        !          4494:                 adv_dvc_varp->iop_base = (AdvPortAddr)
        !          4495:                     (boardp->ioremap_addr +
        !          4496:                      (pci_memory_address - (pci_memory_address & PAGE_MASK)));
        !          4497: #endif /* CONFIG_PCI */
        !          4498: #endif /* version >= v2.1.93 */ 
        !          4499: #endif /* version >= v1,3,0 */
        !          4500: 
        !          4501:                 /*
        !          4502:                  * Even though it isn't used to access the board in
        !          4503:                  * kernels greater than or equal to v1.3.0, save
        !          4504:                  * the I/O Port address so that it can be reported and
        !          4505:                  * displayed.
        !          4506:                  */
        !          4507:                 boardp->ioport = iop;
        !          4508:             }
        !          4509: 
        !          4510: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
        !          4511:             /*
        !          4512:              * Allocate buffer for printing information from
        !          4513:              * /proc/scsi/advansys/[0...].
        !          4514:              */
        !          4515:             if ((boardp->prtbuf =
        !          4516:                 kmalloc(ASC_PRTBUF_SIZE, GFP_ATOMIC)) == NULL) {
        !          4517:                 ASC_PRINT3(
        !          4518: "advansys_detect: board %d: kmalloc(%d, %d) returned NULL\n",
        !          4519:                     boardp->id, ASC_PRTBUF_SIZE, GFP_ATOMIC);
        !          4520:                 scsi_unregister(shp);
        !          4521:                 asc_board_count--;
        !          4522:                 continue;
        !          4523:             }
        !          4524: #endif /* version >= v1.3.0 */
        !          4525: 
        !          4526:             if (ASC_NARROW_BOARD(boardp)) {
        !          4527:                 /*
        !          4528:                  * Set the board bus type and PCI IRQ before
        !          4529:                  * calling AscInitGetConfig().
        !          4530:                  */
        !          4531:                 switch (asc_dvc_varp->bus_type) {
        !          4532:                 case ASC_IS_ISA:
        !          4533:                     shp->unchecked_isa_dma = TRUE;
        !          4534:                     share_irq = FALSE;
        !          4535:                     break;
        !          4536:                 case ASC_IS_VL:
        !          4537:                     shp->unchecked_isa_dma = FALSE;
        !          4538:                     share_irq = FALSE;
        !          4539:                     break;
        !          4540:                 case ASC_IS_EISA:
        !          4541:                     shp->unchecked_isa_dma = FALSE;
        !          4542:                     share_irq = TRUE;
        !          4543:                     break;
        !          4544: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
        !          4545: #ifdef ASC_CONFIG_PCI
        !          4546:                 case ASC_IS_PCI:
        !          4547:                     shp->irq = asc_dvc_varp->irq_no = pciConfig.irqLine;
        !          4548:                     asc_dvc_varp->cfg->pci_device_id = pciConfig.deviceID;
        !          4549:                     asc_dvc_varp->cfg->pci_slot_info =
        !          4550:                         ASC_PCI_MKID(pciDevice.busNumber,
        !          4551:                             pciDevice.slotFound,
        !          4552:                             pciDevice.devFunc);
        !          4553:                     shp->unchecked_isa_dma = FALSE;
        !          4554:                     share_irq = TRUE;
        !          4555:                     break;
        !          4556: #endif /* ASC_CONFIG_PCI */
        !          4557: #else /* version >= v2.1.93 */ 
        !          4558: #ifdef CONFIG_PCI
        !          4559:                 case ASC_IS_PCI:
        !          4560:                     shp->irq = asc_dvc_varp->irq_no = pci_devp->irq;
        !          4561:                     asc_dvc_varp->cfg->pci_device_id = pci_devp->device;
        !          4562:                     asc_dvc_varp->cfg->pci_slot_info =
        !          4563:                         ASC_PCI_MKID(pci_devp->bus->number,
        !          4564:                             PCI_SLOT(pci_devp->devfn),
        !          4565:                             PCI_FUNC(pci_devp->devfn));
        !          4566:                     shp->unchecked_isa_dma = FALSE;
        !          4567:                     share_irq = TRUE;
        !          4568:                     break;
        !          4569: #endif /* CONFIG_PCI */
        !          4570: #endif /* version >= v2.1.93 */ 
        !          4571:                 default:
        !          4572:                     ASC_PRINT2(
        !          4573: "advansys_detect: board %d: unknown adapter type: %d\n",
        !          4574:                         boardp->id, asc_dvc_varp->bus_type);
        !          4575:                     shp->unchecked_isa_dma = TRUE;
        !          4576:                     share_irq = FALSE;
        !          4577:                     break;
        !          4578:                 }
        !          4579:             } else {
        !          4580:                 /*
        !          4581:                  * For Wide boards set PCI information before calling
        !          4582:                  * AdvInitGetConfig().
        !          4583:                  */
        !          4584: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
        !          4585: #ifdef ASC_CONFIG_PCI
        !          4586:                 shp->irq = adv_dvc_varp->irq_no = pciConfig.irqLine;
        !          4587:                 adv_dvc_varp->cfg->pci_device_id = pciConfig.deviceID;
        !          4588:                 adv_dvc_varp->cfg->pci_slot_info =
        !          4589:                 ASC_PCI_MKID(pciDevice.busNumber,
        !          4590:                     pciDevice.slotFound,
        !          4591:                     pciDevice.devFunc);
        !          4592:                 shp->unchecked_isa_dma = FALSE;
        !          4593:                 share_irq = TRUE;
        !          4594: #endif /* ASC_CONFIG_PCI */
        !          4595: #else /* version >= v2.1.93 */ 
        !          4596: #ifdef CONFIG_PCI
        !          4597:                 shp->irq = adv_dvc_varp->irq_no = pci_devp->irq;
        !          4598:                 adv_dvc_varp->cfg->pci_device_id = pci_devp->device;
        !          4599:                 adv_dvc_varp->cfg->pci_slot_info =
        !          4600:                 ASC_PCI_MKID(pci_devp->bus->number,
        !          4601:                     PCI_SLOT(pci_devp->devfn),
        !          4602:                     PCI_FUNC(pci_devp->devfn));
        !          4603:                 shp->unchecked_isa_dma = FALSE;
        !          4604:                 share_irq = TRUE;
        !          4605: #endif /* CONFIG_PCI */
        !          4606: #endif /* version >= v2.1.93 */ 
        !          4607:             }
        !          4608: 
        !          4609:             /*
        !          4610:              * Read the board configuration.
        !          4611:              */
        !          4612:             if (ASC_NARROW_BOARD(boardp)) {
        !          4613:                  /*
        !          4614:                   * NOTE: AscInitGetConfig() may change the board's
        !          4615:                   * bus_type value. The asc_bus[bus] value should no
        !          4616:                   * longer be used. If the bus_type field must be
        !          4617:                   * referenced only use the bit-wise AND operator "&".
        !          4618:                   */
        !          4619:                  ASC_DBG(2, "advansys_detect: AscInitGetConfig()\n");
        !          4620:                 switch(ret = AscInitGetConfig(asc_dvc_varp)) {
        !          4621:                 case 0:    /* No error */
        !          4622:                     break;
        !          4623:                 case ASC_WARN_IO_PORT_ROTATE:
        !          4624:                     ASC_PRINT1(
        !          4625: "AscInitGetConfig: board %d: I/O port address modified\n",
        !          4626:                         boardp->id);
        !          4627:                     break;
        !          4628:                 case ASC_WARN_AUTO_CONFIG:
        !          4629:                     ASC_PRINT1(
        !          4630: "AscInitGetConfig: board %d: I/O port increment switch enabled\n",
        !          4631:                         boardp->id);
        !          4632:                     break;
        !          4633:                 case ASC_WARN_EEPROM_CHKSUM:
        !          4634:                     ASC_PRINT1(
        !          4635: "AscInitGetConfig: board %d: EEPROM checksum error\n",
        !          4636:                         boardp->id);
        !          4637:                     break;
        !          4638:                 case ASC_WARN_IRQ_MODIFIED:
        !          4639:                     ASC_PRINT1(
        !          4640: "AscInitGetConfig: board %d: IRQ modified\n",
        !          4641:                         boardp->id);
        !          4642:                     break;
        !          4643:                 case ASC_WARN_CMD_QNG_CONFLICT:
        !          4644:                     ASC_PRINT1(
        !          4645: "AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
        !          4646:                         boardp->id);
        !          4647:                     break;
        !          4648:                 default:
        !          4649:                     ASC_PRINT2(
        !          4650: "AscInitGetConfig: board %d: unknown warning: %x\n",
        !          4651:                         boardp->id, ret);
        !          4652:                     break;
        !          4653:                 }
        !          4654:                 if ((err_code = asc_dvc_varp->err_code) != 0) {
        !          4655:                     ASC_PRINT3(
        !          4656: "AscInitGetConfig: board %d error: init_state %x, err_code %x\n",
        !          4657:                         boardp->id, asc_dvc_varp->init_state,
        !          4658:                         asc_dvc_varp->err_code);
        !          4659:                 }
        !          4660:             } else {
        !          4661:                 ASC_DBG(2, "advansys_detect: AdvInitGetConfig()\n");
        !          4662:                 if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
        !          4663:                     ASC_PRINT2("AdvInitGetConfig: board %d: warning: %x\n",
        !          4664:                         boardp->id, ret);
        !          4665:                 }
        !          4666:                 if ((err_code = adv_dvc_varp->err_code) != 0) {
        !          4667:                     ASC_PRINT2(
        !          4668: "AdvInitGetConfig: board %d error: err_code %x\n",
        !          4669:                         boardp->id, adv_dvc_varp->err_code);
        !          4670:                 }
        !          4671:             }
        !          4672:         
        !          4673:             if (err_code != 0) {
        !          4674: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
        !          4675:                 kfree(boardp->prtbuf);
        !          4676: #endif /* version >= v1.3.0 */
        !          4677:                 scsi_unregister(shp);
        !          4678:                 asc_board_count--;
        !          4679:                 continue;
        !          4680:             }
        !          4681: 
        !          4682:             /*
        !          4683:              * Save the EEPROM configuration so that it can be displayed
        !          4684:              * from /proc/scsi/advansys/[0...].
        !          4685:              */
        !          4686:             if (ASC_NARROW_BOARD(boardp)) {
        !          4687: 
        !          4688:                 ASCEEP_CONFIG *ep;
        !          4689: 
        !          4690:                 /*
        !          4691:                  * Set the adapter's target id bit in the 'init_tidmask' field.
        !          4692:                  */
        !          4693:                 boardp->init_tidmask |=
        !          4694:                     ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
        !          4695: 
        !          4696:                 /*
        !          4697:                  * Save EEPROM settings for the board.
        !          4698:                  */
        !          4699:                 ep = &boardp->eep_config.asc_eep;
        !          4700: 
        !          4701:                 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
        !          4702:                 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
        !          4703:                 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
        !          4704:                 ep->isa_dma_speed = asc_dvc_varp->cfg->isa_dma_speed;
        !          4705:                 ep->start_motor = asc_dvc_varp->start_motor;
        !          4706:                 ep->cntl = asc_dvc_varp->dvc_cntl;
        !          4707:                 ep->no_scam = asc_dvc_varp->no_scam;
        !          4708:                 ep->max_total_qng = asc_dvc_varp->max_total_qng;
        !          4709:                 ep->chip_scsi_id = asc_dvc_varp->cfg->chip_scsi_id;
        !          4710:                 /* 'max_tag_qng' is set to the same value for every device. */
        !          4711:                 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
        !          4712:                 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
        !          4713:                 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
        !          4714:                 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
        !          4715:                 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
        !          4716:                 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
        !          4717:                 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
        !          4718:                 ep->adapter_info[6] = asc_dvc_varp->cfg->adapter_info[6];
        !          4719: 
        !          4720:                /*
        !          4721:                 * Modify board configuration.
        !          4722:                 */
        !          4723:                 ASC_DBG(2, "advansys_detect: AscInitSetConfig()\n");
        !          4724:                 switch (ret = AscInitSetConfig(asc_dvc_varp)) {
        !          4725:                 case 0:    /* No error. */
        !          4726:                     break;
        !          4727:                 case ASC_WARN_IO_PORT_ROTATE:
        !          4728:                     ASC_PRINT1(
        !          4729: "AscInitSetConfig: board %d: I/O port address modified\n",
        !          4730:                         boardp->id);
        !          4731:                     break;
        !          4732:                 case ASC_WARN_AUTO_CONFIG:
        !          4733:                     ASC_PRINT1(
        !          4734: "AscInitSetConfig: board %d: I/O port increment switch enabled\n",
        !          4735:                         boardp->id);
        !          4736:                     break;
        !          4737:                 case ASC_WARN_EEPROM_CHKSUM:
        !          4738:                     ASC_PRINT1(
        !          4739: "AscInitSetConfig: board %d: EEPROM checksum error\n",
        !          4740:                         boardp->id);
        !          4741:                     break;
        !          4742:                 case ASC_WARN_IRQ_MODIFIED:
        !          4743:                     ASC_PRINT1(
        !          4744: "AscInitSetConfig: board %d: IRQ modified\n",
        !          4745:                         boardp->id);
        !          4746:                     break;
        !          4747:                 case ASC_WARN_CMD_QNG_CONFLICT:
        !          4748:                     ASC_PRINT1(
        !          4749: "AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
        !          4750:                         boardp->id);
        !          4751:                     break;
        !          4752:                 default:
        !          4753:                     ASC_PRINT2(
        !          4754: "AscInitSetConfig: board %d: unknown warning: %x\n",
        !          4755:                         boardp->id, ret);
        !          4756:                     break;
        !          4757:                 }
        !          4758:                 if (asc_dvc_varp->err_code != 0) {
        !          4759:                     ASC_PRINT3(
        !          4760: "AscInitSetConfig: board %d error: init_state %x, err_code %x\n",
        !          4761:                         boardp->id, asc_dvc_varp->init_state,
        !          4762:                         asc_dvc_varp->err_code);
        !          4763: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
        !          4764:                     kfree(boardp->prtbuf);
        !          4765: #endif /* version >= v1.3.0 */
        !          4766:                     scsi_unregister(shp);
        !          4767:                     asc_board_count--;
        !          4768:                     continue;
        !          4769:                 }
        !          4770: 
        !          4771:                 /*
        !          4772:                  * Finish initializing the 'Scsi_Host' structure.
        !          4773:                  */
        !          4774:                 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
        !          4775:                 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
        !          4776:                     shp->irq = asc_dvc_varp->irq_no;
        !          4777:                 }
        !          4778:             } else {
        !          4779: 
        !          4780:                 ADVEEP_CONFIG *ep;
        !          4781: 
        !          4782:                 /*
        !          4783:                  * Save Wide EEP Configuration Information.
        !          4784:                  */
        !          4785:                 ep = &boardp->eep_config.adv_eep;
        !          4786: 
        !          4787:                 ep->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
        !          4788:                 ep->max_host_qng = adv_dvc_varp->max_host_qng;
        !          4789:                 ep->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
        !          4790:                 ep->termination = adv_dvc_varp->cfg->termination;
        !          4791:                 ep->disc_enable = adv_dvc_varp->cfg->disc_enable;
        !          4792:                 ep->bios_ctrl = adv_dvc_varp->bios_ctrl;
        !          4793:                 ep->wdtr_able = adv_dvc_varp->wdtr_able;
        !          4794:                 ep->sdtr_able = adv_dvc_varp->sdtr_able;
        !          4795:                 ep->ultra_able = adv_dvc_varp->ultra_able;
        !          4796:                 ep->tagqng_able = adv_dvc_varp->tagqng_able;
        !          4797:                 ep->start_motor = adv_dvc_varp->start_motor;
        !          4798:                 ep->scsi_reset_delay = adv_dvc_varp->scsi_reset_wait;
        !          4799:                 ep->bios_boot_delay = adv_dvc_varp->cfg->bios_boot_wait;
        !          4800:                 ep->serial_number_word1 = adv_dvc_varp->cfg->serial1;
        !          4801:                 ep->serial_number_word2 = adv_dvc_varp->cfg->serial2;
        !          4802:                 ep->serial_number_word3 = adv_dvc_varp->cfg->serial3;
        !          4803: 
        !          4804:                 /*
        !          4805:                  * Set the adapter's target id bit in the 'init_tidmask' field.
        !          4806:                  */
        !          4807:                 boardp->init_tidmask |=
        !          4808:                     ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
        !          4809: 
        !          4810:                 /*
        !          4811:                  * Finish initializing the 'Scsi_Host' structure.
        !          4812:                  */
        !          4813:                 shp->irq = adv_dvc_varp->irq_no;
        !          4814:             }
        !          4815: 
        !          4816: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
        !          4817:             /*
        !          4818:              * Channels are numbered beginning with 0. For AdvanSys One host
        !          4819:              * structure supports one channel. Multi-channel boards have a
        !          4820:              * separate host structure for each channel. 
        !          4821:              */
        !          4822:             shp->max_channel = 0;
        !          4823: #endif /* version >= v1.3.89 */
        !          4824:             if (ASC_NARROW_BOARD(boardp)) {
        !          4825:                 shp->max_id = ASC_MAX_TID + 1;
        !          4826:                 shp->max_lun = ASC_MAX_LUN + 1;
        !          4827: 
        !          4828:                 shp->io_port = asc_dvc_varp->iop_base;
        !          4829:                 shp->n_io_port = ASC_IOADR_GAP;
        !          4830:                 shp->this_id = asc_dvc_varp->cfg->chip_scsi_id;
        !          4831: 
        !          4832:                 /* Set maximum number of queues the adapter can handle. */
        !          4833:                 shp->can_queue = asc_dvc_varp->max_total_qng;
        !          4834:             } else {
        !          4835:                 shp->max_id = ADV_MAX_TID + 1;
        !          4836:                 shp->max_lun = ADV_MAX_LUN + 1;
        !          4837: 
        !          4838:                 /*
        !          4839:                  * Save the I/O Port address and length even though the
        !          4840:                  * in v1.3.0 and greater kernels the region is not used
        !          4841:                  * by a Wide board. Instead the board is accessed with
        !          4842:                  * Memory Mapped I/O.
        !          4843:                  */
        !          4844:                 shp->io_port = iop;
        !          4845:                 shp->n_io_port = ADV_CONDOR_IOLEN;
        !          4846: 
        !          4847:                 shp->this_id = adv_dvc_varp->chip_scsi_id;
        !          4848: 
        !          4849:                 /* Set maximum number of queues the adapter can handle. */
        !          4850:                 shp->can_queue = adv_dvc_varp->max_host_qng;
        !          4851:             }
        !          4852: 
        !          4853: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89)
        !          4854:             /*
        !          4855:              * In old kernels without tag queuing support and with memory
        !          4856:              * allocation problems set a conservative 'cmd_per_lun' value.
        !          4857:              */
        !          4858: #ifdef MODULE
        !          4859:             shp->cmd_per_lun = 1;
        !          4860: #else /* MODULE */
        !          4861:             shp->cmd_per_lun = 4;
        !          4862: #endif /* MODULE */
        !          4863:             ASC_DBG1(1, "advansys_detect: cmd_per_lun: %d\n", shp->cmd_per_lun);
        !          4864: #else /* version >= v1.3.89 */
        !          4865:             /*
        !          4866:              * Following v1.3.89, 'cmd_per_lun' is no longer needed
        !          4867:              * and should be set to zero.
        !          4868:              *
        !          4869:              * But because of a bug introduced in v1.3.89 if the driver is
        !          4870:              * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
        !          4871:              * SCSI function 'allocate_device' will panic. To allow the driver
        !          4872:              * to work as a module in these kernels set 'cmd_per_lun' to 1.
        !          4873:              */
        !          4874: #ifdef MODULE
        !          4875:             shp->cmd_per_lun = 1;
        !          4876: #else /* MODULE */
        !          4877:             shp->cmd_per_lun = 0;
        !          4878: #endif /* MODULE */
        !          4879:             /*
        !          4880:              * Use the host 'select_queue_depths' function to determine
        !          4881:              * the number of commands to queue per device.
        !          4882:              */
        !          4883:             shp->select_queue_depths = advansys_select_queue_depths;
        !          4884: #endif /* version >= v1.3.89 */
        !          4885: 
        !          4886:             /*
        !          4887:              * Set the maximum number of scatter-gather elements the
        !          4888:              * adapter can handle.
        !          4889:              */
        !          4890:             if (ASC_NARROW_BOARD(boardp)) {
        !          4891:                 /*
        !          4892:                  * Allow two commands with 'sg_tablesize' scatter-gather
        !          4893:                  * elements to be executed simultaneously. This value is
        !          4894:                  * the theoretical hardware limit. It may be decreased
        !          4895:                  * below.
        !          4896:                  */
        !          4897:                 shp->sg_tablesize =
        !          4898:                     (((asc_dvc_varp->max_total_qng - 2) / 2) *
        !          4899:                     ASC_SG_LIST_PER_Q) + 1;
        !          4900:             } else {
        !          4901:                 shp->sg_tablesize = ADV_MAX_SG_LIST;
        !          4902:             }
        !          4903: 
        !          4904: #ifdef MODULE
        !          4905:             /*
        !          4906:              * If the driver is compiled as a module, set a limit on the
        !          4907:              * 'sg_tablesize' value to prevent memory allocation failures.
        !          4908:              * Memory allocation errors are more likely to occur at module
        !          4909:              * load time, then at driver initialization time.
        !          4910:              */
        !          4911:             if (shp->sg_tablesize > 64) {
        !          4912:                 shp->sg_tablesize = 64;
        !          4913:             }
        !          4914: #endif /* MODULE */
        !          4915: 
        !          4916:             /*
        !          4917:              * The value of 'sg_tablesize' can not exceed the SCSI
        !          4918:              * mid-level driver definition of SG_ALL. SG_ALL also
        !          4919:              * must not be exceeded, because it is used to define the
        !          4920:              * size of the scatter-gather table in 'struct asc_sg_head'.
        !          4921:              */
        !          4922:             if (shp->sg_tablesize > SG_ALL) {
        !          4923:                 shp->sg_tablesize = SG_ALL;
        !          4924:             }
        !          4925: 
        !          4926:             ASC_DBG1(1, "advansys_detect: sg_tablesize: %d\n",
        !          4927:                 shp->sg_tablesize);
        !          4928: 
        !          4929:             /* BIOS start address. */
        !          4930:             if (ASC_NARROW_BOARD(boardp)) {
        !          4931:                 shp->base = (char *) ((ulong) AscGetChipBiosAddress(
        !          4932:                                                 asc_dvc_varp->iop_base,
        !          4933:                                                 asc_dvc_varp->bus_type));
        !          4934:             } else {
        !          4935:                 /*
        !          4936:                  * Fill-in BIOS board variables. The Wide BIOS saves
        !          4937:                  * information in LRAM that is used by the driver.
        !          4938:                  */
        !          4939:                 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_SIGNATURE,
        !          4940:                     boardp->bios_signature);
        !          4941:                 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_VERSION,
        !          4942:                     boardp->bios_version);
        !          4943:                 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODESEG,
        !          4944:                     boardp->bios_codeseg);
        !          4945:                 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODELEN,
        !          4946:                     boardp->bios_codelen);
        !          4947: 
        !          4948:                 ASC_DBG2(1,
        !          4949:                     "advansys_detect: bios_signature %x, bios_version %x\n",
        !          4950:                     boardp->bios_signature, boardp->bios_version);
        !          4951: 
        !          4952:                 ASC_DBG2(1,
        !          4953:                     "advansys_detect: bios_codeseg %x, bios_codelen %x\n",
        !          4954:                     boardp->bios_codeseg, boardp->bios_codelen);
        !          4955: 
        !          4956:                 /*
        !          4957:                  * If the BIOS saved a valid signature, then fill in
        !          4958:                  * the BIOS code segment base address.
        !          4959:                  */
        !          4960:                 if (boardp->bios_signature == 0x55AA) {
        !          4961:                     /*
        !          4962:                      * Convert x86 realmode code segment to a linear
        !          4963:                      * address by shifting left 4.
        !          4964:                      */
        !          4965:                     shp->base = (uchar *) (boardp->bios_codeseg << 4);
        !          4966:                 } else {
        !          4967:                     shp->base = 0;
        !          4968:                 }
        !          4969:             }
        !          4970: 
        !          4971:             /*
        !          4972:              * Register Board Resources - I/O Port, DMA, IRQ
        !          4973:              */
        !          4974: 
        !          4975:             /* Register I/O port range. */
        !          4976:             ASC_DBG(2, "advansys_detect: request_region()\n");
        !          4977:             request_region(shp->io_port, shp->n_io_port, "advansys");
        !          4978: 
        !          4979:             /* Register DMA Channel for Narrow boards. */
        !          4980:             shp->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
        !          4981:             if (ASC_NARROW_BOARD(boardp)) {
        !          4982:                 /* Register DMA channel for ISA bus. */
        !          4983:                 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
        !          4984:                     shp->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
        !          4985:                     if ((ret =
        !          4986:                          request_dma(shp->dma_channel, "advansys")) != 0) {
        !          4987:                         ASC_PRINT3(
        !          4988: "advansys_detect: board %d: request_dma() %d failed %d\n",
        !          4989:                             boardp->id, shp->dma_channel, ret);
        !          4990:                         release_region(shp->io_port, shp->n_io_port);
        !          4991: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
        !          4992:                         kfree(boardp->prtbuf);
        !          4993: #endif /* version >= v1.3.0 */
        !          4994:                         scsi_unregister(shp);
        !          4995:                         asc_board_count--;
        !          4996:                         continue;
        !          4997:                     }
        !          4998:                     AscEnableIsaDma(shp->dma_channel);
        !          4999:                 }
        !          5000:             }
        !          5001: 
        !          5002:             /* Register IRQ Number. */
        !          5003:             ASC_DBG1(2, "advansys_detect: request_irq() %d\n", shp->irq);
        !          5004: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
        !          5005:             if ((ret = request_irq(shp->irq, advansys_interrupt,
        !          5006:                             SA_INTERRUPT, "advansys")) != 0)
        !          5007: #else /* version >= v1.3.70 */
        !          5008:            /*
        !          5009:             * If request_irq() fails with the SA_INTERRUPT flag set,
        !          5010:             * then try again without the SA_INTERRUPT flag set. This
        !          5011:             * allows IRQ sharing to work even with other drivers that
        !          5012:             * do not set the SA_INTERRUPT flag.
        !          5013:             *
        !          5014:             * If SA_INTERRUPT is not set, then interrupts are enabled
        !          5015:             * before the driver interrupt function is called.
        !          5016:             */
        !          5017:             if (((ret = request_irq(shp->irq, advansys_interrupt,
        !          5018:                             SA_INTERRUPT | (share_irq == TRUE ? SA_SHIRQ : 0),
        !          5019:                             "advansys", boardp)) != 0) &&
        !          5020:                 ((ret = request_irq(shp->irq, advansys_interrupt,
        !          5021:                             (share_irq == TRUE ? SA_SHIRQ : 0),
        !          5022:                             "advansys", boardp)) != 0))
        !          5023: #endif /* version >= v1.3.70 */
        !          5024:             {
        !          5025:                 if (ret == -EBUSY) {
        !          5026:                     ASC_PRINT2(
        !          5027: "advansys_detect: board %d: request_irq(): IRQ %d already in use.\n",
        !          5028:                         boardp->id, shp->irq);
        !          5029:                 } else if (ret == -EINVAL) {
        !          5030:                     ASC_PRINT2(
        !          5031: "advansys_detect: board %d: request_irq(): IRQ %d not valid.\n",
        !          5032:                         boardp->id, shp->irq);
        !          5033:                 } else {
        !          5034:                     ASC_PRINT3(
        !          5035: "advansys_detect: board %d: request_irq(): IRQ %d failed with %d\n",
        !          5036:                         boardp->id, shp->irq, ret);
        !          5037:                 }
        !          5038:                 release_region(shp->io_port, shp->n_io_port);
        !          5039: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
        !          5040:                 iounmap(boardp->ioremap_addr);
        !          5041: #endif /* version >= v1,3,0 */
        !          5042:                 if (shp->dma_channel != NO_ISA_DMA) {
        !          5043:                     free_dma(shp->dma_channel);
        !          5044:                 }
        !          5045: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
        !          5046:                 kfree(boardp->prtbuf);
        !          5047: #endif /* version >= v1.3.0 */
        !          5048:                 scsi_unregister(shp);
        !          5049:                 asc_board_count--;
        !          5050:                 continue;
        !          5051:             }
        !          5052: 
        !          5053:             /*
        !          5054:              * Initialize board RISC chip and enable interrupts.
        !          5055:              */
        !          5056:             if (ASC_NARROW_BOARD(boardp)) {
        !          5057:                 ASC_DBG(2, "advansys_detect: AscInitAsc1000Driver()\n");
        !          5058:                 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
        !          5059:                 err_code = asc_dvc_varp->err_code;
        !          5060: 
        !          5061:                 if (warn_code || err_code) {
        !          5062:                     ASC_PRINT4(
        !          5063: "AscInitAsc1000Driver: board %d: error: init_state %x, warn %x error %x\n",
        !          5064:                         boardp->id, asc_dvc_varp->init_state,
        !          5065:                         warn_code, err_code);
        !          5066:                 }
        !          5067:             } else {
        !          5068:                 int             req_cnt;
        !          5069:                 adv_req_t       *reqp = NULL;
        !          5070:                 int             sg_cnt;
        !          5071:                 adv_sgblk_t     *sgp = NULL;
        !          5072: 
        !          5073: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
        !          5074:                 req_cnt = sizeof(adv_req_buf)/sizeof(adv_req_t);
        !          5075:                 sg_cnt = sizeof(adv_sgblk_buf)/sizeof(adv_sgblk_t);
        !          5076:                 reqp = (adv_req_t *) &adv_req_buf[0];
        !          5077:                 sgp = (adv_sgblk_t *) &adv_sgblk_buf[0];
        !          5078: #else /* version >= v1.3.0 */
        !          5079:                 /*
        !          5080:                  * Allocate up to 'max_host_qng' request structures for
        !          5081:                  * the Wide board.
        !          5082:                  */
        !          5083:                 for (req_cnt = adv_dvc_varp->max_host_qng;
        !          5084:                     req_cnt > 0; req_cnt--) {
        !          5085: 
        !          5086:                     reqp = (adv_req_t *)
        !          5087:                         kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC);
        !          5088: 
        !          5089:                     ASC_DBG3(1,
        !          5090:                         "advansys_detect: reqp %x, req_cnt %d, bytes %d\n",
        !          5091:                         (unsigned) reqp, req_cnt, sizeof(adv_req_t) * req_cnt);
        !          5092: 
        !          5093:                     if (reqp != NULL) {
        !          5094:                         break;
        !          5095:                     }
        !          5096:                 }
        !          5097: 
        !          5098:                 /*
        !          5099:                  * Allocate up to ADV_TOT_SG_LIST request structures for
        !          5100:                  * the Wide board.
        !          5101:                  */
        !          5102:                 for (sg_cnt = ADV_TOT_SG_LIST; sg_cnt > 0; sg_cnt--) {
        !          5103: 
        !          5104:                     sgp = (adv_sgblk_t *)
        !          5105:                         kmalloc(sizeof(adv_sgblk_t) * sg_cnt, GFP_ATOMIC);
        !          5106: 
        !          5107:                     ASC_DBG3(1,
        !          5108:                         "advansys_detect: sgp %x, sg_cnt %d, bytes %d\n",
        !          5109:                         (unsigned) sgp, sg_cnt, sizeof(adv_sgblk_t) * sg_cnt);
        !          5110: 
        !          5111:                     if (sgp != NULL) {
        !          5112:                         break;
        !          5113:                     }
        !          5114:                 }
        !          5115: #endif /* version >= v1.3.0 */
        !          5116: 
        !          5117:                 /*
        !          5118:                  * If no request structures or scatter-gather structures could
        !          5119:                  * be allocated, then return an error. Otherwise continue with
        !          5120:                  * initialization.
        !          5121:                  */
        !          5122:                 if (reqp == NULL) {
        !          5123:                     ASC_PRINT1(
        !          5124: "advansys_detect: board %d: error: failed to kmalloc() adv_req_t buffer.\n",
        !          5125:                         boardp->id);
        !          5126:                     err_code = ADV_ERROR;
        !          5127:                 } else if (sgp == NULL) {
        !          5128:                     kfree(reqp);
        !          5129:                     ASC_PRINT1(
        !          5130: "advansys_detect: board %d: error: failed to kmalloc() adv_sgblk_t buffer.\n",
        !          5131:                         boardp->id);
        !          5132:                     err_code = ADV_ERROR;
        !          5133:                 } else {
        !          5134:                     
        !          5135:                     /*
        !          5136:                      * Save original pointer for kfree() in case the
        !          5137:                      * driver is built as a module and can be unloaded.
        !          5138:                      */
        !          5139:                     boardp->orig_reqp = reqp;
        !          5140: 
        !          5141:                     /*
        !          5142:                      * Point 'adv_reqp' to the request structures and
        !          5143:                      * link them together.
        !          5144:                      */
        !          5145:                     req_cnt--;
        !          5146:                     reqp[req_cnt].next_reqp = NULL;
        !          5147:                     for (; req_cnt > 0; req_cnt--) {
        !          5148:                         reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
        !          5149:                     }
        !          5150:                     boardp->adv_reqp = &reqp[0];
        !          5151: 
        !          5152:                     /*
        !          5153:                      * Save original pointer for kfree() in case the
        !          5154:                      * driver is built as a module and can be unloaded.
        !          5155:                      */
        !          5156:                     boardp->orig_sgblkp = sgp;
        !          5157: 
        !          5158:                     /*
        !          5159:                      * Point 'adv_sgblkp' to the request structures and
        !          5160:                      * link them together.
        !          5161:                      */
        !          5162:                     sg_cnt--;
        !          5163:                     sgp[sg_cnt].next_sgblkp = NULL;
        !          5164:                     for (; sg_cnt > 0; sg_cnt--) {
        !          5165:                         sgp[sg_cnt - 1].next_sgblkp = &sgp[sg_cnt];
        !          5166:                     }
        !          5167:                     boardp->adv_sgblkp = &sgp[0];
        !          5168: 
        !          5169:                     ASC_DBG(2, "advansys_detect: AdvInitAsc3550Driver()\n");
        !          5170:                     warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
        !          5171:                     err_code = adv_dvc_varp->err_code;
        !          5172: 
        !          5173:                     if (warn_code || err_code) {
        !          5174:                         ASC_PRINT3(
        !          5175: "AdvInitAsc3550Driver: board %d: error: warn %x, error %x\n",
        !          5176:                             boardp->id, warn_code, adv_dvc_varp->err_code);
        !          5177:                     }
        !          5178:                 }
        !          5179:             }
        !          5180: 
        !          5181:             if (err_code != 0) {
        !          5182:                 release_region(shp->io_port, shp->n_io_port);
        !          5183:                 if (ASC_WIDE_BOARD(boardp)) {
        !          5184: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
        !          5185:                     iounmap(boardp->ioremap_addr);
        !          5186: #endif /* version >= v1,3,0 */
        !          5187:                     if (boardp->orig_reqp) {
        !          5188:                         kfree(boardp->orig_reqp);
        !          5189:                         boardp->orig_reqp = boardp->adv_reqp = NULL;
        !          5190:                     }
        !          5191:                     if (boardp->orig_sgblkp) {
        !          5192:                         kfree(boardp->orig_sgblkp);
        !          5193:                         boardp->orig_sgblkp = boardp->adv_sgblkp = NULL;
        !          5194:                     }
        !          5195:                 }
        !          5196:                 if (shp->dma_channel != NO_ISA_DMA) {
        !          5197:                     free_dma(shp->dma_channel);
        !          5198:                 }
        !          5199: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
        !          5200:                 kfree(boardp->prtbuf);
        !          5201: #endif /* version >= v1.3.0 */
        !          5202: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
        !          5203:                 free_irq(shp->irq);
        !          5204: #else /* version >= v1.3.70 */
        !          5205:                 free_irq(shp->irq, boardp);
        !          5206: #endif /* version >= v1.3.70 */
        !          5207:                 scsi_unregister(shp);
        !          5208:                 asc_board_count--;
        !          5209:                 continue;
        !          5210:             }
        !          5211:             ASC_DBG_PRT_SCSI_HOST(2, shp);
        !          5212:         }
        !          5213:     }
        !          5214:     ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n", asc_board_count);
        !          5215:     return asc_board_count;
        !          5216: }
        !          5217: 
        !          5218: /*
        !          5219:  * advansys_release()
        !          5220:  *
        !          5221:  * Release resources allocated for a single AdvanSys adapter.
        !          5222:  */
        !          5223: int
        !          5224: advansys_release(struct Scsi_Host *shp)
        !          5225: {
        !          5226:     asc_board_t    *boardp;
        !          5227: 
        !          5228:     ASC_DBG(1, "advansys_release: begin\n");
        !          5229:     boardp = ASC_BOARDP(shp);
        !          5230: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
        !          5231:     free_irq(shp->irq);
        !          5232: #else /* version >= v1.3.70 */
        !          5233:     free_irq(shp->irq, boardp);
        !          5234: #endif /* version >= v1.3.70 */
        !          5235:     if (shp->dma_channel != NO_ISA_DMA) {
        !          5236:         ASC_DBG(1, "advansys_release: free_dma()\n");
        !          5237:         free_dma(shp->dma_channel);
        !          5238:     }
        !          5239:     release_region(shp->io_port, shp->n_io_port);
        !          5240:     if (ASC_WIDE_BOARD(boardp)) {
        !          5241: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
        !          5242:         iounmap(boardp->ioremap_addr);
        !          5243: #endif /* version >= v1,3,0 */
        !          5244:         if (boardp->orig_reqp) {
        !          5245:             kfree(boardp->orig_reqp);
        !          5246:             boardp->orig_reqp = boardp->adv_reqp = NULL;
        !          5247:         }
        !          5248:         if (boardp->orig_sgblkp) {
        !          5249:             kfree(boardp->orig_sgblkp);
        !          5250:             boardp->orig_sgblkp = boardp->adv_sgblkp = NULL;
        !          5251:         }
        !          5252:     }
        !          5253: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
        !          5254:     ASC_ASSERT(boardp->prtbuf != NULL);
        !          5255:     kfree(boardp->prtbuf);
        !          5256: #endif /* version >= v1.3.0 */
        !          5257:     scsi_unregister(shp);
        !          5258:     ASC_DBG(1, "advansys_release: end\n");
        !          5259:     return 0;
        !          5260: }
        !          5261: 
        !          5262: /*
        !          5263:  * advansys_info()
        !          5264:  *
        !          5265:  * Return suitable for printing on the console with the argument
        !          5266:  * adapter's configuration information.
        !          5267:  *
        !          5268:  * Note: The information line should not exceed ASC_INFO_SIZE bytes,
        !          5269:  * otherwise the static 'info' array will be overrun.
        !          5270:  */
        !          5271: const char *
        !          5272: advansys_info(struct Scsi_Host *shp)
        !          5273: {
        !          5274:     static char     info[ASC_INFO_SIZE];
        !          5275:     asc_board_t     *boardp;
        !          5276:     ASC_DVC_VAR     *asc_dvc_varp;
        !          5277:     ADV_DVC_VAR     *adv_dvc_varp;
        !          5278:     char            *busname;
        !          5279: 
        !          5280:     boardp = ASC_BOARDP(shp);
        !          5281:     if (ASC_NARROW_BOARD(boardp)) {
        !          5282:         asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
        !          5283:         ASC_DBG(1, "advansys_info: begin\n");
        !          5284:         if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
        !          5285:             if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) == ASC_IS_ISAPNP) {
        !          5286:                 busname = "ISA PnP";
        !          5287:             } else {
        !          5288:                 busname = "ISA";
        !          5289:             }
        !          5290:             sprintf(info,
        !          5291: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,92)
        !          5292: "AdvanSys SCSI %s: %s %u CDB: BIOS %X, IO %X/%X, IRQ %u, DMA %u",
        !          5293: #else /* version >= v2.1.92 */ 
        !          5294: "AdvanSys SCSI %s: %s %u CDB: BIOS %X, IO %lX/%X, IRQ %u, DMA %u",
        !          5295: #endif /* version >= v2.1.92 */ 
        !          5296:                 ASC_VERSION, busname, asc_dvc_varp->max_total_qng,
        !          5297:                 (unsigned) shp->base,
        !          5298:                 shp->io_port, shp->n_io_port - 1,
        !          5299:                 shp->irq, shp->dma_channel);
        !          5300:         } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
        !          5301:             if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
        !          5302:                 == ASC_IS_PCI_ULTRA) {
        !          5303:                 busname = "PCI Ultra";
        !          5304:             } else {
        !          5305:                 busname = "PCI";
        !          5306:             }
        !          5307:             sprintf(info,
        !          5308: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,92)
        !          5309:                 "AdvanSys SCSI %s: %s %u CDB: IO %X/%X, IRQ %u",
        !          5310: #else /* version >= v2.1.92 */ 
        !          5311:                 "AdvanSys SCSI %s: %s %u CDB: IO %lX/%X, IRQ %u",
        !          5312: #endif /* version >= v2.1.92 */ 
        !          5313:                 ASC_VERSION, busname, asc_dvc_varp->max_total_qng,
        !          5314:                 shp->io_port, shp->n_io_port - 1, shp->irq);
        !          5315:         } else {
        !          5316:             if (asc_dvc_varp->bus_type & ASC_IS_VL) {
        !          5317:                 busname = "VL";
        !          5318:             } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
        !          5319:                 busname = "EISA";
        !          5320:             } else {
        !          5321:                 busname = "?";
        !          5322:                 ASC_PRINT2(
        !          5323:     "advansys_info: board %d: unknown bus type %d\n",
        !          5324:                     boardp->id, asc_dvc_varp->bus_type);
        !          5325:             }
        !          5326:             sprintf(info,
        !          5327: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,92)
        !          5328:                 "AdvanSys SCSI %s: %s %u CDB: BIOS %X, IO %X/%X, IRQ %u",
        !          5329: #else /* version >= v2.1.92 */ 
        !          5330:                 "AdvanSys SCSI %s: %s %u CDB: BIOS %X, IO %lX/%X, IRQ %u",
        !          5331: #endif /* version >= v2.1.92 */ 
        !          5332:                 ASC_VERSION, busname, asc_dvc_varp->max_total_qng,
        !          5333:                 (unsigned) shp->base, shp->io_port - 1,
        !          5334:                 shp->n_io_port, shp->irq);
        !          5335:         }
        !          5336:     } else {
        !          5337:         /*
        !          5338:          * Wide Adapter Information
        !          5339:          *
        !          5340:          * Memory-mapped I/O is used instead of I/O space to access
        !          5341:          * the adapter, but display the I/O Port range. The Memory
        !          5342:          * I/O address is displayed through the driver /proc file.
        !          5343:          */
        !          5344:         adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
        !          5345:         if (boardp->bios_signature == 0x55AA) {
        !          5346:             sprintf(info,
        !          5347: "AdvanSys SCSI %s: PCI Ultra-Wide: BIOS %X/%X, IO %X/%X, IRQ %u",
        !          5348:                 ASC_VERSION,
        !          5349:                 boardp->bios_codeseg << 4,
        !          5350:                 boardp->bios_codelen > 0 ?
        !          5351:                 (boardp->bios_codelen << 9) - 1 : 0,
        !          5352:                 (unsigned) boardp->ioport, ADV_CONDOR_IOLEN - 1,
        !          5353:                 shp->irq);
        !          5354:         } else {
        !          5355:             sprintf(info,
        !          5356: "AdvanSys SCSI %s: PCI Ultra-Wide: IO %X/%X, IRQ %u",
        !          5357:                 ASC_VERSION,
        !          5358:                 (unsigned) boardp->ioport,
        !          5359:                 (ADV_CONDOR_IOLEN - 1),
        !          5360:                 shp->irq);
        !          5361:         }
        !          5362:     }
        !          5363:     ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
        !          5364:     ASC_DBG(1, "advansys_info: end\n");
        !          5365:     return info;
        !          5366: }
        !          5367: 
        !          5368: /*
        !          5369:  * advansys_command() - polled I/O entrypoint.
        !          5370:  *
        !          5371:  * Apparently host drivers shouldn't return until the command
        !          5372:  * is finished.
        !          5373:  *
        !          5374:  * Note: This is an old interface that is no longer used by the SCSI
        !          5375:  * mid-level driver. The new interface, advansys_queuecommand(),
        !          5376:  * currently handles all requests.
        !          5377:  */
        !          5378: int
        !          5379: advansys_command(Scsi_Cmnd *scp)
        !          5380: {
        !          5381:     ASC_DBG1(1, "advansys_command: scp %x\n", (unsigned) scp);
        !          5382:     ASC_STATS(scp->host, command);
        !          5383:     scp->SCp.Status = 0; /* Set to a known state */
        !          5384:     advansys_queuecommand(scp, advansys_command_done);
        !          5385:     while (scp->SCp.Status == 0) {
        !          5386:         continue;
        !          5387:     }
        !          5388:     ASC_DBG1(1, "advansys_command: result %x\n", scp->result);
        !          5389:     return scp->result;
        !          5390: }
        !          5391: 
        !          5392: /*
        !          5393:  * advansys_queuecommand() - interrupt-driven I/O entrypoint.
        !          5394:  *
        !          5395:  * This function always returns 0. Command return status is saved
        !          5396:  * in the 'scp' result field.
        !          5397:  */
        !          5398: int
        !          5399: advansys_queuecommand(Scsi_Cmnd *scp, void (*done)(Scsi_Cmnd *))
        !          5400: {
        !          5401:     struct Scsi_Host    *shp;
        !          5402:     asc_board_t         *boardp;
        !          5403:     int                 flags;
        !          5404:     Scsi_Cmnd           *done_scp;
        !          5405: 
        !          5406:     shp = scp->host;
        !          5407:     boardp = ASC_BOARDP(shp);
        !          5408:     ASC_STATS(shp, queuecommand);
        !          5409: 
        !          5410:     /*
        !          5411:      * Disable interrupts to preserve request ordering and provide
        !          5412:      * mutually exclusive access to global structures used to initiate
        !          5413:      * a request.
        !          5414:      */
        !          5415:     save_flags(flags);
        !          5416:     cli();
        !          5417: 
        !          5418:     /*
        !          5419:      * Block new commands while handling a reset or abort request.
        !          5420:      */
        !          5421:     if (boardp->flags & (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) {
        !          5422:         if (boardp->flags & ASC_HOST_IN_RESET) {
        !          5423:             ASC_DBG1(1,
        !          5424:                 "advansys_queuecommand: scp %x blocked for reset request\n",
        !          5425:                 (unsigned) scp);
        !          5426:             scp->result = HOST_BYTE(DID_RESET);
        !          5427:         } else {
        !          5428:             ASC_DBG1(1,
        !          5429:                 "advansys_queuecommand: scp %x blocked for abort request\n",
        !          5430:                 (unsigned) scp);
        !          5431:             scp->result = HOST_BYTE(DID_ABORT);
        !          5432:         }
        !          5433: 
        !          5434:         /*
        !          5435:          * Add blocked requests to the board's 'done' queue. The queued
        !          5436:          * requests will be completed at the end of the abort or reset
        !          5437:          * handling.
        !          5438:          */
        !          5439:         asc_enqueue(&boardp->done, scp, ASC_BACK);
        !          5440:         restore_flags(flags);
        !          5441:         return 0;
        !          5442:     }
        !          5443: 
        !          5444:     /*
        !          5445:      * Attempt to execute any waiting commands for the board.
        !          5446:      */
        !          5447:     if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
        !          5448:         ASC_DBG(1,
        !          5449:             "advansys_queuecommand: before asc_execute_queue() waiting\n");
        !          5450:         asc_execute_queue(&boardp->waiting);
        !          5451:     }
        !          5452: 
        !          5453:     /*
        !          5454:      * Save the function pointer to Linux mid-level 'done' function
        !          5455:      * and attempt to execute the command.
        !          5456:      *
        !          5457:      * If ASC_ERROR is returned the request has been added to the
        !          5458:      * board's 'active' queue and will be completed by the interrupt
        !          5459:      * handler.
        !          5460:      *
        !          5461:      * If ASC_BUSY is returned add the request to the board's per
        !          5462:      * target waiting list.
        !          5463:      * 
        !          5464:      * If an error occurred, the request will have been placed on the
        !          5465:      * board's 'done' queue and must be completed before returning.
        !          5466:      */
        !          5467:     scp->scsi_done = done;
        !          5468:     switch (asc_execute_scsi_cmnd(scp)) {
        !          5469:     case ASC_NOERROR:
        !          5470:         break;
        !          5471:     case ASC_BUSY:
        !          5472:         asc_enqueue(&boardp->waiting, scp, ASC_BACK);
        !          5473:         break;
        !          5474:     case ASC_ERROR:
        !          5475:     default:
        !          5476:         done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
        !          5477:         /* Interrupts could be enabled here. */
        !          5478:         asc_scsi_done_list(done_scp);
        !          5479:         break;
        !          5480:     }
        !          5481: 
        !          5482:     restore_flags(flags);
        !          5483:     return 0;
        !          5484: }
        !          5485: 
        !          5486: /*
        !          5487:  * advansys_abort()
        !          5488:  *
        !          5489:  * Abort the command specified by 'scp'.
        !          5490:  */
        !          5491: int
        !          5492: advansys_abort(Scsi_Cmnd *scp)
        !          5493: {
        !          5494:     struct Scsi_Host    *shp;
        !          5495:     asc_board_t         *boardp;
        !          5496:     ASC_DVC_VAR         *asc_dvc_varp;
        !          5497:     ADV_DVC_VAR         *adv_dvc_varp;
        !          5498:     int                 flags;
        !          5499:     int                 do_scsi_done;
        !          5500:     int                 scp_found;
        !          5501:     Scsi_Cmnd           *done_scp = NULL;
        !          5502:     int                 ret;
        !          5503: 
        !          5504:     /* Save current flags and disable interrupts. */
        !          5505:     save_flags(flags);
        !          5506:     cli();
        !          5507: 
        !          5508:     ASC_DBG1(1, "advansys_abort: scp %x\n", (unsigned) scp);
        !          5509: 
        !          5510: #ifdef ADVANSYS_STATS
        !          5511:     if (scp->host != NULL) {
        !          5512:         ASC_STATS(scp->host, abort);
        !          5513:     }    
        !          5514: #endif /* ADVANSYS_STATS */
        !          5515: 
        !          5516: #ifdef ADVANSYS_ASSERT
        !          5517:     do_scsi_done = ASC_ERROR;
        !          5518:     scp_found = ASC_ERROR;
        !          5519:     ret = ASC_ERROR;
        !          5520: #endif /* ADVANSYS_ASSERT */
        !          5521: 
        !          5522: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
        !          5523:     if (scp->serial_number != scp->serial_number_at_timeout) {
        !          5524:         ASC_PRINT1(
        !          5525: "advansys_abort: timeout serial number changed for request %x\n",
        !          5526:             (unsigned) scp);
        !          5527:         do_scsi_done = ASC_FALSE;
        !          5528:         scp_found = ASC_FALSE;
        !          5529:         ret = SCSI_ABORT_NOT_RUNNING;
        !          5530:     } else
        !          5531: #endif /* version >= v1.3.89 */
        !          5532:     if ((shp = scp->host) == NULL) {
        !          5533:         scp->result = HOST_BYTE(DID_ERROR);
        !          5534:         do_scsi_done = ASC_TRUE;
        !          5535:         scp_found = ASC_FALSE;
        !          5536:         ret = SCSI_ABORT_ERROR;
        !          5537:     } else if ((boardp = ASC_BOARDP(shp))->flags & 
        !          5538:                 (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) {
        !          5539:         ASC_PRINT2(
        !          5540: "advansys_abort: board %d: Nested host reset or abort, flags 0x%x\n",
        !          5541:             boardp->id, boardp->flags);
        !          5542:         do_scsi_done = ASC_TRUE;
        !          5543:         if ((asc_rmqueue(&boardp->active, scp) == ASC_TRUE) ||
        !          5544:             (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE)) {
        !          5545:             scp_found = ASC_TRUE;
        !          5546:         } else {
        !          5547:             scp_found = ASC_FALSE;
        !          5548:         }
        !          5549:         scp->result = HOST_BYTE(DID_ERROR);
        !          5550:         ret = SCSI_ABORT_ERROR;
        !          5551:     } else {
        !          5552:         /* Set abort flag to avoid nested reset or abort requests. */
        !          5553:         boardp->flags |= ASC_HOST_IN_ABORT;
        !          5554: 
        !          5555:         do_scsi_done = ASC_TRUE;
        !          5556:         if (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE) {
        !          5557:             /*
        !          5558:              * If asc_rmqueue() found the command on the waiting
        !          5559:              * queue, it had not been sent to the device. After
        !          5560:              * the queue is removed, no other handling is required.
        !          5561:              */
        !          5562:             ASC_DBG1(1, "advansys_abort: scp %x found on waiting queue\n",
        !          5563:                 (unsigned) scp);
        !          5564:             scp_found = ASC_TRUE;
        !          5565:             scp->result = HOST_BYTE(DID_ABORT);
        !          5566:             ret = SCSI_ABORT_SUCCESS;
        !          5567:         } else if (asc_isqueued(&boardp->active, scp) == ASC_TRUE) {
        !          5568:             /*
        !          5569:              * If asc_isqueued() found the command on the active
        !          5570:              * queue, it has been sent to the device. The command
        !          5571:              * will be returned through the interrupt handler after
        !          5572:              * it has been aborted.
        !          5573:              */
        !          5574: 
        !          5575:             if (ASC_NARROW_BOARD(boardp)) {
        !          5576:                 /*
        !          5577:                  * Narrow Board
        !          5578:                  */
        !          5579:                 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
        !          5580:                 scp->result = HOST_BYTE(DID_ABORT);
        !          5581: 
        !          5582:                 sti(); /* Enable interrupts for AscAbortSRB(). */
        !          5583:                 ASC_DBG1(1, "advansys_abort: before AscAbortSRB(), scp %x\n",
        !          5584:                     (unsigned) scp);
        !          5585:                 switch (AscAbortSRB(asc_dvc_varp, (ulong) scp)) {
        !          5586:                 case ASC_TRUE:
        !          5587:                     /* asc_isr_callback() will be called */
        !          5588:                     ASC_DBG(1, "advansys_abort: AscAbortSRB() TRUE\n");
        !          5589:                     ret = SCSI_ABORT_PENDING;
        !          5590:                     break;
        !          5591:                 case ASC_FALSE:
        !          5592:                     /* Request has apparently already completed. */
        !          5593:                     ASC_DBG(1, "advansys_abort: AscAbortSRB() FALSE\n");
        !          5594:                     ret = SCSI_ABORT_NOT_RUNNING;
        !          5595:                     break;
        !          5596:                 case ASC_ERROR:
        !          5597:                 default:
        !          5598:                     ASC_DBG(1, "advansys_abort: AscAbortSRB() ERROR\n");
        !          5599:                     ret = SCSI_ABORT_ERROR;
        !          5600:                     break;
        !          5601:                 }
        !          5602:                 cli();
        !          5603:             } else {
        !          5604:                 /*
        !          5605:                  * Wide Board
        !          5606:                  */
        !          5607:                 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
        !          5608:                 scp->result = HOST_BYTE(DID_ABORT);
        !          5609: 
        !          5610:                 ASC_DBG1(1, "advansys_abort: before AdvAbortSRB(), scp %x\n",
        !          5611:                     (unsigned) scp);
        !          5612:                 switch (AdvAbortSRB(adv_dvc_varp, (ulong) scp)) {
        !          5613:                 case ASC_TRUE:
        !          5614:                     /* asc_isr_callback() will be called */
        !          5615:                     ASC_DBG(1, "advansys_abort: AdvAbortSRB() TRUE\n");
        !          5616:                     ret = SCSI_ABORT_PENDING;
        !          5617:                     break;
        !          5618:                 case ASC_FALSE:
        !          5619:                     /* Request has apparently already completed. */
        !          5620:                     ASC_DBG(1, "advansys_abort: AdvAbortSRB() FALSE\n");
        !          5621:                     ret = SCSI_ABORT_NOT_RUNNING;
        !          5622:                     break;
        !          5623:                 case ASC_ERROR:
        !          5624:                 default:
        !          5625:                     ASC_DBG(1, "advansys_abort: AdvAbortSRB() ERROR\n");
        !          5626:                     ret = SCSI_ABORT_ERROR;
        !          5627:                     break;
        !          5628:                 }
        !          5629:                 /*
        !          5630:                  * Ensure all requests completed by the microcode have
        !          5631:                  * been processed by calling AdvISR().
        !          5632:                  */
        !          5633:                 (void) AdvISR(adv_dvc_varp);
        !          5634:             }
        !          5635: 
        !          5636:             /*
        !          5637:              * The request will either still be on the active queue
        !          5638:              * or have been added to the board's done queue.
        !          5639:              */
        !          5640:             if (asc_rmqueue(&boardp->active, scp) == ASC_TRUE) {
        !          5641:                 scp->result = HOST_BYTE(DID_ABORT);
        !          5642:                 scp_found = ASC_TRUE;
        !          5643:             } else {
        !          5644:                 scp_found = asc_rmqueue(&boardp->done, scp);
        !          5645:                 ASC_ASSERT(scp_found == ASC_TRUE);
        !          5646:             }
        !          5647: 
        !          5648:         } else {
        !          5649:             /*
        !          5650:              * The command was not found on the active or waiting queues.
        !          5651:              */
        !          5652:             do_scsi_done = ASC_TRUE;
        !          5653:             scp_found = ASC_FALSE;
        !          5654:             ret = SCSI_ABORT_NOT_RUNNING;
        !          5655:         }
        !          5656: 
        !          5657:         /* Clear abort flag. */
        !          5658:         boardp->flags &= ~ASC_HOST_IN_ABORT;
        !          5659: 
        !          5660:         /*
        !          5661:          * Because the ASC_HOST_IN_ABORT flag causes both
        !          5662:          * 'advansys_interrupt' and 'asc_isr_callback' to
        !          5663:          * queue requests to the board's 'done' queue and
        !          5664:          * prevents waiting commands from being executed,
        !          5665:          * these queued requests must be handled here.
        !          5666:          */
        !          5667:         done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
        !          5668: 
        !          5669:         /*
        !          5670:          * Start any waiting commands for the board.
        !          5671:          */
        !          5672:         if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
        !          5673:             ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
        !          5674:             asc_execute_queue(&boardp->waiting);
        !          5675:         }
        !          5676:     }
        !          5677: 
        !          5678:     /* Interrupts could be enabled here. */
        !          5679: 
        !          5680:     /*
        !          5681:      * Complete the request to be aborted, unless it has been
        !          5682:      * restarted as detected above, even if it was not found on
        !          5683:      * the device active or waiting queues.
        !          5684:      */
        !          5685:     ASC_ASSERT(do_scsi_done != ASC_ERROR);
        !          5686:     ASC_ASSERT(scp_found != ASC_ERROR);
        !          5687:     if (do_scsi_done == ASC_TRUE) {
        !          5688:         if (scp->scsi_done == NULL) {
        !          5689:             ASC_PRINT1(
        !          5690: "advansys_abort: aborted request scsi_done() is NULL, %x\n",
        !          5691:                 (unsigned) scp);
        !          5692:         } else {
        !          5693:             if (scp_found == ASC_FALSE) {
        !          5694:                 ASC_PRINT1(
        !          5695: "advansys_abort: abort request not active or waiting, completing anyway %x\n",
        !          5696:                     (unsigned) scp);
        !          5697:             }
        !          5698:             ASC_STATS(scp->host, done);
        !          5699:             scp->scsi_done(scp);
        !          5700:         }
        !          5701:     }
        !          5702: 
        !          5703:     /*
        !          5704:      * It is possible for the request done function to re-enable
        !          5705:      * interrupts without confusing the driver. But here interrupts
        !          5706:      * aren't enabled until all requests have been completed.
        !          5707:      */
        !          5708:     if (done_scp != NULL) {
        !          5709:         asc_scsi_done_list(done_scp);
        !          5710:     }
        !          5711: 
        !          5712:     ASC_DBG1(1, "advansys_abort: ret %d\n", ret);
        !          5713: 
        !          5714:     /* Re-enable interrupts, if they were enabled on entry. */
        !          5715:     restore_flags(flags);
        !          5716: 
        !          5717:     ASC_ASSERT(ret != ASC_ERROR);
        !          5718:     return ret;
        !          5719: }
        !          5720: 
        !          5721: /*
        !          5722:  * advansys_reset()
        !          5723:  *
        !          5724:  * Reset the device associated with the command 'scp'.
        !          5725:  */
        !          5726: int
        !          5727: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89)
        !          5728: advansys_reset(Scsi_Cmnd *scp)
        !          5729: #else /* version >= v1.3.89 */
        !          5730: advansys_reset(Scsi_Cmnd *scp, unsigned int reset_flags)
        !          5731: #endif /* version >= v1.3.89 */
        !          5732: {
        !          5733:     struct Scsi_Host     *shp;
        !          5734:     asc_board_t          *boardp;
        !          5735:     ASC_DVC_VAR          *asc_dvc_varp;
        !          5736:     ADV_DVC_VAR          *adv_dvc_varp;
        !          5737:     int                  flags;
        !          5738:     Scsi_Cmnd            *done_scp = NULL, *last_scp = NULL;
        !          5739:     Scsi_Cmnd            *tscp, *new_last_scp;
        !          5740:     int                  do_scsi_done;
        !          5741:     int                  scp_found;
        !          5742:     int                  status;
        !          5743:     int                  target;
        !          5744:     int                  ret;
        !          5745:     int                  device_reset = ASC_FALSE;
        !          5746: 
        !          5747:     /* Save current flags and disable interrupts. */
        !          5748:     save_flags(flags);
        !          5749:     cli();
        !          5750: 
        !          5751:     ASC_DBG1(1, "advansys_reset: %x\n", (unsigned) scp);
        !          5752: 
        !          5753: #ifdef ADVANSYS_STATS
        !          5754:     if (scp->host != NULL) {
        !          5755:         ASC_STATS(scp->host, reset);
        !          5756:     }    
        !          5757: #endif /* ADVANSYS_STATS */
        !          5758: 
        !          5759: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
        !          5760:     if ((reset_flags & SCSI_RESET_ASYNCHRONOUS) &&
        !          5761:         (scp->serial_number != scp->serial_number_at_timeout)) {
        !          5762:         ASC_PRINT1(
        !          5763: "advansys_reset: timeout serial number changed for request %x\n",
        !          5764:             (unsigned) scp);
        !          5765:         do_scsi_done = ASC_FALSE;
        !          5766:         scp_found = ASC_FALSE;
        !          5767:         ret = SCSI_RESET_NOT_RUNNING;
        !          5768:     } else
        !          5769: #endif /* version >= v1.3.89 */
        !          5770:     if ((shp = scp->host) == NULL) {
        !          5771:         scp->result = HOST_BYTE(DID_ERROR);
        !          5772:         do_scsi_done = ASC_TRUE;
        !          5773:         scp_found = ASC_FALSE;
        !          5774:         ret = SCSI_RESET_ERROR;
        !          5775:     } else if ((boardp = ASC_BOARDP(shp))->flags & 
        !          5776:                 (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) {
        !          5777:         ASC_PRINT2(
        !          5778: "advansys_reset: board %d: Nested host reset or abort, flags 0x%x\n",
        !          5779:             boardp->id, boardp->flags);
        !          5780:         do_scsi_done = ASC_TRUE;
        !          5781:         if ((asc_rmqueue(&boardp->active, scp) == ASC_TRUE) ||
        !          5782:             (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE)) {
        !          5783:             scp_found = ASC_TRUE;
        !          5784:         } else {
        !          5785:             scp_found = ASC_FALSE;
        !          5786:         }
        !          5787:         scp->result = HOST_BYTE(DID_ERROR);
        !          5788:         ret = SCSI_RESET_ERROR;
        !          5789:     } else if (jiffies >= boardp->last_reset &&
        !          5790:                jiffies < (boardp->last_reset + (10 * HZ))) {
        !          5791:         /*
        !          5792:          * Don't allow a reset to be attempted within 10 seconds
        !          5793:          * of the last reset.
        !          5794:          *
        !          5795:          * If 'jiffies' wrapping occurs, the reset request will go
        !          5796:          * through, because a wrapped 'jiffies' would not pass the
        !          5797:          * test above.
        !          5798:          */
        !          5799:         ASC_DBG(1,
        !          5800:             "advansys_reset: reset within 10 sec of last reset ignored\n");
        !          5801:         do_scsi_done = ASC_TRUE;
        !          5802:         if ((asc_rmqueue(&boardp->active, scp) == ASC_TRUE) ||
        !          5803:             (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE)) {
        !          5804:             scp_found = ASC_TRUE;
        !          5805:         } else {
        !          5806:             scp_found = ASC_FALSE;
        !          5807:         }
        !          5808:         scp->result = HOST_BYTE(DID_ERROR);
        !          5809:         ret = SCSI_RESET_ERROR;
        !          5810:     } else {
        !          5811:         do_scsi_done = ASC_TRUE;
        !          5812: 
        !          5813:         /* Set reset flag to avoid nested reset or abort requests. */
        !          5814:         boardp->flags |= ASC_HOST_IN_RESET;
        !          5815: 
        !          5816:         /*
        !          5817:           * If the request is on the target waiting or active queue
        !          5818:          * or the board done queue, then remove it and note that it
        !          5819:          * was found.
        !          5820:          */
        !          5821:         if (asc_rmqueue(&boardp->active, scp) == ASC_TRUE) {
        !          5822:             ASC_DBG(1, "advansys_reset: active scp_found = TRUE\n");
        !          5823:             scp_found = ASC_TRUE;
        !          5824:         } else if (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE) {
        !          5825:             ASC_DBG(1, "advansys_reset: waiting scp_found = TRUE\n");
        !          5826:             scp_found = ASC_TRUE;
        !          5827:         } else if (asc_rmqueue(&boardp->done, scp) == ASC_TRUE) {
        !          5828:             scp_found = ASC_TRUE;
        !          5829:         } else {
        !          5830:             scp_found = ASC_FALSE;
        !          5831:         }
        !          5832: 
        !          5833: 
        !          5834:         if (ASC_NARROW_BOARD(boardp)) {
        !          5835:             /*
        !          5836:              * Narrow Board
        !          5837:              *
        !          5838:              * If the suggest reset bus flags are set, then reset the bus.
        !          5839:              * Otherwise only reset the device.
        !          5840:              */
        !          5841:             asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
        !          5842: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
        !          5843:             if (reset_flags &
        !          5844:                 (SCSI_RESET_SUGGEST_BUS_RESET |
        !          5845:                  SCSI_RESET_SUGGEST_HOST_RESET)) {
        !          5846: #endif /* version >= v1.3.89 */
        !          5847: 
        !          5848:                 /*
        !          5849:                  * Reset the target's SCSI bus.
        !          5850:                  */
        !          5851:                 ASC_DBG(1, "advansys_reset: before AscResetSB()\n");
        !          5852:                 sti();    /* Enable interrupts for AscResetSB(). */
        !          5853:                 status = AscResetSB(asc_dvc_varp);
        !          5854:                 cli();
        !          5855:                 switch (status) {
        !          5856:                 case ASC_TRUE:
        !          5857:                     ASC_DBG(1, "advansys_reset: AscResetSB() success\n");
        !          5858:                     ret = SCSI_RESET_SUCCESS;
        !          5859:                     break;
        !          5860:                 case ASC_ERROR:
        !          5861:                 default:
        !          5862:                     ASC_DBG(1, "advansys_reset: AscResetSB() failed\n");
        !          5863:                     ret = SCSI_RESET_ERROR;
        !          5864:                     break;
        !          5865:                 }
        !          5866: 
        !          5867: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
        !          5868:             } else {
        !          5869:                 /*
        !          5870:                  * Reset the specified device. If the device reset fails,
        !          5871:                  * then reset the SCSI bus.
        !          5872:                  */
        !          5873: 
        !          5874:                 ASC_DBG1(1,
        !          5875:                     "advansys_reset: before AscResetDevice(), target %d\n",
        !          5876:                     scp->target);
        !          5877:                 sti();    /* Enable interrupts for AscResetDevice(). */
        !          5878:                 status = AscResetDevice(asc_dvc_varp, scp->target);
        !          5879:                 cli();
        !          5880: 
        !          5881:                 switch (status) {
        !          5882:                 case ASC_TRUE:
        !          5883:                     ASC_DBG(1, "advansys_reset: AscResetDevice() success\n");
        !          5884:                     device_reset = ASC_TRUE;
        !          5885:                     ret = SCSI_RESET_SUCCESS;
        !          5886:                     break;
        !          5887:                 case ASC_ERROR:
        !          5888:                 default:
        !          5889:                     ASC_DBG(1,
        !          5890: "advansys_reset: AscResetDevice() failed; Calling AscResetSB()\n");
        !          5891:                     sti();    /* Enable interrupts for AscResetSB(). */
        !          5892:                     status = AscResetSB(asc_dvc_varp);
        !          5893:                     cli();
        !          5894:                     switch (status) {
        !          5895:                     case ASC_TRUE:
        !          5896:                         ASC_DBG(1, "advansys_reset: AscResetSB() TRUE\n");
        !          5897:                         ret = SCSI_RESET_SUCCESS;
        !          5898:                         break;
        !          5899:                     case ASC_ERROR:
        !          5900:                     default:
        !          5901:                         ASC_DBG(1, "advansys_reset: AscResetSB() ERROR\n");
        !          5902:                         ret = SCSI_RESET_ERROR;
        !          5903:                         break;
        !          5904:                     }
        !          5905:                     break;
        !          5906:                 }
        !          5907:             }
        !          5908: #endif /* version >= v1.3.89 */
        !          5909:         } else {
        !          5910:             /*
        !          5911:              * Wide Board
        !          5912:              *
        !          5913:              * If the suggest reset bus flags are set, then reset the bus.
        !          5914:              * Otherwise only reset the device.
        !          5915:              */
        !          5916:             adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
        !          5917: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
        !          5918:             if (reset_flags &
        !          5919:                 (SCSI_RESET_SUGGEST_BUS_RESET |
        !          5920:                  SCSI_RESET_SUGGEST_HOST_RESET)) {
        !          5921: #endif /* version >= v1.3.89 */
        !          5922: 
        !          5923:                 /*
        !          5924:                  * Reset the target's SCSI bus.
        !          5925:                  */
        !          5926:                 ASC_DBG(1, "advansys_reset: before AdvResetSB()\n");
        !          5927:                 switch (AdvResetSB(adv_dvc_varp)) {
        !          5928:                 case ASC_TRUE:
        !          5929:                     ASC_DBG(1, "advansys_reset: AdvResetSB() success\n");
        !          5930:                     ret = SCSI_RESET_SUCCESS;
        !          5931:                     break;
        !          5932:                 case ASC_FALSE:
        !          5933:                 default:
        !          5934:                     ASC_DBG(1, "advansys_reset: AdvResetSB() failed\n");
        !          5935:                     ret = SCSI_RESET_ERROR;
        !          5936:                     break;
        !          5937:                 }
        !          5938:                 /*
        !          5939:                  * Ensure all requests completed by the microcode have
        !          5940:                  * been processed by calling AdvISR().
        !          5941:                  */
        !          5942:                 (void) AdvISR(adv_dvc_varp);
        !          5943: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
        !          5944:             } else {
        !          5945:                 /*
        !          5946:                  * Reset the specified device. If the device reset fails,
        !          5947:                  * then reset the SCSI bus.
        !          5948:                  */
        !          5949: 
        !          5950:                 ASC_DBG1(1,
        !          5951:                     "advansys_reset: before AdvResetDevice(), target %d\n",
        !          5952:                     scp->target);
        !          5953:                 
        !          5954:                 switch (AdvResetDevice(adv_dvc_varp, scp->target)) {
        !          5955:                 case ASC_TRUE:
        !          5956:                     ASC_DBG(1, "advansys_reset: AdvResetDevice() success\n");
        !          5957:                     device_reset = ASC_TRUE;
        !          5958:                     ret = SCSI_RESET_SUCCESS;
        !          5959:                     break;
        !          5960:                 case ASC_FALSE:
        !          5961:                 default:
        !          5962:                     ASC_DBG(1,
        !          5963: "advansys_reset: AdvResetDevice() failed; Calling AdvResetSB()\n");
        !          5964:                     
        !          5965:                     switch (AdvResetSB(adv_dvc_varp)) {
        !          5966:                     case ASC_TRUE:
        !          5967:                         ASC_DBG(1, "advansys_reset: AdvResetSB() TRUE\n");
        !          5968:                         ret = SCSI_RESET_SUCCESS;
        !          5969:                         break;
        !          5970:                     case ASC_FALSE:
        !          5971:                     default:
        !          5972:                         ASC_DBG(1, "advansys_reset: AdvResetSB() ERROR\n");
        !          5973:                         ret = SCSI_RESET_ERROR;
        !          5974:                         break;
        !          5975:                     }
        !          5976:                     break;
        !          5977:                 }
        !          5978:                 /*
        !          5979:                  * Ensure all requests completed by the microcode have
        !          5980:                  * been processed by calling AdvISR().
        !          5981:                  */
        !          5982:                 (void) AdvISR(adv_dvc_varp);
        !          5983:             }
        !          5984: #endif /* version >= v1.3.89 */
        !          5985:         }
        !          5986: 
        !          5987:         /*
        !          5988:          * Because the ASC_HOST_IN_RESET flag causes both
        !          5989:          * 'advansys_interrupt' and 'asc_isr_callback' to
        !          5990:          * queue requests to the board's 'done' queue and
        !          5991:          * prevents waiting commands from being executed,
        !          5992:          * these queued requests must be handled here.
        !          5993:          */
        !          5994:         done_scp = asc_dequeue_list(&boardp->done, &last_scp,
        !          5995:                                     ASC_TID_ALL);
        !          5996: 
        !          5997:         /*
        !          5998:          * If a device reset was performed dequeue all waiting
        !          5999:          * and active requests for the device and set the request
        !          6000:          * status to DID_RESET.
        !          6001:          *
        !          6002:          * If a SCSI bus reset was performed dequeue all waiting
        !          6003:          * and active requests for all devices and set the request
        !          6004:          * status to DID_RESET.
        !          6005:          */
        !          6006:         if (device_reset == ASC_TRUE) {
        !          6007:             target = scp->target;
        !          6008:         } else {
        !          6009:             target = ASC_TID_ALL;
        !          6010:         }
        !          6011: 
        !          6012:         /*
        !          6013:          * Add active requests to 'done_scp' and set the request status
        !          6014:          * to DID_RESET.
        !          6015:          */
        !          6016:         if (done_scp == NULL) {
        !          6017:             done_scp = asc_dequeue_list(&boardp->active, &last_scp, target);
        !          6018:             for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
        !          6019:                 tscp->result = HOST_BYTE(DID_RESET);
        !          6020:             }
        !          6021:         } else {
        !          6022:             ASC_ASSERT(last_scp != NULL);
        !          6023:             REQPNEXT(last_scp) = asc_dequeue_list(&boardp->active,
        !          6024:                 &new_last_scp, target);
        !          6025:             if (new_last_scp != NULL) {
        !          6026:                 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
        !          6027:                 for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
        !          6028:                     tscp->result = HOST_BYTE(DID_RESET);
        !          6029:                 }
        !          6030:                 last_scp = new_last_scp;
        !          6031:             }
        !          6032:         }
        !          6033: 
        !          6034:         /*
        !          6035:          * Add waiting requests to 'done_scp' and set the request status
        !          6036:          * to DID_RESET.
        !          6037:          */
        !          6038:         if (done_scp == NULL) {
        !          6039:             done_scp = asc_dequeue_list(&boardp->waiting, &last_scp, target);
        !          6040:             for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
        !          6041:                 tscp->result = HOST_BYTE(DID_RESET);
        !          6042:             }
        !          6043:         } else {
        !          6044:             ASC_ASSERT(last_scp != NULL);
        !          6045:             REQPNEXT(last_scp) = asc_dequeue_list(&boardp->waiting,
        !          6046:                 &new_last_scp, target);
        !          6047:             if (new_last_scp != NULL) {
        !          6048:                 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
        !          6049:                 for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
        !          6050:                     tscp->result = HOST_BYTE(DID_RESET);
        !          6051:                 }
        !          6052:                 last_scp = new_last_scp;
        !          6053:             }
        !          6054:         }
        !          6055: 
        !          6056:         /* Save the time of the most recently completed reset. */
        !          6057:         boardp->last_reset = jiffies;
        !          6058: 
        !          6059:         /* Clear reset flag. */
        !          6060:         boardp->flags &= ~ASC_HOST_IN_RESET;
        !          6061: 
        !          6062:         /*
        !          6063:          * Start any waiting commands for the board.
        !          6064:          */
        !          6065:         if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
        !          6066:             ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
        !          6067:             asc_execute_queue(&boardp->waiting);
        !          6068:         }
        !          6069:         ret = SCSI_RESET_SUCCESS;
        !          6070:     }
        !          6071: 
        !          6072:     /* Interrupts could be enabled here. */
        !          6073: 
        !          6074:     ASC_ASSERT(do_scsi_done != ASC_ERROR);
        !          6075:     ASC_ASSERT(scp_found != ASC_ERROR);
        !          6076:     if (do_scsi_done == ASC_TRUE) {
        !          6077:         if (scp->scsi_done == NULL) {
        !          6078:             ASC_PRINT1(
        !          6079: "advansys_reset: reset request scsi_done() is NULL, %x\n",
        !          6080:                 (unsigned) scp);
        !          6081:         } else {
        !          6082:             if (scp_found == ASC_FALSE) {
        !          6083:                 ASC_PRINT1(
        !          6084: "advansys_reset: reset request not active or waiting, completing anyway %x\n",
        !          6085:                     (unsigned) scp);
        !          6086:             }
        !          6087:             ASC_STATS(scp->host, done);
        !          6088:             scp->scsi_done(scp);
        !          6089:         }
        !          6090:     }
        !          6091: 
        !          6092:     /*
        !          6093:      * It is possible for the request done function to re-enable
        !          6094:      * interrupts without confusing the driver. But here interrupts
        !          6095:      * aren't enabled until requests have been completed.
        !          6096:      */
        !          6097:     if (done_scp != NULL) {
        !          6098:         asc_scsi_done_list(done_scp);
        !          6099:     }
        !          6100: 
        !          6101:     ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
        !          6102: 
        !          6103:     /* Re-enable interrupts, if they were enabled on entry. */
        !          6104:     restore_flags(flags);
        !          6105: 
        !          6106:     ASC_ASSERT(ret != ASC_ERROR);
        !          6107:     return ret;
        !          6108: }
        !          6109: 
        !          6110: /*
        !          6111:  * advansys_biosparam()
        !          6112:  *
        !          6113:  * Translate disk drive geometry if the "BIOS greater than 1 GB"
        !          6114:  * support is enabled for a drive.
        !          6115:  *
        !          6116:  * ip (information pointer) is an int array with the following definition:
        !          6117:  * ip[0]: heads
        !          6118:  * ip[1]: sectors
        !          6119:  * ip[2]: cylinders
        !          6120:  */
        !          6121: int
        !          6122: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
        !          6123: advansys_biosparam(Disk *dp, int dep, int ip[])
        !          6124: #else /* version >= v1.3.0 */
        !          6125: advansys_biosparam(Disk *dp, kdev_t dep, int ip[])
        !          6126: #endif /* version >= v1.3.0 */
        !          6127: {
        !          6128:     asc_board_t     *boardp;
        !          6129: 
        !          6130:     ASC_DBG(1, "advansys_biosparam: begin\n");
        !          6131:     ASC_STATS(dp->device->host, biosparam);
        !          6132:     boardp = ASC_BOARDP(dp->device->host);
        !          6133:     if (ASC_NARROW_BOARD(boardp)) {
        !          6134:         if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
        !          6135:              ASC_CNTL_BIOS_GT_1GB) && dp->capacity > 0x200000) {
        !          6136:                 ip[0] = 255;
        !          6137:                 ip[1] = 63;
        !          6138:         } else {
        !          6139:                 ip[0] = 64;
        !          6140:                 ip[1] = 32;
        !          6141:         }
        !          6142:     } else {
        !          6143:         if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
        !          6144:              BIOS_CTRL_EXTENDED_XLAT) && dp->capacity > 0x200000) {
        !          6145:                 ip[0] = 255;
        !          6146:                 ip[1] = 63;
        !          6147:         } else {
        !          6148:                 ip[0] = 64;
        !          6149:                 ip[1] = 32;
        !          6150:         }
        !          6151:     }
        !          6152:     ip[2] = dp->capacity / (ip[0] * ip[1]);
        !          6153:     ASC_DBG(1, "advansys_biosparam: end\n");
        !          6154:     return 0;
        !          6155: }
        !          6156: 
        !          6157: /*
        !          6158:  * advansys_setup()
        !          6159:  *
        !          6160:  * This function is called from init/main.c at boot time.
        !          6161:  * It it passed LILO parameters that can be set from the
        !          6162:  * LILO command line or in /etc/lilo.conf.
        !          6163:  *
        !          6164:  * It is used by the AdvanSys driver to either disable I/O
        !          6165:  * port scanning or to limit scanning to 1 - 4 I/O ports.
        !          6166:  * Regardless of the option setting EISA and PCI boards
        !          6167:  * will still be searched for and detected. This option
        !          6168:  * only affects searching for ISA and VL boards.
        !          6169:  *
        !          6170:  * If ADVANSYS_DEBUG is defined the driver debug level may
        !          6171:  * be set using the 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port.
        !          6172:  *
        !          6173:  * Examples:
        !          6174:  * 1. Eliminate I/O port scanning:
        !          6175:  *         boot: linux advansys=
        !          6176:  *       or
        !          6177:  *         boot: linux advansys=0x0
        !          6178:  * 2. Limit I/O port scanning to one I/O port:
        !          6179:  *        boot: linux advansys=0x110
        !          6180:  * 3. Limit I/O port scanning to four I/O ports:
        !          6181:  *        boot: linux advansys=0x110,0x210,0x230,0x330
        !          6182:  * 4. If ADVANSYS_DEBUG, limit I/O port scanning to four I/O ports and
        !          6183:  *    set the driver debug level to 2.
        !          6184:  *        boot: linux advansys=0x110,0x210,0x230,0x330,0xdeb2
        !          6185:  *
        !          6186:  * ints[0] - number of arguments
        !          6187:  * ints[1] - first argument
        !          6188:  * ints[2] - second argument
        !          6189:  * ...
        !          6190:  */
        !          6191: ASC_INITFUNC(
        !          6192: void
        !          6193: advansys_setup(char *str, int *ints)
        !          6194: )
        !          6195: {
        !          6196:     int    i;
        !          6197: 
        !          6198:     if (asc_iopflag == ASC_TRUE) {
        !          6199:         printk("AdvanSys SCSI: 'advansys' LILO option may appear only once\n");
        !          6200:         return;
        !          6201:     }
        !          6202: 
        !          6203:     asc_iopflag = ASC_TRUE;
        !          6204: 
        !          6205:     if (ints[0] > ASC_NUM_IOPORT_PROBE) {
        !          6206: #ifdef ADVANSYS_DEBUG
        !          6207:         if ((ints[0] == ASC_NUM_IOPORT_PROBE + 1) &&
        !          6208:             (ints[ASC_NUM_IOPORT_PROBE + 1] >> 4 == 0xdeb)) {
        !          6209:             asc_dbglvl = ints[ASC_NUM_IOPORT_PROBE + 1] & 0xf;
        !          6210:         } else {
        !          6211: #endif /* ADVANSYS_DEBUG */
        !          6212:             printk("AdvanSys SCSI: only %d I/O ports accepted\n",
        !          6213:                 ASC_NUM_IOPORT_PROBE);
        !          6214: #ifdef ADVANSYS_DEBUG
        !          6215:         }
        !          6216: #endif /* ADVANSYS_DEBUG */
        !          6217:     }
        !          6218: 
        !          6219: #ifdef ADVANSYS_DEBUG
        !          6220:     ASC_DBG1(1, "advansys_setup: ints[0] %d\n", ints[0]);
        !          6221:     for (i = 1; i < ints[0]; i++) {
        !          6222:         ASC_DBG2(1, " ints[%d] %x", i, ints[i]);
        !          6223:     }
        !          6224:     ASC_DBG(1, "\n");
        !          6225: #endif /* ADVANSYS_DEBUG */
        !          6226: 
        !          6227:     for (i = 1; i <= ints[0] && i <= ASC_NUM_IOPORT_PROBE; i++) {
        !          6228:         asc_ioport[i-1] = ints[i];
        !          6229:         ASC_DBG2(1, "advansys_setup: asc_ioport[%d] %x\n",
        !          6230:             i - 1, asc_ioport[i-1]);
        !          6231:     }
        !          6232: }
        !          6233: 
        !          6234: 
        !          6235: /*
        !          6236:  * --- Loadable Driver Support
        !          6237:  */
        !          6238: 
        !          6239: #ifdef MODULE
        !          6240: Scsi_Host_Template driver_template = ADVANSYS;
        !          6241: # include "scsi_module.c"
        !          6242: #endif /* MODULE */
        !          6243: 
        !          6244: 
        !          6245: /*
        !          6246:  * --- Miscellaneous Driver Functions
        !          6247:  */
        !          6248: 
        !          6249: /*
        !          6250:  * First-level interrupt handler.
        !          6251:  *
        !          6252:  * For versions > v1.3.70, 'dev_id' is a pointer to the interrupting
        !          6253:  * adapter's asc_board_t. Because all boards are currently checked
        !          6254:  * for interrupts on each interrupt, 'dev_id' is not referenced. 'dev_id'
        !          6255:  * could be used to identify an interrupt passed to the AdvanSys driver,
        !          6256:  * which is for a device sharing an interrupt with an AdvanSys adapter.
        !          6257:  */
        !          6258: STATIC void
        !          6259: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
        !          6260: advansys_interrupt(int irq, struct pt_regs *regs)
        !          6261: #else /* version >= v1.3.70 */
        !          6262: advansys_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        !          6263: #endif /* version >= v1.3.70 */
        !          6264: {
        !          6265: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,95)
        !          6266:     int             flags;
        !          6267: #else /* version >= v2.1.95 */
        !          6268:     unsigned long   flags;
        !          6269: #endif /* version >= v2.1.95 */
        !          6270:     int             i;
        !          6271:     asc_board_t     *boardp;
        !          6272:     Scsi_Cmnd       *done_scp = NULL, *last_scp = NULL;
        !          6273:     Scsi_Cmnd       *new_last_scp;
        !          6274: 
        !          6275: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,95)
        !          6276:     /* Disable interrupts, if they aren't already disabled. */
        !          6277:     save_flags(flags);
        !          6278:     cli();
        !          6279: #else /* version >= v2.1.95 */
        !          6280:     /*
        !          6281:      * Disable interrupts, if they aren't already disabled and acquire
        !          6282:      * the I/O spinlock.
        !          6283:      */
        !          6284:     spin_lock_irqsave(&io_request_lock, flags);
        !          6285: #endif /* version >= v2.1.95 */
        !          6286: 
        !          6287:     ASC_DBG(1, "advansys_interrupt: begin\n");
        !          6288: 
        !          6289:     /*
        !          6290:      * Check for interrupts on all boards.
        !          6291:      * AscISR() will call asc_isr_callback().
        !          6292:      */
        !          6293:     for (i = 0; i < asc_board_count; i++) {
        !          6294:         boardp = ASC_BOARDP(asc_host[i]);
        !          6295:         ASC_DBG2(2, "advansys_interrupt: i %d, boardp %lx\n",
        !          6296:             i, (ulong) boardp)            
        !          6297:         if (ASC_NARROW_BOARD(boardp)) {
        !          6298:             /*
        !          6299:              * Narrow Board
        !          6300:              */
        !          6301:             if (AscIsIntPending(asc_host[i]->io_port)) {
        !          6302:                 ASC_STATS(asc_host[i], interrupt);
        !          6303:                 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
        !          6304:                 AscISR(&boardp->dvc_var.asc_dvc_var);
        !          6305:             }
        !          6306:         } else {
        !          6307:             /*
        !          6308:              * Wide Board
        !          6309:              */
        !          6310:             ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
        !          6311:             if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
        !          6312:                 ASC_STATS(asc_host[i], interrupt);
        !          6313:             }
        !          6314:         }
        !          6315: 
        !          6316:         /*
        !          6317:          * Start waiting requests and create a list of completed requests.
        !          6318:          * 
        !          6319:          * If a reset or abort request is being performed for the board,
        !          6320:          * the reset or abort handler will complete pending requests after
        !          6321:          * it has completed.
        !          6322:          */
        !          6323:         if ((boardp->flags & (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) == 0) {
        !          6324:             ASC_DBG2(1, "advansys_interrupt: done_scp %lx, last_scp %lx\n",
        !          6325:                 (ulong) done_scp, (ulong) last_scp);
        !          6326: 
        !          6327:             /* Start any waiting commands for the board. */
        !          6328:             if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
        !          6329:                 ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
        !          6330:                 asc_execute_queue(&boardp->waiting);
        !          6331:             }
        !          6332: 
        !          6333:              /*
        !          6334:               * Add to the list of requests that must be completed.
        !          6335:               *
        !          6336:               * 'done_scp' will always be NULL on the first iteration
        !          6337:               * of this loop. 'last_scp' is set at the same time as
        !          6338:               * 'done_scp'.
        !          6339:               */
        !          6340:             if (done_scp == NULL) {
        !          6341:                 done_scp = asc_dequeue_list(&boardp->done, &last_scp,
        !          6342:                     ASC_TID_ALL);
        !          6343:             } else {
        !          6344:                 ASC_ASSERT(last_scp != NULL);
        !          6345:                 REQPNEXT(last_scp) = asc_dequeue_list(&boardp->done,
        !          6346:                     &new_last_scp, ASC_TID_ALL);
        !          6347:                 if (new_last_scp != NULL) {
        !          6348:                     ASC_ASSERT(REQPNEXT(last_scp) != NULL);
        !          6349:                     last_scp = new_last_scp;
        !          6350:                 }
        !          6351:             }
        !          6352:         }
        !          6353:     }
        !          6354: 
        !          6355:     /* Interrupts could be enabled here. */
        !          6356: 
        !          6357:     /*
        !          6358:      * It is possible for the request done function to re-enable
        !          6359:      * interrupts without confusing the driver. But here the
        !          6360:      * original flags aren't restored until all requests have been
        !          6361:      * completed.
        !          6362:      */
        !          6363:     asc_scsi_done_list(done_scp);
        !          6364: 
        !          6365: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,95)
        !          6366:     /*
        !          6367:      * Restore the original flags which will enable interrupts
        !          6368:      * if and only if they were enabled on entry.
        !          6369:      */
        !          6370:     restore_flags(flags);
        !          6371: #else /* version >= v2.1.95 */
        !          6372:     /*
        !          6373:      * Release the I/O spinlock and restore the original flags
        !          6374:      * which will enable interrupts if and only if they were
        !          6375:      * enabled on entry.
        !          6376:      */
        !          6377:     spin_unlock_irqrestore(&io_request_lock, flags);
        !          6378: #endif /* version >= v2.1.95 */
        !          6379: 
        !          6380:     ASC_DBG(1, "advansys_interrupt: end\n");
        !          6381:     return;
        !          6382: }
        !          6383: 
        !          6384: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
        !          6385: /*
        !          6386:  * Set the number of commands to queue per device for the
        !          6387:  * specified host adapter.
        !          6388:  */
        !          6389: STATIC void
        !          6390: advansys_select_queue_depths(struct Scsi_Host *shp, Scsi_Device *devicelist)
        !          6391: {
        !          6392:     Scsi_Device        *device;
        !          6393:     asc_board_t        *boardp;
        !          6394: 
        !          6395:     boardp = ASC_BOARDP(shp);
        !          6396:     boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
        !          6397:     for (device = devicelist; device != NULL; device = device->next) {
        !          6398:         if (device->host != shp) {
        !          6399:             continue;
        !          6400:         }
        !          6401:         /*
        !          6402:          * Save a pointer to the device and set its initial/maximum
        !          6403:          * queue depth.
        !          6404:          */
        !          6405:         boardp->device[device->id] = device;
        !          6406:         if (ASC_NARROW_BOARD(boardp)) {
        !          6407:             device->queue_depth =
        !          6408:                 boardp->dvc_var.asc_dvc_var.max_dvc_qng[device->id];
        !          6409:         } else {
        !          6410:             device->queue_depth =
        !          6411:                 boardp->dvc_var.adv_dvc_var.max_dvc_qng;
        !          6412:         }
        !          6413:         ASC_DBG3(1, "advansys_select_queue_depths: shp %x, id %d, depth %d\n",
        !          6414:             (unsigned) shp, device->id, device->queue_depth);
        !          6415:     }
        !          6416: }
        !          6417: #endif /* version >= v1.3.89 */
        !          6418: 
        !          6419: /*
        !          6420:  * Function used only with polled I/O requests that are initiated by
        !          6421:  * advansys_command().
        !          6422:  */
        !          6423: STATIC void
        !          6424: advansys_command_done(Scsi_Cmnd *scp)
        !          6425: {
        !          6426:     ASC_DBG1(1, "advansys_command_done: scp %x\n", (unsigned) scp);
        !          6427:     scp->SCp.Status = 1;
        !          6428: }
        !          6429: 
        !          6430: /*
        !          6431:  * Complete all requests on the singly linked list pointed
        !          6432:  * to by 'scp'.
        !          6433:  *
        !          6434:  * Interrupts can be enabled on entry.
        !          6435:  */
        !          6436: STATIC void
        !          6437: asc_scsi_done_list(Scsi_Cmnd *scp)
        !          6438: {
        !          6439:     Scsi_Cmnd    *tscp;
        !          6440: 
        !          6441:     ASC_DBG(2, "asc_scsi_done_list: begin\n");
        !          6442:     while (scp != NULL) {
        !          6443:         ASC_DBG1(3, "asc_scsi_done_list: scp %x\n", (unsigned) scp);
        !          6444:         tscp = REQPNEXT(scp);
        !          6445:         REQPNEXT(scp) = NULL;
        !          6446:         ASC_STATS(scp->host, done);
        !          6447:         ASC_ASSERT(scp->scsi_done != NULL);
        !          6448:         scp->scsi_done(scp);
        !          6449:         scp = tscp;
        !          6450:     }
        !          6451:     ASC_DBG(2, "asc_scsi_done_list: done\n");
        !          6452:     return;
        !          6453: }
        !          6454: 
        !          6455: /*
        !          6456:  * Execute a single 'Scsi_Cmnd'.
        !          6457:  *
        !          6458:  * The function 'done' is called when the request has been completed.
        !          6459:  *
        !          6460:  * Scsi_Cmnd:
        !          6461:  *
        !          6462:  *  host - board controlling device
        !          6463:  *  device - device to send command
        !          6464:  *  target - target of device
        !          6465:  *  lun - lun of device
        !          6466:  *  cmd_len - length of SCSI CDB
        !          6467:  *  cmnd - buffer for SCSI 8, 10, or 12 byte CDB
        !          6468:  *  use_sg - if non-zero indicates scatter-gather request with use_sg elements
        !          6469:  *
        !          6470:  *  if (use_sg == 0) {
        !          6471:  *    request_buffer - buffer address for request
        !          6472:  *    request_bufflen - length of request buffer
        !          6473:  *  } else {
        !          6474:  *    request_buffer - pointer to scatterlist structure
        !          6475:  *  }
        !          6476:  *
        !          6477:  *  sense_buffer - sense command buffer
        !          6478:  *
        !          6479:  *  result (4 bytes of an int):
        !          6480:  *    Byte Meaning
        !          6481:  *    0 SCSI Status Byte Code
        !          6482:  *    1 SCSI One Byte Message Code
        !          6483:  *    2 Host Error Code
        !          6484:  *    3 Mid-Level Error Code
        !          6485:  *
        !          6486:  *  host driver fields:
        !          6487:  *    SCp - Scsi_Pointer used for command processing status
        !          6488:  *    scsi_done - used to save caller's done function
        !          6489:  *    host_scribble - used for pointer to another Scsi_Cmnd
        !          6490:  *
        !          6491:  * If this function returns ASC_NOERROR or ASC_ERROR the request
        !          6492:  * has been enqueued on the board's 'done' queue and must be
        !          6493:  * completed by the caller.
        !          6494:  *
        !          6495:  * If ASC_BUSY is returned the request must be enqueued by the
        !          6496:  * caller and re-tried later.
        !          6497:  */
        !          6498: STATIC int
        !          6499: asc_execute_scsi_cmnd(Scsi_Cmnd *scp)
        !          6500: {
        !          6501:     asc_board_t        *boardp;
        !          6502:     ASC_DVC_VAR        *asc_dvc_varp;
        !          6503:     ADV_DVC_VAR        *adv_dvc_varp;
        !          6504:     ADV_SCSI_REQ_Q     *adv_scsiqp;
        !          6505:     Scsi_Device        *device;
        !          6506:     int                ret;
        !          6507: 
        !          6508:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
        !          6509:     ASC_DBG2(1, "asc_execute_scsi_cmnd: scp %x, done %x\n",
        !          6510:         (unsigned) scp, (unsigned) scp->scsi_done);
        !          6511: 
        !          6512:     boardp = ASC_BOARDP(scp->host);
        !          6513:     device = boardp->device[scp->target];
        !          6514: 
        !          6515:     if (ASC_NARROW_BOARD(boardp)) {
        !          6516:         /*
        !          6517:          * Build and execute Narrow Board request.
        !          6518:          */
        !          6519: 
        !          6520:         asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
        !          6521: 
        !          6522:         /*
        !          6523:          * Build Asc Library request structure using the
        !          6524:          * global structures 'asc_scsi_req' and 'asc_sg_head'.
        !          6525:          *
        !          6526:          * asc_build_req() can not return ASC_BUSY.
        !          6527:          */
        !          6528:         if (asc_build_req(boardp, scp) == ASC_ERROR) {
        !          6529:             ASC_STATS(scp->host, build_error);
        !          6530:             return ASC_ERROR;
        !          6531:         }
        !          6532: 
        !          6533:         /*
        !          6534:          * Execute the command. If there is no error, add the command
        !          6535:          * to the active queue.
        !          6536:          */
        !          6537:         switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
        !          6538:         case ASC_NOERROR:
        !          6539:             ASC_STATS(scp->host, exe_noerror);
        !          6540:             /*
        !          6541:              * Increment monotonically increasing per device successful
        !          6542:              * request counter. Wrapping doesn't matter.
        !          6543:              */
        !          6544:             boardp->reqcnt[scp->target]++;
        !          6545: 
        !          6546: #if ASC_QUEUE_FLOW_CONTROL
        !          6547:             /*
        !          6548:              * Conditionally increment the device queue depth.
        !          6549:              *
        !          6550:              * If no error occurred and there have been 100 consecutive
        !          6551:              * successful requests and the current queue depth is less
        !          6552:              * than the maximum queue depth, then increment the current
        !          6553:              * queue depth.
        !          6554:              */
        !          6555:             if (boardp->nerrcnt[scp->target]++ > 100) {
        !          6556:                 boardp->nerrcnt[scp->target] = 0;
        !          6557:                 if (device != NULL &&
        !          6558:                     (device->queue_curr_depth < device->queue_depth) &&
        !          6559:                     (!(boardp->queue_full &
        !          6560:                        ADV_TID_TO_TIDMASK(scp->target)) ||
        !          6561:                      (boardp->queue_full_cnt[scp->target] >
        !          6562:                       device->queue_curr_depth))) {
        !          6563:                     device->queue_curr_depth++;
        !          6564:                 }
        !          6565:             }
        !          6566: #endif /* ASC_QUEUE_FLOW_CONTROL */
        !          6567:             asc_enqueue(&boardp->active, scp, ASC_BACK);
        !          6568:             ASC_DBG(1,
        !          6569:                 "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
        !          6570:             break;
        !          6571:         case ASC_BUSY:
        !          6572:             /* Caller must enqueue request and retry later. */
        !          6573:             ASC_STATS(scp->host, exe_busy);
        !          6574: #if ASC_QUEUE_FLOW_CONTROL
        !          6575:             /*
        !          6576:              * Clear consecutive no error counter and if possible decrement
        !          6577:              * queue depth.
        !          6578:              */
        !          6579:             boardp->nerrcnt[scp->target] = 0;
        !          6580:             if (device != NULL && device->queue_curr_depth > 1) {
        !          6581:                 device->queue_curr_depth--;
        !          6582:             }
        !          6583: #endif /* ASC_QUEUE_FLOW_CONTROL */
        !          6584:             break;
        !          6585:         case ASC_ERROR:
        !          6586:             ASC_PRINT2(
        !          6587: "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code %x\n",
        !          6588:                 boardp->id, asc_dvc_varp->err_code);
        !          6589:             ASC_STATS(scp->host, exe_error);
        !          6590: #if ASC_QUEUE_FLOW_CONTROL
        !          6591:             /* Clear consecutive no error counter. */
        !          6592:             boardp->nerrcnt[scp->target] = 0;
        !          6593: #endif /* ASC_QUEUE_FLOW_CONTROL */
        !          6594:             scp->result = HOST_BYTE(DID_ERROR);
        !          6595:             asc_enqueue(&boardp->done, scp, ASC_BACK);
        !          6596:             break;
        !          6597:         default:
        !          6598:             ASC_PRINT2(
        !          6599: "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code %x\n",
        !          6600:                 boardp->id, asc_dvc_varp->err_code);
        !          6601:             ASC_STATS(scp->host, exe_unknown);
        !          6602: #if ASC_QUEUE_FLOW_CONTROL
        !          6603:             /* Clear consecutive no error counter. */
        !          6604:             boardp->nerrcnt[scp->target] = 0;
        !          6605: #endif /* ASC_QUEUE_FLOW_CONTROL */
        !          6606:             scp->result = HOST_BYTE(DID_ERROR);
        !          6607:             asc_enqueue(&boardp->done, scp, ASC_BACK);
        !          6608:             break;
        !          6609:         }
        !          6610:     } else {
        !          6611:         /*
        !          6612:          * Build and execute Wide Board request.
        !          6613:          */
        !          6614:         adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
        !          6615: 
        !          6616:         /*
        !          6617:          * Build and get a pointer to an Adv Library request structure.
        !          6618:          *
        !          6619:          * If the request is successfully built then send  it below,
        !          6620:          * otherwise return with an error.
        !          6621:          */
        !          6622:         switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
        !          6623:         case ASC_NOERROR:
        !          6624:             ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
        !          6625:             break;
        !          6626:         case ASC_BUSY:
        !          6627:             ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
        !          6628:             return ASC_BUSY;
        !          6629:         case ASC_ERROR:
        !          6630:         default:
        !          6631:             ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
        !          6632:             ASC_STATS(scp->host, build_error);
        !          6633:             return ASC_ERROR;
        !          6634:         }
        !          6635:     
        !          6636:         /*
        !          6637:          * Execute the command. If there is no error, add the command
        !          6638:          * to the active queue.
        !          6639:          */
        !          6640:         switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
        !          6641:         case ASC_NOERROR:
        !          6642:             ASC_STATS(scp->host, exe_noerror);
        !          6643:             /*
        !          6644:              * Increment monotonically increasing per device successful
        !          6645:              * request counter. Wrapping doesn't matter.
        !          6646:              */
        !          6647:             boardp->reqcnt[scp->target]++;
        !          6648:             asc_enqueue(&boardp->active, scp, ASC_BACK);
        !          6649:             ASC_DBG(1,
        !          6650:                 "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
        !          6651:             break;
        !          6652:         case ASC_BUSY:
        !          6653:             /* Caller must enqueue request and retry later. */
        !          6654:             ASC_STATS(scp->host, exe_busy);
        !          6655:             break;
        !          6656:         case ASC_ERROR:
        !          6657:             ASC_PRINT2(
        !          6658: "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code %x\n",
        !          6659:                 boardp->id, adv_dvc_varp->err_code);
        !          6660:             ASC_STATS(scp->host, exe_error);
        !          6661:             scp->result = HOST_BYTE(DID_ERROR);
        !          6662:             asc_enqueue(&boardp->done, scp, ASC_BACK);
        !          6663:             break;
        !          6664:         default:
        !          6665:             ASC_PRINT2(
        !          6666: "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code %x\n",
        !          6667:                 boardp->id, adv_dvc_varp->err_code);
        !          6668:             ASC_STATS(scp->host, exe_unknown);
        !          6669:             scp->result = HOST_BYTE(DID_ERROR);
        !          6670:             asc_enqueue(&boardp->done, scp, ASC_BACK);
        !          6671:             break;
        !          6672:         }
        !          6673:     }
        !          6674: 
        !          6675:     ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
        !          6676:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
        !          6677:     return ret;
        !          6678: }
        !          6679: 
        !          6680: /*
        !          6681:  * Build a request structure for the Asc Library (Narrow Board).
        !          6682:  *
        !          6683:  * The global structures 'asc_scsi_q' and 'asc_sg_head' are
        !          6684:  * used to build the request.
        !          6685:  *
        !          6686:  * If an error occurs, then return ASC_ERROR.
        !          6687:  */
        !          6688: STATIC int
        !          6689: asc_build_req(asc_board_t *boardp, Scsi_Cmnd *scp)
        !          6690: {
        !          6691:     /*
        !          6692:      * Mutually exclusive access is required to 'asc_scsi_q' and
        !          6693:      * 'asc_sg_head' until after the request is started.
        !          6694:      */
        !          6695:     memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
        !          6696: 
        !          6697:     /*
        !          6698:      * Point the ASC_SCSI_Q to the 'Scsi_Cmnd'.
        !          6699:      */
        !          6700:     asc_scsi_q.q2.srb_ptr = (ulong) scp;
        !          6701: 
        !          6702:     /*
        !          6703:      * Build the ASC_SCSI_Q request.
        !          6704:      */
        !          6705:     ASC_ASSERT(scp->cmd_len <= ASC_MAX_CDB_LEN);
        !          6706:     if (scp->cmd_len > ASC_MAX_CDB_LEN) {
        !          6707:         scp->cmd_len = ASC_MAX_CDB_LEN;
        !          6708:     }
        !          6709:     asc_scsi_q.cdbptr = &scp->cmnd[0];
        !          6710:     asc_scsi_q.q2.cdb_len = scp->cmd_len;
        !          6711:     asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->target);
        !          6712:     asc_scsi_q.q1.target_lun = scp->lun;
        !          6713:     asc_scsi_q.q2.target_ix = ASC_TIDLUN_TO_IX(scp->target, scp->lun);
        !          6714: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
        !          6715:     asc_scsi_q.q1.sense_addr = (ulong) &scp->sense_buffer[0];
        !          6716: #else /* version >= v2.0.0 */
        !          6717:     asc_scsi_q.q1.sense_addr = virt_to_bus(&scp->sense_buffer[0]);
        !          6718: #endif /* version >= v2.0.0 */
        !          6719:     asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
        !          6720: 
        !          6721:     /*
        !          6722:      * If there are any outstanding requests for the current target,
        !          6723:      * then every 255th request send an ORDERED request. This heuristic
        !          6724:      * tries to retain the benefit of request sorting while preventing
        !          6725:      * request starvation. 255 is the max number of tags or pending commands
        !          6726:      * a device may have outstanding.
        !          6727:      *
        !          6728:      * The request count is incremented below for every successfully
        !          6729:      * started request.
        !          6730:      * 
        !          6731:      */
        !          6732:     if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->target] > 0) &&
        !          6733:         (boardp->reqcnt[scp->target] % 255) == 0) {
        !          6734:         asc_scsi_q.q2.tag_code = M2_QTAG_MSG_ORDERED;
        !          6735:     } else {
        !          6736:         asc_scsi_q.q2.tag_code = M2_QTAG_MSG_SIMPLE;
        !          6737:     }
        !          6738: 
        !          6739:     /*
        !          6740:      * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
        !          6741:      * buffer command.
        !          6742:      */
        !          6743:     if (scp->use_sg == 0) {
        !          6744:         /*
        !          6745:          * CDB request of single contiguous buffer.
        !          6746:          */
        !          6747:         ASC_STATS(scp->host, cont_cnt);
        !          6748: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
        !          6749:         asc_scsi_q.q1.data_addr = (ulong) scp->request_buffer;
        !          6750: #else /* version >= v2.0.0 */
        !          6751:         asc_scsi_q.q1.data_addr = virt_to_bus(scp->request_buffer);
        !          6752: #endif /* version >= v2.0.0 */
        !          6753:         asc_scsi_q.q1.data_cnt = scp->request_bufflen;
        !          6754:         ASC_STATS_ADD(scp->host, cont_xfer,
        !          6755:                       ASC_CEILING(scp->request_bufflen, 512));
        !          6756:         asc_scsi_q.q1.sg_queue_cnt = 0;
        !          6757:         asc_scsi_q.sg_head = NULL;
        !          6758:     } else {
        !          6759:         /*
        !          6760:          * CDB scatter-gather request list.
        !          6761:          */
        !          6762:         int                     sgcnt;
        !          6763:         struct scatterlist      *slp;
        !          6764: 
        !          6765:         if (scp->use_sg > scp->host->sg_tablesize) {
        !          6766:             ASC_PRINT3(
        !          6767: "asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
        !          6768:                 boardp->id, scp->use_sg, scp->host->sg_tablesize);
        !          6769:             scp->result = HOST_BYTE(DID_ERROR);
        !          6770:             asc_enqueue(&boardp->done, scp, ASC_BACK);
        !          6771:             return ASC_ERROR;
        !          6772:         }
        !          6773: 
        !          6774:         ASC_STATS(scp->host, sg_cnt);
        !          6775: 
        !          6776:         /*
        !          6777:          * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
        !          6778:          * structure to point to it.
        !          6779:          */
        !          6780:         memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
        !          6781: 
        !          6782:         asc_scsi_q.q1.cntl |= QC_SG_HEAD;
        !          6783:         asc_scsi_q.sg_head = &asc_sg_head;
        !          6784:         asc_scsi_q.q1.data_cnt = 0;
        !          6785:         asc_scsi_q.q1.data_addr = 0;
        !          6786:         asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = scp->use_sg;
        !          6787:         ASC_STATS_ADD(scp->host, sg_elem, asc_sg_head.entry_cnt);
        !          6788: 
        !          6789:         /*
        !          6790:          * Convert scatter-gather list into ASC_SG_HEAD list.
        !          6791:          */
        !          6792:         slp = (struct scatterlist *) scp->request_buffer;
        !          6793:         for (sgcnt = 0; sgcnt < scp->use_sg; sgcnt++, slp++) {
        !          6794: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
        !          6795:             asc_sg_head.sg_list[sgcnt].addr = (ulong) slp->address;
        !          6796: #else /* version >= v2.0.0 */
        !          6797:             asc_sg_head.sg_list[sgcnt].addr = virt_to_bus(slp->address);
        !          6798: #endif /* version >= v2.0.0 */
        !          6799:             asc_sg_head.sg_list[sgcnt].bytes = slp->length;
        !          6800:             ASC_STATS_ADD(scp->host, sg_xfer, ASC_CEILING(slp->length, 512));
        !          6801:         }
        !          6802:     }
        !          6803: 
        !          6804:     ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
        !          6805:     ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
        !          6806: 
        !          6807:     return ASC_NOERROR;
        !          6808: }
        !          6809: 
        !          6810: /*
        !          6811:  * Build a request structure for the Adv Library (Wide Board).
        !          6812:  *
        !          6813:  * If an adv_req_t can not be allocated to issue the request,
        !          6814:  * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
        !          6815:  */
        !          6816: STATIC int
        !          6817: adv_build_req(asc_board_t *boardp, Scsi_Cmnd *scp,
        !          6818:     ADV_SCSI_REQ_Q **adv_scsiqpp)
        !          6819: {
        !          6820:     adv_req_t           *reqp;
        !          6821:     ADV_SCSI_REQ_Q      *scsiqp;
        !          6822:     int                 i;
        !          6823: 
        !          6824:     /*
        !          6825:      * Allocate an adv_req_t structure from the board to execute
        !          6826:      * the command.
        !          6827:      */
        !          6828:     if (boardp->adv_reqp == NULL) {
        !          6829:         ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
        !          6830:         ASC_STATS(scp->host, adv_build_noreq);
        !          6831:         return ASC_BUSY;
        !          6832:     } else {
        !          6833:         reqp = boardp->adv_reqp;
        !          6834:         boardp->adv_reqp = reqp->next_reqp;
        !          6835:         reqp->next_reqp = NULL;
        !          6836:     }
        !          6837: 
        !          6838:     /*
        !          6839:      * Get 4-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
        !          6840:      */
        !          6841:     scsiqp = (ADV_SCSI_REQ_Q *) ADV_DWALIGN(&reqp->scsi_req_q);
        !          6842:     memset(scsiqp, 0, sizeof(ADV_SCSI_REQ_Q));
        !          6843: 
        !          6844:     /*
        !          6845:      * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
        !          6846:      */
        !          6847:     scsiqp->srb_ptr = (ulong) reqp;
        !          6848: 
        !          6849:     /*
        !          6850:      * Set the adv_req_t 'cmndp' to point to the Scsi_Cmnd structure.
        !          6851:      */
        !          6852:     reqp->cmndp = scp;
        !          6853: 
        !          6854:     /*
        !          6855:      * Build the ADV_SCSI_REQ_Q request.
        !          6856:      */
        !          6857: 
        !          6858:     /*
        !          6859:      * Set CDB length and copy it to the request structure.
        !          6860:      */
        !          6861:     ASC_ASSERT(scp->cmd_len <= ASC_MAX_CDB_LEN);
        !          6862:     if (scp->cmd_len > ASC_MAX_CDB_LEN) {
        !          6863:         scp->cmd_len = ASC_MAX_CDB_LEN;
        !          6864:     }
        !          6865:     scsiqp->cdb_len = scp->cmd_len;
        !          6866:     for (i = 0; i < scp->cmd_len; i++) {
        !          6867:         scsiqp->cdb[i] = scp->cmnd[i];
        !          6868:     }
        !          6869: 
        !          6870:     scsiqp->target_id = scp->target;
        !          6871:     scsiqp->target_lun = scp->lun;
        !          6872: 
        !          6873:     scsiqp->vsense_addr = (ulong) &scp->sense_buffer[0];
        !          6874: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
        !          6875:     scsiqp->sense_addr = (ulong) &scp->sense_buffer[0];
        !          6876: #else /* version >= v2.0.0 */
        !          6877:     scsiqp->sense_addr = virt_to_bus(&scp->sense_buffer[0]);
        !          6878: #endif /* version >= v2.0.0 */
        !          6879:     scsiqp->sense_len = sizeof(scp->sense_buffer);
        !          6880: 
        !          6881:     /*
        !          6882:      * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
        !          6883:      * buffer command.
        !          6884:      */
        !          6885:     scsiqp->data_cnt = scp->request_bufflen;
        !          6886:     scsiqp->vdata_addr = (ulong) scp->request_buffer;
        !          6887: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
        !          6888:     scsiqp->data_addr = (ulong) scp->request_buffer;
        !          6889: #else /* version >= v2.0.0 */
        !          6890:     scsiqp->data_addr = virt_to_bus(scp->request_buffer);
        !          6891: #endif /* version >= v2.0.0 */
        !          6892: 
        !          6893:     if (scp->use_sg == 0) {
        !          6894:         /*
        !          6895:          * CDB request of single contiguous buffer.
        !          6896:          */
        !          6897:         reqp->sgblkp = NULL;
        !          6898:         scsiqp->sg_list_ptr = NULL;
        !          6899:         ASC_STATS(scp->host, cont_cnt);
        !          6900:         ASC_STATS_ADD(scp->host, cont_xfer,
        !          6901:                       ASC_CEILING(scp->request_bufflen, 512));
        !          6902:     } else {
        !          6903:         /*
        !          6904:          * CDB scatter-gather request list.
        !          6905:          */
        !          6906:         if (scp->use_sg > ADV_MAX_SG_LIST) {
        !          6907:             ASC_PRINT3(
        !          6908: "adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
        !          6909:                 boardp->id, scp->use_sg, scp->host->sg_tablesize);
        !          6910:             scp->result = HOST_BYTE(DID_ERROR);
        !          6911:             asc_enqueue(&boardp->done, scp, ASC_BACK);
        !          6912: 
        !          6913:             /*
        !          6914:              * Free the 'adv_req_t' structure by adding it back to the
        !          6915:              * board free list.
        !          6916:              */
        !          6917:             reqp->next_reqp = boardp->adv_reqp;
        !          6918:             boardp->adv_reqp = reqp;
        !          6919: 
        !          6920:             return ASC_ERROR;
        !          6921:         }
        !          6922: 
        !          6923:         /*
        !          6924:          * Allocate an 'adv_sgblk_t' structure from the board to
        !          6925:          * execute the command.
        !          6926:          */
        !          6927:         if (boardp->adv_sgblkp == NULL) {
        !          6928:             ASC_DBG(1, "adv_build_req: no free adv_sgblk_t\n");
        !          6929:             ASC_STATS(scp->host, adv_build_nosg);
        !          6930:             /*
        !          6931:              * Free the 'adv_req_t' structure by adding it back to the
        !          6932:              * board free list.
        !          6933:              */
        !          6934:             reqp->next_reqp = boardp->adv_reqp;
        !          6935:             boardp->adv_reqp = reqp;
        !          6936:             return ASC_BUSY;
        !          6937:         } else {
        !          6938:             reqp->sgblkp = boardp->adv_sgblkp;
        !          6939:             boardp->adv_sgblkp = reqp->sgblkp->next_sgblkp;
        !          6940:             reqp->sgblkp->next_sgblkp = NULL;
        !          6941:         }
        !          6942: 
        !          6943:         /*
        !          6944:          * Build scatter-gather list.
        !          6945:          */
        !          6946:         scsiqp->sg_list_ptr = (ADV_SG_BLOCK *)
        !          6947:             ADV_DWALIGN(&reqp->sgblkp->sg_block[0]);
        !          6948: 
        !          6949:         memset(scsiqp->sg_list_ptr, 0, sizeof(ADV_SG_BLOCK) *
        !          6950:             (ADV_NUM_SG_BLOCK + ADV_NUM_PAGE_CROSSING));
        !          6951:          
        !          6952:         if (adv_get_sglist(&boardp->dvc_var.adv_dvc_var, scsiqp, scp) ==
        !          6953:             ADV_ERROR) {
        !          6954: 
        !          6955:             /*
        !          6956:              * Free the adv_sgblk_t structure, if any, by adding it back
        !          6957:              * to the board free list.
        !          6958:              */
        !          6959:             ASC_ASSERT(reqp->sgblkp != NULL);
        !          6960:             reqp->sgblkp->next_sgblkp = boardp->adv_sgblkp;
        !          6961:             boardp->adv_sgblkp = reqp->sgblkp;
        !          6962: 
        !          6963:             /*
        !          6964:              * Free the adv_req_t structure by adding it back to the
        !          6965:              * board free list.
        !          6966:              */
        !          6967:             reqp->next_reqp = boardp->adv_reqp;
        !          6968:             boardp->adv_reqp = reqp;
        !          6969: 
        !          6970:             return ADV_ERROR;
        !          6971:         }
        !          6972: 
        !          6973:         ASC_STATS(scp->host, sg_cnt);
        !          6974:         ASC_STATS_ADD(scp->host, sg_elem, scp->use_sg);
        !          6975:     }
        !          6976: 
        !          6977:     ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
        !          6978:     ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
        !          6979: 
        !          6980:     *adv_scsiqpp = scsiqp;
        !          6981: 
        !          6982:     return ASC_NOERROR;
        !          6983: }
        !          6984: 
        !          6985: /*
        !          6986:  * Build scatter-gather list for Adv Library (Wide Board).
        !          6987:  *
        !          6988:  * Return:
        !          6989:  *      ADV_SUCCESS(1) - SG List successfully created
        !          6990:  *      ADV_ERROR(-1) - SG List creation failed
        !          6991:  */
        !          6992: STATIC int
        !          6993: adv_get_sglist(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp,
        !          6994:     Scsi_Cmnd *scp)
        !          6995: {
        !          6996:     ADV_SG_BLOCK        *sg_block;              /* virtual address of a SG */
        !          6997:     ulong               sg_block_next_addr;     /* block and its next */
        !          6998:     ulong               sg_block_physical_addr;
        !          6999:     int                 sg_block_index, i;      /* how many SG entries */
        !          7000:     struct scatterlist  *slp;
        !          7001:     int                 sg_elem_cnt;
        !          7002: 
        !          7003:     slp = (struct scatterlist *) scp->request_buffer;
        !          7004:     sg_elem_cnt = scp->use_sg;
        !          7005: 
        !          7006:     sg_block = scsiqp->sg_list_ptr;
        !          7007:     sg_block_next_addr = (ulong) sg_block;    /* allow math operation */
        !          7008:     sg_block_physical_addr =
        !          7009: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
        !          7010:         (ulong) scsiqp->sg_list_ptr;
        !          7011: #else /* version >= v2.0.0 */
        !          7012:         virt_to_bus(scsiqp->sg_list_ptr);
        !          7013: #endif /* version >= v2.0.0 */
        !          7014:     ADV_ASSERT(ADV_DWALIGN(sg_block_physical_addr) ==
        !          7015:                    sg_block_physical_addr);
        !          7016:     scsiqp->sg_real_addr = sg_block_physical_addr;
        !          7017: 
        !          7018:     sg_block_index = 0;
        !          7019:     do
        !          7020:     {
        !          7021:         sg_block->first_entry_no = sg_block_index;
        !          7022:         for (i = 0; i < NO_OF_SG_PER_BLOCK; i++)
        !          7023:         {
        !          7024:             sg_block->sg_list[i].sg_addr =
        !          7025: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
        !          7026:                 (ulong) slp->address;
        !          7027: #else /* version >= v2.0.0 */
        !          7028:                 virt_to_bus(slp->address);
        !          7029: #endif /* version >= v2.0.0 */
        !          7030:             sg_block->sg_list[i].sg_count = slp->length;
        !          7031:             ASC_STATS_ADD(scp->host, sg_xfer, ASC_CEILING(slp->length, 512));
        !          7032: 
        !          7033:             if (--sg_elem_cnt == 0)
        !          7034:             {   /* last entry, get out */
        !          7035:                 scsiqp->sg_entry_cnt = sg_block_index + i + 1;
        !          7036:                 sg_block->last_entry_no = sg_block_index + i;
        !          7037:                 sg_block->sg_ptr = 0L;    /* next link = NULL */
        !          7038:                 return ADV_SUCCESS;
        !          7039:             }
        !          7040:             slp++;
        !          7041:         } 
        !          7042:         sg_block_next_addr += sizeof(ADV_SG_BLOCK);
        !          7043:         sg_block_physical_addr += sizeof(ADV_SG_BLOCK);
        !          7044:         ADV_ASSERT(ADV_DWALIGN(sg_block_physical_addr) ==
        !          7045:                        sg_block_physical_addr);
        !          7046: 
        !          7047:         sg_block_index += NO_OF_SG_PER_BLOCK;
        !          7048:         sg_block->sg_ptr = (ADV_SG_BLOCK *) sg_block_physical_addr;
        !          7049:         sg_block->last_entry_no = sg_block_index - 1;
        !          7050:         sg_block = (ADV_SG_BLOCK *) sg_block_next_addr; /* virtual addr */
        !          7051:     }
        !          7052:     while (1);
        !          7053:     /* NOTREACHED */
        !          7054: }
        !          7055: 
        !          7056: /*
        !          7057:  * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
        !          7058:  *
        !          7059:  * Interrupt callback function for the Narrow SCSI Asc Library.
        !          7060:  */
        !          7061: STATIC void
        !          7062: asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
        !          7063: {
        !          7064:     asc_board_t         *boardp;
        !          7065:     Scsi_Cmnd           *scp;
        !          7066:     struct Scsi_Host    *shp;
        !          7067:     int                 underrun = ASC_FALSE;
        !          7068:     int                 i;
        !          7069: 
        !          7070:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
        !          7071:     ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp %x, qdonep %x\n",
        !          7072:         (unsigned) asc_dvc_varp, (unsigned) qdonep);
        !          7073:     ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
        !          7074: 
        !          7075:     /*
        !          7076:      * Get the Scsi_Cmnd structure and Scsi_Host structure for the
        !          7077:      * command that has been completed.
        !          7078:      */
        !          7079:     scp = (Scsi_Cmnd *) qdonep->d2.srb_ptr;
        !          7080:     ASC_DBG1(1, "asc_isr_callback: scp %x\n", (unsigned) scp);
        !          7081: 
        !          7082:     if (scp == NULL) {
        !          7083:         ASC_PRINT("asc_isr_callback: scp is NULL\n");
        !          7084:         return;
        !          7085:     }
        !          7086:     ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
        !          7087: 
        !          7088:     /*
        !          7089:      * If the request's host pointer is not valid, display a
        !          7090:      * message and return.
        !          7091:      */
        !          7092:     shp = scp->host;
        !          7093:     for (i = 0; i < asc_board_count; i++) {
        !          7094:         if (asc_host[i] == shp) {
        !          7095:             break;
        !          7096:         }
        !          7097:     }
        !          7098:     if (i == asc_board_count) {
        !          7099:         ASC_PRINT2("asc_isr_callback: scp %x has bad host pointer, host %x\n",
        !          7100:             (unsigned) scp, (unsigned) shp);
        !          7101:         return;
        !          7102:     }
        !          7103: 
        !          7104:     ASC_STATS(shp, callback);
        !          7105:     ASC_DBG1(1, "asc_isr_callback: shp %x\n", (unsigned) shp);
        !          7106: 
        !          7107:     /*
        !          7108:      * If the request isn't found on the active queue, it may
        !          7109:      * have been removed to handle a reset or abort request.
        !          7110:      * Display a message and return.
        !          7111:      */
        !          7112:     boardp = ASC_BOARDP(shp);
        !          7113:     ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
        !          7114:     if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
        !          7115:         ASC_PRINT2("asc_isr_callback: board %d: scp %x not on active queue\n",
        !          7116:             boardp->id, (unsigned) scp);
        !          7117:         return;
        !          7118:     }
        !          7119: 
        !          7120:     /*
        !          7121:      * Check for an underrun condition.
        !          7122:      */
        !          7123:     if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 && 
        !          7124:         qdonep->remain_bytes <= scp->request_bufflen != 0) {
        !          7125:         ASC_DBG1(1, "asc_isr_callback: underrun condition %u bytes\n",
        !          7126:         (unsigned) qdonep->remain_bytes);
        !          7127:         underrun = ASC_TRUE;
        !          7128:     }
        !          7129: 
        !          7130:     /*
        !          7131:      * 'qdonep' contains the command's ending status.
        !          7132:      */
        !          7133:     switch (qdonep->d3.done_stat) {
        !          7134:     case QD_NO_ERROR:
        !          7135:         ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
        !          7136:         switch (qdonep->d3.host_stat) {
        !          7137:         case QHSTA_NO_ERROR:
        !          7138:             scp->result = 0;
        !          7139:             break;
        !          7140:         default:
        !          7141:             /* QHSTA error occurred */
        !          7142:             scp->result = HOST_BYTE(DID_ERROR);
        !          7143:             break;
        !          7144:         }
        !          7145: 
        !          7146:         /*
        !          7147:          * If an INQUIRY command completed successfully, then call
        !          7148:          * the AscInquiryHandling() function to set-up the device.
        !          7149:          */
        !          7150:         if (scp->cmnd[0] == SCSICMD_Inquiry && scp->lun == 0 &&
        !          7151:             (scp->request_bufflen - qdonep->remain_bytes) >= 8)
        !          7152:         {
        !          7153:             AscInquiryHandling(asc_dvc_varp, scp->target & 0x7,
        !          7154:                 (ASC_SCSI_INQUIRY *) scp->request_buffer);
        !          7155:         }
        !          7156: 
        !          7157:         /*
        !          7158:          * If there was an underrun without any other error,
        !          7159:          * set DID_ERROR to indicate the underrun error.
        !          7160:          *
        !          7161:          * Note: There is no way yet to indicate the number
        !          7162:          * of underrun bytes.
        !          7163:          */
        !          7164:         if (scp->result == 0 && underrun == ASC_TRUE) {
        !          7165:             scp->result = HOST_BYTE(DID_UNDERRUN);
        !          7166:         }
        !          7167:         break;
        !          7168: 
        !          7169:     case QD_WITH_ERROR:
        !          7170:         ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
        !          7171:         switch (qdonep->d3.host_stat) {
        !          7172:         case QHSTA_NO_ERROR:
        !          7173:             if (qdonep->d3.scsi_stat == SS_CHK_CONDITION) {
        !          7174:                 ASC_DBG(2, "asc_isr_callback: SS_CHK_CONDITION\n");
        !          7175:                 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
        !          7176:                     sizeof(scp->sense_buffer));
        !          7177:                 /*
        !          7178:                  * Note: The 'status_byte()' macro used by target drivers
        !          7179:                  * defined in scsi.h shifts the status byte returned by
        !          7180:                  * host drivers right by 1 bit. This is why target drivers
        !          7181:                  * also use right shifted status byte definitions. For
        !          7182:                  * instance target drivers use CHECK_CONDITION, defined to
        !          7183:                  * 0x1, instead of the SCSI defined check condition value
        !          7184:                  * of 0x2. Host drivers are supposed to return the status
        !          7185:                  * byte as it is defined by SCSI.
        !          7186:                  */
        !          7187:                 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
        !          7188:                     STATUS_BYTE(qdonep->d3.scsi_stat); 
        !          7189:             } else {
        !          7190:                 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat); 
        !          7191:             }
        !          7192:             break;
        !          7193: 
        !          7194:         default:
        !          7195:             /* QHSTA error occurred */
        !          7196:             ASC_DBG1(1, "asc_isr_callback: host_stat %x\n",
        !          7197:                 qdonep->d3.host_stat);
        !          7198:             scp->result = HOST_BYTE(DID_BAD_TARGET);
        !          7199:             break;
        !          7200:         }
        !          7201:         break;
        !          7202: 
        !          7203:     case QD_ABORTED_BY_HOST:
        !          7204:         ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
        !          7205:         scp->result = HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.scsi_msg) |
        !          7206:                 STATUS_BYTE(qdonep->d3.scsi_stat);
        !          7207:         break;
        !          7208: 
        !          7209:     default:
        !          7210:         ASC_DBG1(1, "asc_isr_callback: done_stat %x\n", qdonep->d3.done_stat);
        !          7211:         scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.scsi_msg) |
        !          7212:                 STATUS_BYTE(qdonep->d3.scsi_stat);
        !          7213:         break;
        !          7214:     }
        !          7215: 
        !          7216:     /*
        !          7217:      * If the 'init_tidmask' bit isn't already set for the target and the
        !          7218:      * current request finished normally, then set the bit for the target
        !          7219:      * to indicate that a device is present.
        !          7220:      */
        !          7221:     if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->target)) == 0 &&
        !          7222:         qdonep->d3.done_stat == QD_NO_ERROR &&
        !          7223:         qdonep->d3.host_stat == QHSTA_NO_ERROR) {
        !          7224:         boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target);
        !          7225:     }
        !          7226: 
        !          7227:     /* 
        !          7228:      * Because interrupts may be enabled by the 'Scsi_Cmnd' done
        !          7229:      * function, add the command to the end of the board's done queue.
        !          7230:      * The done function for the command will be called from
        !          7231:      * advansys_interrupt().
        !          7232:      */
        !          7233:     asc_enqueue(&boardp->done, scp, ASC_BACK);
        !          7234: 
        !          7235:     return;
        !          7236: }
        !          7237: 
        !          7238: /*
        !          7239:  * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
        !          7240:  *
        !          7241:  * Callback function for the Wide SCSI Adv Library.
        !          7242:  */
        !          7243: STATIC void
        !          7244: adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
        !          7245: {
        !          7246:     asc_board_t         *boardp;
        !          7247:     adv_req_t           *reqp;
        !          7248:     Scsi_Cmnd           *scp;
        !          7249:     struct Scsi_Host    *shp;
        !          7250:     int                 underrun = ASC_FALSE;
        !          7251:     int                 i;
        !          7252: 
        !          7253:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
        !          7254:     ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp %x, scsiqp %x\n",
        !          7255:         (unsigned) adv_dvc_varp, (unsigned) scsiqp);
        !          7256:     ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
        !          7257: 
        !          7258:     /*
        !          7259:      * Get the adv_req_t structure for the command that has been
        !          7260:      * completed. The adv_req_t structure actually contains the
        !          7261:      * completed ADV_SCSI_REQ_Q structure.
        !          7262:      */
        !          7263:     reqp = (adv_req_t *) scsiqp->srb_ptr;
        !          7264:     ASC_DBG1(1, "adv_isr_callback: reqp %x\n", (unsigned) reqp);
        !          7265:     if (reqp == NULL) {
        !          7266:         ASC_PRINT("adv_isr_callback: reqp is NULL\n");
        !          7267:         return;
        !          7268:     }
        !          7269: 
        !          7270:     /*
        !          7271:      * Get the Scsi_Cmnd structure and Scsi_Host structure for the
        !          7272:      * command that has been completed.
        !          7273:      *
        !          7274:      * Note: The adv_req_t request structure and adv_sgblk_t structure,
        !          7275:      * if any, * dropped, because a board structure pointer can not be
        !          7276:      * determined.
        !          7277:      */
        !          7278:     scp = reqp->cmndp;
        !          7279:     ASC_DBG1(1, "adv_isr_callback: scp %x\n", (unsigned) scp);
        !          7280:     if (scp == NULL) {
        !          7281:         ASC_PRINT("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
        !          7282:         return;
        !          7283:     }
        !          7284:     ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
        !          7285: 
        !          7286:     /*
        !          7287:      * If the request's host pointer is not valid, display a message
        !          7288:      * and return.
        !          7289:      */
        !          7290:     shp = scp->host;
        !          7291:     for (i = 0; i < asc_board_count; i++) {
        !          7292:         if (asc_host[i] == shp) {
        !          7293:             break;
        !          7294:         }
        !          7295:     }
        !          7296:     /*
        !          7297:      * Note: If the host structure is not found, the adv_req_t request
        !          7298:      * structure and adv_sgblk_t structure, if any, is dropped.
        !          7299:      */
        !          7300:     if (i == asc_board_count) {
        !          7301:         ASC_PRINT2("adv_isr_callback: scp %x has bad host pointer, host %x\n",
        !          7302:             (unsigned) scp, (unsigned) shp);
        !          7303:         return;
        !          7304:     }
        !          7305: 
        !          7306:     ASC_STATS(shp, callback);
        !          7307:     ASC_DBG1(1, "adv_isr_callback: shp %x\n", (unsigned) shp);
        !          7308: 
        !          7309:     /*
        !          7310:      * If the request isn't found on the active queue, it may have been
        !          7311:      * removed to handle a reset or abort request. Display a message and
        !          7312:      * return.
        !          7313:      *
        !          7314:      * Note: Because the structure may still be in use don't attempt
        !          7315:      * to free the adv_req_t and adv_sgblk_t, if any, structures.
        !          7316:      */
        !          7317:     boardp = ASC_BOARDP(shp);
        !          7318:     ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
        !          7319:     if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
        !          7320:         ASC_PRINT2("adv_isr_callback: board %d: scp %x not on active queue\n",
        !          7321:             boardp->id, (unsigned) scp);
        !          7322:         return;
        !          7323:     }
        !          7324: 
        !          7325:     /*
        !          7326:      * Check for an underrun condition.
        !          7327:      */
        !          7328:     if (scp->request_bufflen != 0 && scsiqp->data_cnt != 0) {
        !          7329:         ASC_DBG1(1, "adv_isr_callback: underrun condition %lu bytes\n",
        !          7330:         scsiqp->data_cnt);
        !          7331:         underrun = ASC_TRUE;
        !          7332:     }
        !          7333: 
        !          7334:     /*
        !          7335:      * 'done_status' contains the command's ending status.
        !          7336:      */
        !          7337:     switch (scsiqp->done_status) {
        !          7338:     case QD_NO_ERROR:
        !          7339:         ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
        !          7340:         switch (scsiqp->host_status) {
        !          7341:         case QHSTA_NO_ERROR:
        !          7342:             scp->result = 0;
        !          7343:             break;
        !          7344:         default:
        !          7345:             /* QHSTA error occurred. */
        !          7346:             ASC_DBG1(2, "adv_isr_callback: host_status %x\n",
        !          7347:                 scsiqp->host_status);
        !          7348:             scp->result = HOST_BYTE(DID_ERROR);
        !          7349:             break;
        !          7350:         }
        !          7351:         /*
        !          7352:          * If there was an underrun without any other error,
        !          7353:          * set DID_ERROR to indicate the underrun error.
        !          7354:          *
        !          7355:          * Note: There is no way yet to indicate the number
        !          7356:          * of underrun bytes.
        !          7357:          */
        !          7358:         if (scp->result == 0 && underrun == ASC_TRUE) {
        !          7359:                 scp->result = HOST_BYTE(DID_UNDERRUN);
        !          7360:         }
        !          7361:         break;
        !          7362: 
        !          7363:     case QD_WITH_ERROR:
        !          7364:         ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
        !          7365:         switch (scsiqp->host_status) {
        !          7366:         case QHSTA_NO_ERROR:
        !          7367:             if (scsiqp->scsi_status == SS_CHK_CONDITION) {
        !          7368:                 ASC_DBG(2, "adv_isr_callback: SS_CHK_CONDITION\n");
        !          7369:                 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
        !          7370:                     sizeof(scp->sense_buffer));
        !          7371:                 /*
        !          7372:                  * Note: The 'status_byte()' macro used by target drivers
        !          7373:                  * defined in scsi.h shifts the status byte returned by
        !          7374:                  * host drivers right by 1 bit. This is why target drivers
        !          7375:                  * also use right shifted status byte definitions. For
        !          7376:                  * instance target drivers use CHECK_CONDITION, defined to
        !          7377:                  * 0x1, instead of the SCSI defined check condition value
        !          7378:                  * of 0x2. Host drivers are supposed to return the status
        !          7379:                  * byte as it is defined by SCSI.
        !          7380:                  */
        !          7381:                 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
        !          7382:                     STATUS_BYTE(scsiqp->scsi_status);
        !          7383:             } else {
        !          7384:                 scp->result = STATUS_BYTE(scsiqp->scsi_status);
        !          7385:             }
        !          7386:             break;
        !          7387: 
        !          7388:         default:
        !          7389:             /* Some other QHSTA error occurred. */
        !          7390:             ASC_DBG1(1, "adv_isr_callback: host_status %x\n",
        !          7391:                 scsiqp->host_status);
        !          7392:             scp->result = HOST_BYTE(DID_BAD_TARGET);
        !          7393:             break;
        !          7394:         }
        !          7395:         break;
        !          7396: 
        !          7397:     case QD_ABORTED_BY_HOST:
        !          7398:         ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
        !          7399:         scp->result = HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
        !          7400:         break;
        !          7401: 
        !          7402:     default:
        !          7403:         ASC_DBG1(1, "adv_isr_callback: done_status %x\n", scsiqp->done_status);
        !          7404:         scp->result = HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
        !          7405:         break;
        !          7406:     }
        !          7407: 
        !          7408:     /*
        !          7409:      * If the 'init_tidmask' bit isn't already set for the target and the
        !          7410:      * current request finished normally, then set the bit for the target
        !          7411:      * to indicate that a device is present.
        !          7412:      */
        !          7413:     if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->target)) == 0 &&
        !          7414:         scsiqp->done_status == QD_NO_ERROR &&
        !          7415:         scsiqp->host_status == QHSTA_NO_ERROR) {
        !          7416:         boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target);
        !          7417:     }
        !          7418: 
        !          7419:     /* 
        !          7420:      * Because interrupts may be enabled by the 'Scsi_Cmnd' done
        !          7421:      * function, add the command to the end of the board's done queue.
        !          7422:      * The done function for the command will be called from
        !          7423:      * advansys_interrupt().
        !          7424:      */
        !          7425:     asc_enqueue(&boardp->done, scp, ASC_BACK);
        !          7426: 
        !          7427:     /*
        !          7428:      * Free the adv_sgblk_t structure, if any, by adding it back
        !          7429:      * to the board free list.
        !          7430:      */
        !          7431:     if (reqp->sgblkp != NULL) {
        !          7432:         reqp->sgblkp->next_sgblkp = boardp->adv_sgblkp;
        !          7433:         boardp->adv_sgblkp = reqp->sgblkp;
        !          7434:     }
        !          7435: 
        !          7436:     /*
        !          7437:      * Free the adv_req_t structure used with the command by adding
        !          7438:      * it back to the board free list.
        !          7439:      */
        !          7440:     reqp->next_reqp = boardp->adv_reqp;
        !          7441:     boardp->adv_reqp = reqp;
        !          7442: 
        !          7443:     ASC_DBG(1, "adv_isr_callback: done\n");
        !          7444: 
        !          7445:     return;
        !          7446: }
        !          7447: 
        !          7448: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
        !          7449: #ifdef ASC_CONFIG_PCI
        !          7450: /*
        !          7451:  * Search for an AdvanSys PCI device in the PCI configuration space.
        !          7452:  */
        !          7453: ASC_INITFUNC(
        !          7454: STATIC int
        !          7455: asc_srch_pci_dev(PCI_DEVICE *pciDevice)
        !          7456: )
        !          7457: {
        !          7458:     int                        ret = PCI_DEVICE_NOT_FOUND;
        !          7459: 
        !          7460:     ASC_DBG(2, "asc_srch_pci_dev: begin\n");
        !          7461: 
        !          7462:     if (pci_scan_method == -1) {
        !          7463:         pci_scan_method = asc_scan_method();
        !          7464:     }
        !          7465:     pciDevice->type = pci_scan_method;
        !          7466:     ASC_DBG1(2, "asc_srch_pci_dev: type %d\n", pciDevice->type);
        !          7467: 
        !          7468:     ret = asc_pci_find_dev(pciDevice);
        !          7469:     ASC_DBG1(2, "asc_srch_pci_dev: asc_pci_find_dev() return %d\n", ret);
        !          7470:     if (ret == PCI_DEVICE_FOUND) {
        !          7471:         pciDevice->slotNumber = pciDevice->slotFound + 1;
        !          7472:         pciDevice->startSlot = pciDevice->slotFound + 1;
        !          7473:     } else {
        !          7474:         if (pciDevice->bridge > pciDevice->busNumber) {
        !          7475:             ASC_DBG2(2, "asc_srch_pci_dev: bridge %x, busNumber %x\n",
        !          7476:                 pciDevice->bridge, pciDevice->busNumber);
        !          7477:             pciDevice->busNumber++;
        !          7478:             pciDevice->slotNumber = 0;
        !          7479:             pciDevice->startSlot = 0;
        !          7480:             pciDevice->endSlot = 0x0f;
        !          7481:             ret = asc_srch_pci_dev(pciDevice);
        !          7482:             ASC_DBG1(2, "asc_srch_pci_dev: recursive call return %d\n", ret);
        !          7483:         }
        !          7484:     }
        !          7485: 
        !          7486:     ASC_DBG1(2, "asc_srch_pci_dev: return %d\n", ret);
        !          7487:     return ret;
        !          7488: }
        !          7489: 
        !          7490: /*
        !          7491:  * Determine the access method to be used for 'pciDevice'.
        !          7492:  */
        !          7493: ASC_INITFUNC(
        !          7494: STATIC uchar
        !          7495: asc_scan_method(void)
        !          7496: )
        !          7497: {
        !          7498:     ushort      data;
        !          7499:     PCI_DATA    pciData;
        !          7500:     uchar       type;
        !          7501:     uchar       slot;
        !          7502: 
        !          7503:     ASC_DBG(2, "asc_scan_method: begin\n");
        !          7504:     memset(&pciData, 0, sizeof(pciData));
        !          7505:     for (type = 1; type < 3; type++) {
        !          7506:         pciData.type = type;
        !          7507:         for (slot = 0; slot < PCI_MAX_SLOT; slot++) {
        !          7508:             pciData.slot = slot;
        !          7509:             data = asc_get_cfg_word(&pciData);
        !          7510:             if ((data != 0xFFFF) && (data != 0x0000)) {
        !          7511:                 ASC_DBG2(4, "asc_scan_method: data %x, type %d\n", data, type);
        !          7512:                 return (type);
        !          7513:             }
        !          7514:         }
        !          7515:     }
        !          7516:     ASC_DBG1(4, "asc_scan_method: type %d\n", type);
        !          7517:     return (type);
        !          7518: }
        !          7519: 
        !          7520: /*
        !          7521:  * Check for an AdvanSys PCI device in 'pciDevice'.
        !          7522:  *
        !          7523:  * Return PCI_DEVICE_FOUND if found, otherwise return PCI_DEVICE_NOT_FOUND.
        !          7524:  */
        !          7525: ASC_INITFUNC(
        !          7526: STATIC int
        !          7527: asc_pci_find_dev(PCI_DEVICE *pciDevice)
        !          7528: )
        !          7529: {
        !          7530:     PCI_DATA    pciData;
        !          7531:     ushort      vendorid, deviceid;
        !          7532:     uchar       classcode, subclass;
        !          7533:     uchar       lslot;
        !          7534: 
        !          7535:     ASC_DBG(3, "asc_pci_find_dev: begin\n");
        !          7536:     pciData.type = pciDevice->type;
        !          7537:     pciData.bus = pciDevice->busNumber;
        !          7538:     pciData.func = pciDevice->devFunc;
        !          7539:     lslot = pciDevice->startSlot;
        !          7540:     for (; lslot < pciDevice->endSlot; lslot++) {
        !          7541:         pciData.slot = lslot;
        !          7542:         pciData.offset = VENDORID_OFFSET;
        !          7543:         vendorid = asc_get_cfg_word(&pciData);
        !          7544:         ASC_DBG1(3, "asc_pci_find_dev: vendorid %x\n", vendorid);
        !          7545:         if (vendorid != 0xffff) {
        !          7546:             pciData.offset = DEVICEID_OFFSET;
        !          7547:             deviceid = asc_get_cfg_word(&pciData);
        !          7548:             ASC_DBG1(3, "asc_pci_find_dev: deviceid %x\n", deviceid);
        !          7549:             if ((vendorid == ASC_PCI_VENDORID) &&
        !          7550:                 ((deviceid == ASC_PCI_DEVICE_ID_1100) ||
        !          7551:                  (deviceid == ASC_PCI_DEVICE_ID_1200) ||
        !          7552:                  (deviceid == ASC_PCI_DEVICE_ID_1300) ||
        !          7553:                  (deviceid == ASC_PCI_DEVICE_ID_2300))) {
        !          7554:                 pciDevice->slotFound = lslot;
        !          7555:                 ASC_DBG(3, "asc_pci_find_dev: PCI_DEVICE_FOUND\n");
        !          7556:                 return PCI_DEVICE_FOUND;
        !          7557:             } else {
        !          7558:                 pciData.offset = SUBCLASS_OFFSET;
        !          7559:                 subclass = asc_get_cfg_byte(&pciData);
        !          7560:                 pciData.offset = CLASSCODE_OFFSET;
        !          7561:                 classcode = asc_get_cfg_byte(&pciData);
        !          7562:                 if ((classcode & PCI_BASE_CLASS_BRIDGE_DEVICE) &&
        !          7563:                     (subclass & PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER)) {
        !          7564:                     pciDevice->bridge++;
        !          7565:                 }
        !          7566:                 ASC_DBG2(3, "asc_pci_find_dev: subclass %x, classcode %x\n",
        !          7567:                     subclass, classcode);
        !          7568:             }
        !          7569:         }
        !          7570:     }
        !          7571:     return PCI_DEVICE_NOT_FOUND;
        !          7572: }
        !          7573: 
        !          7574: /*
        !          7575:  * Read PCI configuration data into 'pciConfig'.
        !          7576:  */
        !          7577: ASC_INITFUNC(
        !          7578: STATIC void
        !          7579: asc_get_pci_cfg(PCI_DEVICE *pciDevice, PCI_CONFIG_SPACE *pciConfig)
        !          7580: )
        !          7581: {
        !          7582:     PCI_DATA    pciData;
        !          7583:     uchar       counter;
        !          7584:     uchar       *localConfig;
        !          7585: 
        !          7586:     ASC_DBG1(4, "asc_get_pci_cfg: slotFound %d\n ",
        !          7587:         pciDevice->slotFound);
        !          7588: 
        !          7589:     pciData.type = pciDevice->type;
        !          7590:     pciData.bus = pciDevice->busNumber;
        !          7591:     pciData.slot = pciDevice->slotFound;
        !          7592:     pciData.func = pciDevice->devFunc;
        !          7593:     localConfig = (uchar *) pciConfig;
        !          7594: 
        !          7595:     for (counter = 0; counter < sizeof(PCI_CONFIG_SPACE); counter++) {
        !          7596:         pciData.offset = counter;
        !          7597:         *localConfig = asc_get_cfg_byte(&pciData);
        !          7598:         ASC_DBG1(4, "asc_get_pci_cfg: byte %x\n", *localConfig);
        !          7599:         localConfig++;
        !          7600:     }
        !          7601:     ASC_DBG1(4, "asc_get_pci_cfg: counter %d\n", counter);
        !          7602: }
        !          7603: 
        !          7604: /*
        !          7605:  * Read a word (16 bits) from the PCI configuration space.
        !          7606:  *
        !          7607:  * The configuration mechanism is checked for the correct access method.
        !          7608:  */
        !          7609: ASC_INITFUNC(
        !          7610: STATIC ushort
        !          7611: asc_get_cfg_word(PCI_DATA *pciData)
        !          7612: )
        !          7613: {
        !          7614:     ushort   tmp;
        !          7615:     ulong    address;
        !          7616:     ulong    lbus = pciData->bus;
        !          7617:     ulong    lslot = pciData->slot;
        !          7618:     ulong    lfunc = pciData->func;
        !          7619:     uchar    t2CFA, t2CF8;
        !          7620:     ulong    t1CF8, t1CFC;
        !          7621: 
        !          7622:     ASC_DBG4(4, "asc_get_cfg_word: type %d, bus %lu, slot %lu, func %lu\n",
        !          7623:         pciData->type, lbus, lslot, lfunc);
        !          7624: 
        !          7625:     /*
        !          7626:      * Check type of configuration mechanism.
        !          7627:      */
        !          7628:     if (pciData->type == 2) {
        !          7629:         /*
        !          7630:          * Save registers to be restored later.
        !          7631:          */
        !          7632:         t2CFA = inp(0xCFA);    /* save PCI bus register */
        !          7633:         t2CF8 = inp(0xCF8);    /* save config space enable register */
        !          7634: 
        !          7635:         /*
        !          7636:          * Write the bus and enable registers.
        !          7637:          */
        !          7638:         /* set for type 1 cycle, if needed */
        !          7639:         outp(0xCFA, pciData->bus);
        !          7640:         /* set the function number */
        !          7641:         outp(0xCF8, 0x10 | (pciData->func << 1)) ;
        !          7642: 
        !          7643:         /*
        !          7644:          * Read the configuration space type 2 locations.
        !          7645:          */
        !          7646:         tmp = (ushort) inpw(0xC000 | ((pciData->slot << 8) + pciData->offset));
        !          7647: 
        !          7648:         outp(0xCFA, t2CFA);    /* save PCI bus register */
        !          7649:         outp(0xCF8, t2CF8);    /* save config space enable register */
        !          7650:     } else {
        !          7651:         /*
        !          7652:          * Type 1 or 3 configuration mechanism.
        !          7653:          *
        !          7654:          * Save the CONFIG_ADDRESS and CONFIG_DATA register values.
        !          7655:          */
        !          7656:         t1CF8 = inpl(0xCF8);
        !          7657:         t1CFC = inpl(0xCFC);
        !          7658: 
        !          7659:         /*
        !          7660:          * enable <31>, bus = <23:16>, slot = <15:11>,
        !          7661:          * func = <10:8>, reg = <7:2>
        !          7662:          */
        !          7663:         address = (ulong) ((lbus << 16) | (lslot << 11) |
        !          7664:             (lfunc << 8) | (pciData->offset & 0xFC) | 0x80000000L);
        !          7665: 
        !          7666:         /*
        !          7667:          * Write out the address to CONFIG_ADDRESS.
        !          7668:          */
        !          7669:         outpl(0xCF8, address);
        !          7670: 
        !          7671:         /*
        !          7672:          * Read in word from CONFIG_DATA.
        !          7673:          */
        !          7674:         tmp = (ushort) ((inpl(0xCFC) >>
        !          7675:                  ((pciData->offset & 2) * 8)) & 0xFFFF);
        !          7676: 
        !          7677:         /*
        !          7678:          * Restore registers.
        !          7679:          */
        !          7680:         outpl(0xCF8, t1CF8);
        !          7681:         outpl(0xCFC, t1CFC);
        !          7682:     }
        !          7683:     ASC_DBG1(4, "asc_get_cfg_word: config data: %x\n", tmp);
        !          7684:     return tmp;
        !          7685: }
        !          7686: 
        !          7687: /*
        !          7688:  * Reads a byte from the PCI configuration space.
        !          7689:  *
        !          7690:  * The configuration mechanism is checked for the correct access method.
        !          7691:  */
        !          7692: ASC_INITFUNC(
        !          7693: STATIC uchar
        !          7694: asc_get_cfg_byte(PCI_DATA *pciData)
        !          7695: )
        !          7696: {
        !          7697:     uchar tmp;
        !          7698:     ulong address;
        !          7699:     ulong lbus = pciData->bus, lslot = pciData->slot, lfunc = pciData->func;
        !          7700:     uchar t2CFA, t2CF8;
        !          7701:     ulong t1CF8, t1CFC;
        !          7702: 
        !          7703:     ASC_DBG1(4, "asc_get_cfg_byte: type: %d\n", pciData->type);
        !          7704: 
        !          7705:     /*
        !          7706:      * Check type of configuration mechanism.
        !          7707:      */
        !          7708:     if (pciData->type == 2) {
        !          7709:         /*
        !          7710:          * Save registers to be restored later.
        !          7711:          */
        !          7712:         t2CFA = inp(0xCFA);    /* save PCI bus register */
        !          7713:         t2CF8 = inp(0xCF8);    /* save config space enable register */
        !          7714: 
        !          7715:         /*
        !          7716:          * Write the bus and enable registers.
        !          7717:          */
        !          7718:         /* set for type 1 cycle, if needed */
        !          7719:         outp(0xCFA, pciData->bus);
        !          7720:         /* set the function number */
        !          7721:         outp(0xCF8, 0x10 | (pciData->func << 1));
        !          7722: 
        !          7723:         /*
        !          7724:          * Read configuration space type 2 locations.
        !          7725:          */
        !          7726:         tmp = inp(0xC000 | ((pciData->slot << 8) + pciData->offset));
        !          7727: 
        !          7728:         /*
        !          7729:          * Restore registers.
        !          7730:          */
        !          7731:         outp(0xCF8, t2CF8);    /* restore the enable register */
        !          7732:         outp(0xCFA, t2CFA);    /* restore PCI bus register */
        !          7733:     } else {
        !          7734:         /*
        !          7735:          * Type 1 or 3 configuration mechanism.
        !          7736:          *
        !          7737:          * Save CONFIG_ADDRESS and CONFIG_DATA register values.
        !          7738:          */
        !          7739:         t1CF8 = inpl(0xCF8);
        !          7740:         t1CFC = inpl(0xCFC);
        !          7741: 
        !          7742:         /*
        !          7743:          * enable <31>, bus = <23:16>, slot = <15:11>, func = <10:8>,
        !          7744:          * reg = <7:2>
        !          7745:          */
        !          7746:         address = (ulong) ((lbus << 16) | (lslot << 11) |
        !          7747:             (lfunc << 8) | (pciData->offset & 0xFC) | 0x80000000L);
        !          7748: 
        !          7749:         /*
        !          7750:          * Write out address to CONFIG_ADDRESS.
        !          7751:          */
        !          7752:         outpl(0xCF8, address);
        !          7753: 
        !          7754:         /*
        !          7755:          * Read in word from CONFIG_DATA.
        !          7756:          */
        !          7757:         tmp = (uchar) ((inpl(0xCFC) >> ((pciData->offset & 3) * 8)) & 0xFF);
        !          7758: 
        !          7759:         /*
        !          7760:          * Restore registers.
        !          7761:          */
        !          7762:         outpl(0xCF8, t1CF8);
        !          7763:         outpl(0xCFC, t1CFC);
        !          7764:     }
        !          7765:     ASC_DBG1(4, "asc_get_cfg_byte: config data: %x\n", tmp);
        !          7766:     return tmp;
        !          7767: }
        !          7768: 
        !          7769: /*
        !          7770:  * Write a byte to the PCI configuration space.
        !          7771:  */
        !          7772: ASC_INITFUNC(
        !          7773: STATIC void
        !          7774: asc_put_cfg_byte(PCI_DATA *pciData, uchar byte_data)
        !          7775: )
        !          7776: {
        !          7777:     ulong tmpl;
        !          7778:     ulong address;
        !          7779:     ulong lbus = pciData->bus, lslot = pciData->slot, lfunc = pciData->func;
        !          7780:     uchar t2CFA, t2CF8;
        !          7781:     ulong t1CF8, t1CFC;
        !          7782: 
        !          7783:     ASC_DBG2(4, "asc_put_cfg_byte: type: %d, byte_data %x\n",
        !          7784:         pciData->type, byte_data);
        !          7785: 
        !          7786:     /*
        !          7787:      * Check type of configuration mechanism.
        !          7788:      */
        !          7789:     if (pciData->type == 2) {
        !          7790: 
        !          7791:         /*
        !          7792:          * Save registers to be restored later.
        !          7793:          */
        !          7794:         t2CFA = inp(0xCFA);    /* save PCI bus register */
        !          7795:         t2CF8 = inp(0xCF8);    /* save config space enable register */
        !          7796: 
        !          7797:         /*
        !          7798:          * Write bus and enable registers.
        !          7799:          */
        !          7800:         outp(0xCFA, pciData->bus);
        !          7801: 
        !          7802:         /*
        !          7803:          * Set the function number.
        !          7804:          */
        !          7805:         outp(0xCF8, 0x10 | (pciData->func << 1));
        !          7806: 
        !          7807:         /*
        !          7808:          * Write the configuration space type 2 locations.
        !          7809:          */
        !          7810:         outp(0xC000 | ((pciData->slot << 8) + pciData->offset), byte_data);
        !          7811: 
        !          7812:         /*
        !          7813:          * Restore registers.
        !          7814:          */
        !          7815:         outp(0xCF8, t2CF8);    /* restore the enable register */
        !          7816:         outp(0xCFA, t2CFA);    /* restore PCI bus register    */
        !          7817:     } else {
        !          7818: 
        !          7819:         /*
        !          7820:          * Type 1 or 3 configuration mechanism.
        !          7821:          *
        !          7822:          * Save the CONFIG_ADDRESS and CONFIG_DATA register values.
        !          7823:          */
        !          7824:         t1CF8 = inpl(0xCF8);
        !          7825:         t1CFC = inpl(0xCFC);
        !          7826: 
        !          7827:         /*
        !          7828:          * enable <31>, bus = <23:16>, slot = <15:11>, func = <10:8>,
        !          7829:          * reg = <7:2>
        !          7830:          */
        !          7831:         address = (ulong) ((lbus << 16) | (lslot << 11) | (lfunc << 8) |
        !          7832:                 (pciData->offset & 0xFC) | 0x80000000L);
        !          7833:         /*
        !          7834:          * Write out address to CONFIG_ADDRESS.
        !          7835:          */
        !          7836:         outpl(0xCF8, address);
        !          7837: 
        !          7838:         /*
        !          7839:          * Write double word to CONFIG_DATA preserving the bytes
        !          7840:          * in the double not written.
        !          7841:          */
        !          7842:         tmpl = inpl(0xCFC) & ~(0xFF << ((pciData->offset & 3) * 8));
        !          7843:         outpl(0xCFC, tmpl | (byte_data << ((pciData->offset & 3) * 8)));
        !          7844: 
        !          7845:         /*
        !          7846:          * Restore registers.
        !          7847:          */
        !          7848:         outpl(0xCF8, t1CF8);
        !          7849:         outpl(0xCFC, t1CFC);
        !          7850:     }
        !          7851:     ASC_DBG(4, "asc_put_cfg_byte: end\n");
        !          7852: }
        !          7853: #endif /* ASC_CONFIG_PCI */
        !          7854: #endif /* version < v2.1.93 */
        !          7855: 
        !          7856: /*
        !          7857:  * Add a 'REQP' to the end of specified queue. Set 'tidmask'
        !          7858:  * to indicate a command is queued for the device.
        !          7859:  *
        !          7860:  * 'flag' may be either ASC_FRONT or ASC_BACK.
        !          7861:  *
        !          7862:  * 'REQPNEXT(reqp)' returns reqp's next pointer.
        !          7863:  */
        !          7864: STATIC void
        !          7865: asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
        !          7866: {
        !          7867:     int        tid;
        !          7868: 
        !          7869:     ASC_DBG3(3, "asc_enqueue: ascq %x, reqp %x, flag %d\n",
        !          7870:         (unsigned) ascq, (unsigned) reqp, flag);
        !          7871:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
        !          7872:     ASC_ASSERT(reqp != NULL);
        !          7873:     ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
        !          7874:     tid = REQPTID(reqp);
        !          7875:     ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
        !          7876:     if (flag == ASC_FRONT) {
        !          7877:         REQPNEXT(reqp) = ascq->q_first[tid];
        !          7878:         ascq->q_first[tid] = reqp;
        !          7879:         /* If the queue was empty, set the last pointer. */
        !          7880:         if (ascq->q_last[tid] == NULL) {
        !          7881:             ascq->q_last[tid] = reqp;
        !          7882:         }
        !          7883:     } else { /* ASC_BACK */
        !          7884:         if (ascq->q_last[tid] != NULL) {
        !          7885:             REQPNEXT(ascq->q_last[tid]) = reqp;
        !          7886:         }
        !          7887:         ascq->q_last[tid] = reqp;
        !          7888:         REQPNEXT(reqp) = NULL;
        !          7889:         /* If the queue was empty, set the first pointer. */
        !          7890:         if (ascq->q_first[tid] == NULL) {
        !          7891:             ascq->q_first[tid] = reqp;
        !          7892:         }
        !          7893:     }
        !          7894:     /* The queue has at least one entry, set its bit. */
        !          7895:     ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
        !          7896: #ifdef ADVANSYS_STATS
        !          7897:     /* Maintain request queue statistics. */
        !          7898:     ascq->q_tot_cnt[tid]++;
        !          7899:     ascq->q_cur_cnt[tid]++;
        !          7900:     if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
        !          7901:         ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
        !          7902:         ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
        !          7903:             tid, ascq->q_max_cnt[tid]);
        !          7904:     }
        !          7905:     REQPTIME(reqp) = REQTIMESTAMP();
        !          7906: #endif /* ADVANSYS_STATS */
        !          7907:     ASC_DBG1(3, "asc_enqueue: reqp %x\n", (unsigned) reqp);
        !          7908:     return;
        !          7909: }
        !          7910: 
        !          7911: /*
        !          7912:  * Return first queued 'REQP' on the specified queue for
        !          7913:  * the specified target device. Clear the 'tidmask' bit for
        !          7914:  * the device if no more commands are left queued for it.
        !          7915:  *
        !          7916:  * 'REQPNEXT(reqp)' returns reqp's next pointer.
        !          7917:  */
        !          7918: STATIC REQP
        !          7919: asc_dequeue(asc_queue_t *ascq, int tid)
        !          7920: {
        !          7921:     REQP    reqp;
        !          7922: 
        !          7923:     ASC_DBG2(3, "asc_dequeue: ascq %x, tid %d\n", (unsigned) ascq, tid);
        !          7924:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
        !          7925:     ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
        !          7926:     if ((reqp = ascq->q_first[tid]) != NULL) {
        !          7927:         ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
        !          7928:         ascq->q_first[tid] = REQPNEXT(reqp);
        !          7929:         /* If the queue is empty, clear its bit and the last pointer. */
        !          7930:         if (ascq->q_first[tid] == NULL) {
        !          7931:             ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
        !          7932:             ASC_ASSERT(ascq->q_last[tid] == reqp);
        !          7933:             ascq->q_last[tid] = NULL;
        !          7934:         }
        !          7935: #ifdef ADVANSYS_STATS
        !          7936:         /* Maintain request queue statistics. */
        !          7937:         ascq->q_cur_cnt[tid]--;
        !          7938:         ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
        !          7939:         REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
        !          7940: #endif /* ADVANSYS_STATS */
        !          7941:     }
        !          7942:     ASC_DBG1(3, "asc_dequeue: reqp %x\n", (unsigned) reqp);
        !          7943:     return reqp;
        !          7944: }
        !          7945: 
        !          7946: /*
        !          7947:  * Return a pointer to a singly linked list of all the requests queued
        !          7948:  * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
        !          7949:  *
        !          7950:  * If 'lastpp' is not NULL, '*lastpp' will be set to point to the 
        !          7951:  * the last request returned in the singly linked list.
        !          7952:  *
        !          7953:  * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
        !          7954:  * then all queued requests are concatenated into one list and
        !          7955:  * returned.
        !          7956:  *
        !          7957:  * Note: If 'lastpp' is used to append a new list to the end of
        !          7958:  * an old list, only change the old list last pointer if '*lastpp'
        !          7959:  * (or the function return value) is not NULL, i.e. use a temporary
        !          7960:  * variable for 'lastpp' and check its value after the function return
        !          7961:  * before assigning it to the list last pointer.
        !          7962:  *
        !          7963:  * Unfortunately collecting queuing time statistics adds overhead to
        !          7964:  * the function that isn't inherent to the function's algorithm.
        !          7965:  */
        !          7966: STATIC REQP
        !          7967: asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
        !          7968: {
        !          7969:     REQP    firstp, lastp;
        !          7970:     int     i;
        !          7971: 
        !          7972:     ASC_DBG2(3, "asc_dequeue_list: ascq %x, tid %d\n", (unsigned) ascq, tid);
        !          7973:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
        !          7974:     ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
        !          7975: 
        !          7976:     /*
        !          7977:      * If 'tid' is not ASC_TID_ALL, return requests only for
        !          7978:      * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
        !          7979:      * requests for all tids.
        !          7980:      */
        !          7981:     if (tid != ASC_TID_ALL) {
        !          7982:         /* Return all requests for the specified 'tid'. */
        !          7983:         if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
        !          7984:             /* List is empty; Set first and last return pointers to NULL. */
        !          7985:             firstp = lastp = NULL;
        !          7986:         } else {
        !          7987:             firstp = ascq->q_first[tid];
        !          7988:             lastp = ascq->q_last[tid];
        !          7989:             ascq->q_first[tid] = ascq->q_last[tid] = NULL;
        !          7990:             ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
        !          7991: #ifdef ADVANSYS_STATS
        !          7992:             {
        !          7993:                 REQP reqp;
        !          7994:                 ascq->q_cur_cnt[tid] = 0;
        !          7995:                 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
        !          7996:                     REQTIMESTAT("asc_dequeue_list", ascq, reqp, tid);
        !          7997:                 }
        !          7998:             }
        !          7999: #endif /* ADVANSYS_STATS */
        !          8000:         }
        !          8001:     } else {
        !          8002:         /* Return all requests for all tids. */
        !          8003:         firstp = lastp = NULL;
        !          8004:         for (i = 0; i <= ADV_MAX_TID; i++) {
        !          8005:             if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
        !          8006:                 if (firstp == NULL) {
        !          8007:                     firstp = ascq->q_first[i];
        !          8008:                     lastp = ascq->q_last[i];
        !          8009:                 } else {
        !          8010:                     ASC_ASSERT(lastp != NULL);
        !          8011:                     REQPNEXT(lastp) = ascq->q_first[i];
        !          8012:                     lastp = ascq->q_last[i];
        !          8013:                 }
        !          8014:                 ascq->q_first[i] = ascq->q_last[i] = NULL;
        !          8015:                 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
        !          8016: #ifdef ADVANSYS_STATS
        !          8017:                 ascq->q_cur_cnt[i] = 0;
        !          8018: #endif /* ADVANSYS_STATS */
        !          8019:             }
        !          8020:         }
        !          8021: #ifdef ADVANSYS_STATS
        !          8022:         {
        !          8023:             REQP reqp;
        !          8024:             for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
        !          8025:                 REQTIMESTAT("asc_dequeue_list", ascq, reqp, reqp->target);
        !          8026:             }
        !          8027:         }
        !          8028: #endif /* ADVANSYS_STATS */
        !          8029:     }
        !          8030:     if (lastpp) {
        !          8031:         *lastpp = lastp;
        !          8032:     }
        !          8033:     ASC_DBG1(3, "asc_dequeue_list: firstp %x\n", (unsigned) firstp);
        !          8034:     return firstp;
        !          8035: }
        !          8036: 
        !          8037: /*
        !          8038:  * Remove the specified 'REQP' from the specified queue for
        !          8039:  * the specified target device. Clear the 'tidmask' bit for the
        !          8040:  * device if no more commands are left queued for it.
        !          8041:  *
        !          8042:  * 'REQPNEXT(reqp)' returns reqp's the next pointer.
        !          8043:  *
        !          8044:  * Return ASC_TRUE if the command was found and removed,
        !          8045:  * otherwise return ASC_FALSE.
        !          8046:  */
        !          8047: STATIC int
        !          8048: asc_rmqueue(asc_queue_t *ascq, REQP reqp)
        !          8049: {
        !          8050:     REQP        currp, prevp;
        !          8051:     int         tid;
        !          8052:     int         ret = ASC_FALSE;
        !          8053: 
        !          8054:     ASC_DBG2(3, "asc_rmqueue: ascq %x, reqp %x\n",
        !          8055:         (unsigned) ascq, (unsigned) reqp);
        !          8056:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
        !          8057:     ASC_ASSERT(reqp != NULL);
        !          8058: 
        !          8059:     tid = REQPTID(reqp);
        !          8060:     ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
        !          8061: 
        !          8062:     /*
        !          8063:      * Handle the common case of 'reqp' being the first
        !          8064:      * entry on the queue.
        !          8065:      */
        !          8066:     if (reqp == ascq->q_first[tid]) {
        !          8067:         ret = ASC_TRUE;
        !          8068:         ascq->q_first[tid] = REQPNEXT(reqp);
        !          8069:         /* If the queue is now empty, clear its bit and the last pointer. */
        !          8070:         if (ascq->q_first[tid] == NULL) {
        !          8071:             ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
        !          8072:             ASC_ASSERT(ascq->q_last[tid] == reqp);
        !          8073:             ascq->q_last[tid] = NULL;
        !          8074:         }
        !          8075:     } else if (ascq->q_first[tid] != NULL) {
        !          8076:         ASC_ASSERT(ascq->q_last[tid] != NULL);
        !          8077:         /*
        !          8078:          * Because the case of 'reqp' being the first entry has been
        !          8079:          * handled above and it is known the queue is not empty, if
        !          8080:          * 'reqp' is found on the queue it is guaranteed the queue will
        !          8081:          * not become empty and that 'q_first[tid]' will not be changed.
        !          8082:          *
        !          8083:          * Set 'prevp' to the first entry, 'currp' to the second entry,
        !          8084:          * and search for 'reqp'.
        !          8085:          */
        !          8086:         for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
        !          8087:              currp; prevp = currp, currp = REQPNEXT(currp)) {
        !          8088:             if (currp == reqp) {
        !          8089:                 ret = ASC_TRUE;
        !          8090:                 REQPNEXT(prevp) = REQPNEXT(currp);
        !          8091:                 REQPNEXT(reqp) = NULL;
        !          8092:                 if (ascq->q_last[tid] == reqp) {
        !          8093:                     ascq->q_last[tid] = prevp;
        !          8094:                 }
        !          8095:                 break;
        !          8096:             }
        !          8097:         }
        !          8098:     }
        !          8099: #ifdef ADVANSYS_STATS
        !          8100:     /* Maintain request queue statistics. */
        !          8101:     if (ret == ASC_TRUE) {
        !          8102:         ascq->q_cur_cnt[tid]--;
        !          8103:         REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
        !          8104:     }
        !          8105:     ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
        !          8106: #endif /* ADVANSYS_STATS */
        !          8107:     ASC_DBG2(3, "asc_rmqueue: reqp %x, ret %d\n", (unsigned) reqp, ret);
        !          8108:     return ret;
        !          8109: }
        !          8110: 
        !          8111: /*
        !          8112:  * If the specified 'REQP' is queued on the specified queue for
        !          8113:  * the specified target device, return ASC_TRUE.
        !          8114:  */
        !          8115: STATIC int
        !          8116: asc_isqueued(asc_queue_t *ascq, REQP reqp)
        !          8117: {
        !          8118:     REQP        treqp;
        !          8119:     int            tid;
        !          8120:     int            ret = ASC_FALSE;
        !          8121: 
        !          8122:     ASC_DBG2(3, "asc_isqueued: ascq %x, reqp %x\n",
        !          8123:         (unsigned) ascq, (unsigned) reqp);
        !          8124:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
        !          8125:     ASC_ASSERT(reqp != NULL);
        !          8126: 
        !          8127:     tid = REQPTID(reqp);
        !          8128:     ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
        !          8129: 
        !          8130:     for (treqp = ascq->q_first[tid]; treqp; treqp = REQPNEXT(treqp)) {
        !          8131:         ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
        !          8132:         if (treqp == reqp) {
        !          8133:             ret = ASC_TRUE;
        !          8134:             break;
        !          8135:         }
        !          8136:     }
        !          8137:     ASC_DBG1(3, "asc_isqueued: ret %x\n", ret);
        !          8138:     return ret;
        !          8139: }
        !          8140: 
        !          8141: /*
        !          8142:  * Execute as many queued requests as possible for the specified queue.
        !          8143:  *
        !          8144:  * Calls asc_execute_scsi_cmnd() to execute a REQP/Scsi_Cmnd.
        !          8145:  */
        !          8146: STATIC void
        !          8147: asc_execute_queue(asc_queue_t *ascq)
        !          8148: {
        !          8149:     ADV_SCSI_BIT_ID_TYPE    scan_tidmask;
        !          8150:     REQP                    reqp;
        !          8151:     int                     i;
        !          8152: 
        !          8153:     ASC_DBG1(1, "asc_execute_queue: ascq %x\n", (unsigned) ascq);
        !          8154:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
        !          8155:     /*
        !          8156:      * Execute queued commands for devices attached to
        !          8157:      * the current board in round-robin fashion.
        !          8158:      */
        !          8159:     scan_tidmask = ascq->q_tidmask;
        !          8160:     do {
        !          8161:         for (i = 0; i <= ADV_MAX_TID; i++) {
        !          8162:             if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
        !          8163:                 if ((reqp = asc_dequeue(ascq, i)) == NULL) {
        !          8164:                     scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
        !          8165:                 } else if (asc_execute_scsi_cmnd((Scsi_Cmnd *) reqp)
        !          8166:                             == ASC_BUSY) {
        !          8167:                     scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
        !          8168:                     /* Put the request back at front of the list. */
        !          8169:                     asc_enqueue(ascq, reqp, ASC_FRONT);
        !          8170:                 }
        !          8171:             }
        !          8172:         }
        !          8173:     } while (scan_tidmask);
        !          8174:     return;
        !          8175: }
        !          8176: 
        !          8177: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
        !          8178: /*
        !          8179:  * asc_prt_board_devices()
        !          8180:  *
        !          8181:  * Print driver information for devices attached to the board.
        !          8182:  *
        !          8183:  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
        !          8184:  * cf. asc_prt_line().
        !          8185:  *
        !          8186:  * Return the number of characters copied into 'cp'. No more than
        !          8187:  * 'cplen' characters will be copied to 'cp'.
        !          8188:  */
        !          8189: STATIC int
        !          8190: asc_prt_board_devices(struct Scsi_Host *shp, char *cp, int cplen)
        !          8191: {
        !          8192:     asc_board_t        *boardp;
        !          8193:     int                leftlen;
        !          8194:     int                totlen;
        !          8195:     int                len;
        !          8196:     int                chip_scsi_id;
        !          8197:     int                i;
        !          8198: 
        !          8199:     boardp = ASC_BOARDP(shp);
        !          8200:     leftlen = cplen;
        !          8201:     totlen = len = 0;
        !          8202: 
        !          8203:     len = asc_prt_line(cp, leftlen,
        !          8204: "\nDevice Information for AdvanSys SCSI Host %d:\n", shp->host_no);
        !          8205:     ASC_PRT_NEXT();
        !          8206: 
        !          8207:     if (ASC_NARROW_BOARD(boardp)) {
        !          8208:         chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
        !          8209:     } else {
        !          8210:         chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
        !          8211:     }
        !          8212: 
        !          8213:     len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
        !          8214:     ASC_PRT_NEXT();
        !          8215:     for (i = 0; i <= ADV_MAX_TID; i++) {
        !          8216:         if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
        !          8217:             len = asc_prt_line(cp, leftlen, " %X,", i);
        !          8218:             ASC_PRT_NEXT();
        !          8219:         }
        !          8220:     }
        !          8221:     len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
        !          8222:     ASC_PRT_NEXT();
        !          8223: 
        !          8224:     return totlen;
        !          8225: }
        !          8226: 
        !          8227: /*
        !          8228:  * Display Wide Board BIOS Information.
        !          8229:  */
        !          8230: STATIC int
        !          8231: asc_prt_adv_bios(struct Scsi_Host *shp, char *cp, int cplen)
        !          8232: {
        !          8233:     asc_board_t        *boardp;
        !          8234:     int                leftlen;
        !          8235:     int                totlen;
        !          8236:     int                len;
        !          8237:     int                upgrade = ASC_FALSE;
        !          8238:     ushort             major, minor, letter;
        !          8239: 
        !          8240:     boardp = ASC_BOARDP(shp);
        !          8241:     leftlen = cplen;
        !          8242:     totlen = len = 0;
        !          8243: 
        !          8244:     len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
        !          8245:     ASC_PRT_NEXT();
        !          8246: 
        !          8247:     /*
        !          8248:      * If the BIOS saved a valid signature, then fill in
        !          8249:      * the BIOS code segment base address.
        !          8250:      */
        !          8251:     if (boardp->bios_signature != 0x55AA) {
        !          8252:         len = asc_prt_line(cp, leftlen, "Pre-3.1\n");
        !          8253:         ASC_PRT_NEXT();
        !          8254:         upgrade = ASC_TRUE;
        !          8255:     } else {
        !          8256:         major = (boardp->bios_version >> 12) & 0xF;
        !          8257:         minor = (boardp->bios_version >> 8) & 0xF;
        !          8258:         letter = (boardp->bios_version & 0xFF);
        !          8259: 
        !          8260:         len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
        !          8261:             major, minor, letter >= 26 ? '?' : letter + 'A');
        !          8262:         ASC_PRT_NEXT();
        !          8263: 
        !          8264:         /* Current available ROM BIOS release is 3.1C. */
        !          8265:         if (major < 3 || (major <= 3 && minor < 1) ||
        !          8266:             (major <= 3 && minor <= 1 && letter < ('C'- 'A'))) {
        !          8267:             upgrade = ASC_TRUE;
        !          8268:         }
        !          8269:     }
        !          8270:     if (upgrade == ASC_TRUE) {
        !          8271:         len = asc_prt_line(cp, leftlen,
        !          8272: "Newer version of ROM BIOS available: ftp://ftp.advansys.com/pub\n");
        !          8273:             ASC_PRT_NEXT();
        !          8274:     }
        !          8275: 
        !          8276:     return totlen;
        !          8277: }
        !          8278: 
        !          8279: /*
        !          8280:  * Add serial number to information bar if signature AAh
        !          8281:  * is found in at bit 15-9 (7 bits) of word 1.
        !          8282:  *
        !          8283:  * Serial Number consists fo 12 alpha-numeric digits.
        !          8284:  *
        !          8285:  *       1 - Product type (A,B,C,D..)  Word0: 15-13 (3 bits)
        !          8286:  *       2 - MFG Location (A,B,C,D..)  Word0: 12-10 (3 bits)
        !          8287:  *     3-4 - Product ID (0-99)         Word0: 9-0 (10 bits)
        !          8288:  *       5 - Product revision (A-J)    Word0:  "         "
        !          8289:  *
        !          8290:  *           Signature                 Word1: 15-9 (7 bits)
        !          8291:  *       6 - Year (0-9)                Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
        !          8292:  *     7-8 - Week of the year (1-52)   Word1: 5-0 (6 bits)
        !          8293:  *
        !          8294:  *    9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
        !          8295:  *
        !          8296:  * Note 1: Only production cards will have a serial number.
        !          8297:  *
        !          8298:  * Note 2: Signature is most significant 7 bits (0xFE).
        !          8299:  *
        !          8300:  * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
        !          8301:  */
        !          8302: STATIC int
        !          8303: asc_get_eeprom_string(ushort *serialnum, uchar *cp)
        !          8304: {
        !          8305:     ushort      w, num;
        !          8306: 
        !          8307:     if ((serialnum[1] & 0xFE00) != ((ushort) 0xAA << 8)) {
        !          8308:         return ASC_FALSE;
        !          8309:     } else {
        !          8310:         /*
        !          8311:          * First word - 6 digits.
        !          8312:          */
        !          8313:         w = serialnum[0];
        !          8314: 
        !          8315:         /* Product type - 1st digit. */
        !          8316:         if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
        !          8317:             /* Product type is P=Prototype */
        !          8318:             *cp += 0x8;
        !          8319:         }
        !          8320:         cp++;
        !          8321: 
        !          8322:         /* Manufacturing location - 2nd digit. */
        !          8323:         *cp++ = 'A' + ((w & 0x1C00) >> 10);
        !          8324: 
        !          8325:         /* Product ID - 3rd, 4th digits. */
        !          8326:         num = w & 0x3FF;
        !          8327:         *cp++ = '0' + (num / 100);
        !          8328:         num %= 100;
        !          8329:         *cp++ = '0' + (num / 10);
        !          8330: 
        !          8331:         /* Product revision - 5th digit. */
        !          8332:         *cp++ = 'A' + (num % 10);
        !          8333: 
        !          8334:         /*
        !          8335:          * Second word
        !          8336:          */
        !          8337:         w = serialnum[1];
        !          8338: 
        !          8339:         /*
        !          8340:          * Year - 6th digit.
        !          8341:          *
        !          8342:          * If bit 15 of third word is set, then the
        !          8343:          * last digit of the year is greater than 7.
        !          8344:          */
        !          8345:         if (serialnum[2] & 0x8000) {
        !          8346:             *cp++ = '8' + ((w & 0x1C0) >> 6);
        !          8347:         } else {
        !          8348:             *cp++ = '0' + ((w & 0x1C0) >> 6);
        !          8349:         }
        !          8350: 
        !          8351:         /* Week of year - 7th, 8th digits. */
        !          8352:         num = w & 0x003F;
        !          8353:         *cp++ = '0' + num / 10;
        !          8354:         num %= 10;
        !          8355:         *cp++ = '0' + num;
        !          8356: 
        !          8357:         /*
        !          8358:          * Third word
        !          8359:          */
        !          8360:         w = serialnum[2] & 0x7FFF;
        !          8361: 
        !          8362:         /* Serial number - 9th digit. */
        !          8363:         *cp++ = 'A' + (w / 1000);
        !          8364: 
        !          8365:         /* 10th, 11th, 12th digits. */
        !          8366:         num = w % 1000;
        !          8367:         *cp++ = '0' + num / 100;
        !          8368:         num %= 100;
        !          8369:         *cp++ = '0' + num / 10;
        !          8370:         num %= 10;
        !          8371:         *cp++ = '0' + num;
        !          8372: 
        !          8373:         *cp = '\0';     /* Null Terminate the string. */
        !          8374:         return ASC_TRUE;
        !          8375:     }
        !          8376: }
        !          8377: 
        !          8378: /*
        !          8379:  * asc_prt_asc_board_eeprom()
        !          8380:  *
        !          8381:  * Print board EEPROM configuration.
        !          8382:  *
        !          8383:  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
        !          8384:  * cf. asc_prt_line().
        !          8385:  *
        !          8386:  * Return the number of characters copied into 'cp'. No more than
        !          8387:  * 'cplen' characters will be copied to 'cp'.
        !          8388:  */
        !          8389: STATIC int
        !          8390: asc_prt_asc_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
        !          8391: {
        !          8392:     asc_board_t        *boardp;
        !          8393:     ASC_DVC_VAR        *asc_dvc_varp;
        !          8394:     int                leftlen;
        !          8395:     int                totlen;
        !          8396:     int                len;
        !          8397:     ASCEEP_CONFIG      *ep;
        !          8398:     int                i;
        !          8399:     int                isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
        !          8400:     uchar              serialstr[13];
        !          8401: 
        !          8402:     boardp = ASC_BOARDP(shp);
        !          8403:     asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
        !          8404:     ep = &boardp->eep_config.asc_eep;
        !          8405: 
        !          8406:     leftlen = cplen;
        !          8407:     totlen = len = 0;
        !          8408: 
        !          8409:     len = asc_prt_line(cp, leftlen,
        !          8410: "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
        !          8411:     ASC_PRT_NEXT();
        !          8412: 
        !          8413:     if (asc_get_eeprom_string((ushort *) &ep->adapter_info[0], serialstr) ==
        !          8414:         ASC_TRUE) {
        !          8415:         len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
        !          8416:         ASC_PRT_NEXT();
        !          8417:     } else {
        !          8418:         if (ep->adapter_info[5] == 0xBB) {
        !          8419:             len = asc_prt_line(cp, leftlen,
        !          8420:                 " Default Settings Used for EEPROM-less Adapter.\n");
        !          8421:             ASC_PRT_NEXT();
        !          8422:         } else {
        !          8423:             len = asc_prt_line(cp, leftlen,
        !          8424:                 " Serial Number Signature Not Present.\n");
        !          8425:             ASC_PRT_NEXT();
        !          8426:         }
        !          8427:     }
        !          8428: 
        !          8429:     len = asc_prt_line(cp, leftlen,
        !          8430: " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
        !          8431:         ep->chip_scsi_id, ep->max_total_qng, ep->max_tag_qng);
        !          8432:     ASC_PRT_NEXT();
        !          8433: 
        !          8434:     len = asc_prt_line(cp, leftlen,
        !          8435: " cntl %x, no_scam %x\n",
        !          8436:         ep->cntl, ep->no_scam);
        !          8437:     ASC_PRT_NEXT();
        !          8438: 
        !          8439:     len = asc_prt_line(cp, leftlen,
        !          8440: " Target ID:           ");
        !          8441:     ASC_PRT_NEXT();
        !          8442:     for (i = 0; i <= ASC_MAX_TID; i++) {
        !          8443:         len = asc_prt_line(cp, leftlen, " %d", i);
        !          8444:         ASC_PRT_NEXT();
        !          8445:     }
        !          8446:     len = asc_prt_line(cp, leftlen, "\n");
        !          8447:     ASC_PRT_NEXT();
        !          8448: 
        !          8449:     len = asc_prt_line(cp, leftlen,
        !          8450: " Disconnects:         ");
        !          8451:     ASC_PRT_NEXT();
        !          8452:     for (i = 0; i <= ASC_MAX_TID; i++) {
        !          8453:         len = asc_prt_line(cp, leftlen, " %c",
        !          8454:             (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
        !          8455:         ASC_PRT_NEXT();
        !          8456:     }
        !          8457:     len = asc_prt_line(cp, leftlen, "\n");
        !          8458:     ASC_PRT_NEXT();
        !          8459: 
        !          8460:     len = asc_prt_line(cp, leftlen,
        !          8461: " Command Queuing:     ");
        !          8462:     ASC_PRT_NEXT();
        !          8463:     for (i = 0; i <= ASC_MAX_TID; i++) {
        !          8464:         len = asc_prt_line(cp, leftlen, " %c",
        !          8465:             (ep->use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
        !          8466:         ASC_PRT_NEXT();
        !          8467:     }
        !          8468:     len = asc_prt_line(cp, leftlen, "\n");
        !          8469:     ASC_PRT_NEXT();
        !          8470: 
        !          8471:     len = asc_prt_line(cp, leftlen,
        !          8472: " Start Motor:         ");
        !          8473:     ASC_PRT_NEXT();
        !          8474:     for (i = 0; i <= ASC_MAX_TID; i++) {
        !          8475:         len = asc_prt_line(cp, leftlen, " %c",
        !          8476:             (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
        !          8477:         ASC_PRT_NEXT();
        !          8478:     }
        !          8479:     len = asc_prt_line(cp, leftlen, "\n");
        !          8480:     ASC_PRT_NEXT();
        !          8481: 
        !          8482:     len = asc_prt_line(cp, leftlen,
        !          8483: " Synchronous Transfer:");
        !          8484:     ASC_PRT_NEXT();
        !          8485:     for (i = 0; i <= ASC_MAX_TID; i++) {
        !          8486:         len = asc_prt_line(cp, leftlen, " %c",
        !          8487:             (ep->init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
        !          8488:         ASC_PRT_NEXT();
        !          8489:     }
        !          8490:     len = asc_prt_line(cp, leftlen, "\n");
        !          8491:     ASC_PRT_NEXT();
        !          8492: 
        !          8493:     if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
        !          8494:         len = asc_prt_line(cp, leftlen,
        !          8495: " Host ISA DMA speed:   %d MB/S\n",
        !          8496:             isa_dma_speed[ep->isa_dma_speed]);
        !          8497:         ASC_PRT_NEXT();
        !          8498:     }
        !          8499: 
        !          8500:      return totlen;
        !          8501: }
        !          8502: 
        !          8503: /*
        !          8504:  * asc_prt_adv_board_eeprom()
        !          8505:  *
        !          8506:  * Print board EEPROM configuration.
        !          8507:  *
        !          8508:  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
        !          8509:  * cf. asc_prt_line().
        !          8510:  *
        !          8511:  * Return the number of characters copied into 'cp'. No more than
        !          8512:  * 'cplen' characters will be copied to 'cp'.
        !          8513:  */
        !          8514: STATIC int
        !          8515: asc_prt_adv_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
        !          8516: {
        !          8517:     asc_board_t        *boardp;
        !          8518:     ADV_DVC_VAR        *adv_dvc_varp;
        !          8519:     int                leftlen;
        !          8520:     int                totlen;
        !          8521:     int                len;
        !          8522:     int                i;
        !          8523:     char               *termstr;
        !          8524:     uchar              serialstr[13];
        !          8525:     ADVEEP_CONFIG      *ep;
        !          8526: 
        !          8527:     boardp = ASC_BOARDP(shp);
        !          8528:     adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
        !          8529:     ep = &boardp->eep_config.adv_eep;
        !          8530: 
        !          8531:     leftlen = cplen;
        !          8532:     totlen = len = 0;
        !          8533: 
        !          8534:     len = asc_prt_line(cp, leftlen,
        !          8535: "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
        !          8536:     ASC_PRT_NEXT();
        !          8537: 
        !          8538:     if (asc_get_eeprom_string(&ep->serial_number_word1, serialstr) ==
        !          8539:         ASC_TRUE) {
        !          8540:         len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
        !          8541:         ASC_PRT_NEXT();
        !          8542:     } else {
        !          8543:         len = asc_prt_line(cp, leftlen,
        !          8544:             " Serial Number Signature Not Present.\n");
        !          8545:         ASC_PRT_NEXT();
        !          8546:     }
        !          8547: 
        !          8548:     len = asc_prt_line(cp, leftlen,
        !          8549: " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
        !          8550:         ep->adapter_scsi_id, ep->max_host_qng, ep->max_dvc_qng);
        !          8551:     ASC_PRT_NEXT();
        !          8552: 
        !          8553:     switch (ep->termination) {
        !          8554:         case 1:
        !          8555:             termstr = "Low Off/High Off";
        !          8556:             break;
        !          8557:         case 2:
        !          8558:             termstr = "Low Off/High On";
        !          8559:             break;
        !          8560:         case 3:
        !          8561:             termstr = "Low On/High On";
        !          8562:             break;
        !          8563:         default:
        !          8564:         case 0:
        !          8565:             termstr = "Automatic";
        !          8566:             break;
        !          8567:     }
        !          8568: 
        !          8569:     len = asc_prt_line(cp, leftlen,
        !          8570: " termination: %u (%s), bios_ctrl: %x\n",
        !          8571:         ep->termination, termstr, ep->bios_ctrl);
        !          8572:     ASC_PRT_NEXT();
        !          8573: 
        !          8574:     len = asc_prt_line(cp, leftlen,
        !          8575: " Target ID:           ");
        !          8576:     ASC_PRT_NEXT();
        !          8577:     for (i = 0; i <= ADV_MAX_TID; i++) {
        !          8578:         len = asc_prt_line(cp, leftlen, " %X", i);
        !          8579:         ASC_PRT_NEXT();
        !          8580:     }
        !          8581:     len = asc_prt_line(cp, leftlen, "\n");
        !          8582:     ASC_PRT_NEXT();
        !          8583: 
        !          8584:     len = asc_prt_line(cp, leftlen,
        !          8585: " Disconnects:         ");
        !          8586:     ASC_PRT_NEXT();
        !          8587:     for (i = 0; i <= ADV_MAX_TID; i++) {
        !          8588:         len = asc_prt_line(cp, leftlen, " %c",
        !          8589:             (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
        !          8590:         ASC_PRT_NEXT();
        !          8591:     }
        !          8592:     len = asc_prt_line(cp, leftlen, "\n");
        !          8593:     ASC_PRT_NEXT();
        !          8594: 
        !          8595:     len = asc_prt_line(cp, leftlen,
        !          8596: " Command Queuing:     ");
        !          8597:     ASC_PRT_NEXT();
        !          8598:     for (i = 0; i <= ADV_MAX_TID; i++) {
        !          8599:         len = asc_prt_line(cp, leftlen, " %c",
        !          8600:             (ep->tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
        !          8601:         ASC_PRT_NEXT();
        !          8602:     }
        !          8603:     len = asc_prt_line(cp, leftlen, "\n");
        !          8604:     ASC_PRT_NEXT();
        !          8605: 
        !          8606:     len = asc_prt_line(cp, leftlen,
        !          8607: " Start Motor:         ");
        !          8608:     ASC_PRT_NEXT();
        !          8609:     for (i = 0; i <= ADV_MAX_TID; i++) {
        !          8610:         len = asc_prt_line(cp, leftlen, " %c",
        !          8611:             (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
        !          8612:         ASC_PRT_NEXT();
        !          8613:     }
        !          8614:     len = asc_prt_line(cp, leftlen, "\n");
        !          8615:     ASC_PRT_NEXT();
        !          8616: 
        !          8617:     len = asc_prt_line(cp, leftlen,
        !          8618: " Synchronous Transfer:");
        !          8619:     ASC_PRT_NEXT();
        !          8620:     for (i = 0; i <= ADV_MAX_TID; i++) {
        !          8621:         len = asc_prt_line(cp, leftlen, " %c",
        !          8622:             (ep->sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
        !          8623:         ASC_PRT_NEXT();
        !          8624:     }
        !          8625:     len = asc_prt_line(cp, leftlen, "\n");
        !          8626:     ASC_PRT_NEXT();
        !          8627: 
        !          8628:     len = asc_prt_line(cp, leftlen,
        !          8629: " Ultra Transfer:      ");
        !          8630:     ASC_PRT_NEXT();
        !          8631:     for (i = 0; i <= ADV_MAX_TID; i++) {
        !          8632:         len = asc_prt_line(cp, leftlen, " %c",
        !          8633:             (ep->ultra_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
        !          8634:         ASC_PRT_NEXT();
        !          8635:     }
        !          8636:     len = asc_prt_line(cp, leftlen, "\n");
        !          8637:     ASC_PRT_NEXT();
        !          8638: 
        !          8639:     len = asc_prt_line(cp, leftlen,
        !          8640: " Wide Transfer:       ");
        !          8641:     ASC_PRT_NEXT();
        !          8642:     for (i = 0; i <= ADV_MAX_TID; i++) {
        !          8643:         len = asc_prt_line(cp, leftlen, " %c",
        !          8644:             (ep->wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
        !          8645:         ASC_PRT_NEXT();
        !          8646:     }
        !          8647:     len = asc_prt_line(cp, leftlen, "\n");
        !          8648:     ASC_PRT_NEXT();
        !          8649: 
        !          8650:     return totlen;
        !          8651: }
        !          8652: 
        !          8653: /*
        !          8654:  * asc_prt_driver_conf()
        !          8655:  *
        !          8656:  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
        !          8657:  * cf. asc_prt_line().
        !          8658:  *
        !          8659:  * Return the number of characters copied into 'cp'. No more than
        !          8660:  * 'cplen' characters will be copied to 'cp'.
        !          8661:  */
        !          8662: STATIC int
        !          8663: asc_prt_driver_conf(struct Scsi_Host *shp, char *cp, int cplen)
        !          8664: {
        !          8665:     asc_board_t            *boardp;
        !          8666:     int                    leftlen;
        !          8667:     int                    totlen;
        !          8668:     int                    len;
        !          8669:     int                    chip_scsi_id;
        !          8670: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
        !          8671:     int                    i;
        !          8672: #endif /* version >= v1.3.89 */
        !          8673: 
        !          8674:     boardp = ASC_BOARDP(shp);
        !          8675: 
        !          8676:     leftlen = cplen;
        !          8677:     totlen = len = 0;
        !          8678: 
        !          8679:     len = asc_prt_line(cp, leftlen,
        !          8680: "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
        !          8681:         shp->host_no);
        !          8682:     ASC_PRT_NEXT();
        !          8683: 
        !          8684:     len = asc_prt_line(cp, leftlen,
        !          8685: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89)
        !          8686: " host_busy %u, last_reset %u, max_id %u, max_lun %u\n",
        !          8687:         shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun);
        !          8688: #else /* version >= v1.3.89 */
        !          8689: " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
        !          8690:         shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun,
        !          8691:         shp->max_channel);
        !          8692: #endif /* version >= v1.3.89 */
        !          8693:     ASC_PRT_NEXT();
        !          8694:     
        !          8695:     len = asc_prt_line(cp, leftlen,
        !          8696: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,57)
        !          8697: " can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
        !          8698:         shp->can_queue, shp->this_id, shp->sg_tablesize, shp->cmd_per_lun);
        !          8699: #else /* version >= v1.3.57 */
        !          8700: " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
        !          8701:         shp->unique_id, shp->can_queue, shp->this_id, shp->sg_tablesize,
        !          8702:         shp->cmd_per_lun);
        !          8703: #endif /* version >= v1.3.57 */
        !          8704:     ASC_PRT_NEXT();
        !          8705: 
        !          8706:     len = asc_prt_line(cp, leftlen,
        !          8707: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,57)
        !          8708: " unchecked_isa_dma %d, loaded_as_module %d\n",
        !          8709:         shp->unchecked_isa_dma, shp->loaded_as_module);
        !          8710: #else /* version >= v1.3.57 */
        !          8711: " unchecked_isa_dma %d, use_clustering %d, loaded_as_module %d\n",
        !          8712:         shp->unchecked_isa_dma, shp->use_clustering, shp->loaded_as_module);
        !          8713: #endif /* version >= v1.3.57 */
        !          8714:     ASC_PRT_NEXT();
        !          8715: 
        !          8716:     len = asc_prt_line(cp, leftlen, " flags %x, last_reset %x, jiffies %x\n",
        !          8717:         boardp->flags, boardp->last_reset, jiffies);
        !          8718:     ASC_PRT_NEXT();
        !          8719: 
        !          8720:     if (ASC_NARROW_BOARD(boardp)) {
        !          8721:         chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
        !          8722:     } else {
        !          8723:         chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
        !          8724:     }
        !          8725: 
        !          8726: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
        !          8727:     if (boardp->flags & ASC_SELECT_QUEUE_DEPTHS) {
        !          8728:         len = asc_prt_line(cp, leftlen, " queue_depth:");
        !          8729:         ASC_PRT_NEXT();
        !          8730:         for (i = 0; i <= ADV_MAX_TID; i++) {
        !          8731:             if ((chip_scsi_id == i) ||
        !          8732:                 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
        !          8733:                 continue;
        !          8734:             }
        !          8735:             if (boardp->device[i] == NULL) {
        !          8736:                 continue;
        !          8737:             }
        !          8738:             len = asc_prt_line(cp, leftlen, " %X:%d",
        !          8739:                 i, boardp->device[i]->queue_depth);
        !          8740:             ASC_PRT_NEXT();
        !          8741:         }
        !          8742:         len = asc_prt_line(cp, leftlen, "\n");
        !          8743:         ASC_PRT_NEXT();
        !          8744:     }
        !          8745: #endif /* version >= v1.3.89 */
        !          8746: 
        !          8747: #if ASC_QUEUE_FLOW_CONTROL
        !          8748:     if (ASC_NARROW_BOARD(boardp)) {
        !          8749:         len = asc_prt_line(cp, leftlen, " queue_curr_depth:");
        !          8750:         ASC_PRT_NEXT();
        !          8751:         /* Use ASC_MAX_TID for Narrow Board. */
        !          8752:         for (i = 0; i <= ASC_MAX_TID; i++) {
        !          8753:             if ((boardp->asc_dvc_cfg.chip_scsi_id == i) ||
        !          8754:                 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
        !          8755:                 continue;
        !          8756:             }
        !          8757:             if (boardp->device[i] == NULL) {
        !          8758:                 continue;
        !          8759:             }
        !          8760:             len = asc_prt_line(cp, leftlen, " %d:%d",
        !          8761:                 i, boardp->device[i]->queue_curr_depth);
        !          8762:             ASC_PRT_NEXT();
        !          8763:         }
        !          8764:         len = asc_prt_line(cp, leftlen, "\n");
        !          8765:         ASC_PRT_NEXT();
        !          8766: 
        !          8767:         len = asc_prt_line(cp, leftlen, " queue_count:");
        !          8768:         ASC_PRT_NEXT();
        !          8769:         /* Use ASC_MAX_TID for Narrow Board. */
        !          8770:         for (i = 0; i <= ASC_MAX_TID; i++) {
        !          8771:             if ((boardp->asc_dvc_cfg.chip_scsi_id == i) ||
        !          8772:                 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
        !          8773:                 continue;
        !          8774:             }
        !          8775:             if (boardp->device[i] == NULL) {
        !          8776:                 continue;
        !          8777:             }
        !          8778:             len = asc_prt_line(cp, leftlen, " %d:%d",
        !          8779:                 i, boardp->device[i]->queue_count);
        !          8780:             ASC_PRT_NEXT();
        !          8781:         }
        !          8782:         len = asc_prt_line(cp, leftlen, "\n");
        !          8783:         ASC_PRT_NEXT();
        !          8784:     }
        !          8785: #endif /* ASC_QUEUE_FLOW_CONTROL */
        !          8786: 
        !          8787:     return totlen;
        !          8788: }
        !          8789: 
        !          8790: /*
        !          8791:  * asc_prt_asc_board_info()
        !          8792:  *
        !          8793:  * Print dynamic board configuration information.
        !          8794:  *
        !          8795:  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
        !          8796:  * cf. asc_prt_line().
        !          8797:  *
        !          8798:  * Return the number of characters copied into 'cp'. No more than
        !          8799:  * 'cplen' characters will be copied to 'cp'.
        !          8800:  */
        !          8801: STATIC int
        !          8802: asc_prt_asc_board_info(struct Scsi_Host *shp, char *cp, int cplen)
        !          8803: {
        !          8804:     asc_board_t            *boardp;
        !          8805:     int                    leftlen;
        !          8806:     int                    totlen;
        !          8807:     int                    len;
        !          8808:     ASC_DVC_VAR            *v;
        !          8809:     ASC_DVC_CFG            *c;
        !          8810:     int                    i;
        !          8811: 
        !          8812:     boardp = ASC_BOARDP(shp);
        !          8813:     v = &boardp->dvc_var.asc_dvc_var;
        !          8814:     c = &boardp->dvc_cfg.asc_dvc_cfg;
        !          8815: 
        !          8816:     leftlen = cplen;
        !          8817:     totlen = len = 0;
        !          8818: 
        !          8819:     len = asc_prt_line(cp, leftlen,
        !          8820: "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
        !          8821:     shp->host_no);
        !          8822:     ASC_PRT_NEXT();
        !          8823: 
        !          8824:     len = asc_prt_line(cp, leftlen,
        !          8825: " chip_version %u, lib_version %x, lib_serial_no %u, mcode_date %x\n",
        !          8826:         c->chip_version, c->lib_version, c->lib_serial_no, c->mcode_date);
        !          8827:     ASC_PRT_NEXT();
        !          8828: 
        !          8829:     len = asc_prt_line(cp, leftlen,
        !          8830: " mcode_version %x, err_code %u\n",
        !          8831:          c->mcode_version, v->err_code);
        !          8832:     ASC_PRT_NEXT();
        !          8833: 
        !          8834:     /* Current number of commands waiting for the host. */
        !          8835:     len = asc_prt_line(cp, leftlen,
        !          8836: " Total Command Pending: %d\n", v->cur_total_qng);
        !          8837:     ASC_PRT_NEXT();
        !          8838: 
        !          8839:     len = asc_prt_line(cp, leftlen,
        !          8840: " Command Queuing:");
        !          8841:     ASC_PRT_NEXT();
        !          8842:     for (i = 0; i <= ASC_MAX_TID; i++) {
        !          8843:         if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
        !          8844:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
        !          8845:             continue;
        !          8846:         }
        !          8847:         len = asc_prt_line(cp, leftlen, " %d:%c",
        !          8848:             i, (v->use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
        !          8849:         ASC_PRT_NEXT();
        !          8850:     }
        !          8851:     len = asc_prt_line(cp, leftlen, "\n");
        !          8852:     ASC_PRT_NEXT();
        !          8853: 
        !          8854:     /* Current number of commands waiting for a device. */
        !          8855:     len = asc_prt_line(cp, leftlen,
        !          8856: " Command Queue Pending:");
        !          8857:     ASC_PRT_NEXT();
        !          8858:     for (i = 0; i <= ASC_MAX_TID; i++) {
        !          8859:         if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
        !          8860:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
        !          8861:             continue;
        !          8862:         }
        !          8863:         len = asc_prt_line(cp, leftlen, " %d:%u", i, v->cur_dvc_qng[i]);
        !          8864:         ASC_PRT_NEXT();
        !          8865:     }
        !          8866:     len = asc_prt_line(cp, leftlen, "\n");
        !          8867:     ASC_PRT_NEXT();
        !          8868: 
        !          8869:     /* Current limit on number of commands that can be sent to a device. */
        !          8870:     len = asc_prt_line(cp, leftlen,
        !          8871: " Command Queue Limit:");
        !          8872:     ASC_PRT_NEXT();
        !          8873:     for (i = 0; i <= ASC_MAX_TID; i++) {
        !          8874:         if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
        !          8875:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
        !          8876:             continue;
        !          8877:         }
        !          8878:         len = asc_prt_line(cp, leftlen, " %d:%u", i, v->max_dvc_qng[i]);
        !          8879:         ASC_PRT_NEXT();
        !          8880:     }
        !          8881:     len = asc_prt_line(cp, leftlen, "\n");
        !          8882:     ASC_PRT_NEXT();
        !          8883: 
        !          8884:     /* Indicate whether the device has returned queue full status. */
        !          8885:     len = asc_prt_line(cp, leftlen,
        !          8886: " Command Queue Full:");
        !          8887:     ASC_PRT_NEXT();
        !          8888:     for (i = 0; i <= ASC_MAX_TID; i++) {
        !          8889:         if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
        !          8890:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
        !          8891:             continue;
        !          8892:         }
        !          8893:         if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
        !          8894:             len = asc_prt_line(cp, leftlen, " %d:Y-%d",
        !          8895:                 i, boardp->queue_full_cnt[i]);
        !          8896:         } else {
        !          8897:             len = asc_prt_line(cp, leftlen, " %d:N", i);
        !          8898:         }
        !          8899:         ASC_PRT_NEXT();
        !          8900:     }
        !          8901:     len = asc_prt_line(cp, leftlen, "\n");
        !          8902:     ASC_PRT_NEXT();
        !          8903: 
        !          8904:     len = asc_prt_line(cp, leftlen,
        !          8905: " Synchronous Transfer:");
        !          8906:     ASC_PRT_NEXT();
        !          8907:     for (i = 0; i <= ASC_MAX_TID; i++) {
        !          8908:         if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
        !          8909:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
        !          8910:             continue;
        !          8911:         }
        !          8912:         len = asc_prt_line(cp, leftlen, " %d:%c",
        !          8913:             i, (v->sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
        !          8914:         ASC_PRT_NEXT();
        !          8915:     }
        !          8916:     len = asc_prt_line(cp, leftlen, "\n");
        !          8917:     ASC_PRT_NEXT();
        !          8918: 
        !          8919:     for (i = 0; i <= ASC_MAX_TID; i++) {
        !          8920:         uchar syn_period_ix;
        !          8921: 
        !          8922:         if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
        !          8923:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
        !          8924:             continue;
        !          8925:         }
        !          8926:         if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
        !          8927:             continue;
        !          8928:         }
        !          8929:         syn_period_ix = (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index - 1);
        !          8930:         len = asc_prt_line(cp, leftlen, "  %d:", i);
        !          8931:         ASC_PRT_NEXT();
        !          8932: 
        !          8933:         len = asc_prt_line(cp, leftlen,
        !          8934:             " Transfer Period Factor: %d (%d.%d Mhz),",
        !          8935:             v->sdtr_period_tbl[syn_period_ix],
        !          8936:             250 / v->sdtr_period_tbl[syn_period_ix],
        !          8937:             ASC_TENTHS(250, v->sdtr_period_tbl[syn_period_ix]));
        !          8938:         ASC_PRT_NEXT();
        !          8939: 
        !          8940:         len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d\n",
        !          8941:             boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET);
        !          8942:         ASC_PRT_NEXT();
        !          8943:     }
        !          8944: 
        !          8945:     return totlen;
        !          8946: }
        !          8947: 
        !          8948: /*
        !          8949:  * asc_prt_adv_board_info()
        !          8950:  *
        !          8951:  * Print dynamic board configuration information.
        !          8952:  *
        !          8953:  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
        !          8954:  * cf. asc_prt_line().
        !          8955:  *
        !          8956:  * Return the number of characters copied into 'cp'. No more than
        !          8957:  * 'cplen' characters will be copied to 'cp'.
        !          8958:  */
        !          8959: STATIC int
        !          8960: asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen)
        !          8961: {
        !          8962:     asc_board_t            *boardp;
        !          8963:     int                    leftlen;
        !          8964:     int                    totlen;
        !          8965:     int                    len;
        !          8966:     int                    i;
        !          8967:     ADV_DVC_VAR            *v;
        !          8968:     ADV_DVC_CFG            *c;
        !          8969:     AdvPortAddr            iop_base;
        !          8970:     ushort                 chip_scsi_id;
        !          8971:     ushort                 lramword;
        !          8972:     uchar                  lrambyte;
        !          8973:     ushort                 sdtr_able;
        !          8974:     ushort                 period;
        !          8975: 
        !          8976:     boardp = ASC_BOARDP(shp);
        !          8977:     v = &boardp->dvc_var.adv_dvc_var;
        !          8978:     c = &boardp->dvc_cfg.adv_dvc_cfg;
        !          8979:     iop_base = v->iop_base;
        !          8980:     chip_scsi_id = v->chip_scsi_id;
        !          8981: 
        !          8982:     leftlen = cplen;
        !          8983:     totlen = len = 0;
        !          8984: 
        !          8985:     len = asc_prt_line(cp, leftlen,
        !          8986: "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
        !          8987:     shp->host_no);
        !          8988:     ASC_PRT_NEXT();
        !          8989: 
        !          8990:     len = asc_prt_line(cp, leftlen,
        !          8991: " iop_base %lx, cable_detect: %X, err_code %u, idle_cmd_done %u\n",
        !          8992:          v->iop_base,
        !          8993:          AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1) & CABLE_DETECT,
        !          8994:          v->err_code, v->idle_cmd_done);
        !          8995:     ASC_PRT_NEXT();
        !          8996: 
        !          8997:     len = asc_prt_line(cp, leftlen,
        !          8998: " chip_version %u, lib_version %x, mcode_date %x, mcode_version %x\n",
        !          8999:         c->chip_version, c->lib_version, c->mcode_date, c->mcode_version);
        !          9000:     ASC_PRT_NEXT();
        !          9001: 
        !          9002:     AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, lramword);
        !          9003:     len = asc_prt_line(cp, leftlen,
        !          9004: " Queuing Enabled:");
        !          9005:     ASC_PRT_NEXT();
        !          9006:     for (i = 0; i <= ADV_MAX_TID; i++) {
        !          9007:         if ((chip_scsi_id == i) ||
        !          9008:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
        !          9009:             continue;
        !          9010:         }
        !          9011: 
        !          9012:         len = asc_prt_line(cp, leftlen, " %X:%c",
        !          9013:             i, (lramword & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
        !          9014:         ASC_PRT_NEXT();
        !          9015:     }
        !          9016:     len = asc_prt_line(cp, leftlen, "\n");
        !          9017:     ASC_PRT_NEXT();
        !          9018: 
        !          9019:     len = asc_prt_line(cp, leftlen,
        !          9020: " Queue Limit:");
        !          9021:     ASC_PRT_NEXT();
        !          9022:     for (i = 0; i <= ADV_MAX_TID; i++) {
        !          9023:         if ((chip_scsi_id == i) ||
        !          9024:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
        !          9025:             continue;
        !          9026:         }
        !          9027: 
        !          9028:         AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i, lrambyte);
        !          9029: 
        !          9030:         len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
        !          9031:         ASC_PRT_NEXT();
        !          9032:     }
        !          9033:     len = asc_prt_line(cp, leftlen, "\n");
        !          9034:     ASC_PRT_NEXT();
        !          9035: 
        !          9036:     len = asc_prt_line(cp, leftlen,
        !          9037: " Command Pending:");
        !          9038:     ASC_PRT_NEXT();
        !          9039:     for (i = 0; i <= ADV_MAX_TID; i++) {
        !          9040:         if ((chip_scsi_id == i) ||
        !          9041:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
        !          9042:             continue;
        !          9043:         }
        !          9044: 
        !          9045:         AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i, lrambyte);
        !          9046: 
        !          9047:         len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
        !          9048:         ASC_PRT_NEXT();
        !          9049:     }
        !          9050:     len = asc_prt_line(cp, leftlen, "\n");
        !          9051:     ASC_PRT_NEXT();
        !          9052: 
        !          9053:     AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, lramword);
        !          9054:     len = asc_prt_line(cp, leftlen,
        !          9055: " Wide Enabled:");
        !          9056:     ASC_PRT_NEXT();
        !          9057:     for (i = 0; i <= ADV_MAX_TID; i++) {
        !          9058:         if ((chip_scsi_id == i) ||
        !          9059:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
        !          9060:             continue;
        !          9061:         }
        !          9062: 
        !          9063:         len = asc_prt_line(cp, leftlen, " %X:%c",
        !          9064:             i, (lramword & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
        !          9065:         ASC_PRT_NEXT();
        !          9066:     }
        !          9067:     len = asc_prt_line(cp, leftlen, "\n");
        !          9068:     ASC_PRT_NEXT();
        !          9069: 
        !          9070:     len = asc_prt_line(cp, leftlen,
        !          9071: " Transfer Bit Width:");
        !          9072:     ASC_PRT_NEXT();
        !          9073:     for (i = 0; i <= ADV_MAX_TID; i++) {
        !          9074:         if ((chip_scsi_id == i) ||
        !          9075:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
        !          9076:             continue;
        !          9077:         }
        !          9078: 
        !          9079:         AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
        !          9080:             lramword);
        !          9081:         len = asc_prt_line(cp, leftlen, " %X:%d",
        !          9082:             i, (lramword & 0x8000) ? 16 : 8);
        !          9083:         ASC_PRT_NEXT();
        !          9084:     }
        !          9085:     len = asc_prt_line(cp, leftlen, "\n");
        !          9086:     ASC_PRT_NEXT();
        !          9087: 
        !          9088:     AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
        !          9089:     len = asc_prt_line(cp, leftlen,
        !          9090: " Synchronous Enabled:");
        !          9091:     ASC_PRT_NEXT();
        !          9092:     for (i = 0; i <= ADV_MAX_TID; i++) {
        !          9093:         if ((chip_scsi_id == i) ||
        !          9094:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
        !          9095:             continue;
        !          9096:         }
        !          9097: 
        !          9098:         len = asc_prt_line(cp, leftlen, " %X:%c",
        !          9099:             i, (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
        !          9100:         ASC_PRT_NEXT();
        !          9101:     }
        !          9102:     len = asc_prt_line(cp, leftlen, "\n");
        !          9103:     ASC_PRT_NEXT();
        !          9104: 
        !          9105:     for (i = 0; i <= ADV_MAX_TID; i++) {
        !          9106: 
        !          9107:         AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
        !          9108:             lramword);
        !          9109:         lramword &= ~0x8000;
        !          9110: 
        !          9111:         if ((chip_scsi_id == i) ||
        !          9112:             ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0) ||
        !          9113:             (lramword == 0)) {
        !          9114:             continue;
        !          9115:         }
        !          9116: 
        !          9117:         len = asc_prt_line(cp, leftlen, "  %X:", i);
        !          9118:         ASC_PRT_NEXT();
        !          9119:         
        !          9120:         period = (((lramword >> 8) * 25) + 50)/4;
        !          9121: 
        !          9122:         len = asc_prt_line(cp, leftlen,
        !          9123:             " Transfer Period Factor: %d (%d.%d Mhz),",
        !          9124:             period, 250/period, ASC_TENTHS(250, period));
        !          9125:         ASC_PRT_NEXT();
        !          9126: 
        !          9127:         len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d\n",
        !          9128:             lramword & 0x1F);
        !          9129:         ASC_PRT_NEXT();
        !          9130:     }
        !          9131: 
        !          9132:     return totlen;
        !          9133: }
        !          9134: 
        !          9135: /*
        !          9136:  * asc_proc_copy() 
        !          9137:  *
        !          9138:  * Copy proc information to a read buffer taking into account the current
        !          9139:  * read offset in the file and the remaining space in the read buffer.
        !          9140:  */
        !          9141: STATIC int
        !          9142: asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
        !          9143:               char *cp, int cplen)
        !          9144: {
        !          9145:     int cnt = 0;
        !          9146:     
        !          9147:     ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
        !          9148:             (unsigned) offset, (unsigned) advoffset, cplen);
        !          9149:     if (offset <= advoffset) {
        !          9150:         /* Read offset below current offset, copy everything. */
        !          9151:         cnt = ASC_MIN(cplen, leftlen);
        !          9152:         ASC_DBG3(2, "asc_proc_copy: curbuf %x, cp %x, cnt %d\n",
        !          9153:                 (unsigned) curbuf, (unsigned) cp, cnt);
        !          9154:         memcpy(curbuf, cp, cnt);
        !          9155:     } else if (offset < advoffset + cplen) {
        !          9156:         /* Read offset within current range, partial copy. */
        !          9157:         cnt = (advoffset + cplen) - offset;
        !          9158:         cp = (cp + cplen) - cnt;
        !          9159:         cnt = ASC_MIN(cnt, leftlen);
        !          9160:         ASC_DBG3(2, "asc_proc_copy: curbuf %x, cp %x, cnt %d\n",
        !          9161:                 (unsigned) curbuf, (unsigned) cp, cnt);
        !          9162:         memcpy(curbuf, cp, cnt);
        !          9163:     }
        !          9164:     return cnt;
        !          9165: }
        !          9166: 
        !          9167: /*
        !          9168:  * asc_prt_line()
        !          9169:  *
        !          9170:  * If 'cp' is NULL print to the console, otherwise print to a buffer.
        !          9171:  *
        !          9172:  * Return 0 if printing to the console, otherwise return the number of
        !          9173:  * bytes written to the buffer.
        !          9174:  *
        !          9175:  * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
        !          9176:  * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
        !          9177:  */
        !          9178: STATIC int
        !          9179: asc_prt_line(char *buf, int buflen, char *fmt, ...)
        !          9180: {
        !          9181:     va_list        args;
        !          9182:     int            ret;
        !          9183:     char        s[ASC_PRTLINE_SIZE];
        !          9184: 
        !          9185:     va_start(args, fmt);
        !          9186:     ret = vsprintf(s, fmt, args);
        !          9187:     ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
        !          9188:     if (buf == NULL) {
        !          9189:         (void) printk(s);
        !          9190:         ret = 0;
        !          9191:     } else {
        !          9192:         ret = ASC_MIN(buflen, ret);
        !          9193:         memcpy(buf, s, ret);
        !          9194:     }
        !          9195:     va_end(args);
        !          9196:     return ret;
        !          9197: }
        !          9198: #endif /* version >= v1.3.0 */
        !          9199: 
        !          9200: 
        !          9201: /*
        !          9202:  * --- Functions Required by the Asc Library
        !          9203:  */
        !          9204: 
        !          9205: /*
        !          9206:  * Delay for 'n' milliseconds. Don't use the 'jiffies'
        !          9207:  * global variable which is incremented once every 5 ms
        !          9208:  * from a timer interrupt, because this function may be
        !          9209:  * called when interrupts are disabled.
        !          9210:  */
        !          9211: STATIC void
        !          9212: DvcSleepMilliSecond(ulong n)
        !          9213: {
        !          9214:     ulong i;
        !          9215: 
        !          9216:     ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", n);
        !          9217:     for (i = 0; i < n; i++) {
        !          9218:         udelay(1000);
        !          9219:     }
        !          9220: }
        !          9221: 
        !          9222: STATIC int
        !          9223: DvcEnterCritical(void)
        !          9224: {
        !          9225:     int    flags;
        !          9226: 
        !          9227:     save_flags(flags);
        !          9228:     cli();
        !          9229:     return flags;
        !          9230: }
        !          9231: 
        !          9232: STATIC void
        !          9233: DvcLeaveCritical(int flags)
        !          9234: {
        !          9235:     restore_flags(flags);
        !          9236: }
        !          9237: 
        !          9238: STATIC ulong
        !          9239: DvcGetSGList(ASC_DVC_VAR *asc_dvc_sg, uchar *buf_addr, ulong buf_len,
        !          9240:              ASC_SG_HEAD *asc_sg_head_ptr)
        !          9241: {
        !          9242:     ulong buf_size;
        !          9243: 
        !          9244:     buf_size = buf_len;
        !          9245:     asc_sg_head_ptr->entry_cnt = 1;
        !          9246: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
        !          9247:     asc_sg_head_ptr->sg_list[0].addr = (ulong) buf_addr;
        !          9248: #else /* version >= v2.0.0 */
        !          9249:     asc_sg_head_ptr->sg_list[0].addr = virt_to_bus(buf_addr);
        !          9250: #endif /* version >= v2.0.0 */
        !          9251:     asc_sg_head_ptr->sg_list[0].bytes = buf_size;
        !          9252:     return buf_size;
        !          9253: }
        !          9254: 
        !          9255: /*
        !          9256:  * void
        !          9257:  * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, ushort *outbuf, int words)
        !          9258:  *
        !          9259:  * Calling/Exit State:
        !          9260:  *    none
        !          9261:  *
        !          9262:  * Description:
        !          9263:  *     Output an ASC_SCSI_Q structure to the chip
        !          9264:  */
        !          9265: STATIC void
        !          9266: DvcPutScsiQ(PortAddr iop_base, ushort s_addr, ushort *outbuf, int words)
        !          9267: {
        !          9268:     int    i;
        !          9269: 
        !          9270:     ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", (uchar *) outbuf, 2 * words);
        !          9271:     AscSetChipLramAddr(iop_base, s_addr);
        !          9272:     for (i = 0; i < words; i++, outbuf++) {
        !          9273:         if (i == 2 || i == 10) {
        !          9274:             continue;
        !          9275:         }
        !          9276:         AscSetChipLramDataNoSwap(iop_base, *outbuf);
        !          9277:     }
        !          9278: }
        !          9279: 
        !          9280: /*
        !          9281:  * void
        !          9282:  * DvcGetQinfo(PortAddr iop_base, ushort s_addr, ushort *inbuf, int words)
        !          9283:  *
        !          9284:  * Calling/Exit State:
        !          9285:  *    none
        !          9286:  *
        !          9287:  * Description:
        !          9288:  *     Input an ASC_QDONE_INFO structure from the chip
        !          9289:  */
        !          9290: STATIC void
        !          9291: DvcGetQinfo(PortAddr iop_base, ushort s_addr, ushort *inbuf, int words)
        !          9292: {
        !          9293:     int    i;
        !          9294: 
        !          9295:     AscSetChipLramAddr(iop_base, s_addr);
        !          9296:     for (i = 0; i < words; i++, inbuf++) {
        !          9297:         if (i == 5) {
        !          9298:             continue;
        !          9299:         }
        !          9300:         *inbuf = AscGetChipLramDataNoSwap(iop_base);
        !          9301:     }
        !          9302:     ASC_DBG_PRT_HEX(2, "DvcGetQinfo", (uchar *) inbuf, 2 * words);
        !          9303: }
        !          9304: 
        !          9305: /*
        !          9306:  * void    DvcOutPortWords(ushort iop_base, ushort &outbuf, int words)
        !          9307:  *
        !          9308:  * Calling/Exit State:
        !          9309:  *    none
        !          9310:  *
        !          9311:  * Description:
        !          9312:  *     output a buffer to an i/o port address
        !          9313:  */
        !          9314: STATIC void
        !          9315: DvcOutPortWords(ushort iop_base, ushort *outbuf, int words)
        !          9316: {
        !          9317:     int    i;
        !          9318: 
        !          9319:     for (i = 0; i < words; i++, outbuf++)
        !          9320:         outpw(iop_base, *outbuf);
        !          9321: }
        !          9322: 
        !          9323: /*
        !          9324:  * void    DvcInPortWords(ushort iop_base, ushort &outbuf, int words)
        !          9325:  *
        !          9326:  * Calling/Exit State:
        !          9327:  *    none
        !          9328:  *
        !          9329:  * Description:
        !          9330:  *     input a buffer from an i/o port address
        !          9331:  */
        !          9332: STATIC void
        !          9333: DvcInPortWords(ushort iop_base, ushort *inbuf, int words)
        !          9334: {
        !          9335:     int    i;
        !          9336: 
        !          9337:     for (i = 0; i < words; i++, inbuf++)
        !          9338:         *inbuf = inpw(iop_base);
        !          9339: }
        !          9340: 
        !          9341: /*
        !          9342:  * void DvcOutPortDWords(PortAddr port, ulong *pdw, int dwords)
        !          9343:  *
        !          9344:  * Calling/Exit State:
        !          9345:  *    none
        !          9346:  *
        !          9347:  * Description:
        !          9348:  *     output a buffer of 32-bit integers to an i/o port address in
        !          9349:  *  16 bit integer units
        !          9350:  */
        !          9351: STATIC void  
        !          9352: DvcOutPortDWords(PortAddr port, ulong *pdw, int dwords)
        !          9353: {
        !          9354:     int        i;
        !          9355:     int        words;
        !          9356:     ushort    *pw;
        !          9357: 
        !          9358:     pw = (ushort *) pdw;
        !          9359:     words = dwords << 1;
        !          9360:     for(i = 0; i < words; i++, pw++) {
        !          9361:         outpw(port, *pw);
        !          9362:     }
        !          9363:     return;
        !          9364: }
        !          9365: 
        !          9366: /*
        !          9367:  * Read a PCI configuration byte.
        !          9368:  */
        !          9369: ASC_INITFUNC(
        !          9370: STATIC uchar
        !          9371: DvcReadPCIConfigByte(
        !          9372:         ASC_DVC_VAR asc_ptr_type *asc_dvc, 
        !          9373:         ushort offset)
        !          9374: )
        !          9375: {
        !          9376: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
        !          9377: #ifdef ASC_CONFIG_PCI
        !          9378:     PCI_DATA    pciData;
        !          9379: 
        !          9380:     pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
        !          9381:     pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
        !          9382:     pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
        !          9383:     pciData.offset = offset;
        !          9384:     pciData.type = pci_scan_method;
        !          9385:     return asc_get_cfg_byte(&pciData);
        !          9386: #else /* ASC_CONFIG_PCI */
        !          9387:     return 0;
        !          9388: #endif /* ASC_CONFIG_PCI */
        !          9389: #else /* version >= v2.1.93 */ 
        !          9390: #ifdef CONFIG_PCI
        !          9391:     uchar byte_data;
        !          9392:     pcibios_read_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
        !          9393:         PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
        !          9394:             ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
        !          9395:         offset, &byte_data);
        !          9396:     return byte_data;
        !          9397: #else /* CONFIG_PCI */
        !          9398:     return 0;
        !          9399: #endif /* CONFIG_PCI */
        !          9400: #endif /* version >= v2.1.93 */ 
        !          9401: }
        !          9402: 
        !          9403: /*
        !          9404:  * Write a PCI configuration byte.
        !          9405:  */
        !          9406: ASC_INITFUNC(
        !          9407: STATIC void
        !          9408: DvcWritePCIConfigByte(
        !          9409:         ASC_DVC_VAR asc_ptr_type *asc_dvc, 
        !          9410:         ushort offset, 
        !          9411:         uchar  byte_data)
        !          9412: )
        !          9413: {
        !          9414: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
        !          9415: #ifdef ASC_CONFIG_PCI
        !          9416:     PCI_DATA    pciData;
        !          9417: 
        !          9418:     pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
        !          9419:     pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
        !          9420:     pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
        !          9421:     pciData.offset = offset;
        !          9422:     pciData.type = pci_scan_method;
        !          9423:     asc_put_cfg_byte(&pciData, byte_data);
        !          9424: #endif /* ASC_CONFIG_PCI */
        !          9425: #else /* version >= v2.1.93 */ 
        !          9426: #ifdef CONFIG_PCI
        !          9427:     pcibios_write_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
        !          9428:         PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
        !          9429:             ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
        !          9430:         offset, byte_data);
        !          9431: #endif /* CONFIG_PCI */
        !          9432: #endif /* version >= v2.1.93 */ 
        !          9433: }
        !          9434: 
        !          9435: /*
        !          9436:  * Return the BIOS address of the adapter at the specified
        !          9437:  * I/O port and with the specified bus type.
        !          9438:  */
        !          9439: ASC_INITFUNC(
        !          9440: STATIC ushort
        !          9441: AscGetChipBiosAddress(
        !          9442:         PortAddr iop_base,
        !          9443:         ushort bus_type
        !          9444: )
        !          9445: )
        !          9446: {
        !          9447:     ushort  cfg_lsw ;
        !          9448:     ushort  bios_addr ;
        !          9449: 
        !          9450:     /*
        !          9451:      * The PCI BIOS is re-located by the motherboard BIOS. Because
        !          9452:      * of this the driver can not determine where a PCI BIOS is
        !          9453:      * loaded and executes.
        !          9454:      */
        !          9455:     if (bus_type & ASC_IS_PCI)
        !          9456:     {
        !          9457:         return(0);
        !          9458:     }
        !          9459: 
        !          9460:     if((bus_type & ASC_IS_EISA) != 0)
        !          9461:     {
        !          9462:         cfg_lsw = AscGetEisaChipCfg(iop_base) ;
        !          9463:         cfg_lsw &= 0x000F ;
        !          9464:         bios_addr = (ushort)(ASC_BIOS_MIN_ADDR  +
        !          9465:                                 (cfg_lsw * ASC_BIOS_BANK_SIZE)) ;
        !          9466:         return(bios_addr) ;
        !          9467:     }/* if */
        !          9468: 
        !          9469:     cfg_lsw = AscGetChipCfgLsw(iop_base) ;
        !          9470: 
        !          9471:     /*
        !          9472:     *  ISA PnP uses the top bit as the 32K BIOS flag
        !          9473:     */
        !          9474:     if (bus_type == ASC_IS_ISAPNP)
        !          9475:     {
        !          9476:         cfg_lsw &= 0x7FFF;
        !          9477:     }/* if */
        !          9478: 
        !          9479:     bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) +
        !          9480:             ASC_BIOS_MIN_ADDR) ;
        !          9481:     return(bios_addr) ;
        !          9482: }
        !          9483: 
        !          9484: 
        !          9485: /*
        !          9486:  * --- Functions Required by the Adv Library
        !          9487:  */
        !          9488: 
        !          9489: /*
        !          9490:  * DvcGetPhyAddr()
        !          9491:  *
        !          9492:  * Return the physical address of 'vaddr' and set '*lenp' to the
        !          9493:  * number of physically contiguous bytes that follow 'vaddr'.
        !          9494:  * 'flag' indicates the type of structure whose physical address
        !          9495:  * is being translated.
        !          9496:  *
        !          9497:  * Note: Because Linux currently doesn't page the kernel and all
        !          9498:  * kernel buffers are physically contiguous, leave '*lenp' unchanged.
        !          9499:  */
        !          9500: ulong
        !          9501: DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
        !          9502:         uchar *vaddr, long *lenp, int flag)
        !          9503: {
        !          9504:     ulong                paddr;
        !          9505: 
        !          9506: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
        !          9507:     paddr = (ulong) vaddr;
        !          9508: #else /* version >= v2.0.0 */
        !          9509:     paddr = virt_to_bus(vaddr);
        !          9510: #endif /* version >= v2.0.0 */
        !          9511: 
        !          9512:     ASC_DBG4(4,
        !          9513:         "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n", 
        !          9514:         (ulong) vaddr, (ulong) lenp, (ulong) *((ulong *) lenp), paddr);
        !          9515: 
        !          9516:     return paddr;
        !          9517: }
        !          9518: 
        !          9519: /*
        !          9520:  * Read a PCI configuration byte.
        !          9521:  */
        !          9522: ASC_INITFUNC(
        !          9523: STATIC uchar
        !          9524: DvcAdvReadPCIConfigByte(
        !          9525:         ADV_DVC_VAR *asc_dvc, 
        !          9526:         ushort offset)
        !          9527: )
        !          9528: {
        !          9529: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
        !          9530: #ifdef ASC_CONFIG_PCI
        !          9531:     PCI_DATA    pciData;
        !          9532: 
        !          9533:     pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
        !          9534:     pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
        !          9535:     pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
        !          9536:     pciData.offset = offset;
        !          9537:     pciData.type = pci_scan_method;
        !          9538:     return asc_get_cfg_byte(&pciData);
        !          9539: #else /* ASC_CONFIG_PCI */
        !          9540:     return 0;
        !          9541: #endif /* ASC_CONFIG_PCI */
        !          9542: #else /* version >= v2.1.93 */ 
        !          9543: #ifdef CONFIG_PCI
        !          9544:     uchar byte_data;
        !          9545:     pcibios_read_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
        !          9546:         PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
        !          9547:             ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
        !          9548:         offset, &byte_data);
        !          9549:     return byte_data;
        !          9550: #else /* CONFIG_PCI */
        !          9551:     return 0;
        !          9552: #endif /* CONFIG_PCI */
        !          9553: #endif /* version >= v2.1.93 */ 
        !          9554: }
        !          9555: 
        !          9556: /*
        !          9557:  * Write a PCI configuration byte.
        !          9558:  */
        !          9559: ASC_INITFUNC(
        !          9560: STATIC void
        !          9561: DvcAdvWritePCIConfigByte(
        !          9562:         ADV_DVC_VAR *asc_dvc, 
        !          9563:         ushort offset, 
        !          9564:         uchar  byte_data)
        !          9565: )
        !          9566: {
        !          9567: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
        !          9568: #ifdef ASC_CONFIG_PCI
        !          9569:     PCI_DATA    pciData;
        !          9570: 
        !          9571:     pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
        !          9572:     pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
        !          9573:     pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
        !          9574:     pciData.offset = offset;
        !          9575:     pciData.type = pci_scan_method;
        !          9576:     asc_put_cfg_byte(&pciData, byte_data);
        !          9577: #endif /* ASC_CONFIG_PCI */
        !          9578: #else /* version >= v2.1.93 */ 
        !          9579: #ifdef CONFIG_PCI
        !          9580:     pcibios_write_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
        !          9581:         PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
        !          9582:             ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
        !          9583:         offset, byte_data);
        !          9584: #endif /* CONFIG_PCI */
        !          9585: #endif /* version >= v2.1.93 */ 
        !          9586: }
        !          9587: 
        !          9588: /*
        !          9589:  * --- Tracing and Debugging Functions
        !          9590:  */
        !          9591: 
        !          9592: #ifdef ADVANSYS_STATS
        !          9593: /*
        !          9594:  * asc_prt_board_stats()
        !          9595:  *
        !          9596:  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
        !          9597:  * cf. asc_prt_line().
        !          9598:  *
        !          9599:  * Return the number of characters copied into 'cp'. No more than
        !          9600:  * 'cplen' characters will be copied to 'cp'.
        !          9601:  */
        !          9602: STATIC int
        !          9603: asc_prt_board_stats(struct Scsi_Host *shp, char *cp, int cplen)
        !          9604: {
        !          9605:     int                    leftlen;
        !          9606:     int                    totlen;
        !          9607:     int                    len;
        !          9608:     struct asc_stats       *s;
        !          9609:     int                    i;
        !          9610:     ushort                 chip_scsi_id;
        !          9611:     asc_board_t            *boardp;
        !          9612:     asc_queue_t            *active;
        !          9613:     asc_queue_t            *waiting;
        !          9614: 
        !          9615:     leftlen = cplen;
        !          9616:     totlen = len = 0;
        !          9617: 
        !          9618:     boardp = ASC_BOARDP(shp);
        !          9619:     s = &boardp->asc_stats;
        !          9620: 
        !          9621:     len = asc_prt_line(cp, leftlen,
        !          9622: "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", shp->host_no);
        !          9623:     ASC_PRT_NEXT();
        !          9624:     
        !          9625:     len = asc_prt_line(cp, leftlen,
        !          9626: " command %lu, queuecommand %lu, abort %lu, reset %lu, biosparam %lu\n",
        !          9627:         s->command, s->queuecommand, s->abort, s->reset, s->biosparam);
        !          9628:     ASC_PRT_NEXT();
        !          9629: 
        !          9630:     len = asc_prt_line(cp, leftlen,
        !          9631: " interrupt %lu, callback %lu, done %lu\n",
        !          9632:         s->interrupt, s->callback, s->done);
        !          9633:     ASC_PRT_NEXT();
        !          9634: 
        !          9635:     len = asc_prt_line(cp, leftlen,
        !          9636: " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
        !          9637:         s->exe_noerror, s->exe_busy, s->exe_error, s->exe_unknown);
        !          9638:     ASC_PRT_NEXT();
        !          9639: 
        !          9640:     if (ASC_NARROW_BOARD(boardp)) {
        !          9641:         len = asc_prt_line(cp, leftlen,
        !          9642: " build_error %lu\n",
        !          9643:          s->build_error);
        !          9644:     } else {
        !          9645:         len = asc_prt_line(cp, leftlen,
        !          9646: " build_error %lu, build_noreq %lu, build_nosg %lu\n",
        !          9647:          s->build_error, s->adv_build_noreq, s->adv_build_nosg);
        !          9648:     }
        !          9649:     ASC_PRT_NEXT();
        !          9650: 
        !          9651:     /*
        !          9652:      * Display data transfer statistics.
        !          9653:      */
        !          9654:     if (s->cont_cnt > 0) {
        !          9655:         len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
        !          9656:         ASC_PRT_NEXT();
        !          9657: 
        !          9658:         len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
        !          9659:                     s->cont_xfer/2,
        !          9660:                     ASC_TENTHS(s->cont_xfer, 2));
        !          9661:         ASC_PRT_NEXT();
        !          9662: 
        !          9663:         /* Contiguous transfer average size */
        !          9664:         len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
        !          9665:                     (s->cont_xfer/2)/s->cont_cnt,
        !          9666:                     ASC_TENTHS((s->cont_xfer/2), s->cont_cnt));
        !          9667:         ASC_PRT_NEXT();
        !          9668:     }
        !          9669: 
        !          9670:     if (s->sg_cnt > 0) {
        !          9671: 
        !          9672:         len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
        !          9673:                     s->sg_cnt, s->sg_elem);
        !          9674:         ASC_PRT_NEXT();
        !          9675: 
        !          9676:         len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
        !          9677:                     s->sg_xfer/2,
        !          9678:                     ASC_TENTHS(s->sg_xfer, 2));
        !          9679:         ASC_PRT_NEXT();
        !          9680: 
        !          9681:         /* Scatter gather transfer statistics */
        !          9682:         len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
        !          9683:                     s->sg_elem/s->sg_cnt,
        !          9684:                     ASC_TENTHS(s->sg_elem, s->sg_cnt));
        !          9685:         ASC_PRT_NEXT();
        !          9686: 
        !          9687:         len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
        !          9688:                     (s->sg_xfer/2)/s->sg_elem,
        !          9689:                     ASC_TENTHS((s->sg_xfer/2), s->sg_elem));
        !          9690:         ASC_PRT_NEXT();
        !          9691: 
        !          9692:         len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
        !          9693:                     (s->sg_xfer/2)/s->sg_cnt,
        !          9694:                     ASC_TENTHS((s->sg_xfer/2), s->sg_cnt));
        !          9695:         ASC_PRT_NEXT();
        !          9696:     }
        !          9697: 
        !          9698:     /*
        !          9699:      * Display request queuing statistics.
        !          9700:      */
        !          9701:     len = asc_prt_line(cp, leftlen,
        !          9702: " Active and Waiting Request Queues (Time Unit: %d HZ):\n", HZ);
        !          9703:     ASC_PRT_NEXT();
        !          9704: 
        !          9705:     active = &ASC_BOARDP(shp)->active;
        !          9706:     waiting = &ASC_BOARDP(shp)->waiting;
        !          9707: 
        !          9708:     if (ASC_NARROW_BOARD(boardp)) {
        !          9709:         chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
        !          9710:     } else {
        !          9711:         chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
        !          9712:     }
        !          9713: 
        !          9714:     for (i = 0; i <= ADV_MAX_TID; i++) {
        !          9715: 
        !          9716:         if ((chip_scsi_id == i) ||
        !          9717:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
        !          9718:             continue;
        !          9719:         }
        !          9720: 
        !          9721:         if (active->q_tot_cnt[i] > 0 || waiting->q_tot_cnt[i] > 0) {
        !          9722:             len = asc_prt_line(cp, leftlen, " target %d\n", i);
        !          9723:             ASC_PRT_NEXT();
        !          9724: 
        !          9725:             len = asc_prt_line(cp, leftlen,
        !          9726: "   active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
        !          9727:                 active->q_cur_cnt[i], active->q_max_cnt[i],
        !          9728:                 active->q_tot_cnt[i],
        !          9729:                 active->q_min_tim[i], active->q_max_tim[i],
        !          9730:                 (active->q_tot_cnt[i] == 0) ? 0 :
        !          9731:                 (active->q_tot_tim[i]/active->q_tot_cnt[i]),
        !          9732:                 (active->q_tot_cnt[i] == 0) ? 0 :
        !          9733:                 ASC_TENTHS(active->q_tot_tim[i], active->q_tot_cnt[i]));
        !          9734:             ASC_PRT_NEXT();
        !          9735: 
        !          9736:             len = asc_prt_line(cp, leftlen,
        !          9737: "   waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
        !          9738:                 waiting->q_cur_cnt[i], waiting->q_max_cnt[i],
        !          9739:                 waiting->q_tot_cnt[i],
        !          9740:                 waiting->q_min_tim[i], waiting->q_max_tim[i],
        !          9741:                 (waiting->q_tot_cnt[i] == 0) ? 0 :
        !          9742:                 (waiting->q_tot_tim[i]/waiting->q_tot_cnt[i]),
        !          9743:                 (waiting->q_tot_cnt[i] == 0) ? 0 :
        !          9744:                 ASC_TENTHS(waiting->q_tot_tim[i], waiting->q_tot_cnt[i]));
        !          9745:             ASC_PRT_NEXT();
        !          9746:         }
        !          9747:     }
        !          9748: 
        !          9749:      return totlen;
        !          9750: }
        !          9751: #endif /* ADVANSYS_STATS */
        !          9752: 
        !          9753: #ifdef ADVANSYS_DEBUG
        !          9754: /*
        !          9755:  * asc_prt_scsi_host()
        !          9756:  */
        !          9757: STATIC void 
        !          9758: asc_prt_scsi_host(struct Scsi_Host *s)
        !          9759: {
        !          9760:     asc_board_t         *boardp;
        !          9761: 
        !          9762:     boardp = ASC_BOARDP(s);
        !          9763: 
        !          9764:     printk("Scsi_Host at addr %x\n", (unsigned) s);
        !          9765:     printk(
        !          9766: " next %x, extra_bytes %u, host_busy %u, host_no %d, last_reset %d,\n",
        !          9767:         (unsigned) s->next, s->extra_bytes, s->host_busy, s->host_no,
        !          9768:         (unsigned) s->last_reset);
        !          9769: 
        !          9770:     printk(
        !          9771: " host_wait %x, host_queue %x, hostt %x, block %x,\n",
        !          9772:         (unsigned) s->host_wait, (unsigned) s->host_queue,
        !          9773:         (unsigned) s->hostt, (unsigned) s->block);
        !          9774: 
        !          9775:     printk(
        !          9776: " wish_block %d, base %x, io_port %d, n_io_port %d, irq %d, dma_channel %d,\n",
        !          9777:         s->wish_block, (unsigned) s->base, s->io_port, s->n_io_port,
        !          9778:         s->irq, s->dma_channel);
        !          9779: 
        !          9780:     printk(
        !          9781: " this_id %d, can_queue %d,\n", s->this_id, s->can_queue);
        !          9782: 
        !          9783:     printk(
        !          9784: " cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d, loaded_as_module %d\n",
        !          9785:         s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma,
        !          9786:         s->loaded_as_module);
        !          9787: 
        !          9788:     if (ASC_NARROW_BOARD(boardp)) {
        !          9789:         asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
        !          9790:         asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
        !          9791:     } else {
        !          9792:         asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
        !          9793:         asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
        !          9794:     }
        !          9795: }
        !          9796: 
        !          9797: /*
        !          9798:  * asc_prt_scsi_cmnd()
        !          9799:  */
        !          9800: STATIC void 
        !          9801: asc_prt_scsi_cmnd(Scsi_Cmnd *s)
        !          9802: {
        !          9803:     printk("Scsi_Cmnd at addr %x\n", (unsigned) s);
        !          9804: 
        !          9805: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
        !          9806:     printk(
        !          9807: " host %x, device %x, target %u, lun %u\n",
        !          9808:         (unsigned) s->host, (unsigned) s->device, s->target, s->lun);
        !          9809: #else /* version >= v1.3.0 */
        !          9810:     printk(
        !          9811: " host %x, device %x, target %u, lun %u, channel %u,\n",
        !          9812:         (unsigned) s->host, (unsigned) s->device, s->target, s->lun,
        !          9813:         s->channel);
        !          9814: #endif /* version >= v1.3.0 */
        !          9815: 
        !          9816:     asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
        !          9817: 
        !          9818:     printk(
        !          9819: " use_sg %u, sglist_len %u, abort_reason %x\n",
        !          9820:         s->use_sg, s->sglist_len, s->abort_reason);
        !          9821: 
        !          9822: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89)
        !          9823:     printk(
        !          9824: " retries %d, allowed %d\n",
        !          9825:          s->retries, s->allowed);
        !          9826: #else /* version >= v1.3.89 */
        !          9827:     printk(
        !          9828: " serial_number %x, serial_number_at_timeout %x, retries %d, allowed %d\n",
        !          9829:         (unsigned) s->serial_number, (unsigned) s->serial_number_at_timeout,
        !          9830:          s->retries, s->allowed);
        !          9831: #endif /* version >= v1.3.89 */
        !          9832: 
        !          9833:     printk(
        !          9834: " timeout_per_command %d, timeout_total %d, timeout %d\n",
        !          9835:         s->timeout_per_command, s->timeout_total, s->timeout);
        !          9836: 
        !          9837:     printk(
        !          9838: " internal_timeout %u, flags %u, this_count %d\n",
        !          9839:         s->internal_timeout, s->flags, s->this_count);
        !          9840: 
        !          9841:     printk(
        !          9842: " scsi_done %x, done %x, host_scribble %x, result %x\n",
        !          9843:         (unsigned) s->scsi_done, (unsigned) s->done,
        !          9844:         (unsigned) s->host_scribble, s->result);
        !          9845: 
        !          9846:     printk(
        !          9847: " tag %u, pid %u\n",
        !          9848:         (unsigned) s->tag, (unsigned) s->pid);
        !          9849: }
        !          9850: 
        !          9851: /*
        !          9852:  * asc_prt_asc_dvc_var()
        !          9853:  */
        !          9854: STATIC void 
        !          9855: asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
        !          9856: {
        !          9857:     printk("ASC_DVC_VAR at addr %x\n", (unsigned) h);
        !          9858: 
        !          9859:     printk(
        !          9860: " iop_base %x, err_code %x, dvc_cntl %x, bug_fix_cntl %d,\n",
        !          9861:         h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
        !          9862: 
        !          9863:     printk(
        !          9864: " bus_type %d, isr_callback %x, exe_callback %x, init_sdtr %x,\n",
        !          9865:         h->bus_type, (unsigned) h->isr_callback, (unsigned) h->exe_callback,
        !          9866:         (unsigned) h->init_sdtr);
        !          9867: 
        !          9868:     printk(
        !          9869: " sdtr_done %x, use_tagged_qng %x, unit_not_ready %x, chip_no %x,\n",
        !          9870:         (unsigned) h->sdtr_done, (unsigned) h->use_tagged_qng,
        !          9871:         (unsigned) h->unit_not_ready, (unsigned) h->chip_no);
        !          9872:         
        !          9873:     printk(
        !          9874: " queue_full_or_busy %x, start_motor %x, scsi_reset_wait %x, irq_no %x,\n",
        !          9875:         (unsigned) h->queue_full_or_busy, (unsigned) h->start_motor,
        !          9876:         (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
        !          9877: 
        !          9878:     printk(
        !          9879: " is_in_int %x, max_total_qng %x, cur_total_qng %x, in_critical_cnt %x,\n",
        !          9880:         (unsigned) h->is_in_int, (unsigned) h->max_total_qng,
        !          9881:         (unsigned) h->cur_total_qng, (unsigned) h->in_critical_cnt);
        !          9882: 
        !          9883:     printk(
        !          9884: " last_q_shortage %x, init_state %x, no_scam %x, pci_fix_asyn_xfer %x,\n",
        !          9885:         (unsigned) h->last_q_shortage, (unsigned) h->init_state,
        !          9886:         (unsigned) h->no_scam, (unsigned) h->pci_fix_asyn_xfer);
        !          9887: 
        !          9888:     printk(
        !          9889: " cfg %x, saved_ptr2func %x\n",
        !          9890:         (unsigned) h->cfg, (unsigned) h->saved_ptr2func);
        !          9891: }
        !          9892: 
        !          9893: /*
        !          9894:  * asc_prt_asc_dvc_cfg()
        !          9895:  */
        !          9896: STATIC void 
        !          9897: asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
        !          9898: {
        !          9899:     printk("ASC_DVC_CFG at addr %x\n", (unsigned) h);
        !          9900: 
        !          9901:     printk(
        !          9902: " can_tagged_qng %x, cmd_qng_enabled %x, disc_enable %x, sdtr_enable %x,\n",
        !          9903:             h->can_tagged_qng, h->cmd_qng_enabled, h->disc_enable,
        !          9904:             h->sdtr_enable);
        !          9905: 
        !          9906:     printk(
        !          9907: " chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
        !          9908:              h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
        !          9909:              h->chip_version);
        !          9910: 
        !          9911:     printk(
        !          9912: " pci_device_id %d, lib_serial_no %x, lib_version %x, mcode_date %x,\n",
        !          9913:           h->pci_device_id, h->lib_serial_no, h->lib_version, h->mcode_date);
        !          9914: 
        !          9915:     printk(
        !          9916: " mcode_version %d, overrun_buf %x\n",
        !          9917:             h->mcode_version, (unsigned) h->overrun_buf);
        !          9918: }
        !          9919: 
        !          9920: /*
        !          9921:  * asc_prt_asc_scsi_q()
        !          9922:  */
        !          9923: STATIC void 
        !          9924: asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
        !          9925: {
        !          9926:     ASC_SG_HEAD    *sgp;
        !          9927:     int i;
        !          9928: 
        !          9929:     printk("ASC_SCSI_Q at addr %x\n", (unsigned) q);
        !          9930: 
        !          9931:     printk(
        !          9932: " target_ix %u, target_lun %u, srb_ptr %x, tag_code %u,\n",
        !          9933:             q->q2.target_ix, q->q1.target_lun,
        !          9934:             (unsigned) q->q2.srb_ptr, q->q2.tag_code);
        !          9935: 
        !          9936:     printk(
        !          9937: " data_addr %x, data_cnt %lu, sense_addr %x, sense_len %u,\n",
        !          9938:             (unsigned) q->q1.data_addr, q->q1.data_cnt,
        !          9939:             (unsigned) q->q1.sense_addr, q->q1.sense_len);
        !          9940: 
        !          9941:     printk(
        !          9942: " cdbptr %x, cdb_len %u, sg_head %x, sg_queue_cnt %u\n",
        !          9943:             (unsigned) q->cdbptr, q->q2.cdb_len,
        !          9944:             (unsigned) q->sg_head, q->q1.sg_queue_cnt);
        !          9945: 
        !          9946:     if (q->sg_head) {
        !          9947:         sgp = q->sg_head;
        !          9948:         printk("ASC_SG_HEAD at addr %x\n", (unsigned) sgp);
        !          9949:         printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, sgp->queue_cnt);
        !          9950:         for (i = 0; i < sgp->entry_cnt; i++) {
        !          9951:             printk(" [%u]: addr %x, bytes %lu\n",
        !          9952:                 i, (unsigned) sgp->sg_list[i].addr, sgp->sg_list[i].bytes);
        !          9953:         }
        !          9954: 
        !          9955:     }
        !          9956: }
        !          9957: 
        !          9958: /*
        !          9959:  * asc_prt_asc_qdone_info()
        !          9960:  */
        !          9961: STATIC void 
        !          9962: asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
        !          9963: {
        !          9964:     printk("ASC_QDONE_INFO at addr %x\n", (unsigned) q);
        !          9965:     printk(
        !          9966: " srb_ptr %x, target_ix %u, cdb_len %u, tag_code %u, done_stat %x\n",
        !          9967:             (unsigned) q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
        !          9968:             q->d2.tag_code, q->d3.done_stat);
        !          9969:     printk(
        !          9970: " host_stat %x, scsi_stat %x, scsi_msg %x\n",
        !          9971:             q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
        !          9972: }
        !          9973: 
        !          9974: /*
        !          9975:  * asc_prt_adv_dvc_var()
        !          9976:  *
        !          9977:  * Display an ADV_DVC_VAR structure.
        !          9978:  */
        !          9979: STATIC void 
        !          9980: asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
        !          9981: {
        !          9982:     printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong) h);
        !          9983: 
        !          9984:     printk(
        !          9985: "  iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
        !          9986:         (ulong) h->iop_base, h->err_code, (unsigned) h->ultra_able);
        !          9987: 
        !          9988:     printk(
        !          9989: "  isr_callback 0x%x, sdtr_able 0x%x, wdtr_able 0x%x\n",
        !          9990:         (unsigned) h->isr_callback, (unsigned) h->wdtr_able,
        !          9991:         (unsigned) h->sdtr_able);
        !          9992: 
        !          9993:     printk(
        !          9994: "  start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
        !          9995:         (unsigned) h->start_motor,
        !          9996:         (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
        !          9997: 
        !          9998:     printk(
        !          9999: "  max_host_qng 0x%x, cur_host_qng 0x%x, max_dvc_qng 0x%x\n",
        !          10000:         (unsigned) h->max_host_qng, (unsigned) h->cur_host_qng,
        !          10001:         (unsigned) h->max_dvc_qng);
        !          10002: 
        !          10003:     printk(
        !          10004: "  no_scam 0x%x, tagqng_able 0x%x, chip_scsi_id 0x%x, cfg 0x%lx\n",
        !          10005:         (unsigned) h->no_scam, (unsigned) h->tagqng_able,
        !          10006:         (unsigned) h->chip_scsi_id, (ulong) h->cfg);
        !          10007: 
        !          10008: }
        !          10009: 
        !          10010: /*
        !          10011:  * asc_prt_adv_dvc_cfg()
        !          10012:  *
        !          10013:  * Display an ADV_DVC_CFG structure.
        !          10014:  */
        !          10015: STATIC void 
        !          10016: asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
        !          10017: {
        !          10018:     printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong) h);
        !          10019: 
        !          10020:     printk(
        !          10021: "  disc_enable 0x%x, termination 0x%x\n",
        !          10022:         h->disc_enable, h->termination);
        !          10023: 
        !          10024:     printk(
        !          10025: "  chip_version 0x%x, mcode_date 0x%x\n",
        !          10026:         h->chip_version, h->mcode_date);
        !          10027: 
        !          10028:     printk(
        !          10029: "  mcode_version 0x%x, pci_device_id 0x%x, lib_version 0x%x\n",
        !          10030:        h->mcode_version, h->pci_device_id, h->lib_version);
        !          10031: 
        !          10032:     printk(
        !          10033: "  control_flag 0x%x, pci_slot_info 0x%x\n",
        !          10034:        h->control_flag, h->pci_slot_info);
        !          10035: }
        !          10036: 
        !          10037: /*
        !          10038:  * asc_prt_adv_scsi_req_q()
        !          10039:  *
        !          10040:  * Display an ADV_SCSI_REQ_Q structure.
        !          10041:  */
        !          10042: STATIC void 
        !          10043: asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
        !          10044: {
        !          10045:     int                 i;
        !          10046:     struct asc_sg_block *sg_ptr;
        !          10047: 
        !          10048:     printk("ADV_SCSI_REQ_Q at addr %x\n", (unsigned) q);
        !          10049: 
        !          10050:     printk(
        !          10051: "  target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
        !          10052:             q->target_id, q->target_lun, q->srb_ptr, q->a_flag);
        !          10053: 
        !          10054:     printk("  cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
        !          10055:             q->cntl, q->data_addr, q->vdata_addr);
        !          10056: 
        !          10057:     printk(
        !          10058: "  data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
        !          10059:             q->data_cnt, q->sense_addr, q->sense_len);
        !          10060: 
        !          10061:     printk(
        !          10062: "  cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
        !          10063:             q->cdb_len, q->done_status, q->host_status, q->scsi_status);
        !          10064: 
        !          10065:     printk(
        !          10066: "  vsense_addr 0x%lx, scsiq_ptr 0x%lx, ux_wk_data_cnt %lu\n",
        !          10067:             (ulong) q->vsense_addr, (ulong) q->scsiq_ptr,
        !          10068:             (ulong) q->ux_wk_data_cnt);
        !          10069: 
        !          10070:     printk(
        !          10071: "  sg_list_ptr 0x%lx, sg_real_addr 0x%lx, sg_entry_cnt %u\n",
        !          10072:             (ulong) q->sg_list_ptr, (ulong) q->sg_real_addr, q->sg_entry_cnt);
        !          10073: 
        !          10074:     printk(
        !          10075: "  ux_sg_ix %u, orig_sense_len %u\n",
        !          10076:             q->ux_sg_ix, q->orig_sense_len);
        !          10077: 
        !          10078:     /* Display the request's ADV_SG_BLOCK structures. */
        !          10079:     for (sg_ptr = q->sg_list_ptr, i = 0; sg_ptr != NULL;
        !          10080:         sg_ptr = sg_ptr->sg_ptr, i++) {
        !          10081:         /*
        !          10082:          * 'sg_ptr' is a physical address. Convert it to a virtual
        !          10083:          * address by indexing 'i' into the virtual address array
        !          10084:          * 'sg_list_ptr'.
        !          10085:          *
        !          10086:          * At the end of the each iteration of the loop 'sg_ptr' is
        !          10087:          * converted back into a physical address by setting 'sg_ptr'
        !          10088:          *  to the next pointer 'sg_ptr->sg_ptr'.
        !          10089:          */
        !          10090:         sg_ptr = &(((ADV_SG_BLOCK *) (q->sg_list_ptr))[i]);
        !          10091:         asc_prt_adv_sgblock(i, sg_ptr);
        !          10092:     }
        !          10093: }
        !          10094: 
        !          10095: /*
        !          10096:  * asc_prt_adv_sgblock()
        !          10097:  *
        !          10098:  * Display an ADV_SG_BLOCK structure.
        !          10099:  */
        !          10100: STATIC void
        !          10101: asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
        !          10102: {
        !          10103:     int i, s;
        !          10104: 
        !          10105:     /* Calculate starting entry number for the current block. */
        !          10106:     s = sgblockno * NO_OF_SG_PER_BLOCK;
        !          10107: 
        !          10108:     printk(" ADV_SG_BLOCK at addr 0x%lx (sgblockno %lu)\n",
        !          10109:         (ulong) b, (ulong) sgblockno);
        !          10110:     printk(
        !          10111: "  first_entry_no %lu, last_entry_no %lu, sg_ptr 0x%lx\n",
        !          10112:         (ulong) b->first_entry_no, (ulong) b->last_entry_no, (ulong) b->sg_ptr);
        !          10113:     ASC_ASSERT(b->first_entry_no - s >= 0);
        !          10114:     ASC_ASSERT(b->last_entry_no - s >= 0);
        !          10115:     ASC_ASSERT(b->last_entry_no - s <= NO_OF_SG_PER_BLOCK);
        !          10116:     ASC_ASSERT(b->first_entry_no - s <= NO_OF_SG_PER_BLOCK);
        !          10117:     ASC_ASSERT(b->first_entry_no - s <= NO_OF_SG_PER_BLOCK);
        !          10118:     ASC_ASSERT(b->first_entry_no - s <= b->last_entry_no - s);
        !          10119:     for (i = b->first_entry_no - s; i <= b->last_entry_no - s; i++) {
        !          10120:         printk("  [%lu]: sg_addr 0x%lx, sg_count 0x%lx\n",
        !          10121:             (ulong) i, (ulong) b->sg_list[i].sg_addr,
        !          10122:             (ulong) b->sg_list[i].sg_count);
        !          10123:     }
        !          10124: }
        !          10125: 
        !          10126: /*
        !          10127:  * asc_prt_hex()
        !          10128:  *
        !          10129:  * Print hexadecimal output in 4 byte groupings 32 bytes 
        !          10130:  * or 8 double-words per line.
        !          10131:  */
        !          10132: STATIC void 
        !          10133: asc_prt_hex(char *f, uchar *s, int l)
        !          10134: {
        !          10135:     int            i;
        !          10136:     int            j;
        !          10137:     int            k;
        !          10138:     int            m;
        !          10139: 
        !          10140:     printk("%s: (%d bytes)\n", f, l);
        !          10141: 
        !          10142:     for (i = 0; i < l; i += 32) {
        !          10143:         
        !          10144:         /* Display a maximum of 8 double-words per line. */
        !          10145:         if ((k = (l - i) / 4) >= 8) {
        !          10146:             k = 8;
        !          10147:             m = 0;
        !          10148:         } else {
        !          10149:             m = (l - i) % 4 ;
        !          10150:         }
        !          10151: 
        !          10152:         for (j = 0; j < k; j++) {
        !          10153:             printk(" %2.2X%2.2X%2.2X%2.2X",
        !          10154:                 (unsigned) s[i+(j*4)], (unsigned) s[i+(j*4)+1],
        !          10155:                 (unsigned) s[i+(j*4)+2], (unsigned) s[i+(j*4)+3]);
        !          10156:         }
        !          10157: 
        !          10158:         switch (m) {
        !          10159:         case 0:
        !          10160:         default:
        !          10161:             break;
        !          10162:         case 1:
        !          10163:             printk(" %2.2X",
        !          10164:                 (unsigned) s[i+(j*4)]);
        !          10165:             break;
        !          10166:         case 2:
        !          10167:             printk(" %2.2X%2.2X",
        !          10168:                 (unsigned) s[i+(j*4)],
        !          10169:                 (unsigned) s[i+(j*4)+1]);
        !          10170:             break;
        !          10171:         case 3:
        !          10172:             printk(" %2.2X%2.2X%2.2X",
        !          10173:                 (unsigned) s[i+(j*4)+1],
        !          10174:                 (unsigned) s[i+(j*4)+2],
        !          10175:                 (unsigned) s[i+(j*4)+3]);
        !          10176:             break;
        !          10177:         }
        !          10178: 
        !          10179:         printk("\n");
        !          10180:     }
        !          10181: }
        !          10182: #endif /* ADVANSYS_DEBUG */
        !          10183: 
        !          10184: #ifdef ADVANSYS_ASSERT
        !          10185: /*
        !          10186:  * interrupts_enabled()
        !          10187:  *
        !          10188:  * Return 1 if interrupts are enabled, otherwise return 0.
        !          10189:  */
        !          10190: STATIC int
        !          10191: interrupts_enabled(void)
        !          10192: {
        !          10193:     int flags;
        !          10194: 
        !          10195:     save_flags(flags);
        !          10196:     if (flags & 0x0200) {
        !          10197:         return ASC_TRUE;
        !          10198:     } else {
        !          10199:         return ASC_FALSE;
        !          10200:     }
        !          10201: }
        !          10202: #endif /* ADVANSYS_ASSERT */
        !          10203: 
        !          10204: 
        !          10205: /*
        !          10206:  * --- Asc Library Functions
        !          10207:  */
        !          10208: 
        !          10209: ASC_INITFUNC(
        !          10210: STATIC ushort
        !          10211: AscGetEisaChipCfg(
        !          10212:                      PortAddr iop_base
        !          10213: )
        !          10214: )
        !          10215: {
        !          10216:     PortAddr            eisa_cfg_iop;
        !          10217: 
        !          10218:     eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
        !          10219:       (PortAddr) (ASC_EISA_CFG_IOP_MASK);
        !          10220:     return (inpw(eisa_cfg_iop));
        !          10221: }
        !          10222: 
        !          10223: ASC_INITFUNC(
        !          10224: STATIC uchar
        !          10225: AscSetChipScsiID(
        !          10226:                     PortAddr iop_base,
        !          10227:                     uchar new_host_id
        !          10228: )
        !          10229: )
        !          10230: {
        !          10231:     ushort              cfg_lsw;
        !          10232: 
        !          10233:     if (AscGetChipScsiID(iop_base) == new_host_id) {
        !          10234:         return (new_host_id);
        !          10235:     }
        !          10236:     cfg_lsw = AscGetChipCfgLsw(iop_base);
        !          10237:     cfg_lsw &= 0xF8FF;
        !          10238:     cfg_lsw |= (ushort) ((new_host_id & ASC_MAX_TID) << 8);
        !          10239:     AscSetChipCfgLsw(iop_base, cfg_lsw);
        !          10240:     return (AscGetChipScsiID(iop_base));
        !          10241: }
        !          10242: 
        !          10243: ASC_INITFUNC(
        !          10244: STATIC uchar
        !          10245: AscGetChipScsiCtrl(
        !          10246:                       PortAddr iop_base
        !          10247: )
        !          10248: )
        !          10249: {
        !          10250:     uchar               sc;
        !          10251: 
        !          10252:     AscSetBank(iop_base, 1);
        !          10253:     sc = inp(iop_base + IOP_REG_SC);
        !          10254:     AscSetBank(iop_base, 0);
        !          10255:     return (sc);
        !          10256: }
        !          10257: 
        !          10258: ASC_INITFUNC(
        !          10259: STATIC uchar
        !          10260: AscGetChipVersion(
        !          10261:                      PortAddr iop_base,
        !          10262:                      ushort bus_type
        !          10263: )
        !          10264: )
        !          10265: {
        !          10266:     if ((bus_type & ASC_IS_EISA) != 0) {
        !          10267:         PortAddr            eisa_iop;
        !          10268:         uchar               revision;
        !          10269:         eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
        !          10270:           (PortAddr) ASC_EISA_REV_IOP_MASK;
        !          10271:         revision = inp(eisa_iop);
        !          10272:         return ((uchar) ((ASC_CHIP_MIN_VER_EISA - 1) + revision));
        !          10273:     }
        !          10274:     return (AscGetChipVerNo(iop_base));
        !          10275: }
        !          10276: 
        !          10277: ASC_INITFUNC(
        !          10278: STATIC ushort
        !          10279: AscGetChipBusType(
        !          10280:                      PortAddr iop_base
        !          10281: )
        !          10282: )
        !          10283: {
        !          10284:     ushort              chip_ver;
        !          10285: 
        !          10286:     chip_ver = AscGetChipVerNo(iop_base);
        !          10287:     if (
        !          10288:            (chip_ver >= ASC_CHIP_MIN_VER_VL)
        !          10289:            && (chip_ver <= ASC_CHIP_MAX_VER_VL)
        !          10290: ) {
        !          10291:         if (
        !          10292:                ((iop_base & 0x0C30) == 0x0C30)
        !          10293:                || ((iop_base & 0x0C50) == 0x0C50)
        !          10294: ) {
        !          10295:             return (ASC_IS_EISA);
        !          10296:         }
        !          10297:         return (ASC_IS_VL);
        !          10298:     }
        !          10299:     if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
        !          10300:         (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
        !          10301:         if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
        !          10302:             return (ASC_IS_ISAPNP);
        !          10303:         }
        !          10304:         return (ASC_IS_ISA);
        !          10305:     } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
        !          10306:                (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
        !          10307:         return (ASC_IS_PCI);
        !          10308:     }
        !          10309:     return (0);
        !          10310: }
        !          10311: 
        !          10312: ASC_INITFUNC(
        !          10313: STATIC ulong
        !          10314: AscLoadMicroCode(
        !          10315:                     PortAddr iop_base,
        !          10316:                     ushort s_addr,
        !          10317:                     ushort *mcode_buf,
        !          10318:                     ushort mcode_size
        !          10319: )
        !          10320: )
        !          10321: {
        !          10322:     ulong               chksum;
        !          10323:     ushort              mcode_word_size;
        !          10324:     ushort              mcode_chksum;
        !          10325: 
        !          10326:     mcode_word_size = (ushort) (mcode_size >> 1);
        !          10327:     AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
        !          10328:     AscMemWordCopyToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
        !          10329:     chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
        !          10330:     mcode_chksum = (ushort) AscMemSumLramWord(iop_base,
        !          10331:                                               (ushort) ASC_CODE_SEC_BEG,
        !          10332:           (ushort) ((mcode_size - s_addr - (ushort) ASC_CODE_SEC_BEG) / 2));
        !          10333:     AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
        !          10334:     AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
        !          10335:     return (chksum);
        !          10336: }
        !          10337: 
        !          10338: ASC_INITFUNC(
        !          10339: STATIC int
        !          10340: AscFindSignature(
        !          10341:                     PortAddr iop_base
        !          10342: )
        !          10343: )
        !          10344: {
        !          10345:     ushort              sig_word;
        !          10346: 
        !          10347:     if (AscGetChipSignatureByte(iop_base) == (uchar) ASC_1000_ID1B) {
        !          10348:         sig_word = AscGetChipSignatureWord(iop_base);
        !          10349:         if ((sig_word == (ushort) ASC_1000_ID0W) ||
        !          10350:             (sig_word == (ushort) ASC_1000_ID0W_FIX)) {
        !          10351:             return (1);
        !          10352:         }
        !          10353:     }
        !          10354:     return (0);
        !          10355: }
        !          10356: 
        !          10357: STATIC uchar _isa_pnp_inited ASC_INITDATA = 0;
        !          10358: STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] ASC_INITDATA =
        !          10359: {
        !          10360:     0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
        !          10361:     ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
        !          10362: };
        !          10363: 
        !          10364: ASC_INITFUNC(
        !          10365: STATIC PortAddr
        !          10366: AscSearchIOPortAddr(
        !          10367:                        PortAddr iop_beg,
        !          10368:                        ushort bus_type
        !          10369: )
        !          10370: )
        !          10371: {
        !          10372:     if (bus_type & ASC_IS_VL) {
        !          10373:         while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
        !          10374:             if (AscGetChipVersion(iop_beg, bus_type) <= ASC_CHIP_MAX_VER_VL) {
        !          10375:                 return (iop_beg);
        !          10376:             }
        !          10377:         }
        !          10378:         return (0);
        !          10379:     }
        !          10380:     if (bus_type & ASC_IS_ISA) {
        !          10381:         if (_isa_pnp_inited == 0) {
        !          10382:             AscSetISAPNPWaitForKey();
        !          10383:             _isa_pnp_inited++;
        !          10384:         }
        !          10385:         while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
        !          10386:             if ((AscGetChipVersion(iop_beg, bus_type) & ASC_CHIP_VER_ISA_BIT) != 0) {
        !          10387:                 return (iop_beg);
        !          10388:             }
        !          10389:         }
        !          10390:         return (0);
        !          10391:     }
        !          10392:     if (bus_type & ASC_IS_EISA) {
        !          10393:         if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) {
        !          10394:             return (iop_beg);
        !          10395:         }
        !          10396:         return (0);
        !          10397:     }
        !          10398:     return (0);
        !          10399: }
        !          10400: 
        !          10401: ASC_INITFUNC(
        !          10402: STATIC PortAddr
        !          10403: AscSearchIOPortAddr11(
        !          10404:                          PortAddr s_addr
        !          10405: )
        !          10406: )
        !          10407: {
        !          10408:     int                 i;
        !          10409:     PortAddr            iop_base;
        !          10410: 
        !          10411:     for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) {
        !          10412:         if (_asc_def_iop_base[i] > s_addr) {
        !          10413:             break;
        !          10414:         }
        !          10415:     }
        !          10416:     for (; i < ASC_IOADR_TABLE_MAX_IX; i++) {
        !          10417:         iop_base = _asc_def_iop_base[i];
        !          10418:         if (check_region(iop_base, ASC_IOADR_GAP) != 0) {
        !          10419:             ASC_DBG1(1,
        !          10420:                "AscSearchIOPortAddr11: check_region() failed I/O port %x\n",
        !          10421:                      iop_base);
        !          10422:             continue;
        !          10423:         }
        !          10424:         ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port %x\n", iop_base);
        !          10425:         if (AscFindSignature(iop_base)) {
        !          10426:             return (iop_base);
        !          10427:         }
        !          10428:     }
        !          10429:     return (0);
        !          10430: }
        !          10431: 
        !          10432: ASC_INITFUNC(
        !          10433: STATIC void
        !          10434: AscToggleIRQAct(
        !          10435:                    PortAddr iop_base
        !          10436: )
        !          10437: )
        !          10438: {
        !          10439:     AscSetChipStatus(iop_base, CIW_IRQ_ACT);
        !          10440:     AscSetChipStatus(iop_base, 0);
        !          10441:     return;
        !          10442: }
        !          10443: 
        !          10444: ASC_INITFUNC(
        !          10445: STATIC void
        !          10446: AscSetISAPNPWaitForKey(
        !          10447:     void)
        !          10448: )
        !          10449: {
        !          10450:     outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
        !          10451:     outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
        !          10452:     return;
        !          10453: }
        !          10454: 
        !          10455: ASC_INITFUNC(
        !          10456: STATIC uchar
        !          10457: AscGetChipIRQ(
        !          10458:                  PortAddr iop_base,
        !          10459:                  ushort bus_type
        !          10460: )
        !          10461: )
        !          10462: {
        !          10463:     ushort              cfg_lsw;
        !          10464:     uchar               chip_irq;
        !          10465: 
        !          10466:     if ((bus_type & ASC_IS_EISA) != 0) {
        !          10467:         cfg_lsw = AscGetEisaChipCfg(iop_base);
        !          10468:         chip_irq = (uchar) (((cfg_lsw >> 8) & 0x07) + 10);
        !          10469:         if ((chip_irq == 13) || (chip_irq > 15)) {
        !          10470:             return (0);
        !          10471:         }
        !          10472:         return (chip_irq);
        !          10473:     }
        !          10474:     if ((bus_type & ASC_IS_VL) != 0) {
        !          10475:         cfg_lsw = AscGetChipCfgLsw(iop_base);
        !          10476:         chip_irq = (uchar) (((cfg_lsw >> 2) & 0x07));
        !          10477:         if ((chip_irq == 0) ||
        !          10478:             (chip_irq == 4) ||
        !          10479:             (chip_irq == 7)) {
        !          10480:             return (0);
        !          10481:         }
        !          10482:         return ((uchar) (chip_irq + (ASC_MIN_IRQ_NO - 1)));
        !          10483:     }
        !          10484:     cfg_lsw = AscGetChipCfgLsw(iop_base);
        !          10485:     chip_irq = (uchar) (((cfg_lsw >> 2) & 0x03));
        !          10486:     if (chip_irq == 3)
        !          10487:         chip_irq += (uchar) 2;
        !          10488:     return ((uchar) (chip_irq + ASC_MIN_IRQ_NO));
        !          10489: }
        !          10490: 
        !          10491: ASC_INITFUNC(
        !          10492: STATIC uchar
        !          10493: AscSetChipIRQ(
        !          10494:                  PortAddr iop_base,
        !          10495:                  uchar irq_no,
        !          10496:                  ushort bus_type
        !          10497: )
        !          10498: )
        !          10499: {
        !          10500:     ushort              cfg_lsw;
        !          10501: 
        !          10502:     if ((bus_type & ASC_IS_VL) != 0) {
        !          10503:         if (irq_no != 0) {
        !          10504:             if ((irq_no < ASC_MIN_IRQ_NO) || (irq_no > ASC_MAX_IRQ_NO)) {
        !          10505:                 irq_no = 0;
        !          10506:             } else {
        !          10507:                 irq_no -= (uchar) ((ASC_MIN_IRQ_NO - 1));
        !          10508:             }
        !          10509:         }
        !          10510:         cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE3);
        !          10511:         cfg_lsw |= (ushort) 0x0010;
        !          10512:         AscSetChipCfgLsw(iop_base, cfg_lsw);
        !          10513:         AscToggleIRQAct(iop_base);
        !          10514:         cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE0);
        !          10515:         cfg_lsw |= (ushort) ((irq_no & 0x07) << 2);
        !          10516:         AscSetChipCfgLsw(iop_base, cfg_lsw);
        !          10517:         AscToggleIRQAct(iop_base);
        !          10518:         return (AscGetChipIRQ(iop_base, bus_type));
        !          10519:     }
        !          10520:     if ((bus_type & (ASC_IS_ISA)) != 0) {
        !          10521:         if (irq_no == 15)
        !          10522:             irq_no -= (uchar) 2;
        !          10523:         irq_no -= (uchar) ASC_MIN_IRQ_NO;
        !          10524:         cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFF3);
        !          10525:         cfg_lsw |= (ushort) ((irq_no & 0x03) << 2);
        !          10526:         AscSetChipCfgLsw(iop_base, cfg_lsw);
        !          10527:         return (AscGetChipIRQ(iop_base, bus_type));
        !          10528:     }
        !          10529:     return (0);
        !          10530: }
        !          10531: 
        !          10532: ASC_INITFUNC(
        !          10533: STATIC void
        !          10534: AscEnableIsaDma(
        !          10535:                    uchar dma_channel
        !          10536: )
        !          10537: )
        !          10538: {
        !          10539:     if (dma_channel < 4) {
        !          10540:         outp(0x000B, (ushort) (0xC0 | dma_channel));
        !          10541:         outp(0x000A, dma_channel);
        !          10542:     } else if (dma_channel < 8) {
        !          10543:         outp(0x00D6, (ushort) (0xC0 | (dma_channel - 4)));
        !          10544:         outp(0x00D4, (ushort) (dma_channel - 4));
        !          10545:     }
        !          10546:     return;
        !          10547: }
        !          10548: 
        !          10549: STATIC int 
        !          10550: AscIsrChipHalted(
        !          10551:                     REG ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          10552: )
        !          10553: {
        !          10554:     EXT_MSG             ext_msg;
        !          10555:     EXT_MSG             out_msg;
        !          10556:     ushort              halt_q_addr;
        !          10557:     int                 sdtr_accept;
        !          10558:     ushort              int_halt_code;
        !          10559:     ASC_SCSI_BIT_ID_TYPE scsi_busy;
        !          10560:     ASC_SCSI_BIT_ID_TYPE target_id;
        !          10561:     PortAddr            iop_base;
        !          10562:     uchar               tag_code;
        !          10563:     uchar               q_status;
        !          10564:     uchar               halt_qp;
        !          10565:     uchar               sdtr_data;
        !          10566:     uchar               target_ix;
        !          10567:     uchar               q_cntl, tid_no;
        !          10568:     uchar               cur_dvc_qng;
        !          10569:     uchar               asyn_sdtr;
        !          10570:     uchar               scsi_status;
        !          10571:     asc_board_t            *boardp;
        !          10572: 
        !          10573:     ASC_ASSERT(asc_dvc->drv_ptr != 0);
        !          10574:     boardp = (asc_board_t *) asc_dvc->drv_ptr;
        !          10575: 
        !          10576:     iop_base = asc_dvc->iop_base;
        !          10577:     int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
        !          10578: 
        !          10579:     halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
        !          10580:     halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
        !          10581:     target_ix = AscReadLramByte(iop_base,
        !          10582:                    (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TARGET_IX));
        !          10583:     q_cntl = AscReadLramByte(iop_base,
        !          10584:                         (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL));
        !          10585:     tid_no = ASC_TIX_TO_TID(target_ix);
        !          10586:     target_id = (uchar) ASC_TID_TO_TARGET_ID(tid_no);
        !          10587:     if (asc_dvc->pci_fix_asyn_xfer & target_id) {
        !          10588: 
        !          10589:         asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
        !          10590:     } else {
        !          10591:         asyn_sdtr = 0;
        !          10592:     }
        !          10593:     if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
        !          10594:         if (asc_dvc->pci_fix_asyn_xfer & target_id) {
        !          10595:             AscSetChipSDTR(iop_base, 0, tid_no);
        !          10596:             boardp->sdtr_data[tid_no] = 0;
        !          10597:         }
        !          10598:         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
        !          10599:         return (0);
        !          10600:     } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
        !          10601:         if (asc_dvc->pci_fix_asyn_xfer & target_id) {
        !          10602:             AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
        !          10603:             boardp->sdtr_data[tid_no] = asyn_sdtr;
        !          10604:         }
        !          10605:         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
        !          10606:         return (0);
        !          10607:     } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
        !          10608: 
        !          10609:         AscMemWordCopyFromLram(iop_base,
        !          10610:                                ASCV_MSGIN_BEG,
        !          10611:                                (ushort *) & ext_msg,
        !          10612:                                (ushort) (sizeof (EXT_MSG) >> 1));
        !          10613: 
        !          10614:         if (ext_msg.msg_type == MS_EXTEND &&
        !          10615:             ext_msg.msg_req == MS_SDTR_CODE &&
        !          10616:             ext_msg.msg_len == MS_SDTR_LEN) {
        !          10617:             sdtr_accept = TRUE;
        !          10618:             if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
        !          10619: 
        !          10620:                 sdtr_accept = FALSE;
        !          10621:                 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
        !          10622:             }
        !          10623:             if ((ext_msg.xfer_period <
        !          10624:                  asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index]) ||
        !          10625:                 (ext_msg.xfer_period >
        !          10626:                  asc_dvc->sdtr_period_tbl[asc_dvc->max_sdtr_index])) {
        !          10627:                 sdtr_accept = FALSE;
        !          10628:                 ext_msg.xfer_period =
        !          10629:                     asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index];
        !          10630:             }
        !          10631:             if (sdtr_accept) {
        !          10632:                 sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
        !          10633:                                            ext_msg.req_ack_offset);
        !          10634:                 if ((sdtr_data == 0xFF)) {
        !          10635: 
        !          10636:                     q_cntl |= QC_MSG_OUT;
        !          10637:                     asc_dvc->init_sdtr &= ~target_id;
        !          10638:                     asc_dvc->sdtr_done &= ~target_id;
        !          10639:                     AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
        !          10640:                     boardp->sdtr_data[tid_no] = asyn_sdtr;
        !          10641:                 }
        !          10642:             }
        !          10643:             if (ext_msg.req_ack_offset == 0) {
        !          10644: 
        !          10645:                 q_cntl &= ~QC_MSG_OUT;
        !          10646:                 asc_dvc->init_sdtr &= ~target_id;
        !          10647:                 asc_dvc->sdtr_done &= ~target_id;
        !          10648:                 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
        !          10649:             } else {
        !          10650:                 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
        !          10651: 
        !          10652:                     q_cntl &= ~QC_MSG_OUT;
        !          10653:                     asc_dvc->sdtr_done |= target_id;
        !          10654:                     asc_dvc->init_sdtr |= target_id;
        !          10655:                     asc_dvc->pci_fix_asyn_xfer &= ~target_id;
        !          10656:                     sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
        !          10657:                                                ext_msg.req_ack_offset);
        !          10658:                     AscSetChipSDTR(iop_base, sdtr_data, tid_no);
        !          10659:                     boardp->sdtr_data[tid_no] = sdtr_data;
        !          10660:                 } else {
        !          10661: 
        !          10662:                     q_cntl |= QC_MSG_OUT;
        !          10663:                     AscMsgOutSDTR(asc_dvc,
        !          10664:                                   ext_msg.xfer_period,
        !          10665:                                   ext_msg.req_ack_offset);
        !          10666:                     asc_dvc->pci_fix_asyn_xfer &= ~target_id;
        !          10667:                     sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
        !          10668:                                                ext_msg.req_ack_offset);
        !          10669:                     AscSetChipSDTR(iop_base, sdtr_data, tid_no);
        !          10670:                     boardp->sdtr_data[tid_no] = sdtr_data;
        !          10671:                     asc_dvc->sdtr_done |= target_id;
        !          10672:                     asc_dvc->init_sdtr |= target_id;
        !          10673:                 }
        !          10674:             }
        !          10675: 
        !          10676:             AscWriteLramByte(iop_base,
        !          10677:                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
        !          10678:                              q_cntl);
        !          10679:             AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
        !          10680:             return (0);
        !          10681:         } else if (ext_msg.msg_type == MS_EXTEND &&
        !          10682:                    ext_msg.msg_req == MS_WDTR_CODE &&
        !          10683:                    ext_msg.msg_len == MS_WDTR_LEN) {
        !          10684: 
        !          10685:             ext_msg.wdtr_width = 0;
        !          10686:             AscMemWordCopyToLram(iop_base,
        !          10687:                                  ASCV_MSGOUT_BEG,
        !          10688:                                  (ushort *) & ext_msg,
        !          10689:                                  (ushort) (sizeof (EXT_MSG) >> 1));
        !          10690:             q_cntl |= QC_MSG_OUT;
        !          10691:             AscWriteLramByte(iop_base,
        !          10692:                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
        !          10693:                              q_cntl);
        !          10694:             AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
        !          10695:             return (0);
        !          10696:         } else {
        !          10697: 
        !          10698:             ext_msg.msg_type = M1_MSG_REJECT;
        !          10699:             AscMemWordCopyToLram(iop_base,
        !          10700:                                  ASCV_MSGOUT_BEG,
        !          10701:                                  (ushort *) & ext_msg,
        !          10702:                                  (ushort) (sizeof (EXT_MSG) >> 1));
        !          10703:             q_cntl |= QC_MSG_OUT;
        !          10704:             AscWriteLramByte(iop_base,
        !          10705:                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
        !          10706:                              q_cntl);
        !          10707:             AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
        !          10708:             return (0);
        !          10709:         }
        !          10710:     } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
        !          10711: 
        !          10712:         q_cntl |= QC_REQ_SENSE;
        !          10713: 
        !          10714:         if ((asc_dvc->init_sdtr & target_id) != 0) {
        !          10715: 
        !          10716:             asc_dvc->sdtr_done &= ~target_id;
        !          10717: 
        !          10718:             sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
        !          10719:             q_cntl |= QC_MSG_OUT;
        !          10720:             AscMsgOutSDTR(asc_dvc,
        !          10721:                           asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
        !          10722:                            (uchar) (asc_dvc->max_sdtr_index - 1)],
        !          10723:                           (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
        !          10724:         }
        !          10725: 
        !          10726:         AscWriteLramByte(iop_base,
        !          10727:                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
        !          10728:                          q_cntl);
        !          10729: 
        !          10730:         tag_code = AscReadLramByte(iop_base,
        !          10731:                     (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE));
        !          10732:         tag_code &= 0xDC;
        !          10733:         if (
        !          10734:                (asc_dvc->pci_fix_asyn_xfer & target_id)
        !          10735:                && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
        !          10736: ) {
        !          10737: 
        !          10738:             tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
        !          10739:                          | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
        !          10740: 
        !          10741:         }
        !          10742:         AscWriteLramByte(iop_base,
        !          10743:                      (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE),
        !          10744:                          tag_code);
        !          10745: 
        !          10746:         q_status = AscReadLramByte(iop_base,
        !          10747:                       (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS));
        !          10748:         q_status |= (QS_READY | QS_BUSY);
        !          10749:         AscWriteLramByte(iop_base,
        !          10750:                        (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
        !          10751:                          q_status);
        !          10752: 
        !          10753:         scsi_busy = AscReadLramByte(iop_base,
        !          10754:                                     (ushort) ASCV_SCSIBUSY_B);
        !          10755:         scsi_busy &= ~target_id;
        !          10756:         AscWriteLramByte(iop_base, (ushort) ASCV_SCSIBUSY_B, scsi_busy);
        !          10757: 
        !          10758:         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
        !          10759:         return (0);
        !          10760:     } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
        !          10761: 
        !          10762:         AscMemWordCopyFromLram(iop_base,
        !          10763:                                ASCV_MSGOUT_BEG,
        !          10764:                                (ushort *) & out_msg,
        !          10765:                                (ushort) (sizeof (EXT_MSG) >> 1));
        !          10766: 
        !          10767:         if ((out_msg.msg_type == MS_EXTEND) &&
        !          10768:             (out_msg.msg_len == MS_SDTR_LEN) &&
        !          10769:             (out_msg.msg_req == MS_SDTR_CODE)) {
        !          10770: 
        !          10771:             asc_dvc->init_sdtr &= ~target_id;
        !          10772:             asc_dvc->sdtr_done &= ~target_id;
        !          10773:             AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
        !          10774:             boardp->sdtr_data[tid_no] = asyn_sdtr;
        !          10775:         }
        !          10776:         q_cntl &= ~QC_MSG_OUT;
        !          10777:         AscWriteLramByte(iop_base,
        !          10778:                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
        !          10779:                          q_cntl);
        !          10780:         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
        !          10781:         return (0);
        !          10782:     } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
        !          10783: 
        !          10784:         scsi_status = AscReadLramByte(iop_base,
        !          10785:           (ushort) ((ushort) halt_q_addr + (ushort) ASC_SCSIQ_SCSI_STATUS));
        !          10786:         cur_dvc_qng = AscReadLramByte(iop_base,
        !          10787:                      (ushort) ((ushort) ASC_QADR_BEG + (ushort) target_ix));
        !          10788:         if ((cur_dvc_qng > 0) &&
        !          10789:             (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
        !          10790: 
        !          10791:             scsi_busy = AscReadLramByte(iop_base,
        !          10792:                                         (ushort) ASCV_SCSIBUSY_B);
        !          10793:             scsi_busy |= target_id;
        !          10794:             AscWriteLramByte(iop_base,
        !          10795:                              (ushort) ASCV_SCSIBUSY_B, scsi_busy);
        !          10796:             asc_dvc->queue_full_or_busy |= target_id;
        !          10797: 
        !          10798:             if (scsi_status == SS_QUEUE_FULL) {
        !          10799:                 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
        !          10800:                     cur_dvc_qng -= 1;
        !          10801:                     asc_dvc->max_dvc_qng[tid_no] = cur_dvc_qng;
        !          10802: 
        !          10803:                     AscWriteLramByte(iop_base,
        !          10804:                           (ushort) ((ushort) ASCV_MAX_DVC_QNG_BEG +
        !          10805:                            (ushort) tid_no),
        !          10806:                           cur_dvc_qng);
        !          10807: 
        !          10808:                     /*
        !          10809:                      * Set the device queue depth to the number of
        !          10810:                      * active requests when the QUEUE FULL condition
        !          10811:                      * was encountered.
        !          10812:                      */
        !          10813:                     boardp->queue_full |= target_id;
        !          10814:                     boardp->queue_full_cnt[tid_no] = cur_dvc_qng;
        !          10815: #if ASC_QUEUE_FLOW_CONTROL
        !          10816:                     if (boardp->device[tid_no] != NULL &&
        !          10817:                         boardp->device[tid_no]->queue_curr_depth >
        !          10818:                         cur_dvc_qng) {
        !          10819:                         boardp->device[tid_no]->queue_curr_depth =
        !          10820:                             cur_dvc_qng;
        !          10821:                     }
        !          10822: #endif /* ASC_QUEUE_FLOW_CONTROL */
        !          10823:                 }
        !          10824:             }
        !          10825:         }
        !          10826:         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
        !          10827:         return (0);
        !          10828:     }
        !          10829:     return (0);
        !          10830: }
        !          10831: 
        !          10832: STATIC uchar
        !          10833: _AscCopyLramScsiDoneQ(
        !          10834:                          PortAddr iop_base,
        !          10835:                          ushort q_addr,
        !          10836:                          REG ASC_QDONE_INFO * scsiq,
        !          10837:                          ulong max_dma_count
        !          10838: )
        !          10839: {
        !          10840:     ushort              _val;
        !          10841:     uchar               sg_queue_cnt;
        !          10842: 
        !          10843:     DvcGetQinfo(iop_base,
        !          10844:                 (ushort) (q_addr + (ushort) ASC_SCSIQ_DONE_INFO_BEG),
        !          10845:                 (ushort *) scsiq,
        !          10846:               (ushort) ((sizeof (ASC_SCSIQ_2) + sizeof (ASC_SCSIQ_3)) / 2));
        !          10847:     _val = AscReadLramWord(iop_base,
        !          10848:                            (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS));
        !          10849:     scsiq->q_status = (uchar) _val;
        !          10850:     scsiq->q_no = (uchar) (_val >> 8);
        !          10851:     _val = AscReadLramWord(iop_base,
        !          10852:                            (ushort) (q_addr + (ushort) ASC_SCSIQ_B_CNTL));
        !          10853:     scsiq->cntl = (uchar) _val;
        !          10854:     sg_queue_cnt = (uchar) (_val >> 8);
        !          10855:     _val = AscReadLramWord(iop_base,
        !          10856:                         (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SENSE_LEN));
        !          10857:     scsiq->sense_len = (uchar) _val;
        !          10858:     scsiq->extra_bytes = (uchar) (_val >> 8);
        !          10859:     scsiq->remain_bytes = AscReadLramWord(iop_base,
        !          10860:                  (ushort) (q_addr + (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT));
        !          10861:     scsiq->remain_bytes &= max_dma_count;
        !          10862:     return (sg_queue_cnt);
        !          10863: }
        !          10864: 
        !          10865: STATIC int
        !          10866: AscIsrQDone(
        !          10867:                REG ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          10868: )
        !          10869: {
        !          10870:     uchar               next_qp;
        !          10871:     uchar               n_q_used;
        !          10872:     uchar               sg_list_qp;
        !          10873:     uchar               sg_queue_cnt;
        !          10874:     uchar               q_cnt;
        !          10875:     uchar               done_q_tail;
        !          10876:     uchar               tid_no;
        !          10877:     ASC_SCSI_BIT_ID_TYPE scsi_busy;
        !          10878:     ASC_SCSI_BIT_ID_TYPE target_id;
        !          10879:     PortAddr            iop_base;
        !          10880:     ushort              q_addr;
        !          10881:     ushort              sg_q_addr;
        !          10882:     uchar               cur_target_qng;
        !          10883:     ASC_QDONE_INFO      scsiq_buf;
        !          10884:     REG ASC_QDONE_INFO *scsiq;
        !          10885:     int                 false_overrun;
        !          10886:     ASC_ISR_CALLBACK    asc_isr_callback;
        !          10887: 
        !          10888:     iop_base = asc_dvc->iop_base;
        !          10889:     asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
        !          10890:     n_q_used = 1;
        !          10891:     scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
        !          10892:     done_q_tail = (uchar) AscGetVarDoneQTail(iop_base);
        !          10893:     q_addr = ASC_QNO_TO_QADDR(done_q_tail);
        !          10894:     next_qp = AscReadLramByte(iop_base,
        !          10895:                               (ushort) (q_addr + (ushort) ASC_SCSIQ_B_FWD));
        !          10896:     if (next_qp != ASC_QLINK_END) {
        !          10897:         AscPutVarDoneQTail(iop_base, next_qp);
        !          10898:         q_addr = ASC_QNO_TO_QADDR(next_qp);
        !          10899:         sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
        !          10900:             asc_dvc->max_dma_count);
        !          10901:         AscWriteLramByte(iop_base,
        !          10902:                          (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
        !          10903:              (uchar) (scsiq->q_status & (uchar) ~ (QS_READY | QS_ABORTED)));
        !          10904:         tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
        !          10905:         target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
        !          10906:         if ((scsiq->cntl & QC_SG_HEAD) != 0) {
        !          10907:             sg_q_addr = q_addr;
        !          10908:             sg_list_qp = next_qp;
        !          10909:             for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
        !          10910:                 sg_list_qp = AscReadLramByte(iop_base,
        !          10911:                            (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_FWD));
        !          10912:                 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
        !          10913:                 if (sg_list_qp == ASC_QLINK_END) {
        !          10914:                     AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SG_Q_LINKS);
        !          10915:                     scsiq->d3.done_stat = QD_WITH_ERROR;
        !          10916:                     scsiq->d3.host_stat = QHSTA_D_QDONE_SG_LIST_CORRUPTED;
        !          10917:                     goto FATAL_ERR_QDONE;
        !          10918:                 }
        !          10919:                 AscWriteLramByte(iop_base,
        !          10920:                          (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
        !          10921:                                  QS_FREE);
        !          10922:             }
        !          10923:             n_q_used = sg_queue_cnt + 1;
        !          10924:             AscPutVarDoneQTail(iop_base, sg_list_qp);
        !          10925:         }
        !          10926:         if (asc_dvc->queue_full_or_busy & target_id) {
        !          10927:             cur_target_qng = AscReadLramByte(iop_base,
        !          10928:             (ushort) ((ushort) ASC_QADR_BEG + (ushort) scsiq->d2.target_ix));
        !          10929:             if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
        !          10930:                 scsi_busy = AscReadLramByte(iop_base,
        !          10931:                                             (ushort) ASCV_SCSIBUSY_B);
        !          10932:                 scsi_busy &= ~target_id;
        !          10933:                 AscWriteLramByte(iop_base,
        !          10934:                                  (ushort) ASCV_SCSIBUSY_B, scsi_busy);
        !          10935:                 asc_dvc->queue_full_or_busy &= ~target_id;
        !          10936:             }
        !          10937:         }
        !          10938:         if (asc_dvc->cur_total_qng >= n_q_used) {
        !          10939:             asc_dvc->cur_total_qng -= n_q_used;
        !          10940:             if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
        !          10941:                 asc_dvc->cur_dvc_qng[tid_no]--;
        !          10942:             }
        !          10943:         } else {
        !          10944:             AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
        !          10945:             scsiq->d3.done_stat = QD_WITH_ERROR;
        !          10946:             goto FATAL_ERR_QDONE;
        !          10947:         }
        !          10948:         if ((scsiq->d2.srb_ptr == 0UL) ||
        !          10949:             ((scsiq->q_status & QS_ABORTED) != 0)) {
        !          10950:             return (0x11);
        !          10951:         } else if (scsiq->q_status == QS_DONE) {
        !          10952:             false_overrun = FALSE;
        !          10953:             if (scsiq->extra_bytes != 0) {
        !          10954:                 scsiq->remain_bytes += (ulong) scsiq->extra_bytes;
        !          10955:             }
        !          10956:             if (scsiq->d3.done_stat == QD_WITH_ERROR) {
        !          10957:                 if (scsiq->d3.host_stat == QHSTA_M_DATA_OVER_RUN) {
        !          10958:                     if ((scsiq->cntl & (QC_DATA_IN | QC_DATA_OUT)) == 0) {
        !          10959:                         scsiq->d3.done_stat = QD_NO_ERROR;
        !          10960:                         scsiq->d3.host_stat = QHSTA_NO_ERROR;
        !          10961:                     } else if (false_overrun) {
        !          10962:                         scsiq->d3.done_stat = QD_NO_ERROR;
        !          10963:                         scsiq->d3.host_stat = QHSTA_NO_ERROR;
        !          10964:                     }
        !          10965:                 } else if (scsiq->d3.host_stat ==
        !          10966:                            QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
        !          10967:                     AscStopChip(iop_base);
        !          10968:                     AscSetChipControl(iop_base,
        !          10969:                         (uchar) (CC_SCSI_RESET | CC_HALT));
        !          10970:                     DvcDelayNanoSecond(asc_dvc, 60000);
        !          10971:                     AscSetChipControl(iop_base, CC_HALT);
        !          10972:                     AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
        !          10973:                     AscSetChipStatus(iop_base, 0);
        !          10974:                     AscSetChipControl(iop_base, 0);
        !          10975:                 }
        !          10976:             }
        !          10977:             if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
        !          10978:                 (*asc_isr_callback) (asc_dvc, scsiq);
        !          10979:             } else {
        !          10980:                 if ((AscReadLramByte(iop_base,
        !          10981:                           (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG)) ==
        !          10982:                      SCSICMD_StartStopUnit)) {
        !          10983:                     asc_dvc->unit_not_ready &= ~target_id;
        !          10984:                     if (scsiq->d3.done_stat != QD_NO_ERROR) {
        !          10985:                         asc_dvc->start_motor &= ~target_id;
        !          10986:                     }
        !          10987:                 }
        !          10988:             }
        !          10989:             return (1);
        !          10990:         } else {
        !          10991:             AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
        !          10992:           FATAL_ERR_QDONE:
        !          10993:             if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
        !          10994:                 (*asc_isr_callback) (asc_dvc, scsiq);
        !          10995:             }
        !          10996:             return (0x80);
        !          10997:         }
        !          10998:     }
        !          10999:     return (0);
        !          11000: }
        !          11001: 
        !          11002: STATIC int
        !          11003: AscISR(
        !          11004:           REG ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          11005: )
        !          11006: {
        !          11007:     ASC_CS_TYPE         chipstat;
        !          11008:     PortAddr            iop_base;
        !          11009:     ushort              saved_ram_addr;
        !          11010:     uchar               ctrl_reg;
        !          11011:     uchar               saved_ctrl_reg;
        !          11012:     int                 int_pending;
        !          11013:     int                 status;
        !          11014:     uchar               host_flag;
        !          11015: 
        !          11016:     iop_base = asc_dvc->iop_base;
        !          11017:     int_pending = FALSE;
        !          11018:     if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
        !          11019:         || (asc_dvc->isr_callback == 0)
        !          11020: ) {
        !          11021:         return (ERR);
        !          11022:     }
        !          11023:     if (asc_dvc->in_critical_cnt != 0) {
        !          11024:         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
        !          11025:         return (ERR);
        !          11026:     }
        !          11027:     if (asc_dvc->is_in_int) {
        !          11028:         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
        !          11029:         return (ERR);
        !          11030:     }
        !          11031:     asc_dvc->is_in_int = TRUE;
        !          11032:     ctrl_reg = AscGetChipControl(iop_base);
        !          11033:     saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
        !          11034:                                    CC_SINGLE_STEP | CC_DIAG | CC_TEST));
        !          11035:     chipstat = AscGetChipStatus(iop_base);
        !          11036:     if (chipstat & CSW_SCSI_RESET_LATCH) {
        !          11037:         if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
        !          11038:             int_pending = TRUE;
        !          11039:             asc_dvc->sdtr_done = 0;
        !          11040:             saved_ctrl_reg &= (uchar) (~CC_HALT);
        !          11041:             while (AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) ;
        !          11042:             AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
        !          11043:             AscSetChipControl(iop_base, CC_HALT);
        !          11044:             AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
        !          11045:             AscSetChipStatus(iop_base, 0);
        !          11046:             chipstat = AscGetChipStatus(iop_base);
        !          11047:         }
        !          11048:     }
        !          11049:     saved_ram_addr = AscGetChipLramAddr(iop_base);
        !          11050:     host_flag = AscReadLramByte(iop_base,
        !          11051:         ASCV_HOST_FLAG_B) & (uchar) (~ASC_HOST_FLAG_IN_ISR);
        !          11052:     AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
        !          11053:                      (uchar) (host_flag | (uchar) ASC_HOST_FLAG_IN_ISR));
        !          11054:     if ((chipstat & CSW_INT_PENDING)
        !          11055:         || (int_pending)
        !          11056: ) {
        !          11057:         AscAckInterrupt(iop_base);
        !          11058:         int_pending = TRUE;
        !          11059:         if ((chipstat & CSW_HALTED) &&
        !          11060:             (ctrl_reg & CC_SINGLE_STEP)) {
        !          11061:             if (AscIsrChipHalted(asc_dvc) == ERR) {
        !          11062:                 goto ISR_REPORT_QDONE_FATAL_ERROR;
        !          11063:             } else {
        !          11064:                 saved_ctrl_reg &= (uchar) (~CC_HALT);
        !          11065:             }
        !          11066:         } else {
        !          11067:           ISR_REPORT_QDONE_FATAL_ERROR:
        !          11068:             if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
        !          11069:                 while (((status = AscIsrQDone(asc_dvc)) & 0x01) != 0) {
        !          11070:                 }
        !          11071:             } else {
        !          11072:                 do {
        !          11073:                     if ((status = AscIsrQDone(asc_dvc)) == 1) {
        !          11074:                         break;
        !          11075:                     }
        !          11076:                 } while (status == 0x11);
        !          11077:             }
        !          11078:             if ((status & 0x80) != 0)
        !          11079:                 int_pending = ERR;
        !          11080:         }
        !          11081:     }
        !          11082:     AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
        !          11083:     AscSetChipLramAddr(iop_base, saved_ram_addr);
        !          11084:     AscSetChipControl(iop_base, saved_ctrl_reg);
        !          11085:     asc_dvc->is_in_int = FALSE;
        !          11086:     return (int_pending);
        !          11087: }
        !          11088: 
        !          11089: STATIC uchar _asc_mcode_buf[] ASC_INITDATA =
        !          11090: {
        !          11091:   0x01,  0x03,  0x01,  0x19,  0x0F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
        !          11092:   0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
        !          11093:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
        !          11094:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
        !          11095:   0x00,  0x00,  0x00,  0x00,  0x91,  0x10,  0x0A,  0x05,  0x01,  0x00,  0x00,  0x00,  0x00,  0xFF,  0x00,  0x00,
        !          11096:   0x00,  0x00,  0x00,  0x00,  0xFF,  0x80,  0xFF,  0xFF,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
        !          11097:   0x00,  0x00,  0x00,  0x23,  0x00,  0x24,  0x00,  0x00,  0x00,  0x07,  0x00,  0xFF,  0x00,  0x00,  0x00,  0x00,
        !          11098:   0xFF,  0xFF,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xE2,  0x88,  0x00,  0x00,  0x00,  0x00,
        !          11099:   0x80,  0x73,  0x48,  0x04,  0x36,  0x00,  0x00,  0xA2,  0xC2,  0x00,  0x80,  0x73,  0x03,  0x23,  0x36,  0x40,
        !          11100:   0xB6,  0x00,  0x36,  0x00,  0x05,  0xD6,  0x0C,  0xD2,  0x12,  0xDA,  0x00,  0xA2,  0xC2,  0x00,  0x92,  0x80,
        !          11101:   0x1E,  0x98,  0x50,  0x00,  0xF5,  0x00,  0x48,  0x98,  0xDF,  0x23,  0x36,  0x60,  0xB6,  0x00,  0x92,  0x80,
        !          11102:   0x4F,  0x00,  0xF5,  0x00,  0x48,  0x98,  0xEF,  0x23,  0x36,  0x60,  0xB6,  0x00,  0x92,  0x80,  0x80,  0x62,
        !          11103:   0x92,  0x80,  0x00,  0x46,  0x17,  0xEE,  0x13,  0xEA,  0x02,  0x01,  0x09,  0xD8,  0xCD,  0x04,  0x4D,  0x00,
        !          11104:   0x00,  0xA3,  0xD6,  0x00,  0xA6,  0x97,  0x7F,  0x23,  0x04,  0x61,  0x84,  0x01,  0xE6,  0x84,  0xD2,  0xC1,
        !          11105:   0x80,  0x73,  0xCD,  0x04,  0x4D,  0x00,  0x00,  0xA3,  0xE2,  0x01,  0xA6,  0x97,  0xCE,  0x81,  0x00,  0x33,
        !          11106:   0x02,  0x00,  0xC0,  0x88,  0x80,  0x73,  0x80,  0x77,  0x00,  0x01,  0x01,  0xA1,  0x02,  0x01,  0x4F,  0x00,
        !          11107:   0x84,  0x97,  0x07,  0xA6,  0x0C,  0x01,  0x00,  0x33,  0x03,  0x00,  0xC0,  0x88,  0x03,  0x03,  0x03,  0xDE,
        !          11108:   0x00,  0x33,  0x05,  0x00,  0xC0,  0x88,  0xCE,  0x00,  0x69,  0x60,  0xCE,  0x00,  0x02,  0x03,  0x4A,  0x60,
        !          11109:   0x00,  0xA2,  0x80,  0x01,  0x80,  0x63,  0x07,  0xA6,  0x2C,  0x01,  0x80,  0x81,  0x03,  0x03,  0x80,  0x63,
        !          11110:   0xE2,  0x00,  0x07,  0xA6,  0x3C,  0x01,  0x00,  0x33,  0x04,  0x00,  0xC0,  0x88,  0x03,  0x07,  0x02,  0x01,
        !          11111:   0x04,  0xCA,  0x0D,  0x23,  0x68,  0x98,  0x4D,  0x04,  0x04,  0x85,  0x05,  0xD8,  0x0D,  0x23,  0x68,  0x98,
        !          11112:   0xCD,  0x04,  0x15,  0x23,  0xF6,  0x88,  0xFB,  0x23,  0x02,  0x61,  0x82,  0x01,  0x80,  0x63,  0x02,  0x03,
        !          11113:   0x06,  0xA3,  0x6A,  0x01,  0x00,  0x33,  0x0A,  0x00,  0xC0,  0x88,  0x4E,  0x00,  0x07,  0xA3,  0x76,  0x01,
        !          11114:   0x00,  0x33,  0x0B,  0x00,  0xC0,  0x88,  0xCD,  0x04,  0x36,  0x2D,  0x00,  0x33,  0x1A,  0x00,  0xC0,  0x88,
        !          11115:   0x50,  0x04,  0x90,  0x81,  0x06,  0xAB,  0x8A,  0x01,  0x90,  0x81,  0x4E,  0x00,  0x07,  0xA3,  0x9A,  0x01,
        !          11116:   0x50,  0x00,  0x00,  0xA3,  0x44,  0x01,  0x00,  0x05,  0x84,  0x81,  0x46,  0x97,  0x02,  0x01,  0x05,  0xC6,
        !          11117:   0x04,  0x23,  0xA0,  0x01,  0x15,  0x23,  0xA1,  0x01,  0xC6,  0x81,  0xFD,  0x23,  0x02,  0x61,  0x82,  0x01,
        !          11118:   0x0A,  0xDA,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA0,  0xBC,  0x01,  0x80,  0x63,  0xCD,  0x04,  0x36,  0x2D,
        !          11119:   0x00,  0x33,  0x1B,  0x00,  0xC0,  0x88,  0x06,  0x23,  0x68,  0x98,  0xCD,  0x04,  0xE6,  0x84,  0x06,  0x01,
        !          11120:   0x00,  0xA2,  0xDC,  0x01,  0x57,  0x60,  0x00,  0xA0,  0xE2,  0x01,  0xE6,  0x84,  0x80,  0x23,  0xA0,  0x01,
        !          11121:   0xE6,  0x84,  0x80,  0x73,  0x4B,  0x00,  0x06,  0x61,  0x00,  0xA2,  0x08,  0x02,  0x04,  0x01,  0x0C,  0xDE,
        !          11122:   0x02,  0x01,  0x03,  0xCC,  0x4F,  0x00,  0x84,  0x97,  0x04,  0x82,  0x08,  0x23,  0x02,  0x41,  0x82,  0x01,
        !          11123:   0x4F,  0x00,  0x62,  0x97,  0x48,  0x04,  0x84,  0x80,  0xF0,  0x97,  0x00,  0x46,  0x56,  0x00,  0x03,  0xC0,
        !          11124:   0x01,  0x23,  0xE8,  0x00,  0x81,  0x73,  0x06,  0x29,  0x03,  0x42,  0x06,  0xE2,  0x03,  0xEE,  0x67,  0xEB,
        !          11125:   0x11,  0x23,  0xF6,  0x88,  0x04,  0x98,  0xF4,  0x80,  0x80,  0x73,  0x80,  0x77,  0x07,  0xA4,  0x32,  0x02,
        !          11126:   0x7C,  0x95,  0x06,  0xA6,  0x3C,  0x02,  0x03,  0xA6,  0x4C,  0x04,  0xC0,  0x88,  0x04,  0x01,  0x03,  0xD8,
        !          11127:   0xB2,  0x98,  0x6A,  0x96,  0x4E,  0x82,  0xFE,  0x95,  0x80,  0x67,  0x83,  0x03,  0x80,  0x63,  0xB6,  0x2D,
        !          11128:   0x02,  0xA6,  0x78,  0x02,  0x07,  0xA6,  0x66,  0x02,  0x06,  0xA6,  0x6A,  0x02,  0x03,  0xA6,  0x6E,  0x02,
        !          11129:   0x00,  0x33,  0x10,  0x00,  0xC0,  0x88,  0x7C,  0x95,  0x50,  0x82,  0x60,  0x96,  0x50,  0x82,  0x04,  0x23,
        !          11130:   0xA0,  0x01,  0x14,  0x23,  0xA1,  0x01,  0x3C,  0x84,  0x04,  0x01,  0x0C,  0xDC,  0xE0,  0x23,  0x25,  0x61,
        !          11131:   0xEF,  0x00,  0x14,  0x01,  0x4F,  0x04,  0xA8,  0x01,  0x6F,  0x00,  0xA5,  0x01,  0x03,  0x23,  0xA4,  0x01,
        !          11132:   0x06,  0x23,  0x9C,  0x01,  0x24,  0x2B,  0x1C,  0x01,  0x02,  0xA6,  0xB6,  0x02,  0x07,  0xA6,  0x66,  0x02,
        !          11133:   0x06,  0xA6,  0x6A,  0x02,  0x03,  0xA6,  0x20,  0x04,  0x01,  0xA6,  0xC0,  0x02,  0x00,  0xA6,  0xC0,  0x02,
        !          11134:   0x00,  0x33,  0x12,  0x00,  0xC0,  0x88,  0x00,  0x0E,  0x80,  0x63,  0x00,  0x43,  0x00,  0xA0,  0x98,  0x02,
        !          11135:   0x4D,  0x04,  0x04,  0x01,  0x0B,  0xDC,  0xE7,  0x23,  0x04,  0x61,  0x84,  0x01,  0x10,  0x31,  0x12,  0x35,
        !          11136:   0x14,  0x01,  0xEC,  0x00,  0x6C,  0x38,  0x00,  0x3F,  0x00,  0x00,  0xF6,  0x82,  0x18,  0x23,  0x04,  0x61,
        !          11137:   0x18,  0xA0,  0xEE,  0x02,  0x04,  0x01,  0x9C,  0xC8,  0x00,  0x33,  0x1F,  0x00,  0xC0,  0x88,  0x08,  0x31,
        !          11138:   0x0A,  0x35,  0x0C,  0x39,  0x0E,  0x3D,  0x7E,  0x98,  0xB6,  0x2D,  0x01,  0xA6,  0x20,  0x03,  0x00,  0xA6,
        !          11139:   0x20,  0x03,  0x07,  0xA6,  0x18,  0x03,  0x06,  0xA6,  0x1C,  0x03,  0x03,  0xA6,  0x20,  0x04,  0x02,  0xA6,
        !          11140:   0x78,  0x02,  0x00,  0x33,  0x33,  0x00,  0xC0,  0x88,  0x7C,  0x95,  0xFA,  0x82,  0x60,  0x96,  0xFA,  0x82,
        !          11141:   0x82,  0x98,  0x80,  0x42,  0x7E,  0x98,  0x60,  0xE4,  0x04,  0x01,  0x29,  0xC8,  0x31,  0x05,  0x07,  0x01,
        !          11142:   0x00,  0xA2,  0x60,  0x03,  0x00,  0x43,  0x87,  0x01,  0x05,  0x05,  0x86,  0x98,  0x7E,  0x98,  0x00,  0xA6,
        !          11143:   0x22,  0x03,  0x07,  0xA6,  0x58,  0x03,  0x03,  0xA6,  0x3C,  0x04,  0x06,  0xA6,  0x5C,  0x03,  0x01,  0xA6,
        !          11144:   0x22,  0x03,  0x00,  0x33,  0x25,  0x00,  0xC0,  0x88,  0x7C,  0x95,  0x3E,  0x83,  0x60,  0x96,  0x3E,  0x83,
        !          11145:   0x04,  0x01,  0x0C,  0xCE,  0x03,  0xC8,  0x00,  0x33,  0x42,  0x00,  0xC0,  0x88,  0x00,  0x01,  0x05,  0x05,
        !          11146:   0xFF,  0xA2,  0x7E,  0x03,  0xB1,  0x01,  0x08,  0x23,  0xB2,  0x01,  0x3A,  0x83,  0x05,  0x05,  0x15,  0x01,
        !          11147:   0x00,  0xA2,  0x9E,  0x03,  0xEC,  0x00,  0x6E,  0x00,  0x95,  0x01,  0x6C,  0x38,  0x00,  0x3F,  0x00,  0x00,
        !          11148:   0x01,  0xA6,  0x9A,  0x03,  0x00,  0xA6,  0x9A,  0x03,  0x12,  0x84,  0x80,  0x42,  0x7E,  0x98,  0x01,  0xA6,
        !          11149:   0xA8,  0x03,  0x00,  0xA6,  0xC0,  0x03,  0x12,  0x84,  0xA6,  0x98,  0x80,  0x42,  0x01,  0xA6,  0xA8,  0x03,
        !          11150:   0x07,  0xA6,  0xB6,  0x03,  0xD8,  0x83,  0x7C,  0x95,  0xAC,  0x83,  0x00,  0x33,  0x2F,  0x00,  0xC0,  0x88,
        !          11151:   0xA6,  0x98,  0x80,  0x42,  0x00,  0xA6,  0xC0,  0x03,  0x07,  0xA6,  0xCE,  0x03,  0xD8,  0x83,  0x7C,  0x95,
        !          11152:   0xC4,  0x83,  0x00,  0x33,  0x26,  0x00,  0xC0,  0x88,  0x38,  0x2B,  0x80,  0x32,  0x80,  0x36,  0x04,  0x23,
        !          11153:   0xA0,  0x01,  0x12,  0x23,  0xA1,  0x01,  0x12,  0x84,  0x06,  0xF0,  0x06,  0xA4,  0xF6,  0x03,  0x80,  0x6B,
        !          11154:   0x05,  0x23,  0x83,  0x03,  0x80,  0x63,  0x03,  0xA6,  0x10,  0x04,  0x07,  0xA6,  0x08,  0x04,  0x06,  0xA6,
        !          11155:   0x0C,  0x04,  0x00,  0x33,  0x17,  0x00,  0xC0,  0x88,  0x7C,  0x95,  0xF6,  0x83,  0x60,  0x96,  0xF6,  0x83,
        !          11156:   0x20,  0x84,  0x06,  0xF0,  0x06,  0xA4,  0x20,  0x04,  0x80,  0x6B,  0x05,  0x23,  0x83,  0x03,  0x80,  0x63,
        !          11157:   0xB6,  0x2D,  0x03,  0xA6,  0x3C,  0x04,  0x07,  0xA6,  0x34,  0x04,  0x06,  0xA6,  0x38,  0x04,  0x00,  0x33,
        !          11158:   0x30,  0x00,  0xC0,  0x88,  0x7C,  0x95,  0x20,  0x84,  0x60,  0x96,  0x20,  0x84,  0x1D,  0x01,  0x06,  0xCC,
        !          11159:   0x00,  0x33,  0x00,  0x84,  0xC0,  0x20,  0x00,  0x23,  0xEA,  0x00,  0x81,  0x62,  0xA2,  0x0D,  0x80,  0x63,
        !          11160:   0x07,  0xA6,  0x5A,  0x04,  0x00,  0x33,  0x18,  0x00,  0xC0,  0x88,  0x03,  0x03,  0x80,  0x63,  0xA3,  0x01,
        !          11161:   0x07,  0xA4,  0x64,  0x04,  0x23,  0x01,  0x00,  0xA2,  0x86,  0x04,  0x0A,  0xA0,  0x76,  0x04,  0xE0,  0x00,
        !          11162:   0x00,  0x33,  0x1D,  0x00,  0xC0,  0x88,  0x0B,  0xA0,  0x82,  0x04,  0xE0,  0x00,  0x00,  0x33,  0x1E,  0x00,
        !          11163:   0xC0,  0x88,  0x42,  0x23,  0xF6,  0x88,  0x00,  0x23,  0x22,  0xA3,  0xE6,  0x04,  0x08,  0x23,  0x22,  0xA3,
        !          11164:   0xA2,  0x04,  0x28,  0x23,  0x22,  0xA3,  0xAE,  0x04,  0x02,  0x23,  0x22,  0xA3,  0xC4,  0x04,  0x42,  0x23,
        !          11165:   0xF6,  0x88,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA0,  0xAE,  0x04,  0x45,  0x23,  0xF6,  0x88,  0x04,  0x98,
        !          11166:   0x00,  0xA2,  0xC0,  0x04,  0xB2,  0x98,  0x00,  0x33,  0x00,  0x82,  0xC0,  0x20,  0x81,  0x62,  0xF0,  0x81,
        !          11167:   0x47,  0x23,  0xF6,  0x88,  0x04,  0x01,  0x0B,  0xDE,  0x04,  0x98,  0xB2,  0x98,  0x00,  0x33,  0x00,  0x81,
        !          11168:   0xC0,  0x20,  0x81,  0x62,  0x14,  0x01,  0x00,  0xA0,  0x08,  0x02,  0x43,  0x23,  0xF6,  0x88,  0x04,  0x23,
        !          11169:   0xA0,  0x01,  0x44,  0x23,  0xA1,  0x01,  0x80,  0x73,  0x4D,  0x00,  0x03,  0xA3,  0xF4,  0x04,  0x00,  0x33,
        !          11170:   0x27,  0x00,  0xC0,  0x88,  0x04,  0x01,  0x04,  0xDC,  0x02,  0x23,  0xA2,  0x01,  0x04,  0x23,  0xA0,  0x01,
        !          11171:   0x04,  0x98,  0x26,  0x95,  0x4B,  0x00,  0xF6,  0x00,  0x4F,  0x04,  0x4F,  0x00,  0x00,  0xA3,  0x22,  0x05,
        !          11172:   0x00,  0x05,  0x76,  0x00,  0x06,  0x61,  0x00,  0xA2,  0x1C,  0x05,  0x0A,  0x85,  0x46,  0x97,  0xCD,  0x04,
        !          11173:   0x24,  0x85,  0x48,  0x04,  0x84,  0x80,  0x02,  0x01,  0x03,  0xDA,  0x80,  0x23,  0x82,  0x01,  0x34,  0x85,
        !          11174:   0x02,  0x23,  0xA0,  0x01,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA2,  0x40,  0x05,  0x1D,  0x01,  0x04,  0xD6,
        !          11175:   0xFF,  0x23,  0x86,  0x41,  0x4B,  0x60,  0xCB,  0x00,  0xFF,  0x23,  0x80,  0x01,  0x49,  0x00,  0x81,  0x01,
        !          11176:   0x04,  0x01,  0x02,  0xC8,  0x30,  0x01,  0x80,  0x01,  0xF7,  0x04,  0x03,  0x01,  0x49,  0x04,  0x80,  0x01,
        !          11177:   0xC9,  0x00,  0x00,  0x05,  0x00,  0x01,  0xFF,  0xA0,  0x60,  0x05,  0x77,  0x04,  0x01,  0x23,  0xEA,  0x00,
        !          11178:   0x5D,  0x00,  0xFE,  0xC7,  0x00,  0x62,  0x00,  0x23,  0xEA,  0x00,  0x00,  0x63,  0x07,  0xA4,  0xF8,  0x05,
        !          11179:   0x03,  0x03,  0x02,  0xA0,  0x8E,  0x05,  0xF4,  0x85,  0x00,  0x33,  0x2D,  0x00,  0xC0,  0x88,  0x04,  0xA0,
        !          11180:   0xB8,  0x05,  0x80,  0x63,  0x00,  0x23,  0xDF,  0x00,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA2,  0xA4,  0x05,
        !          11181:   0x1D,  0x01,  0x06,  0xD6,  0x02,  0x23,  0x02,  0x41,  0x82,  0x01,  0x50,  0x00,  0x62,  0x97,  0x04,  0x85,
        !          11182:   0x04,  0x23,  0x02,  0x41,  0x82,  0x01,  0x04,  0x85,  0x08,  0xA0,  0xBE,  0x05,  0xF4,  0x85,  0x03,  0xA0,
        !          11183:   0xC4,  0x05,  0xF4,  0x85,  0x01,  0xA0,  0xCE,  0x05,  0x88,  0x00,  0x80,  0x63,  0xCC,  0x86,  0x07,  0xA0,
        !          11184:   0xEE,  0x05,  0x5F,  0x00,  0x00,  0x2B,  0xDF,  0x08,  0x00,  0xA2,  0xE6,  0x05,  0x80,  0x67,  0x80,  0x63,
        !          11185:   0x01,  0xA2,  0x7A,  0x06,  0x7C,  0x85,  0x06,  0x23,  0x68,  0x98,  0x48,  0x23,  0xF6,  0x88,  0x07,  0x23,
        !          11186:   0x80,  0x00,  0x06,  0x87,  0x80,  0x63,  0x7C,  0x85,  0x00,  0x23,  0xDF,  0x00,  0x00,  0x63,  0x4A,  0x00,
        !          11187:   0x06,  0x61,  0x00,  0xA2,  0x36,  0x06,  0x1D,  0x01,  0x16,  0xD4,  0xC0,  0x23,  0x07,  0x41,  0x83,  0x03,
        !          11188:   0x80,  0x63,  0x06,  0xA6,  0x1C,  0x06,  0x00,  0x33,  0x37,  0x00,  0xC0,  0x88,  0x1D,  0x01,  0x01,  0xD6,
        !          11189:   0x20,  0x23,  0x63,  0x60,  0x83,  0x03,  0x80,  0x63,  0x02,  0x23,  0xDF,  0x00,  0x07,  0xA6,  0x7C,  0x05,
        !          11190:   0xEF,  0x04,  0x6F,  0x00,  0x00,  0x63,  0x4B,  0x00,  0x06,  0x41,  0xCB,  0x00,  0x52,  0x00,  0x06,  0x61,
        !          11191:   0x00,  0xA2,  0x4E,  0x06,  0x1D,  0x01,  0x03,  0xCA,  0xC0,  0x23,  0x07,  0x41,  0x00,  0x63,  0x1D,  0x01,
        !          11192:   0x04,  0xCC,  0x00,  0x33,  0x00,  0x83,  0xC0,  0x20,  0x81,  0x62,  0x80,  0x23,  0x07,  0x41,  0x00,  0x63,
        !          11193:   0x80,  0x67,  0x08,  0x23,  0x83,  0x03,  0x80,  0x63,  0x00,  0x63,  0x01,  0x23,  0xDF,  0x00,  0x06,  0xA6,
        !          11194:   0x84,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x80,  0x67,  0x80,  0x63,  0x00,  0x33,  0x00,  0x40,  0xC0,  0x20,
        !          11195:   0x81,  0x62,  0x00,  0x63,  0x00,  0x00,  0xFE,  0x95,  0x83,  0x03,  0x80,  0x63,  0x06,  0xA6,  0x94,  0x06,
        !          11196:   0x07,  0xA6,  0x7C,  0x05,  0x00,  0x00,  0x01,  0xA0,  0x14,  0x07,  0x00,  0x2B,  0x40,  0x0E,  0x80,  0x63,
        !          11197:   0x01,  0x00,  0x06,  0xA6,  0xAA,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x40,  0x0E,  0x80,  0x63,  0x00,  0x43,
        !          11198:   0x00,  0xA0,  0xA2,  0x06,  0x06,  0xA6,  0xBC,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x80,  0x67,  0x40,  0x0E,
        !          11199:   0x80,  0x63,  0x07,  0xA6,  0x7C,  0x05,  0x00,  0x23,  0xDF,  0x00,  0x00,  0x63,  0x07,  0xA6,  0xD6,  0x06,
        !          11200:   0x00,  0x33,  0x2A,  0x00,  0xC0,  0x88,  0x03,  0x03,  0x80,  0x63,  0x89,  0x00,  0x0A,  0x2B,  0x07,  0xA6,
        !          11201:   0xE8,  0x06,  0x00,  0x33,  0x29,  0x00,  0xC0,  0x88,  0x00,  0x43,  0x00,  0xA2,  0xF4,  0x06,  0xC0,  0x0E,
        !          11202:   0x80,  0x63,  0xDE,  0x86,  0xC0,  0x0E,  0x00,  0x33,  0x00,  0x80,  0xC0,  0x20,  0x81,  0x62,  0x04,  0x01,
        !          11203:   0x02,  0xDA,  0x80,  0x63,  0x7C,  0x85,  0x80,  0x7B,  0x80,  0x63,  0x06,  0xA6,  0x8C,  0x06,  0x00,  0x33,
        !          11204:   0x2C,  0x00,  0xC0,  0x88,  0x0C,  0xA2,  0x2E,  0x07,  0xFE,  0x95,  0x83,  0x03,  0x80,  0x63,  0x06,  0xA6,
        !          11205:   0x2C,  0x07,  0x07,  0xA6,  0x7C,  0x05,  0x00,  0x33,  0x3D,  0x00,  0xC0,  0x88,  0x00,  0x00,  0x80,  0x67,
        !          11206:   0x83,  0x03,  0x80,  0x63,  0x0C,  0xA0,  0x44,  0x07,  0x07,  0xA6,  0x7C,  0x05,  0xBF,  0x23,  0x04,  0x61,
        !          11207:   0x84,  0x01,  0xE6,  0x84,  0x00,  0x63,  0xF0,  0x04,  0x01,  0x01,  0xF1,  0x00,  0x00,  0x01,  0xF2,  0x00,
        !          11208:   0x01,  0x05,  0x80,  0x01,  0x72,  0x04,  0x71,  0x00,  0x81,  0x01,  0x70,  0x04,  0x80,  0x05,  0x81,  0x05,
        !          11209:   0x00,  0x63,  0xF0,  0x04,  0xF2,  0x00,  0x72,  0x04,  0x01,  0x01,  0xF1,  0x00,  0x70,  0x00,  0x81,  0x01,
        !          11210:   0x70,  0x04,  0x71,  0x00,  0x81,  0x01,  0x72,  0x00,  0x80,  0x01,  0x71,  0x04,  0x70,  0x00,  0x80,  0x01,
        !          11211:   0x70,  0x04,  0x00,  0x63,  0xF0,  0x04,  0xF2,  0x00,  0x72,  0x04,  0x00,  0x01,  0xF1,  0x00,  0x70,  0x00,
        !          11212:   0x80,  0x01,  0x70,  0x04,  0x71,  0x00,  0x80,  0x01,  0x72,  0x00,  0x81,  0x01,  0x71,  0x04,  0x70,  0x00,
        !          11213:   0x81,  0x01,  0x70,  0x04,  0x00,  0x63,  0x00,  0x23,  0xB3,  0x01,  0x83,  0x05,  0xA3,  0x01,  0xA2,  0x01,
        !          11214:   0xA1,  0x01,  0x01,  0x23,  0xA0,  0x01,  0x00,  0x01,  0xC8,  0x00,  0x03,  0xA1,  0xC4,  0x07,  0x00,  0x33,
        !          11215:   0x07,  0x00,  0xC0,  0x88,  0x80,  0x05,  0x81,  0x05,  0x04,  0x01,  0x11,  0xC8,  0x48,  0x00,  0xB0,  0x01,
        !          11216:   0xB1,  0x01,  0x08,  0x23,  0xB2,  0x01,  0x05,  0x01,  0x48,  0x04,  0x00,  0x43,  0x00,  0xA2,  0xE4,  0x07,
        !          11217:   0x00,  0x05,  0xDA,  0x87,  0x00,  0x01,  0xC8,  0x00,  0xFF,  0x23,  0x80,  0x01,  0x05,  0x05,  0x00,  0x63,
        !          11218:   0xF7,  0x04,  0x1A,  0x09,  0xF6,  0x08,  0x6E,  0x04,  0x00,  0x02,  0x80,  0x43,  0x76,  0x08,  0x80,  0x02,
        !          11219:   0x77,  0x04,  0x00,  0x63,  0xF7,  0x04,  0x1A,  0x09,  0xF6,  0x08,  0x6E,  0x04,  0x00,  0x02,  0x00,  0xA0,
        !          11220:   0x14,  0x08,  0x16,  0x88,  0x00,  0x43,  0x76,  0x08,  0x80,  0x02,  0x77,  0x04,  0x00,  0x63,  0xF3,  0x04,
        !          11221:   0x00,  0x23,  0xF4,  0x00,  0x74,  0x00,  0x80,  0x43,  0xF4,  0x00,  0xCF,  0x40,  0x00,  0xA2,  0x44,  0x08,
        !          11222:   0x74,  0x04,  0x02,  0x01,  0xF7,  0xC9,  0xF6,  0xD9,  0x00,  0x01,  0x01,  0xA1,  0x24,  0x08,  0x04,  0x98,
        !          11223:   0x26,  0x95,  0x24,  0x88,  0x73,  0x04,  0x00,  0x63,  0xF3,  0x04,  0x75,  0x04,  0x5A,  0x88,  0x02,  0x01,
        !          11224:   0x04,  0xD8,  0x46,  0x97,  0x04,  0x98,  0x26,  0x95,  0x4A,  0x88,  0x75,  0x00,  0x00,  0xA3,  0x64,  0x08,
        !          11225:   0x00,  0x05,  0x4E,  0x88,  0x73,  0x04,  0x00,  0x63,  0x80,  0x7B,  0x80,  0x63,  0x06,  0xA6,  0x76,  0x08,
        !          11226:   0x00,  0x33,  0x3E,  0x00,  0xC0,  0x88,  0x80,  0x67,  0x83,  0x03,  0x80,  0x63,  0x00,  0x63,  0x38,  0x2B,
        !          11227:   0x9C,  0x88,  0x38,  0x2B,  0x92,  0x88,  0x32,  0x09,  0x31,  0x05,  0x92,  0x98,  0x05,  0x05,  0xB2,  0x09,
        !          11228:   0x00,  0x63,  0x00,  0x32,  0x00,  0x36,  0x00,  0x3A,  0x00,  0x3E,  0x00,  0x63,  0x80,  0x32,  0x80,  0x36,
        !          11229:   0x80,  0x3A,  0x80,  0x3E,  0x00,  0x63,  0x38,  0x2B,  0x40,  0x32,  0x40,  0x36,  0x40,  0x3A,  0x40,  0x3E,
        !          11230:   0x00,  0x63,  0x5A,  0x20,  0xC9,  0x40,  0x00,  0xA0,  0xB2,  0x08,  0x5D,  0x00,  0xFE,  0xC3,  0x00,  0x63,
        !          11231:   0x80,  0x73,  0xE6,  0x20,  0x02,  0x23,  0xE8,  0x00,  0x82,  0x73,  0xFF,  0xFD,  0x80,  0x73,  0x13,  0x23,
        !          11232:   0xF6,  0x88,  0x66,  0x20,  0xC0,  0x20,  0x04,  0x23,  0xA0,  0x01,  0xA1,  0x23,  0xA1,  0x01,  0x81,  0x62,
        !          11233:   0xE0,  0x88,  0x80,  0x73,  0x80,  0x77,  0x68,  0x00,  0x00,  0xA2,  0x80,  0x00,  0x03,  0xC2,  0xF1,  0xC7,
        !          11234:   0x41,  0x23,  0xF6,  0x88,  0x11,  0x23,  0xA1,  0x01,  0x04,  0x23,  0xA0,  0x01,  0xE6,  0x84,
        !          11235: };
        !          11236: 
        !          11237: STATIC ushort _asc_mcode_size ASC_INITDATA = sizeof(_asc_mcode_buf);
        !          11238: STATIC ulong _asc_mcode_chksum ASC_INITDATA = 0x012B5442UL;
        !          11239: 
        !          11240: #define ASC_SYN_OFFSET_ONE_DISABLE_LIST  16
        !          11241: STATIC uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] =
        !          11242: {
        !          11243:     SCSICMD_Inquiry,
        !          11244:     SCSICMD_RequestSense,
        !          11245:     SCSICMD_ReadCapacity,
        !          11246:     SCSICMD_ReadTOC,
        !          11247:     SCSICMD_ModeSelect6,
        !          11248:     SCSICMD_ModeSense6,
        !          11249:     SCSICMD_ModeSelect10,
        !          11250:     SCSICMD_ModeSense10,
        !          11251:     0xFF,
        !          11252:     0xFF,
        !          11253:     0xFF,
        !          11254:     0xFF,
        !          11255:     0xFF,
        !          11256:     0xFF,
        !          11257:     0xFF,
        !          11258:     0xFF
        !          11259: };
        !          11260: 
        !          11261: STATIC int
        !          11262: AscExeScsiQueue(
        !          11263:                    REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          11264:                    REG ASC_SCSI_Q * scsiq
        !          11265: )
        !          11266: {
        !          11267:     PortAddr            iop_base;
        !          11268:     int                 last_int_level;
        !          11269:     int                 sta;
        !          11270:     int                 n_q_required;
        !          11271:     int                 disable_syn_offset_one_fix;
        !          11272:     int                 i;
        !          11273:     ulong               addr;
        !          11274:     ASC_EXE_CALLBACK    asc_exe_callback;
        !          11275:     ushort              sg_entry_cnt = 0;
        !          11276:     ushort              sg_entry_cnt_minus_one = 0;
        !          11277:     uchar               target_ix;
        !          11278:     uchar               tid_no;
        !          11279:     uchar               sdtr_data;
        !          11280:     uchar               extra_bytes;
        !          11281:     uchar               scsi_cmd;
        !          11282:     uchar               disable_cmd;
        !          11283:     ASC_SG_HEAD *sg_head;
        !          11284:     ulong               data_cnt;
        !          11285: 
        !          11286:     iop_base = asc_dvc->iop_base;
        !          11287:     sg_head = scsiq->sg_head;
        !          11288:     asc_exe_callback = (ASC_EXE_CALLBACK) asc_dvc->exe_callback;
        !          11289:     if (asc_dvc->err_code != 0)
        !          11290:         return (ERR);
        !          11291:     if (scsiq == (ASC_SCSI_Q *) 0L) {
        !          11292:         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
        !          11293:         return (ERR);
        !          11294:     }
        !          11295:     scsiq->q1.q_no = 0;
        !          11296:     if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
        !          11297:         scsiq->q1.extra_bytes = 0;
        !          11298:     }
        !          11299:     sta = 0;
        !          11300:     target_ix = scsiq->q2.target_ix;
        !          11301:     tid_no = ASC_TIX_TO_TID(target_ix);
        !          11302:     n_q_required = 1;
        !          11303:     if (scsiq->cdbptr[0] == SCSICMD_RequestSense) {
        !          11304:         if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
        !          11305:             asc_dvc->sdtr_done &= ~scsiq->q1.target_id ;
        !          11306:             sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
        !          11307:             AscMsgOutSDTR(asc_dvc,
        !          11308:                           asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
        !          11309:                           (uchar) (asc_dvc->max_sdtr_index - 1)],
        !          11310:                           (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
        !          11311:             scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
        !          11312:         }
        !          11313:     }
        !          11314:     last_int_level = DvcEnterCritical();
        !          11315:     if (asc_dvc->in_critical_cnt != 0) {
        !          11316:         DvcLeaveCritical(last_int_level);
        !          11317:         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
        !          11318:         return (ERR);
        !          11319:     }
        !          11320:     asc_dvc->in_critical_cnt++;
        !          11321:     if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
        !          11322:         if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
        !          11323:             asc_dvc->in_critical_cnt--;
        !          11324:             DvcLeaveCritical(last_int_level);
        !          11325:             return (ERR);
        !          11326:         }
        !          11327:         if (sg_entry_cnt > ASC_MAX_SG_LIST) {
        !          11328:             return (ERR);
        !          11329:         }
        !          11330:         if (sg_entry_cnt == 1) {
        !          11331:             scsiq->q1.data_addr = sg_head->sg_list[0].addr;
        !          11332:             scsiq->q1.data_cnt = sg_head->sg_list[0].bytes;
        !          11333:             scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
        !          11334:         }
        !          11335:         sg_entry_cnt_minus_one = sg_entry_cnt - 1;
        !          11336:     }
        !          11337:     scsi_cmd = scsiq->cdbptr[0];
        !          11338:     disable_syn_offset_one_fix = FALSE;
        !          11339:     if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
        !          11340:         !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
        !          11341:         if (scsiq->q1.cntl & QC_SG_HEAD) {
        !          11342:             data_cnt = 0;
        !          11343:             for (i = 0; i < sg_entry_cnt; i++) {
        !          11344:                 data_cnt += sg_head->sg_list[i].bytes;
        !          11345:             }
        !          11346:         } else {
        !          11347:             data_cnt = scsiq->q1.data_cnt;
        !          11348:         }
        !          11349:         if (data_cnt != 0UL) {
        !          11350:             if (data_cnt < 512UL) {
        !          11351:                 disable_syn_offset_one_fix = TRUE;
        !          11352:             } else {
        !          11353:                 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST; i++) {
        !          11354:                     disable_cmd = _syn_offset_one_disable_cmd[i];
        !          11355:                     if (disable_cmd == 0xFF) {
        !          11356:                         break;
        !          11357:                     }
        !          11358:                     if (scsi_cmd == disable_cmd) {
        !          11359:                         disable_syn_offset_one_fix = TRUE;
        !          11360:                         break;
        !          11361:                     }
        !          11362:                 }
        !          11363:             }
        !          11364:         }
        !          11365:     }
        !          11366:     if (disable_syn_offset_one_fix) {
        !          11367:         scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
        !          11368:         scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
        !          11369:                                ASC_TAG_FLAG_DISABLE_DISCONNECT);
        !          11370:     } else {
        !          11371:         scsiq->q2.tag_code &= 0x23;
        !          11372:     }
        !          11373:     if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
        !          11374:         if (asc_dvc->bug_fix_cntl) {
        !          11375:             if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
        !          11376:                 if ((scsi_cmd == SCSICMD_Read6) ||
        !          11377:                     (scsi_cmd == SCSICMD_Read10)) {
        !          11378:                     addr = sg_head->sg_list[sg_entry_cnt_minus_one].addr +
        !          11379:                       sg_head->sg_list[sg_entry_cnt_minus_one].bytes;
        !          11380:                     extra_bytes = (uchar) ((ushort) addr & 0x0003);
        !          11381:                     if ((extra_bytes != 0) &&
        !          11382:                         ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
        !          11383:                          == 0)) {
        !          11384:                         scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
        !          11385:                         scsiq->q1.extra_bytes = extra_bytes;
        !          11386:                         sg_head->sg_list[sg_entry_cnt_minus_one].bytes -=
        !          11387:                             (ulong) extra_bytes;
        !          11388:                     }
        !          11389:                 }
        !          11390:             }
        !          11391:         }
        !          11392:         sg_head->entry_to_copy = sg_head->entry_cnt;
        !          11393:         n_q_required = AscSgListToQueue(sg_entry_cnt);
        !          11394:         if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
        !          11395:             (uint) n_q_required) || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
        !          11396:             if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
        !          11397:                                         n_q_required)) == 1) {
        !          11398:                 asc_dvc->in_critical_cnt--;
        !          11399:                 if (asc_exe_callback != 0) {
        !          11400:                     (*asc_exe_callback) (asc_dvc, scsiq);
        !          11401:                 }
        !          11402:                 DvcLeaveCritical(last_int_level);
        !          11403:                 return (sta);
        !          11404:             }
        !          11405:         }
        !          11406:     } else {
        !          11407:         if (asc_dvc->bug_fix_cntl) {
        !          11408:             if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
        !          11409:                 if ((scsi_cmd == SCSICMD_Read6) ||
        !          11410:                     (scsi_cmd == SCSICMD_Read10)) {
        !          11411:                     addr = scsiq->q1.data_addr + scsiq->q1.data_cnt;
        !          11412:                     extra_bytes = (uchar) ((ushort) addr & 0x0003);
        !          11413:                     if ((extra_bytes != 0) &&
        !          11414:                         ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
        !          11415:                           == 0)) {
        !          11416:                         if (((ushort) scsiq->q1.data_cnt & 0x01FF) == 0) {
        !          11417:                             scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
        !          11418:                             scsiq->q1.data_cnt -= (ulong) extra_bytes;
        !          11419:                             scsiq->q1.extra_bytes = extra_bytes;
        !          11420:                         }
        !          11421:                     }
        !          11422:                 }
        !          11423:             }
        !          11424:         }
        !          11425:         n_q_required = 1;
        !          11426:         if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
        !          11427:             ((scsiq->q1.cntl & QC_URGENT) != 0)) {
        !          11428:             if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
        !          11429:                                         n_q_required)) == 1) {
        !          11430:                 asc_dvc->in_critical_cnt--;
        !          11431:                 if (asc_exe_callback != 0) {
        !          11432:                     (*asc_exe_callback) (asc_dvc, scsiq);
        !          11433:                 }
        !          11434:                 DvcLeaveCritical(last_int_level);
        !          11435:                 return (sta);
        !          11436:             }
        !          11437:         }
        !          11438:     }
        !          11439:     asc_dvc->in_critical_cnt--;
        !          11440:     DvcLeaveCritical(last_int_level);
        !          11441:     return (sta);
        !          11442: }
        !          11443: 
        !          11444: STATIC int
        !          11445: AscSendScsiQueue(
        !          11446:                     REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          11447:                     REG ASC_SCSI_Q * scsiq,
        !          11448:                     uchar n_q_required
        !          11449: )
        !          11450: {
        !          11451:     PortAddr            iop_base;
        !          11452:     uchar               free_q_head;
        !          11453:     uchar               next_qp;
        !          11454:     uchar               tid_no;
        !          11455:     uchar               target_ix;
        !          11456:     int                 sta;
        !          11457: 
        !          11458:     iop_base = asc_dvc->iop_base;
        !          11459:     target_ix = scsiq->q2.target_ix;
        !          11460:     tid_no = ASC_TIX_TO_TID(target_ix);
        !          11461:     sta = 0;
        !          11462:     free_q_head = (uchar) AscGetVarFreeQHead(iop_base);
        !          11463:     if (n_q_required > 1) {
        !          11464:         if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
        !          11465:                                        free_q_head, (uchar) (n_q_required)))
        !          11466:             != (uchar) ASC_QLINK_END) {
        !          11467:             asc_dvc->last_q_shortage = 0;
        !          11468:             scsiq->sg_head->queue_cnt = n_q_required - 1;
        !          11469:             scsiq->q1.q_no = free_q_head;
        !          11470:             if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
        !          11471:                                               free_q_head)) == 1) {
        !          11472:                 AscPutVarFreeQHead(iop_base, next_qp);
        !          11473:                 asc_dvc->cur_total_qng += (uchar) (n_q_required);
        !          11474:                 asc_dvc->cur_dvc_qng[tid_no]++;
        !          11475:             }
        !          11476:             return (sta);
        !          11477:         }
        !          11478:     } else if (n_q_required == 1) {
        !          11479:         if ((next_qp = AscAllocFreeQueue(iop_base,
        !          11480:                                          free_q_head)) != ASC_QLINK_END) {
        !          11481:             scsiq->q1.q_no = free_q_head;
        !          11482:             if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
        !          11483:                                         free_q_head)) == 1) {
        !          11484:                 AscPutVarFreeQHead(iop_base, next_qp);
        !          11485:                 asc_dvc->cur_total_qng++;
        !          11486:                 asc_dvc->cur_dvc_qng[tid_no]++;
        !          11487:             }
        !          11488:             return (sta);
        !          11489:         }
        !          11490:     }
        !          11491:     return (sta);
        !          11492: }
        !          11493: 
        !          11494: STATIC int
        !          11495: AscSgListToQueue(
        !          11496:                     int sg_list
        !          11497: )
        !          11498: {
        !          11499:     int                 n_sg_list_qs;
        !          11500: 
        !          11501:     n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
        !          11502:     if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
        !          11503:         n_sg_list_qs++;
        !          11504:     return (n_sg_list_qs + 1);
        !          11505: }
        !          11506: 
        !          11507: 
        !          11508: STATIC uint
        !          11509: AscGetNumOfFreeQueue(
        !          11510:                         REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          11511:                         uchar target_ix,
        !          11512:                         uchar n_qs
        !          11513: )
        !          11514: {
        !          11515:     uint                cur_used_qs;
        !          11516:     uint                cur_free_qs;
        !          11517:     ASC_SCSI_BIT_ID_TYPE target_id;
        !          11518:     uchar               tid_no;
        !          11519: 
        !          11520:     target_id = ASC_TIX_TO_TARGET_ID(target_ix);
        !          11521:     tid_no = ASC_TIX_TO_TID(target_ix);
        !          11522:     if ((asc_dvc->unit_not_ready & target_id) ||
        !          11523:         (asc_dvc->queue_full_or_busy & target_id)) {
        !          11524:         return (0);
        !          11525:     }
        !          11526:     if (n_qs == 1) {
        !          11527:         cur_used_qs = (uint) asc_dvc->cur_total_qng +
        !          11528:           (uint) asc_dvc->last_q_shortage +
        !          11529:           (uint) ASC_MIN_FREE_Q;
        !          11530:     } else {
        !          11531:         cur_used_qs = (uint) asc_dvc->cur_total_qng +
        !          11532:           (uint) ASC_MIN_FREE_Q;
        !          11533:     }
        !          11534:     if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
        !          11535:         cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
        !          11536:         if (asc_dvc->cur_dvc_qng[tid_no] >=
        !          11537:             asc_dvc->max_dvc_qng[tid_no]) {
        !          11538:             return (0);
        !          11539:         }
        !          11540:         return (cur_free_qs);
        !          11541:     }
        !          11542:     if (n_qs > 1) {
        !          11543:         if ((n_qs > asc_dvc->last_q_shortage) && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
        !          11544:             asc_dvc->last_q_shortage = n_qs;
        !          11545:         }
        !          11546:     }
        !          11547:     return (0);
        !          11548: }
        !          11549: 
        !          11550: STATIC int
        !          11551: AscPutReadyQueue(
        !          11552:                     REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          11553:                     REG ASC_SCSI_Q * scsiq,
        !          11554:                     uchar q_no
        !          11555: )
        !          11556: {
        !          11557:     ushort              q_addr;
        !          11558:     uchar               tid_no;
        !          11559:     uchar               sdtr_data;
        !          11560:     uchar               syn_period_ix;
        !          11561:     uchar               syn_offset;
        !          11562:     PortAddr            iop_base;
        !          11563: 
        !          11564:     iop_base = asc_dvc->iop_base;
        !          11565:     if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
        !          11566:         ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
        !          11567:         tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
        !          11568:         sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
        !          11569:         syn_period_ix = (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
        !          11570:         syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
        !          11571:         AscMsgOutSDTR(asc_dvc,
        !          11572:                       asc_dvc->sdtr_period_tbl[syn_period_ix],
        !          11573:                       syn_offset);
        !          11574:         scsiq->q1.cntl |= QC_MSG_OUT;
        !          11575:     }
        !          11576:     q_addr = ASC_QNO_TO_QADDR(q_no);
        !          11577:     if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
        !          11578:         scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
        !          11579:     }
        !          11580:     scsiq->q1.status = QS_FREE;
        !          11581:     AscMemWordCopyToLram(iop_base,
        !          11582:                          (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG),
        !          11583:                          (ushort *) scsiq->cdbptr,
        !          11584:                          (ushort) ((ushort) scsiq->q2.cdb_len >> 1));
        !          11585:     DvcPutScsiQ(iop_base,
        !          11586:                 (ushort) (q_addr + (ushort) ASC_SCSIQ_CPY_BEG),
        !          11587:                 (ushort *) & scsiq->q1.cntl,
        !          11588:       (ushort) ((((sizeof (ASC_SCSIQ_1) + sizeof (ASC_SCSIQ_2)) / 2) - 1)));
        !          11589:     AscWriteLramWord(iop_base,
        !          11590:                      (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
        !          11591:              (ushort) (((ushort) scsiq->q1.q_no << 8) | (ushort) QS_READY));
        !          11592:     return (1);
        !          11593: }
        !          11594: 
        !          11595: STATIC int
        !          11596: AscPutReadySgListQueue(
        !          11597:                           REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          11598:                           REG ASC_SCSI_Q * scsiq,
        !          11599:                           uchar q_no
        !          11600: )
        !          11601: {
        !          11602:     int                 sta;
        !          11603:     int                 i;
        !          11604:     ASC_SG_HEAD *sg_head;
        !          11605:     ASC_SG_LIST_Q       scsi_sg_q;
        !          11606:     ulong               saved_data_addr;
        !          11607:     ulong               saved_data_cnt;
        !          11608:     PortAddr            iop_base;
        !          11609:     ushort              sg_list_dwords;
        !          11610:     ushort              sg_index;
        !          11611:     ushort              sg_entry_cnt;
        !          11612:     ushort              q_addr;
        !          11613:     uchar               next_qp;
        !          11614: 
        !          11615:     iop_base = asc_dvc->iop_base;
        !          11616:     sg_head = scsiq->sg_head;
        !          11617:     saved_data_addr = scsiq->q1.data_addr;
        !          11618:     saved_data_cnt = scsiq->q1.data_cnt;
        !          11619:     scsiq->q1.data_addr = sg_head->sg_list[0].addr;
        !          11620:     scsiq->q1.data_cnt = sg_head->sg_list[0].bytes;
        !          11621:     sg_entry_cnt = sg_head->entry_cnt - 1;
        !          11622:     if (sg_entry_cnt != 0) {
        !          11623:         scsiq->q1.cntl |= QC_SG_HEAD;
        !          11624:         q_addr = ASC_QNO_TO_QADDR(q_no);
        !          11625:         sg_index = 1;
        !          11626:         scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
        !          11627:         scsi_sg_q.sg_head_qp = q_no;
        !          11628:         scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
        !          11629:         for (i = 0; i < sg_head->queue_cnt; i++) {
        !          11630:             scsi_sg_q.seq_no = i + 1;
        !          11631:             if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
        !          11632:                 sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
        !          11633:                 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
        !          11634:                 if (i == 0) {
        !          11635:                     scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q;
        !          11636:                     scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q;
        !          11637:                 } else {
        !          11638:                     scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
        !          11639:                     scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
        !          11640:                 }
        !          11641:             } else {
        !          11642:                 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
        !          11643:                 sg_list_dwords = sg_entry_cnt << 1;
        !          11644:                 if (i == 0) {
        !          11645:                     scsi_sg_q.sg_list_cnt = sg_entry_cnt;
        !          11646:                     scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt;
        !          11647:                 } else {
        !          11648:                     scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
        !          11649:                     scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
        !          11650:                 }
        !          11651:                 sg_entry_cnt = 0;
        !          11652:             }
        !          11653:             next_qp = AscReadLramByte(iop_base,
        !          11654:                                       (ushort) (q_addr + ASC_SCSIQ_B_FWD));
        !          11655:             scsi_sg_q.q_no = next_qp;
        !          11656:             q_addr = ASC_QNO_TO_QADDR(next_qp);
        !          11657:             AscMemWordCopyToLram(iop_base,
        !          11658:                                  (ushort) (q_addr + ASC_SCSIQ_SGHD_CPY_BEG),
        !          11659:                                  (ushort *) & scsi_sg_q,
        !          11660:                                  (ushort) (sizeof (ASC_SG_LIST_Q) >> 1));
        !          11661:             AscMemDWordCopyToLram(iop_base,
        !          11662:                                   (ushort) (q_addr + ASC_SGQ_LIST_BEG),
        !          11663:                               (ulong *) & sg_head->sg_list[sg_index],
        !          11664:                                   (ushort) sg_list_dwords);
        !          11665:             sg_index += ASC_SG_LIST_PER_Q;
        !          11666:         }
        !          11667:     } else {
        !          11668:         scsiq->q1.cntl &= ~QC_SG_HEAD;
        !          11669:     }
        !          11670:     sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
        !          11671:     scsiq->q1.data_addr = saved_data_addr;
        !          11672:     scsiq->q1.data_cnt = saved_data_cnt;
        !          11673:     return (sta);
        !          11674: }
        !          11675: 
        !          11676: STATIC int
        !          11677: AscAbortSRB(
        !          11678:                REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          11679:                ulong srb_ptr
        !          11680: )
        !          11681: {
        !          11682:     int                 sta;
        !          11683:     ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready;
        !          11684:     PortAddr            iop_base;
        !          11685: 
        !          11686:     iop_base = asc_dvc->iop_base;
        !          11687:     sta = ERR;
        !          11688:     saved_unit_not_ready = asc_dvc->unit_not_ready;
        !          11689:     asc_dvc->unit_not_ready = 0xFF;
        !          11690:     AscWaitISRDone(asc_dvc);
        !          11691:     if (AscStopQueueExe(iop_base) == 1) {
        !          11692:         if (AscRiscHaltedAbortSRB(asc_dvc, srb_ptr) == 1) {
        !          11693:             sta = 1;
        !          11694:             AscCleanUpBusyQueue(iop_base);
        !          11695:             AscStartQueueExe(iop_base);
        !          11696:         } else {
        !          11697:             sta = 0;
        !          11698:             AscStartQueueExe(iop_base);
        !          11699:         }
        !          11700:     }
        !          11701:     asc_dvc->unit_not_ready = saved_unit_not_ready;
        !          11702:     return (sta);
        !          11703: }
        !          11704: 
        !          11705: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
        !          11706: STATIC int
        !          11707: AscResetDevice(
        !          11708:                   REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          11709:                   uchar target_ix
        !          11710: )
        !          11711: {
        !          11712:     PortAddr            iop_base;
        !          11713:     int                 sta;
        !          11714:     uchar               tid_no;
        !          11715: 
        !          11716:     ASC_SCSI_BIT_ID_TYPE target_id;
        !          11717:     int                 i;
        !          11718:     ASC_SCSI_REQ_Q      scsiq_buf;
        !          11719:     ASC_SCSI_REQ_Q *scsiq;
        !          11720:     uchar       *buf;
        !          11721:     ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready;
        !          11722:     iop_base = asc_dvc->iop_base;
        !          11723:     tid_no = ASC_TIX_TO_TID(target_ix);
        !          11724:     target_id = ASC_TID_TO_TARGET_ID(tid_no);
        !          11725:     saved_unit_not_ready = asc_dvc->unit_not_ready;
        !          11726:     asc_dvc->unit_not_ready = target_id;
        !          11727:     sta = ERR;
        !          11728:     AscWaitTixISRDone(asc_dvc, target_ix);
        !          11729:     if (AscStopQueueExe(iop_base) == 1) {
        !          11730:         if (AscRiscHaltedAbortTIX(asc_dvc, target_ix) == 1) {
        !          11731:             AscCleanUpBusyQueue(iop_base);
        !          11732:             AscStartQueueExe(iop_base);
        !          11733:             AscWaitTixISRDone(asc_dvc, target_ix);
        !          11734:             sta = TRUE;
        !          11735:             scsiq = (ASC_SCSI_REQ_Q *) & scsiq_buf;
        !          11736:             buf = (uchar *) & scsiq_buf;
        !          11737:             for (i = 0; i < sizeof (ASC_SCSI_REQ_Q); i++) {
        !          11738:                 *buf++ = 0x00;
        !          11739:             }
        !          11740:             scsiq->r1.status = (uchar) QS_READY;
        !          11741:             scsiq->r2.cdb_len = 6;
        !          11742:             scsiq->r2.tag_code = M2_QTAG_MSG_SIMPLE;
        !          11743:             scsiq->r1.target_id = target_id;
        !          11744:             scsiq->r2.target_ix = ASC_TIDLUN_TO_IX(tid_no, 0);
        !          11745:             scsiq->cdbptr = (uchar *) scsiq->cdb;
        !          11746:             scsiq->r1.cntl = QC_NO_CALLBACK | QC_MSG_OUT | QC_URGENT;
        !          11747:             AscWriteLramByte(asc_dvc->iop_base, ASCV_MSGOUT_BEG,
        !          11748:                              M1_BUS_DVC_RESET);
        !          11749:             asc_dvc->unit_not_ready &= ~target_id;
        !          11750:             asc_dvc->sdtr_done |= target_id;
        !          11751:             if (AscExeScsiQueue(asc_dvc, (ASC_SCSI_Q *) scsiq)
        !          11752:                 == 1) {
        !          11753:                 asc_dvc->unit_not_ready = target_id;
        !          11754:                 DvcSleepMilliSecond(1000);
        !          11755:                 _AscWaitQDone(iop_base, (ASC_SCSI_Q *) scsiq);
        !          11756:                 if (AscStopQueueExe(iop_base) == 1) {
        !          11757:                     AscCleanUpDiscQueue(iop_base);
        !          11758:                     AscStartQueueExe(iop_base);
        !          11759:                     if (asc_dvc->pci_fix_asyn_xfer & target_id) {
        !          11760:                         AscSetRunChipSynRegAtID(iop_base, tid_no,
        !          11761:                                              ASYN_SDTR_DATA_FIX_PCI_REV_AB);
        !          11762:                     }
        !          11763:                     AscWaitTixISRDone(asc_dvc, target_ix);
        !          11764:                 }
        !          11765:             } else {
        !          11766:                 sta = 0;
        !          11767:             }
        !          11768:             asc_dvc->sdtr_done &= ~target_id;
        !          11769:         } else {
        !          11770:             sta = ERR;
        !          11771:             AscStartQueueExe(iop_base);
        !          11772:         }
        !          11773:     }
        !          11774:     asc_dvc->unit_not_ready = saved_unit_not_ready;
        !          11775:     return (sta);
        !          11776: }
        !          11777: #endif /* version >= v1.3.89 */
        !          11778: 
        !          11779: STATIC int
        !          11780: AscResetSB(
        !          11781:               REG ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          11782: )
        !          11783: {
        !          11784:     int                 sta;
        !          11785:     int                 i;
        !          11786:     PortAddr            iop_base;
        !          11787: 
        !          11788:     iop_base = asc_dvc->iop_base;
        !          11789:     asc_dvc->unit_not_ready = 0xFF;
        !          11790:     sta = TRUE;
        !          11791:     AscWaitISRDone(asc_dvc);
        !          11792:     AscStopQueueExe(iop_base);
        !          11793:     asc_dvc->sdtr_done = 0;
        !          11794:     AscResetChipAndScsiBus(asc_dvc);
        !          11795:     DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
        !          11796:     AscReInitLram(asc_dvc);
        !          11797:     for (i = 0; i <= ASC_MAX_TID; i++) {
        !          11798:         asc_dvc->cur_dvc_qng[i] = 0;
        !          11799:         if (asc_dvc->pci_fix_asyn_xfer & (ASC_SCSI_BIT_ID_TYPE) (0x01 << i)) {
        !          11800:             AscSetChipSynRegAtID(iop_base, i, ASYN_SDTR_DATA_FIX_PCI_REV_AB);
        !          11801:         }
        !          11802:     }
        !          11803:     asc_dvc->err_code = 0;
        !          11804:     AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
        !          11805:     if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
        !          11806:         sta = ERR;
        !          11807:     }
        !          11808:     if (AscStartChip(iop_base) == 0) {
        !          11809:         sta = ERR;
        !          11810:     }
        !          11811:     AscStartQueueExe(iop_base);
        !          11812:     asc_dvc->unit_not_ready = 0;
        !          11813:     asc_dvc->queue_full_or_busy = 0;
        !          11814:     return (sta);
        !          11815: }
        !          11816: 
        !          11817: STATIC int
        !          11818: AscSetRunChipSynRegAtID(
        !          11819:                            PortAddr iop_base,
        !          11820:                            uchar tid_no,
        !          11821:                            uchar sdtr_data
        !          11822: )
        !          11823: {
        !          11824:     int                 sta = FALSE;
        !          11825: 
        !          11826:     if (AscHostReqRiscHalt(iop_base)) {
        !          11827:         sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
        !          11828:         AscStartChip(iop_base);
        !          11829:         return (sta);
        !          11830:     }
        !          11831:     return (sta);
        !          11832: }
        !          11833: 
        !          11834: STATIC int
        !          11835: AscSetChipSynRegAtID(
        !          11836:                         PortAddr iop_base,
        !          11837:                         uchar id,
        !          11838:                         uchar sdtr_data
        !          11839: )
        !          11840: {
        !          11841:     ASC_SCSI_BIT_ID_TYPE org_id;
        !          11842:     int                 i;
        !          11843:     int                 sta = TRUE;
        !          11844: 
        !          11845:     AscSetBank(iop_base, 1);
        !          11846:     org_id = AscReadChipDvcID(iop_base);
        !          11847:     for (i = 0; i <= ASC_MAX_TID; i++) {
        !          11848:         if (org_id == (0x01 << i))
        !          11849:             break;
        !          11850:     }
        !          11851:     org_id = i;
        !          11852:     AscWriteChipDvcID(iop_base, id);
        !          11853:     if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
        !          11854:         AscSetBank(iop_base, 0);
        !          11855:         AscSetChipSyn(iop_base, sdtr_data);
        !          11856:         if (AscGetChipSyn(iop_base) != sdtr_data) {
        !          11857:             sta = FALSE;
        !          11858:         }
        !          11859:     } else {
        !          11860:         sta = FALSE;
        !          11861:     }
        !          11862:     AscSetBank(iop_base, 1);
        !          11863:     AscWriteChipDvcID(iop_base, org_id);
        !          11864:     AscSetBank(iop_base, 0);
        !          11865:     return (sta);
        !          11866: }
        !          11867: 
        !          11868: STATIC int
        !          11869: AscReInitLram(
        !          11870:                  REG ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          11871: )
        !          11872: {
        !          11873:     AscInitLram(asc_dvc);
        !          11874:     AscInitQLinkVar(asc_dvc);
        !          11875:     return (0);
        !          11876: }
        !          11877: 
        !          11878: STATIC ushort
        !          11879: AscInitLram(
        !          11880:                REG ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          11881: )
        !          11882: {
        !          11883:     uchar               i;
        !          11884:     ushort              s_addr;
        !          11885:     PortAddr            iop_base;
        !          11886:     ushort              warn_code;
        !          11887: 
        !          11888:     iop_base = asc_dvc->iop_base;
        !          11889:     warn_code = 0;
        !          11890:     AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
        !          11891:                (ushort) (((int) (asc_dvc->max_total_qng + 2 + 1) * 64) >> 1)
        !          11892: );
        !          11893:     i = ASC_MIN_ACTIVE_QNO;
        !          11894:     s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
        !          11895:     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
        !          11896:                      (uchar) (i + 1));
        !          11897:     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
        !          11898:                      (uchar) (asc_dvc->max_total_qng));
        !          11899:     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
        !          11900:                      (uchar) i);
        !          11901:     i++;
        !          11902:     s_addr += ASC_QBLK_SIZE;
        !          11903:     for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
        !          11904:         AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
        !          11905:                          (uchar) (i + 1));
        !          11906:         AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
        !          11907:                          (uchar) (i - 1));
        !          11908:         AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
        !          11909:                          (uchar) i);
        !          11910:     }
        !          11911:     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
        !          11912:                      (uchar) ASC_QLINK_END);
        !          11913:     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
        !          11914:                      (uchar) (asc_dvc->max_total_qng - 1));
        !          11915:     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
        !          11916:                      (uchar) asc_dvc->max_total_qng);
        !          11917:     i++;
        !          11918:     s_addr += ASC_QBLK_SIZE;
        !          11919:     for (; i <= (uchar) (asc_dvc->max_total_qng + 3);
        !          11920:          i++, s_addr += ASC_QBLK_SIZE) {
        !          11921:         AscWriteLramByte(iop_base,
        !          11922:                          (ushort) (s_addr + (ushort) ASC_SCSIQ_B_FWD), i);
        !          11923:         AscWriteLramByte(iop_base,
        !          11924:                          (ushort) (s_addr + (ushort) ASC_SCSIQ_B_BWD), i);
        !          11925:         AscWriteLramByte(iop_base,
        !          11926:                          (ushort) (s_addr + (ushort) ASC_SCSIQ_B_QNO), i);
        !          11927:     }
        !          11928:     return (warn_code);
        !          11929: }
        !          11930: 
        !          11931: STATIC ushort
        !          11932: AscInitQLinkVar(
        !          11933:                    REG ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          11934: )
        !          11935: {
        !          11936:     PortAddr            iop_base;
        !          11937:     int                 i;
        !          11938:     ushort              lram_addr;
        !          11939: 
        !          11940:     iop_base = asc_dvc->iop_base;
        !          11941:     AscPutRiscVarFreeQHead(iop_base, 1);
        !          11942:     AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
        !          11943:     AscPutVarFreeQHead(iop_base, 1);
        !          11944:     AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
        !          11945:     AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
        !          11946:                      (uchar) ((int) asc_dvc->max_total_qng + 1));
        !          11947:     AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
        !          11948:                      (uchar) ((int) asc_dvc->max_total_qng + 2));
        !          11949:     AscWriteLramByte(iop_base, (ushort) ASCV_TOTAL_READY_Q_B,
        !          11950:                      asc_dvc->max_total_qng);
        !          11951:     AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
        !          11952:     AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
        !          11953:     AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
        !          11954:     AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
        !          11955:     AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
        !          11956:     AscPutQDoneInProgress(iop_base, 0);
        !          11957:     lram_addr = ASC_QADR_BEG;
        !          11958:     for (i = 0; i < 32; i++, lram_addr += 2) {
        !          11959:         AscWriteLramWord(iop_base, lram_addr, 0);
        !          11960:     }
        !          11961:     return (0);
        !          11962: }
        !          11963: 
        !          11964: STATIC int
        !          11965: AscSetLibErrorCode(
        !          11966:                       REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          11967:                       ushort err_code
        !          11968: )
        !          11969: {
        !          11970:     if (asc_dvc->err_code == 0) {
        !          11971:         asc_dvc->err_code = err_code;
        !          11972:         AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
        !          11973:                          err_code);
        !          11974:     }
        !          11975:     return (err_code);
        !          11976: }
        !          11977: 
        !          11978: 
        !          11979: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
        !          11980: STATIC int
        !          11981: _AscWaitQDone(
        !          11982:                  PortAddr iop_base,
        !          11983:                  REG ASC_SCSI_Q * scsiq
        !          11984: )
        !          11985: {
        !          11986:     ushort              q_addr;
        !          11987:     uchar               q_status;
        !          11988:     int                 count = 0;
        !          11989: 
        !          11990:     while (scsiq->q1.q_no == 0) ;
        !          11991:     q_addr = ASC_QNO_TO_QADDR(scsiq->q1.q_no);
        !          11992:     do {
        !          11993:         q_status = AscReadLramByte(iop_base, q_addr + ASC_SCSIQ_B_STATUS);
        !          11994:         DvcSleepMilliSecond(100L);
        !          11995:         if (count++ > 30) {
        !          11996:             return (0);
        !          11997:         }
        !          11998:     } while ((q_status & QS_READY) != 0);
        !          11999:     return (1);
        !          12000: }
        !          12001: #endif /* version >= v1.3.89 */
        !          12002: 
        !          12003: STATIC uchar 
        !          12004: AscMsgOutSDTR(
        !          12005:                  REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          12006:                  uchar sdtr_period,
        !          12007:                  uchar sdtr_offset
        !          12008: )
        !          12009: {
        !          12010:     EXT_MSG             sdtr_buf;
        !          12011:     uchar               sdtr_period_index;
        !          12012:     PortAddr            iop_base;
        !          12013: 
        !          12014:     iop_base = asc_dvc->iop_base;
        !          12015:     sdtr_buf.msg_type = MS_EXTEND;
        !          12016:     sdtr_buf.msg_len = MS_SDTR_LEN;
        !          12017:     sdtr_buf.msg_req = MS_SDTR_CODE;
        !          12018:     sdtr_buf.xfer_period = sdtr_period;
        !          12019:     sdtr_offset &= ASC_SYN_MAX_OFFSET;
        !          12020:     sdtr_buf.req_ack_offset = sdtr_offset;
        !          12021:     if ((sdtr_period_index =
        !          12022:          AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
        !          12023:         asc_dvc->max_sdtr_index) {
        !          12024:         AscMemWordCopyToLram(iop_base,
        !          12025:                              ASCV_MSGOUT_BEG,
        !          12026:                              (ushort *) & sdtr_buf,
        !          12027:                              (ushort) (sizeof (EXT_MSG) >> 1));
        !          12028:         return ((sdtr_period_index << 4) | sdtr_offset);
        !          12029:     } else {
        !          12030: 
        !          12031:         sdtr_buf.req_ack_offset = 0;
        !          12032:         AscMemWordCopyToLram(iop_base,
        !          12033:                              ASCV_MSGOUT_BEG,
        !          12034:                              (ushort *) & sdtr_buf,
        !          12035:                              (ushort) (sizeof (EXT_MSG) >> 1));
        !          12036:         return (0);
        !          12037:     }
        !          12038: }
        !          12039: 
        !          12040: STATIC uchar
        !          12041: AscCalSDTRData(
        !          12042:                   REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          12043:                   uchar sdtr_period,
        !          12044:                   uchar syn_offset
        !          12045: )
        !          12046: {
        !          12047:     uchar               byte;
        !          12048:     uchar               sdtr_period_ix;
        !          12049: 
        !          12050:     sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
        !          12051:     if (
        !          12052:            (sdtr_period_ix > asc_dvc->max_sdtr_index)
        !          12053: ) {
        !          12054:         return (0xFF);
        !          12055:     }
        !          12056:     byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
        !          12057:     return (byte);
        !          12058: }
        !          12059: 
        !          12060: STATIC void
        !          12061: AscSetChipSDTR(
        !          12062:                   PortAddr iop_base,
        !          12063:                   uchar sdtr_data,
        !          12064:                   uchar tid_no
        !          12065: )
        !          12066: {
        !          12067:     AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
        !          12068:     AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
        !          12069:     return;
        !          12070: }
        !          12071: 
        !          12072: STATIC uchar
        !          12073: AscGetSynPeriodIndex(
        !          12074:                         ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          12075:                         ruchar syn_time
        !          12076: )
        !          12077: {
        !          12078:     ruchar             *period_table;
        !          12079:     int                 max_index;
        !          12080:     int                 min_index;
        !          12081:     int                 i;
        !          12082: 
        !          12083:     period_table = asc_dvc->sdtr_period_tbl;
        !          12084:     max_index = (int) asc_dvc->max_sdtr_index;
        !          12085:     min_index = (int)asc_dvc->host_init_sdtr_index ;
        !          12086:     if ((syn_time <= period_table[max_index])) {
        !          12087:         for (i = min_index; i < (max_index - 1); i++) {
        !          12088:             if (syn_time <= period_table[i]) {
        !          12089:                 return ((uchar) i);
        !          12090:             }
        !          12091:         }
        !          12092:         return ((uchar) max_index);
        !          12093:     } else {
        !          12094:         return ((uchar) (max_index + 1));
        !          12095:     }
        !          12096: }
        !          12097: 
        !          12098: STATIC uchar
        !          12099: AscAllocFreeQueue(
        !          12100:                      PortAddr iop_base,
        !          12101:                      uchar free_q_head
        !          12102: )
        !          12103: {
        !          12104:     ushort              q_addr;
        !          12105:     uchar               next_qp;
        !          12106:     uchar               q_status;
        !          12107: 
        !          12108:     q_addr = ASC_QNO_TO_QADDR(free_q_head);
        !          12109:     q_status = (uchar) AscReadLramByte(iop_base,
        !          12110:                                     (ushort) (q_addr + ASC_SCSIQ_B_STATUS));
        !          12111:     next_qp = AscReadLramByte(iop_base,
        !          12112:                               (ushort) (q_addr + ASC_SCSIQ_B_FWD));
        !          12113:     if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
        !          12114:         return (next_qp);
        !          12115:     }
        !          12116:     return (ASC_QLINK_END);
        !          12117: }
        !          12118: 
        !          12119: STATIC uchar
        !          12120: AscAllocMultipleFreeQueue(
        !          12121:                              PortAddr iop_base,
        !          12122:                              uchar free_q_head,
        !          12123:                              uchar n_free_q
        !          12124: )
        !          12125: {
        !          12126:     uchar               i;
        !          12127: 
        !          12128:     for (i = 0; i < n_free_q; i++) {
        !          12129:         if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
        !          12130:             == ASC_QLINK_END) {
        !          12131:             return (ASC_QLINK_END);
        !          12132:         }
        !          12133:     }
        !          12134:     return (free_q_head);
        !          12135: }
        !          12136: 
        !          12137: STATIC int
        !          12138: AscRiscHaltedAbortSRB(
        !          12139:                          REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          12140:                          ulong srb_ptr
        !          12141: )
        !          12142: {
        !          12143:     PortAddr            iop_base;
        !          12144:     ushort              q_addr;
        !          12145:     uchar               q_no;
        !          12146:     ASC_QDONE_INFO      scsiq_buf;
        !          12147:     ASC_QDONE_INFO *scsiq;
        !          12148:     ASC_ISR_CALLBACK    asc_isr_callback;
        !          12149:     int                 last_int_level;
        !          12150: 
        !          12151:     iop_base = asc_dvc->iop_base;
        !          12152:     asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
        !          12153:     last_int_level = DvcEnterCritical();
        !          12154:     scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
        !          12155:     for (q_no = ASC_MIN_ACTIVE_QNO; q_no <= asc_dvc->max_total_qng;
        !          12156:          q_no++) {
        !          12157:         q_addr = ASC_QNO_TO_QADDR(q_no);
        !          12158:         scsiq->d2.srb_ptr = AscReadLramDWord(iop_base,
        !          12159:                            (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR));
        !          12160:         if (scsiq->d2.srb_ptr == srb_ptr) {
        !          12161:             _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count);
        !          12162:             if (((scsiq->q_status & QS_READY) != 0)
        !          12163:                  && ((scsiq->q_status & QS_ABORTED) == 0)
        !          12164:                  && ((scsiq->cntl & QCSG_SG_XFER_LIST) == 0)) {
        !          12165:                 scsiq->q_status |= QS_ABORTED;
        !          12166:                 scsiq->d3.done_stat = QD_ABORTED_BY_HOST;
        !          12167:                 AscWriteLramDWord(iop_base,
        !          12168:                             (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR),
        !          12169:                                   0L);
        !          12170:                 AscWriteLramByte(iop_base,
        !          12171:                             (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
        !          12172:                                  scsiq->q_status);
        !          12173:                 (*asc_isr_callback) (asc_dvc, scsiq);
        !          12174:                 return (1);
        !          12175:             }
        !          12176:         }
        !          12177:     }
        !          12178:     DvcLeaveCritical(last_int_level);
        !          12179:     return (0);
        !          12180: }
        !          12181: 
        !          12182: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
        !          12183: STATIC int
        !          12184: AscRiscHaltedAbortTIX(
        !          12185:                          REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          12186:                          uchar target_ix
        !          12187: )
        !          12188: {
        !          12189:     PortAddr            iop_base;
        !          12190:     ushort              q_addr;
        !          12191:     uchar               q_no;
        !          12192:     ASC_QDONE_INFO      scsiq_buf;
        !          12193:     ASC_QDONE_INFO *scsiq;
        !          12194:     ASC_ISR_CALLBACK    asc_isr_callback;
        !          12195:     int                 last_int_level;
        !          12196: 
        !          12197:     iop_base = asc_dvc->iop_base;
        !          12198:     asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
        !          12199:     last_int_level = DvcEnterCritical();
        !          12200:     scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
        !          12201:     for (q_no = ASC_MIN_ACTIVE_QNO; q_no <= asc_dvc->max_total_qng;
        !          12202:          q_no++) {
        !          12203:         q_addr = ASC_QNO_TO_QADDR(q_no);
        !          12204:         _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count);
        !          12205:         if (((scsiq->q_status & QS_READY) != 0) &&
        !          12206:             ((scsiq->q_status & QS_ABORTED) == 0) &&
        !          12207:             ((scsiq->cntl & QCSG_SG_XFER_LIST) == 0)) {
        !          12208:             if (scsiq->d2.target_ix == target_ix) {
        !          12209:                 scsiq->q_status |= QS_ABORTED;
        !          12210:                 scsiq->d3.done_stat = QD_ABORTED_BY_HOST;
        !          12211:                 AscWriteLramDWord(iop_base,
        !          12212:                             (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR),
        !          12213:                                   0L);
        !          12214:                 AscWriteLramByte(iop_base,
        !          12215:                             (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
        !          12216:                                  scsiq->q_status);
        !          12217:                 (*asc_isr_callback) (asc_dvc, scsiq);
        !          12218:             }
        !          12219:         }
        !          12220:     }
        !          12221:     DvcLeaveCritical(last_int_level);
        !          12222:     return (1);
        !          12223: }
        !          12224: #endif /* version >= v1.3.89 */
        !          12225: 
        !          12226: STATIC int
        !          12227: AscHostReqRiscHalt(
        !          12228:                       PortAddr iop_base
        !          12229: )
        !          12230: {
        !          12231:     int                 count = 0;
        !          12232:     int                 sta = 0;
        !          12233:     uchar               saved_stop_code;
        !          12234: 
        !          12235:     if (AscIsChipHalted(iop_base))
        !          12236:         return (1);
        !          12237:     saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
        !          12238:     AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
        !          12239:                      ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP
        !          12240: );
        !          12241:     do {
        !          12242:         if (AscIsChipHalted(iop_base)) {
        !          12243:             sta = 1;
        !          12244:             break;
        !          12245:         }
        !          12246:         DvcSleepMilliSecond(100);
        !          12247:     } while (count++ < 20);
        !          12248:     AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
        !          12249:     return (sta);
        !          12250: }
        !          12251: 
        !          12252: STATIC int
        !          12253: AscStopQueueExe(
        !          12254:                    PortAddr iop_base
        !          12255: )
        !          12256: {
        !          12257:     int                 count = 0;
        !          12258: 
        !          12259:     if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
        !          12260:         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
        !          12261:                          ASC_STOP_REQ_RISC_STOP);
        !          12262:         do {
        !          12263:             if (
        !          12264:                    AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
        !          12265:                    ASC_STOP_ACK_RISC_STOP) {
        !          12266:                 return (1);
        !          12267:             }
        !          12268:             DvcSleepMilliSecond(100);
        !          12269:         } while (count++ < 20);
        !          12270:     }
        !          12271:     return (0);
        !          12272: }
        !          12273: 
        !          12274: STATIC int
        !          12275: AscStartQueueExe(
        !          12276:                     PortAddr iop_base
        !          12277: )
        !          12278: {
        !          12279:     if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
        !          12280:         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
        !          12281:     }
        !          12282:     return (1);
        !          12283: }
        !          12284: 
        !          12285: STATIC int
        !          12286: AscCleanUpBusyQueue(
        !          12287:                        PortAddr iop_base
        !          12288: )
        !          12289: {
        !          12290:     int                 count;
        !          12291:     uchar               stop_code;
        !          12292: 
        !          12293:     count = 0;
        !          12294:     if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
        !          12295:         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
        !          12296:                          ASC_STOP_CLEAN_UP_BUSY_Q);
        !          12297:         do {
        !          12298:             stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
        !          12299:             if ((stop_code & ASC_STOP_CLEAN_UP_BUSY_Q) == 0)
        !          12300:                 break;
        !          12301:             DvcSleepMilliSecond(100);
        !          12302:         } while (count++ < 20);
        !          12303:     }
        !          12304:     return (1);
        !          12305: }
        !          12306: 
        !          12307: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
        !          12308: STATIC int
        !          12309: AscCleanUpDiscQueue(
        !          12310:                        PortAddr iop_base
        !          12311: )
        !          12312: {
        !          12313:     int                 count;
        !          12314:     uchar               stop_code;
        !          12315: 
        !          12316:     count = 0;
        !          12317:     if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
        !          12318:         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
        !          12319:                          ASC_STOP_CLEAN_UP_DISC_Q);
        !          12320:         do {
        !          12321:             stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
        !          12322:             if ((stop_code & ASC_STOP_CLEAN_UP_DISC_Q) == 0)
        !          12323:                 break;
        !          12324:             DvcSleepMilliSecond(100);
        !          12325:         } while (count++ < 20);
        !          12326:     }
        !          12327:     return (1);
        !          12328: }
        !          12329: #endif /* version >= v1.3.89 */
        !          12330: 
        !          12331: STATIC int
        !          12332: AscWaitTixISRDone(
        !          12333:                      ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          12334:                      uchar target_ix
        !          12335: )
        !          12336: {
        !          12337:     uchar               cur_req;
        !          12338:     uchar               tid_no;
        !          12339:     int                 i = 0;
        !          12340: 
        !          12341:     tid_no = ASC_TIX_TO_TID(target_ix);
        !          12342:     while (i++ < 10) {
        !          12343:         if ((cur_req = asc_dvc->cur_dvc_qng[tid_no]) == 0) {
        !          12344:             break;
        !          12345:         }
        !          12346:         DvcSleepMilliSecond(1000L);
        !          12347:         if (asc_dvc->cur_dvc_qng[tid_no] == cur_req) {
        !          12348:             break;
        !          12349:         }
        !          12350:     }
        !          12351:     return (1);
        !          12352: }
        !          12353: 
        !          12354: STATIC int
        !          12355: AscWaitISRDone(
        !          12356:                   REG ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          12357: )
        !          12358: {
        !          12359:     int                 tid;
        !          12360: 
        !          12361:     for (tid = 0; tid <= ASC_MAX_TID; tid++) {
        !          12362:         AscWaitTixISRDone(asc_dvc, ASC_TID_TO_TIX(tid));
        !          12363:     }
        !          12364:     return (1);
        !          12365: }
        !          12366: 
        !          12367: STATIC ulong
        !          12368: AscGetOnePhyAddr(
        !          12369:                     REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
        !          12370:                     uchar * buf_addr,
        !          12371:                     ulong buf_size
        !          12372: )
        !          12373: {
        !          12374:     ASC_MIN_SG_HEAD     sg_head;
        !          12375: 
        !          12376:     sg_head.entry_cnt = ASC_MIN_SG_LIST;
        !          12377:     if (DvcGetSGList(asc_dvc, (uchar *) buf_addr,
        !          12378:                   buf_size, (ASC_SG_HEAD *) & sg_head) != buf_size) {
        !          12379:         return (0L);
        !          12380:     }
        !          12381:     if (sg_head.entry_cnt > 1) {
        !          12382:         return (0L);
        !          12383:     }
        !          12384:     return (sg_head.sg_list[0].addr);
        !          12385: }
        !          12386: 
        !          12387: STATIC void
        !          12388: DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
        !          12389: {
        !          12390:     udelay(micro_sec);
        !          12391: }
        !          12392: 
        !          12393: STATIC void
        !          12394: DvcDelayNanoSecond(ASC_DVC_VAR asc_ptr_type * asc_dvc, ulong nano_sec)
        !          12395: {
        !          12396:     udelay((nano_sec + 999)/1000);
        !          12397: }
        !          12398: 
        !          12399: ASC_INITFUNC(
        !          12400: STATIC ulong
        !          12401: AscGetEisaProductID(
        !          12402:                        PortAddr iop_base
        !          12403: )
        !          12404: )
        !          12405: {
        !          12406:     PortAddr            eisa_iop;
        !          12407:     ushort              product_id_high, product_id_low;
        !          12408:     ulong               product_id;
        !          12409: 
        !          12410:     eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK;
        !          12411:     product_id_low = inpw(eisa_iop);
        !          12412:     product_id_high = inpw(eisa_iop + 2);
        !          12413:     product_id = ((ulong) product_id_high << 16) | (ulong) product_id_low;
        !          12414:     return (product_id);
        !          12415: }
        !          12416: 
        !          12417: ASC_INITFUNC(
        !          12418: STATIC PortAddr
        !          12419: AscSearchIOPortAddrEISA(
        !          12420:                            PortAddr iop_base
        !          12421: )
        !          12422: )
        !          12423: {
        !          12424:     ulong               eisa_product_id;
        !          12425: 
        !          12426:     if (iop_base == 0) {
        !          12427:         iop_base = ASC_EISA_MIN_IOP_ADDR;
        !          12428:     } else {
        !          12429:         if (iop_base == ASC_EISA_MAX_IOP_ADDR)
        !          12430:             return (0);
        !          12431:         if ((iop_base & 0x0050) == 0x0050) {
        !          12432:             iop_base += ASC_EISA_BIG_IOP_GAP;
        !          12433:         } else {
        !          12434:             iop_base += ASC_EISA_SMALL_IOP_GAP;
        !          12435:         }
        !          12436:     }
        !          12437:     while (iop_base <= ASC_EISA_MAX_IOP_ADDR) {
        !          12438:         eisa_product_id = AscGetEisaProductID(iop_base);
        !          12439:         if ((eisa_product_id == ASC_EISA_ID_740) ||
        !          12440:             (eisa_product_id == ASC_EISA_ID_750)) {
        !          12441:             if (AscFindSignature(iop_base)) {
        !          12442:                 inpw(iop_base + 4);
        !          12443:                 return (iop_base);
        !          12444:             }
        !          12445:         }
        !          12446:         if (iop_base == ASC_EISA_MAX_IOP_ADDR)
        !          12447:             return (0);
        !          12448:         if ((iop_base & 0x0050) == 0x0050) {
        !          12449:             iop_base += ASC_EISA_BIG_IOP_GAP;
        !          12450:         } else {
        !          12451:             iop_base += ASC_EISA_SMALL_IOP_GAP;
        !          12452:         }
        !          12453:     }
        !          12454:     return (0);
        !          12455: }
        !          12456: 
        !          12457: STATIC int
        !          12458: AscStartChip(
        !          12459:                 PortAddr iop_base
        !          12460: )
        !          12461: {
        !          12462:     AscSetChipControl(iop_base, 0);
        !          12463:     if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
        !          12464:         return (0);
        !          12465:     }
        !          12466:     return (1);
        !          12467: }
        !          12468: 
        !          12469: STATIC int
        !          12470: AscStopChip(
        !          12471:                PortAddr iop_base
        !          12472: )
        !          12473: {
        !          12474:     uchar               cc_val;
        !          12475: 
        !          12476:     cc_val = AscGetChipControl(iop_base) & (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
        !          12477:     AscSetChipControl(iop_base, (uchar) (cc_val | CC_HALT));
        !          12478:     AscSetChipIH(iop_base, INS_HALT);
        !          12479:     AscSetChipIH(iop_base, INS_RFLAG_WTM);
        !          12480:     if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
        !          12481:         return (0);
        !          12482:     }
        !          12483:     return (1);
        !          12484: }
        !          12485: 
        !          12486: STATIC int
        !          12487: AscIsChipHalted(
        !          12488:                    PortAddr iop_base
        !          12489: )
        !          12490: {
        !          12491:     if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
        !          12492:         if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
        !          12493:             return (1);
        !          12494:         }
        !          12495:     }
        !          12496:     return (0);
        !          12497: }
        !          12498: 
        !          12499: STATIC void
        !          12500: AscSetChipIH(
        !          12501:                 PortAddr iop_base,
        !          12502:                 ushort ins_code
        !          12503: )
        !          12504: {
        !          12505:     AscSetBank(iop_base, 1);
        !          12506:     AscWriteChipIH(iop_base, ins_code);
        !          12507:     AscSetBank(iop_base, 0);
        !          12508:     return;
        !          12509: }
        !          12510: 
        !          12511: STATIC void
        !          12512: AscAckInterrupt(
        !          12513:                    PortAddr iop_base
        !          12514: )
        !          12515: {
        !          12516:     uchar               host_flag;
        !          12517:     uchar               risc_flag;
        !          12518:     ushort              loop;
        !          12519: 
        !          12520:     loop = 0;
        !          12521:     do {
        !          12522:         risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
        !          12523:         if (loop++ > 0x7FFF) {
        !          12524:             break;
        !          12525:         }
        !          12526:     } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
        !          12527:     host_flag = AscReadLramByte(iop_base, ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
        !          12528:     AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
        !          12529:                      (uchar) (host_flag | ASC_HOST_FLAG_ACK_INT));
        !          12530:     AscSetChipStatus(iop_base, CIW_INT_ACK);
        !          12531:     loop = 0;
        !          12532:     while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
        !          12533:         AscSetChipStatus(iop_base, CIW_INT_ACK);
        !          12534:         if (loop++ > 3) {
        !          12535:             break;
        !          12536:         }
        !          12537:     }
        !          12538:     AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
        !          12539:     return;
        !          12540: }
        !          12541: 
        !          12542: STATIC void
        !          12543: AscDisableInterrupt(
        !          12544:                        PortAddr iop_base
        !          12545: )
        !          12546: {
        !          12547:     ushort              cfg;
        !          12548: 
        !          12549:     cfg = AscGetChipCfgLsw(iop_base);
        !          12550:     AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
        !          12551:     return;
        !          12552: }
        !          12553: 
        !          12554: STATIC void
        !          12555: AscEnableInterrupt(
        !          12556:                       PortAddr iop_base
        !          12557: )
        !          12558: {
        !          12559:     ushort              cfg;
        !          12560: 
        !          12561:     cfg = AscGetChipCfgLsw(iop_base);
        !          12562:     AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
        !          12563:     return;
        !          12564: }
        !          12565: 
        !          12566: 
        !          12567: 
        !          12568: STATIC void
        !          12569: AscSetBank(
        !          12570:               PortAddr iop_base,
        !          12571:               uchar bank
        !          12572: )
        !          12573: {
        !          12574:     uchar               val;
        !          12575: 
        !          12576:     val = AscGetChipControl(iop_base) &
        !          12577:       (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET | CC_CHIP_RESET));
        !          12578:     if (bank == 1) {
        !          12579:         val |= CC_BANK_ONE;
        !          12580:     } else if (bank == 2) {
        !          12581:         val |= CC_DIAG | CC_BANK_ONE;
        !          12582:     } else {
        !          12583:         val &= ~CC_BANK_ONE;
        !          12584:     }
        !          12585:     AscSetChipControl(iop_base, val);
        !          12586:     return;
        !          12587: }
        !          12588: 
        !          12589: STATIC int
        !          12590: AscResetChipAndScsiBus(
        !          12591:                           ASC_DVC_VAR *asc_dvc
        !          12592: )
        !          12593: {
        !          12594:     PortAddr    iop_base;
        !          12595: 
        !          12596:     iop_base = asc_dvc->iop_base;
        !          12597:     while (AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) ;
        !          12598:     AscStopChip(iop_base);
        !          12599:     AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
        !          12600:     DvcDelayNanoSecond(asc_dvc, 60000);
        !          12601:     AscSetChipIH(iop_base, INS_RFLAG_WTM);
        !          12602:     AscSetChipIH(iop_base, INS_HALT);
        !          12603:     AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
        !          12604:     AscSetChipControl(iop_base, CC_HALT);
        !          12605:     DvcSleepMilliSecond(200);
        !          12606:     AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
        !          12607:     AscSetChipStatus(iop_base, 0);
        !          12608:     return (AscIsChipHalted(iop_base));
        !          12609: }
        !          12610: 
        !          12611: ASC_INITFUNC(
        !          12612: STATIC ulong
        !          12613: AscGetMaxDmaCount(
        !          12614:                      ushort bus_type
        !          12615: )
        !          12616: )
        !          12617: {
        !          12618:     if (bus_type & ASC_IS_ISA)
        !          12619:         return (ASC_MAX_ISA_DMA_COUNT);
        !          12620:     else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
        !          12621:         return (ASC_MAX_VL_DMA_COUNT);
        !          12622:     return (ASC_MAX_PCI_DMA_COUNT);
        !          12623: }
        !          12624: 
        !          12625: ASC_INITFUNC(
        !          12626: STATIC ushort
        !          12627: AscGetIsaDmaChannel(
        !          12628:                        PortAddr iop_base
        !          12629: )
        !          12630: )
        !          12631: {
        !          12632:     ushort              channel;
        !          12633: 
        !          12634:     channel = AscGetChipCfgLsw(iop_base) & 0x0003;
        !          12635:     if (channel == 0x03)
        !          12636:         return (0);
        !          12637:     else if (channel == 0x00)
        !          12638:         return (7);
        !          12639:     return (channel + 4);
        !          12640: }
        !          12641: 
        !          12642: ASC_INITFUNC(
        !          12643: STATIC ushort
        !          12644: AscSetIsaDmaChannel(
        !          12645:                        PortAddr iop_base,
        !          12646:                        ushort dma_channel
        !          12647: )
        !          12648: )
        !          12649: {
        !          12650:     ushort              cfg_lsw;
        !          12651:     uchar               value;
        !          12652: 
        !          12653:     if ((dma_channel >= 5) && (dma_channel <= 7)) {
        !          12654:         if (dma_channel == 7)
        !          12655:             value = 0x00;
        !          12656:         else
        !          12657:             value = dma_channel - 4;
        !          12658:         cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
        !          12659:         cfg_lsw |= value;
        !          12660:         AscSetChipCfgLsw(iop_base, cfg_lsw);
        !          12661:         return (AscGetIsaDmaChannel(iop_base));
        !          12662:     }
        !          12663:     return (0);
        !          12664: }
        !          12665: 
        !          12666: ASC_INITFUNC(
        !          12667: STATIC uchar
        !          12668: AscSetIsaDmaSpeed(
        !          12669:                      PortAddr iop_base,
        !          12670:                      uchar speed_value
        !          12671: )
        !          12672: )
        !          12673: {
        !          12674:     speed_value &= 0x07;
        !          12675:     AscSetBank(iop_base, 1);
        !          12676:     AscWriteChipDmaSpeed(iop_base, speed_value);
        !          12677:     AscSetBank(iop_base, 0);
        !          12678:     return (AscGetIsaDmaSpeed(iop_base));
        !          12679: }
        !          12680: 
        !          12681: ASC_INITFUNC(
        !          12682: STATIC uchar
        !          12683: AscGetIsaDmaSpeed(
        !          12684:                      PortAddr iop_base
        !          12685: )
        !          12686: )
        !          12687: {
        !          12688:     uchar               speed_value;
        !          12689: 
        !          12690:     AscSetBank(iop_base, 1);
        !          12691:     speed_value = AscReadChipDmaSpeed(iop_base);
        !          12692:     speed_value &= 0x07;
        !          12693:     AscSetBank(iop_base, 0);
        !          12694:     return (speed_value);
        !          12695: }
        !          12696: 
        !          12697: ASC_INITFUNC(
        !          12698: STATIC ushort
        !          12699: AscReadPCIConfigWord(
        !          12700:     ASC_DVC_VAR asc_ptr_type *asc_dvc,
        !          12701:     ushort pci_config_offset)
        !          12702: )
        !          12703: {
        !          12704:     uchar       lsb, msb;
        !          12705: 
        !          12706:     lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset);
        !          12707:     msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1);
        !          12708:     return ((ushort) ((msb << 8) | lsb));
        !          12709: }
        !          12710: 
        !          12711: ASC_INITFUNC(
        !          12712: STATIC ushort 
        !          12713: AscInitGetConfig(
        !          12714:         ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          12715: )
        !          12716: )
        !          12717: {
        !          12718:     ushort              warn_code;
        !          12719:     PortAddr            iop_base;
        !          12720:     ushort              PCIDeviceID;
        !          12721:     ushort              PCIVendorID;
        !          12722:     uchar               PCIRevisionID;
        !          12723:     uchar               prevCmdRegBits;
        !          12724: 
        !          12725:     warn_code = 0;
        !          12726:     iop_base = asc_dvc->iop_base;
        !          12727:     asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
        !          12728:     if (asc_dvc->err_code != 0) {
        !          12729:         return (UW_ERR);
        !          12730:     }
        !          12731:     if (asc_dvc->bus_type == ASC_IS_PCI) {
        !          12732:         PCIVendorID = AscReadPCIConfigWord(asc_dvc,
        !          12733:                                     AscPCIConfigVendorIDRegister);
        !          12734: 
        !          12735:         PCIDeviceID = AscReadPCIConfigWord(asc_dvc,
        !          12736:                                     AscPCIConfigDeviceIDRegister);
        !          12737: 
        !          12738:         PCIRevisionID = DvcReadPCIConfigByte(asc_dvc,
        !          12739:                                     AscPCIConfigRevisionIDRegister);
        !          12740: 
        !          12741:         if (PCIVendorID != ASC_PCI_VENDORID) {
        !          12742:             warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
        !          12743:         }
        !          12744:         prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc,
        !          12745:                                     AscPCIConfigCommandRegister);
        !          12746: 
        !          12747:         if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster) !=
        !          12748:             AscPCICmdRegBits_IOMemBusMaster) {
        !          12749:             DvcWritePCIConfigByte(asc_dvc,
        !          12750:                             AscPCIConfigCommandRegister,
        !          12751:                             (prevCmdRegBits |
        !          12752:                              AscPCICmdRegBits_IOMemBusMaster));
        !          12753: 
        !          12754:             if ((DvcReadPCIConfigByte(asc_dvc,
        !          12755:                                 AscPCIConfigCommandRegister)
        !          12756:                  & AscPCICmdRegBits_IOMemBusMaster)
        !          12757:                 != AscPCICmdRegBits_IOMemBusMaster) {
        !          12758:                 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
        !          12759:             }
        !          12760:         }
        !          12761:         if ((PCIDeviceID == ASC_PCI_DEVICEID_1200A) ||
        !          12762:             (PCIDeviceID == ASC_PCI_DEVICEID_1200B)) {
        !          12763:             DvcWritePCIConfigByte(asc_dvc,
        !          12764:                             AscPCIConfigLatencyTimer, 0x00);
        !          12765:             if (DvcReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer)
        !          12766:                 != 0x00) {
        !          12767:                 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
        !          12768:             }
        !          12769:         } else if (PCIDeviceID == ASC_PCI_DEVICEID_ULTRA) {
        !          12770:             if (DvcReadPCIConfigByte(asc_dvc,
        !          12771:                                 AscPCIConfigLatencyTimer) < 0x20) {
        !          12772:                 DvcWritePCIConfigByte(asc_dvc,
        !          12773:                                     AscPCIConfigLatencyTimer, 0x20);
        !          12774: 
        !          12775:                 if (DvcReadPCIConfigByte(asc_dvc,
        !          12776:                                     AscPCIConfigLatencyTimer) < 0x20) {
        !          12777:                     warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
        !          12778:                 }
        !          12779:             }
        !          12780:         }
        !          12781:     }
        !          12782: 
        !          12783:     if (AscFindSignature(iop_base)) {
        !          12784:         warn_code |= AscInitAscDvcVar(asc_dvc);
        !          12785:         warn_code |= AscInitFromEEP(asc_dvc);
        !          12786:         asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
        !          12787:         if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) {
        !          12788:             asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
        !          12789:         }
        !          12790:     } else {
        !          12791:         asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
        !          12792:     }
        !          12793:     return(warn_code);
        !          12794: }
        !          12795: 
        !          12796: ASC_INITFUNC(
        !          12797: STATIC ushort
        !          12798: AscInitSetConfig(
        !          12799:                     ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          12800: )
        !          12801: )
        !          12802: {
        !          12803:     ushort              warn_code = 0;
        !          12804: 
        !          12805:     asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
        !          12806:     if (asc_dvc->err_code != 0)
        !          12807:         return (UW_ERR);
        !          12808:     if (AscFindSignature(asc_dvc->iop_base)) {
        !          12809:         warn_code |= AscInitFromAscDvcVar(asc_dvc);
        !          12810:         asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
        !          12811:     } else {
        !          12812:         asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
        !          12813:     }
        !          12814:     return (warn_code);
        !          12815: }
        !          12816: 
        !          12817: ASC_INITFUNC(
        !          12818: STATIC ushort
        !          12819: AscInitFromAscDvcVar(
        !          12820:                         ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          12821: )
        !          12822: )
        !          12823: {
        !          12824:     PortAddr            iop_base;
        !          12825:     ushort              cfg_msw;
        !          12826:     ushort              warn_code;
        !          12827:     ushort              pci_device_id;
        !          12828: 
        !          12829:     iop_base = asc_dvc->iop_base;
        !          12830:     pci_device_id = asc_dvc->cfg->pci_device_id;
        !          12831:     warn_code = 0;
        !          12832:     cfg_msw = AscGetChipCfgMsw(iop_base);
        !          12833:     if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
        !          12834:         cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
        !          12835:         warn_code |= ASC_WARN_CFG_MSW_RECOVER;
        !          12836:         AscSetChipCfgMsw(iop_base, cfg_msw);
        !          12837:     }
        !          12838:     if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
        !          12839:         asc_dvc->cfg->cmd_qng_enabled) {
        !          12840:         asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
        !          12841:         warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
        !          12842:     }
        !          12843:     if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
        !          12844:         warn_code |= ASC_WARN_AUTO_CONFIG;
        !          12845:     }
        !          12846:     if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
        !          12847:         if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
        !          12848:             != asc_dvc->irq_no) {
        !          12849:             asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
        !          12850:         }
        !          12851:     }
        !          12852:     if (asc_dvc->bus_type & ASC_IS_PCI) {
        !          12853:         cfg_msw &= 0xFFC0;
        !          12854:         AscSetChipCfgMsw(iop_base, cfg_msw);
        !          12855:         if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
        !          12856:         } else {
        !          12857:             if ((pci_device_id == ASC_PCI_DEVICE_ID_REV_A) ||
        !          12858:                 (pci_device_id == ASC_PCI_DEVICE_ID_REV_B)) {
        !          12859:                 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
        !          12860:                 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
        !          12861:             }
        !          12862:         }
        !          12863:     } else if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
        !          12864:         if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
        !          12865:             == ASC_CHIP_VER_ASYN_BUG) {
        !          12866:             asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
        !          12867:         }
        !          12868:     }
        !          12869:     if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
        !          12870:         asc_dvc->cfg->chip_scsi_id) {
        !          12871:         asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
        !          12872:     }
        !          12873:     if (asc_dvc->bus_type & ASC_IS_ISA) {
        !          12874:         AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
        !          12875:         AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
        !          12876:     }
        !          12877:     return (warn_code);
        !          12878: }
        !          12879: 
        !          12880: ASC_INITFUNC(
        !          12881: STATIC ushort
        !          12882: AscInitAsc1000Driver(
        !          12883:                         ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          12884: )
        !          12885: )
        !          12886: {
        !          12887:     ushort              warn_code;
        !          12888:     PortAddr            iop_base;
        !          12889:     extern ushort       _asc_mcode_size;
        !          12890:     extern ulong        _asc_mcode_chksum;
        !          12891:     extern uchar        _asc_mcode_buf[];
        !          12892: 
        !          12893:     iop_base = asc_dvc->iop_base;
        !          12894:     warn_code = 0;
        !          12895:     if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
        !          12896:         !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
        !          12897:         AscResetChipAndScsiBus(asc_dvc);
        !          12898:         DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
        !          12899:     }
        !          12900:     asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
        !          12901:     if (asc_dvc->err_code != 0)
        !          12902:         return (UW_ERR);
        !          12903:     if (!AscFindSignature(asc_dvc->iop_base)) {
        !          12904:         asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
        !          12905:         return (warn_code);
        !          12906:     }
        !          12907:     AscDisableInterrupt(iop_base);
        !          12908:     warn_code |= AscInitLram(asc_dvc);
        !          12909:     if (asc_dvc->err_code != 0)
        !          12910:         return (UW_ERR);
        !          12911:     if (AscLoadMicroCode(iop_base, 0, (ushort *) _asc_mcode_buf,
        !          12912:                          _asc_mcode_size) != _asc_mcode_chksum) {
        !          12913:         asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
        !          12914:         return (warn_code);
        !          12915:     }
        !          12916:     warn_code |= AscInitMicroCodeVar(asc_dvc);
        !          12917:     asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
        !          12918:     AscEnableInterrupt(iop_base);
        !          12919:     return (warn_code);
        !          12920: }
        !          12921: 
        !          12922: ASC_INITFUNC(
        !          12923: STATIC ushort
        !          12924: AscInitAscDvcVar(
        !          12925:                     ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          12926: )
        !          12927: )
        !          12928: {
        !          12929:     int                 i;
        !          12930:     PortAddr            iop_base;
        !          12931:     ushort              warn_code;
        !          12932:     uchar               chip_version;
        !          12933: 
        !          12934:     iop_base = asc_dvc->iop_base;
        !          12935:     warn_code = 0;
        !          12936:     asc_dvc->err_code = 0;
        !          12937:     if ((asc_dvc->bus_type &
        !          12938:          (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
        !          12939:         asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
        !          12940:     }
        !          12941:     AscSetChipControl(iop_base, CC_HALT);
        !          12942:     AscSetChipStatus(iop_base, 0);
        !          12943:     asc_dvc->bug_fix_cntl = 0;
        !          12944:     asc_dvc->pci_fix_asyn_xfer = 0;
        !          12945:     asc_dvc->pci_fix_asyn_xfer_always = 0;
        !          12946:     asc_dvc->init_state = 0;
        !          12947:     asc_dvc->sdtr_done = 0;
        !          12948:     asc_dvc->cur_total_qng = 0;
        !          12949:     asc_dvc->is_in_int = 0;
        !          12950:     asc_dvc->in_critical_cnt = 0;
        !          12951:     asc_dvc->last_q_shortage = 0;
        !          12952:     asc_dvc->use_tagged_qng = 0;
        !          12953:     asc_dvc->no_scam = 0;
        !          12954:     asc_dvc->unit_not_ready = 0;
        !          12955:     asc_dvc->queue_full_or_busy = 0;
        !          12956:     asc_dvc->redo_scam = 0 ;
        !          12957:     asc_dvc->res2 = 0 ;
        !          12958:     asc_dvc->host_init_sdtr_index = 0 ;
        !          12959:     asc_dvc->res7 = 0 ;
        !          12960:     asc_dvc->res8 = 0 ;
        !          12961:     asc_dvc->cfg->can_tagged_qng = 0 ;
        !          12962:     asc_dvc->cfg->cmd_qng_enabled = 0;
        !          12963:     asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
        !          12964:     asc_dvc->init_sdtr = 0;
        !          12965:     asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
        !          12966:     asc_dvc->scsi_reset_wait = 3;
        !          12967:     asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
        !          12968:     asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
        !          12969:     asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
        !          12970:     asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
        !          12971:     asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
        !          12972:     asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
        !          12973:     asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
        !          12974:       ASC_LIB_VERSION_MINOR;
        !          12975:     chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
        !          12976:     asc_dvc->cfg->chip_version = chip_version;
        !          12977:     asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
        !          12978:     asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
        !          12979:     asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
        !          12980:     asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
        !          12981:     asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
        !          12982:     asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
        !          12983:     asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
        !          12984:     asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
        !          12985:     asc_dvc->max_sdtr_index = 7;
        !          12986:     if ((asc_dvc->bus_type & ASC_IS_PCI) &&
        !          12987:         (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
        !          12988:         asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
        !          12989:         asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
        !          12990:         asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
        !          12991:         asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
        !          12992:         asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
        !          12993:         asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
        !          12994:         asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
        !          12995:         asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
        !          12996:         asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
        !          12997:         asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
        !          12998:         asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
        !          12999:         asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
        !          13000:         asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
        !          13001:         asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
        !          13002:         asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
        !          13003:         asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
        !          13004:         asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
        !          13005:         asc_dvc->max_sdtr_index = 15;
        !          13006:         if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150)
        !          13007:         {
        !          13008:             AscSetExtraControl(iop_base,
        !          13009:                 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
        !          13010:         } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
        !          13011:             AscSetExtraControl(iop_base,
        !          13012:                 (SEC_ACTIVE_NEGATE | SEC_ENABLE_FILTER));
        !          13013:         }
        !          13014:     }
        !          13015:     if (asc_dvc->bus_type == ASC_IS_PCI) {
        !          13016:            AscSetExtraControl(iop_base, (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
        !          13017:     }
        !          13018: 
        !          13019:     asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
        !          13020:     if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
        !          13021:         AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
        !          13022:         asc_dvc->bus_type = ASC_IS_ISAPNP;
        !          13023:     }
        !          13024:     if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
        !          13025:         asc_dvc->cfg->isa_dma_channel = (uchar) AscGetIsaDmaChannel(iop_base);
        !          13026:     }
        !          13027:     for (i = 0; i <= ASC_MAX_TID; i++) {
        !          13028:         asc_dvc->cur_dvc_qng[i] = 0;
        !          13029:         asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
        !          13030:         asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *) 0L;
        !          13031:         asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *) 0L;
        !          13032:         asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
        !          13033:     }
        !          13034:     return (warn_code);
        !          13035: }
        !          13036: 
        !          13037: ASC_INITFUNC(
        !          13038: STATIC ushort
        !          13039: AscInitFromEEP(
        !          13040:                   ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          13041: )
        !          13042: )
        !          13043: {
        !          13044:     ASCEEP_CONFIG       eep_config_buf;
        !          13045:     ASCEEP_CONFIG       *eep_config;
        !          13046:     PortAddr            iop_base;
        !          13047:     ushort              chksum;
        !          13048:     ushort              warn_code;
        !          13049:     ushort              cfg_msw, cfg_lsw;
        !          13050:     int                 i;
        !          13051:     int                 write_eep = 0;
        !          13052: 
        !          13053:     iop_base = asc_dvc->iop_base;
        !          13054:     warn_code = 0;
        !          13055:     AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
        !          13056:     AscStopQueueExe(iop_base);
        !          13057:     if ((AscStopChip(iop_base) == FALSE) ||
        !          13058:         (AscGetChipScsiCtrl(iop_base) != 0)) {
        !          13059:         asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
        !          13060:         AscResetChipAndScsiBus(asc_dvc);
        !          13061:         DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
        !          13062:     }
        !          13063:     if (AscIsChipHalted(iop_base) == FALSE) {
        !          13064:         asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
        !          13065:         return (warn_code);
        !          13066:     }
        !          13067:     AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
        !          13068:     if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
        !          13069:         asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
        !          13070:         return (warn_code);
        !          13071:     }
        !          13072:     eep_config = (ASCEEP_CONFIG *) & eep_config_buf;
        !          13073:     cfg_msw = AscGetChipCfgMsw(iop_base);
        !          13074:     cfg_lsw = AscGetChipCfgLsw(iop_base);
        !          13075:     if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
        !          13076:         cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
        !          13077:         warn_code |= ASC_WARN_CFG_MSW_RECOVER;
        !          13078:         AscSetChipCfgMsw(iop_base, cfg_msw);
        !          13079:     }
        !          13080:     chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
        !          13081:     if (chksum == 0) {
        !          13082:         chksum = 0xaa55;
        !          13083:     }
        !          13084:     if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
        !          13085:         warn_code |= ASC_WARN_AUTO_CONFIG;
        !          13086:         if (asc_dvc->cfg->chip_version == 3) {
        !          13087:             if (eep_config->cfg_lsw != cfg_lsw) {
        !          13088:                 warn_code |= ASC_WARN_EEPROM_RECOVER;
        !          13089:                 eep_config->cfg_lsw = AscGetChipCfgLsw(iop_base);
        !          13090:             }
        !          13091:             if (eep_config->cfg_msw != cfg_msw) {
        !          13092:                 warn_code |= ASC_WARN_EEPROM_RECOVER;
        !          13093:                 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
        !          13094:             }
        !          13095:         }
        !          13096:     }
        !          13097:     eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
        !          13098:     eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
        !          13099:     if (chksum != eep_config->chksum) {
        !          13100:             if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
        !          13101:                     ASC_CHIP_VER_PCI_ULTRA_3050 )
        !          13102:             {
        !          13103:                 eep_config->init_sdtr = 0xFF;
        !          13104:                 eep_config->disc_enable = 0xFF;
        !          13105:                 eep_config->start_motor = 0xFF;
        !          13106:                 eep_config->use_cmd_qng = 0;
        !          13107:                 eep_config->max_total_qng = 0xF0;
        !          13108:                 eep_config->max_tag_qng = 0x20;
        !          13109:                 eep_config->cntl = 0xBFFF;
        !          13110:                 eep_config->chip_scsi_id = 7;
        !          13111:                 eep_config->no_scam = 0;
        !          13112:                 eep_config->adapter_info[0] = 0;
        !          13113:                 eep_config->adapter_info[1] = 0;
        !          13114:                 eep_config->adapter_info[2] = 0;
        !          13115:                 eep_config->adapter_info[3] = 0;
        !          13116:                 eep_config->adapter_info[4] = 0;
        !          13117:                 /* Indicate EEPROM-less board. */
        !          13118:                 eep_config->adapter_info[5] = 0xBB;
        !          13119:             } else {
        !          13120:                 write_eep = 1 ;
        !          13121:                 warn_code |= ASC_WARN_EEPROM_CHKSUM ;
        !          13122:             }
        !          13123:     }
        !          13124:     asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr ;
        !          13125:     asc_dvc->cfg->disc_enable = eep_config->disc_enable;
        !          13126:     asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
        !          13127:     asc_dvc->cfg->isa_dma_speed = eep_config->isa_dma_speed;
        !          13128:     asc_dvc->start_motor = eep_config->start_motor;
        !          13129:     asc_dvc->dvc_cntl = eep_config->cntl;
        !          13130:     asc_dvc->no_scam = eep_config->no_scam;
        !          13131:     asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
        !          13132:     asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
        !          13133:     asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
        !          13134:     asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
        !          13135:     asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
        !          13136:     asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
        !          13137:     if (!AscTestExternalLram(asc_dvc)) {
        !          13138:         if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA)) {
        !          13139:             eep_config->max_total_qng = ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
        !          13140:             eep_config->max_tag_qng = ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
        !          13141:         } else {
        !          13142:             eep_config->cfg_msw |= 0x0800;
        !          13143:             cfg_msw |= 0x0800;
        !          13144:             AscSetChipCfgMsw(iop_base, cfg_msw);
        !          13145:             eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
        !          13146:             eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
        !          13147:         }
        !          13148:     } else {
        !          13149:     }
        !          13150:     if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
        !          13151:         eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
        !          13152:     }
        !          13153:     if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
        !          13154:         eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
        !          13155:     }
        !          13156:     if (eep_config->max_tag_qng > eep_config->max_total_qng) {
        !          13157:         eep_config->max_tag_qng = eep_config->max_total_qng;
        !          13158:     }
        !          13159:     if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
        !          13160:         eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
        !          13161:     }
        !          13162:     asc_dvc->max_total_qng = eep_config->max_total_qng;
        !          13163:     if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
        !          13164:         eep_config->use_cmd_qng) {
        !          13165:         eep_config->disc_enable = eep_config->use_cmd_qng;
        !          13166:         warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
        !          13167:     }
        !          13168:     if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
        !          13169:         asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
        !          13170:     }
        !          13171:     eep_config->chip_scsi_id &= ASC_MAX_TID;
        !          13172:     asc_dvc->cfg->chip_scsi_id = eep_config->chip_scsi_id;
        !          13173:     if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
        !          13174:         !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
        !          13175:         asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
        !          13176:     }
        !          13177: 
        !          13178:     for (i = 0; i <= ASC_MAX_TID; i++) {
        !          13179:         asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
        !          13180:         asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
        !          13181:         asc_dvc->cfg->sdtr_period_offset[i] =
        !          13182:             (uchar) (ASC_DEF_SDTR_OFFSET |
        !          13183:                      (asc_dvc->host_init_sdtr_index << 4));
        !          13184:     }
        !          13185:     eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
        !          13186:     if (write_eep) {
        !          13187:         (void) AscSetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
        !          13188:     }
        !          13189:     return (warn_code);
        !          13190: }
        !          13191: 
        !          13192: ASC_INITFUNC(
        !          13193: STATIC ushort
        !          13194: AscInitMicroCodeVar(
        !          13195:                        ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          13196: )
        !          13197: )
        !          13198: {
        !          13199:     int                 i;
        !          13200:     ushort              warn_code;
        !          13201:     PortAddr            iop_base;
        !          13202:     ulong               phy_addr;
        !          13203: 
        !          13204:     iop_base = asc_dvc->iop_base;
        !          13205:     warn_code = 0;
        !          13206:     for (i = 0; i <= ASC_MAX_TID; i++) {
        !          13207:         AscPutMCodeInitSDTRAtID(iop_base, i,
        !          13208:                                 asc_dvc->cfg->sdtr_period_offset[i]
        !          13209: );
        !          13210:     }
        !          13211:     AscInitQLinkVar(asc_dvc);
        !          13212:     AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
        !          13213:                      asc_dvc->cfg->disc_enable);
        !          13214:     AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
        !          13215:                      ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
        !          13216:     if ((phy_addr = AscGetOnePhyAddr(asc_dvc,
        !          13217:                                  (uchar *) asc_dvc->cfg->overrun_buf,
        !          13218:                                      ASC_OVERRUN_BSIZE)) == 0L) {
        !          13219:         asc_dvc->err_code |= ASC_IERR_GET_PHY_ADDR;
        !          13220:     } else {
        !          13221:         phy_addr = (phy_addr & 0xFFFFFFF8UL) + 8;
        !          13222:         AscWriteLramDWord(iop_base, ASCV_OVERRUN_PADDR_D, phy_addr);
        !          13223:         AscWriteLramDWord(iop_base, ASCV_OVERRUN_BSIZE_D,
        !          13224:                           ASC_OVERRUN_BSIZE - 8);
        !          13225:     }
        !          13226:     asc_dvc->cfg->mcode_date = AscReadLramWord(iop_base,
        !          13227:                                                (ushort) ASCV_MC_DATE_W);
        !          13228:     asc_dvc->cfg->mcode_version = AscReadLramWord(iop_base,
        !          13229:                                                   (ushort) ASCV_MC_VER_W);
        !          13230:     AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
        !          13231:     if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
        !          13232:         asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
        !          13233:         return (warn_code);
        !          13234:     }
        !          13235:     if (AscStartChip(iop_base) != 1) {
        !          13236:         asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
        !          13237:         return (warn_code);
        !          13238:     }
        !          13239:     return (warn_code);
        !          13240: }
        !          13241: 
        !          13242: ASC_INITFUNC(
        !          13243: STATIC int
        !          13244: AscTestExternalLram(
        !          13245:                        ASC_DVC_VAR asc_ptr_type * asc_dvc
        !          13246: )
        !          13247: )
        !          13248: {
        !          13249:     PortAddr            iop_base;
        !          13250:     ushort              q_addr;
        !          13251:     ushort              saved_word;
        !          13252:     int                 sta;
        !          13253: 
        !          13254:     iop_base = asc_dvc->iop_base;
        !          13255:     sta = 0;
        !          13256:     q_addr = ASC_QNO_TO_QADDR(241);
        !          13257:     saved_word = AscReadLramWord(iop_base, q_addr);
        !          13258:     AscSetChipLramAddr(iop_base, q_addr);
        !          13259:     AscSetChipLramData(iop_base, 0x55AA);
        !          13260:     DvcSleepMilliSecond(10);
        !          13261:     AscSetChipLramAddr(iop_base, q_addr);
        !          13262:     if (AscGetChipLramData(iop_base) == 0x55AA) {
        !          13263:         sta = 1;
        !          13264:         AscWriteLramWord(iop_base, q_addr, saved_word);
        !          13265:     }
        !          13266:     return (sta);
        !          13267: }
        !          13268: 
        !          13269: ASC_INITFUNC(
        !          13270: STATIC int
        !          13271: AscWriteEEPCmdReg(
        !          13272:                      PortAddr iop_base,
        !          13273:                      uchar cmd_reg
        !          13274: )
        !          13275: )
        !          13276: {
        !          13277:     uchar               read_back;
        !          13278:     int                 retry;
        !          13279: 
        !          13280:     retry = 0;
        !          13281:     while (TRUE) {
        !          13282:         AscSetChipEEPCmd(iop_base, cmd_reg);
        !          13283:         DvcSleepMilliSecond(1);
        !          13284:         read_back = AscGetChipEEPCmd(iop_base);
        !          13285:         if (read_back == cmd_reg) {
        !          13286:             return (1);
        !          13287:         }
        !          13288:         if (retry++ > ASC_EEP_MAX_RETRY) {
        !          13289:             return (0);
        !          13290:         }
        !          13291:     }
        !          13292: }
        !          13293: 
        !          13294: ASC_INITFUNC(
        !          13295: STATIC int
        !          13296: AscWriteEEPDataReg(
        !          13297:                       PortAddr iop_base,
        !          13298:                       ushort data_reg
        !          13299: )
        !          13300: )
        !          13301: {
        !          13302:     ushort              read_back;
        !          13303:     int                 retry;
        !          13304: 
        !          13305:     retry = 0;
        !          13306:     while (TRUE) {
        !          13307:         AscSetChipEEPData(iop_base, data_reg);
        !          13308:         DvcSleepMilliSecond(1);
        !          13309:         read_back = AscGetChipEEPData(iop_base);
        !          13310:         if (read_back == data_reg) {
        !          13311:             return (1);
        !          13312:         }
        !          13313:         if (retry++ > ASC_EEP_MAX_RETRY) {
        !          13314:             return (0);
        !          13315:         }
        !          13316:     }
        !          13317: }
        !          13318: 
        !          13319: ASC_INITFUNC(
        !          13320: STATIC void
        !          13321: AscWaitEEPRead(
        !          13322:                   void
        !          13323: )
        !          13324: )
        !          13325: {
        !          13326:     DvcSleepMilliSecond(1);
        !          13327:     return;
        !          13328: }
        !          13329: 
        !          13330: ASC_INITFUNC(
        !          13331: STATIC void
        !          13332: AscWaitEEPWrite(
        !          13333:                    void
        !          13334: )
        !          13335: )
        !          13336: {
        !          13337:     DvcSleepMilliSecond(20);
        !          13338:     return;
        !          13339: }
        !          13340: 
        !          13341: ASC_INITFUNC(
        !          13342: STATIC ushort
        !          13343: AscReadEEPWord(
        !          13344:                   PortAddr iop_base,
        !          13345:                   uchar addr
        !          13346: )
        !          13347: )
        !          13348: {
        !          13349:     ushort              read_wval;
        !          13350:     uchar               cmd_reg;
        !          13351: 
        !          13352:     AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
        !          13353:     AscWaitEEPRead();
        !          13354:     cmd_reg = addr | ASC_EEP_CMD_READ;
        !          13355:     AscWriteEEPCmdReg(iop_base, cmd_reg);
        !          13356:     AscWaitEEPRead();
        !          13357:     read_wval = AscGetChipEEPData(iop_base);
        !          13358:     AscWaitEEPRead();
        !          13359:     return (read_wval);
        !          13360: }
        !          13361: 
        !          13362: ASC_INITFUNC(
        !          13363: STATIC ushort
        !          13364: AscWriteEEPWord(
        !          13365:                    PortAddr iop_base,
        !          13366:                    uchar addr,
        !          13367:                    ushort word_val
        !          13368: )
        !          13369: )
        !          13370: {
        !          13371:     ushort              read_wval;
        !          13372: 
        !          13373:     read_wval = AscReadEEPWord(iop_base, addr);
        !          13374:     if (read_wval != word_val) {
        !          13375:         AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
        !          13376:         AscWaitEEPRead();
        !          13377:         AscWriteEEPDataReg(iop_base, word_val);
        !          13378:         AscWaitEEPRead();
        !          13379:         AscWriteEEPCmdReg(iop_base,
        !          13380:                           (uchar) ((uchar) ASC_EEP_CMD_WRITE | addr));
        !          13381:         AscWaitEEPWrite();
        !          13382:         AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
        !          13383:         AscWaitEEPRead();
        !          13384:         return (AscReadEEPWord(iop_base, addr));
        !          13385:     }
        !          13386:     return (read_wval);
        !          13387: }
        !          13388: 
        !          13389: ASC_INITFUNC(
        !          13390: STATIC ushort
        !          13391: AscGetEEPConfig(
        !          13392:                    PortAddr iop_base,
        !          13393:                    ASCEEP_CONFIG * cfg_buf, ushort bus_type
        !          13394: )
        !          13395: )
        !          13396: {
        !          13397:     ushort              wval;
        !          13398:     ushort              sum;
        !          13399:     ushort      *wbuf;
        !          13400:     int                 cfg_beg;
        !          13401:     int                 cfg_end;
        !          13402:     int                 s_addr;
        !          13403:     int                 isa_pnp_wsize;
        !          13404: 
        !          13405:     wbuf = (ushort *) cfg_buf;
        !          13406:     sum = 0;
        !          13407:     isa_pnp_wsize = 0;
        !          13408:     for (s_addr = 0; s_addr < (2 + isa_pnp_wsize); s_addr++, wbuf++) {
        !          13409:         wval = AscReadEEPWord(iop_base, (uchar) s_addr);
        !          13410:         sum += wval;
        !          13411:         *wbuf = wval;
        !          13412:     }
        !          13413:     if (bus_type & ASC_IS_VL) {
        !          13414:         cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
        !          13415:         cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
        !          13416:     } else {
        !          13417:         cfg_beg = ASC_EEP_DVC_CFG_BEG;
        !          13418:         cfg_end = ASC_EEP_MAX_DVC_ADDR;
        !          13419:     }
        !          13420:     for (s_addr = cfg_beg; s_addr <= (cfg_end - 1);
        !          13421:          s_addr++, wbuf++) {
        !          13422:         wval = AscReadEEPWord(iop_base, (uchar) s_addr);
        !          13423:         sum += wval;
        !          13424:         *wbuf = wval;
        !          13425:     }
        !          13426:     *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
        !          13427:     return (sum);
        !          13428: }
        !          13429: 
        !          13430: ASC_INITFUNC(
        !          13431: STATIC int
        !          13432: AscSetEEPConfigOnce(
        !          13433:                        PortAddr iop_base,
        !          13434:                        ASCEEP_CONFIG * cfg_buf, ushort bus_type
        !          13435: )
        !          13436: )
        !          13437: {
        !          13438:     int                 n_error;
        !          13439:     ushort      *wbuf;
        !          13440:     ushort              sum;
        !          13441:     int                 s_addr;
        !          13442:     int                 cfg_beg;
        !          13443:     int                 cfg_end;
        !          13444: 
        !          13445:     wbuf = (ushort *) cfg_buf;
        !          13446:     n_error = 0;
        !          13447:     sum = 0;
        !          13448:     for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
        !          13449:         sum += *wbuf;
        !          13450:         if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
        !          13451:             n_error++;
        !          13452:         }
        !          13453:     }
        !          13454:     if (bus_type & ASC_IS_VL) {
        !          13455:         cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
        !          13456:         cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
        !          13457:     } else {
        !          13458:         cfg_beg = ASC_EEP_DVC_CFG_BEG;
        !          13459:         cfg_end = ASC_EEP_MAX_DVC_ADDR;
        !          13460:     }
        !          13461:     for (s_addr = cfg_beg; s_addr <= (cfg_end - 1);
        !          13462:          s_addr++, wbuf++) {
        !          13463:         sum += *wbuf;
        !          13464:         if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
        !          13465:             n_error++;
        !          13466:         }
        !          13467:     }
        !          13468:     *wbuf = sum;
        !          13469:     if (sum != AscWriteEEPWord(iop_base, (uchar) s_addr, sum)) {
        !          13470:         n_error++;
        !          13471:     }
        !          13472:     wbuf = (ushort *) cfg_buf;
        !          13473:     for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
        !          13474:         if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
        !          13475:             n_error++;
        !          13476:         }
        !          13477:     }
        !          13478:     for (s_addr = cfg_beg; s_addr <= cfg_end;
        !          13479:          s_addr++, wbuf++) {
        !          13480:         if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
        !          13481:             n_error++;
        !          13482:         }
        !          13483:     }
        !          13484:     return (n_error);
        !          13485: }
        !          13486: 
        !          13487: ASC_INITFUNC(
        !          13488: STATIC int
        !          13489: AscSetEEPConfig(
        !          13490:                    PortAddr iop_base,
        !          13491:                    ASCEEP_CONFIG * cfg_buf, ushort bus_type
        !          13492: )
        !          13493: )
        !          13494: {
        !          13495:     int            retry;
        !          13496:     int            n_error;
        !          13497: 
        !          13498:     retry = 0;
        !          13499:     while (TRUE) {
        !          13500:         if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
        !          13501:                                            bus_type)) == 0) {
        !          13502:             break;
        !          13503:         }
        !          13504:         if (++retry > ASC_EEP_MAX_RETRY) {
        !          13505:             break;
        !          13506:         }
        !          13507:     }
        !          13508:     return (n_error);
        !          13509: }
        !          13510: 
        !          13511: STATIC void
        !          13512: AscAsyncFix(
        !          13513:                ASC_DVC_VAR asc_ptr_type *asc_dvc,
        !          13514:                uchar tid_no,
        !          13515:                ASC_SCSI_INQUIRY *inq)
        !          13516: {
        !          13517:     uchar                dvc_type;
        !          13518:     ASC_SCSI_BIT_ID_TYPE tid_bits;
        !          13519: 
        !          13520:     dvc_type = inq->byte0.peri_dvc_type;
        !          13521:     tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
        !          13522: 
        !          13523:     if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) {
        !          13524:         if (!(asc_dvc->init_sdtr & tid_bits)) {
        !          13525:             if ((dvc_type == SCSI_TYPE_CDROM) &&
        !          13526:                 (AscCompareString((uchar *) inq->vendor_id,
        !          13527:                     (uchar *) "HP ", 3) == 0)) {
        !          13528:                 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
        !          13529:             }
        !          13530:             asc_dvc->pci_fix_asyn_xfer |= tid_bits;
        !          13531:             if ((dvc_type == SCSI_TYPE_PROC) ||
        !          13532:                 (dvc_type == SCSI_TYPE_SCANNER)) {
        !          13533:                 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
        !          13534:             }
        !          13535:             if ((dvc_type == SCSI_TYPE_SASD) &&
        !          13536:                 (AscCompareString((uchar *) inq->vendor_id,
        !          13537:                  (uchar *) "TANDBERG", 8) == 0) &&
        !          13538:                 (AscCompareString((uchar *) inq->product_id,
        !          13539:                  (uchar *) " TDC 36", 7) == 0)) {
        !          13540:                 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
        !          13541:             }
        !          13542:             if ((dvc_type == SCSI_TYPE_SASD) &&
        !          13543:                 (AscCompareString((uchar *) inq->vendor_id,
        !          13544:                  (uchar *) "WANGTEK ", 8) == 0)) {
        !          13545:                 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
        !          13546:             }
        !          13547: 
        !          13548:             if ((dvc_type == SCSI_TYPE_CDROM) &&
        !          13549:                 (AscCompareString((uchar *) inq->vendor_id,
        !          13550:                  (uchar *) "NEC     ", 8) == 0) &&
        !          13551:                 (AscCompareString((uchar *) inq->product_id,
        !          13552:                  (uchar *) "CD-ROM DRIVE    ", 16) == 0)) {
        !          13553:                 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
        !          13554:             }
        !          13555: 
        !          13556:             if ((dvc_type == SCSI_TYPE_CDROM) &&
        !          13557:                 (AscCompareString((uchar *) inq->vendor_id,
        !          13558:                  (uchar *) "YAMAHA", 6) == 0) &&
        !          13559:                 (AscCompareString((uchar *) inq->product_id,
        !          13560:                  (uchar *) "CDR400", 6) == 0)) {
        !          13561:                 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
        !          13562:             }
        !          13563:             if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
        !          13564:                 AscSetRunChipSynRegAtID(asc_dvc->iop_base, tid_no,
        !          13565:                                         ASYN_SDTR_DATA_FIX_PCI_REV_AB);
        !          13566:             }
        !          13567:         }
        !          13568:     }
        !          13569:     return;
        !          13570: }
        !          13571: 
        !          13572: STATIC int
        !          13573: AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq)
        !          13574: {
        !          13575:     if ((inq->add_len >= 32) &&
        !          13576:         (AscCompareString((uchar *) inq->vendor_id,
        !          13577:             (uchar *) "QUANTUM XP34301", 15) == 0) &&
        !          13578:         (AscCompareString((uchar *) inq->product_rev_level,
        !          13579:             (uchar *) "1071", 4) == 0))
        !          13580:     {
        !          13581:         return 0;
        !          13582:     }
        !          13583:     return 1;
        !          13584: }
        !          13585: 
        !          13586: STATIC void
        !          13587: AscInquiryHandling(ASC_DVC_VAR asc_ptr_type *asc_dvc,
        !          13588:                    uchar tid_no, ASC_SCSI_INQUIRY *inq)
        !          13589: {
        !          13590:     ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no);
        !          13591:     ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng;
        !          13592: 
        !          13593:     orig_init_sdtr = asc_dvc->init_sdtr;
        !          13594:     orig_use_tagged_qng = asc_dvc->use_tagged_qng;
        !          13595: 
        !          13596:     asc_dvc->init_sdtr &= ~tid_bit;
        !          13597:     asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
        !          13598:     asc_dvc->use_tagged_qng &= ~tid_bit;
        !          13599: 
        !          13600:     if (inq->byte3.rsp_data_fmt >= 2 || inq->byte2.ansi_apr_ver >= 2) {
        !          13601:         if ((asc_dvc->cfg->sdtr_enable & tid_bit) && inq->byte7.Sync) {
        !          13602:             asc_dvc->init_sdtr |= tid_bit;
        !          13603:         }
        !          13604:         if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) && inq->byte7.CmdQue) {
        !          13605:             if (AscTagQueuingSafe(inq)) {
        !          13606:                 asc_dvc->use_tagged_qng |= tid_bit;
        !          13607:                 asc_dvc->cfg->can_tagged_qng |= tid_bit;
        !          13608:             }
        !          13609:         }
        !          13610:     }
        !          13611:     if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) {
        !          13612:         AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
        !          13613:                          asc_dvc->cfg->disc_enable);
        !          13614:         AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
        !          13615:                          asc_dvc->use_tagged_qng);
        !          13616:         AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
        !          13617:                          asc_dvc->cfg->can_tagged_qng);
        !          13618: 
        !          13619:         asc_dvc->max_dvc_qng[tid_no] =
        !          13620:           asc_dvc->cfg->max_tag_qng[tid_no];
        !          13621:         AscWriteLramByte(asc_dvc->iop_base,
        !          13622:                          (ushort) (ASCV_MAX_DVC_QNG_BEG + tid_no),
        !          13623:                          asc_dvc->max_dvc_qng[tid_no]);
        !          13624:     }
        !          13625:     if (orig_init_sdtr != asc_dvc->init_sdtr) {
        !          13626:         AscAsyncFix(asc_dvc, tid_no, inq);
        !          13627:     }
        !          13628:     return;
        !          13629: }
        !          13630: 
        !          13631: STATIC int
        !          13632: AscCompareString(
        !          13633:                     ruchar * str1,
        !          13634:                     ruchar * str2,
        !          13635:                     int len
        !          13636: )
        !          13637: {
        !          13638:     int                 i;
        !          13639:     int                 diff;
        !          13640: 
        !          13641:     for (i = 0; i < len; i++) {
        !          13642:         diff = (int) (str1[i] - str2[i]);
        !          13643:         if (diff != 0)
        !          13644:             return (diff);
        !          13645:     }
        !          13646:     return (0);
        !          13647: }
        !          13648: 
        !          13649: STATIC uchar
        !          13650: AscReadLramByte(
        !          13651:                    PortAddr iop_base,
        !          13652:                    ushort addr
        !          13653: )
        !          13654: {
        !          13655:     uchar               byte_data;
        !          13656:     ushort              word_data;
        !          13657: 
        !          13658:     if (isodd_word(addr)) {
        !          13659:         AscSetChipLramAddr(iop_base, addr - 1);
        !          13660:         word_data = AscGetChipLramData(iop_base);
        !          13661:         byte_data = (uchar) ((word_data >> 8) & 0xFF);
        !          13662:     } else {
        !          13663:         AscSetChipLramAddr(iop_base, addr);
        !          13664:         word_data = AscGetChipLramData(iop_base);
        !          13665:         byte_data = (uchar) (word_data & 0xFF);
        !          13666:     }
        !          13667:     return (byte_data);
        !          13668: }
        !          13669: 
        !          13670: STATIC ushort
        !          13671: AscReadLramWord(
        !          13672:                    PortAddr iop_base,
        !          13673:                    ushort addr
        !          13674: )
        !          13675: {
        !          13676:     ushort              word_data;
        !          13677: 
        !          13678:     AscSetChipLramAddr(iop_base, addr);
        !          13679:     word_data = AscGetChipLramData(iop_base);
        !          13680:     return (word_data);
        !          13681: }
        !          13682: 
        !          13683: STATIC ulong
        !          13684: AscReadLramDWord(
        !          13685:                     PortAddr iop_base,
        !          13686:                     ushort addr
        !          13687: )
        !          13688: {
        !          13689:     ushort              val_low, val_high;
        !          13690:     ulong               dword_data;
        !          13691: 
        !          13692:     AscSetChipLramAddr(iop_base, addr);
        !          13693:     val_low = AscGetChipLramData(iop_base);
        !          13694:     val_high = AscGetChipLramData(iop_base);
        !          13695:     dword_data = ((ulong) val_high << 16) | (ulong) val_low;
        !          13696:     return (dword_data);
        !          13697: }
        !          13698: 
        !          13699: STATIC void
        !          13700: AscWriteLramWord(
        !          13701:                     PortAddr iop_base,
        !          13702:                     ushort addr,
        !          13703:                     ushort word_val
        !          13704: )
        !          13705: {
        !          13706:     AscSetChipLramAddr(iop_base, addr);
        !          13707:     AscSetChipLramData(iop_base, word_val);
        !          13708:     return;
        !          13709: }
        !          13710: 
        !          13711: STATIC void
        !          13712: AscWriteLramDWord(
        !          13713:                      PortAddr iop_base,
        !          13714:                      ushort addr,
        !          13715:                      ulong dword_val
        !          13716: )
        !          13717: {
        !          13718:     ushort              word_val;
        !          13719: 
        !          13720:     AscSetChipLramAddr(iop_base, addr);
        !          13721:     word_val = (ushort) dword_val;
        !          13722:     AscSetChipLramData(iop_base, word_val);
        !          13723:     word_val = (ushort) (dword_val >> 16);
        !          13724:     AscSetChipLramData(iop_base, word_val);
        !          13725:     return;
        !          13726: }
        !          13727: 
        !          13728: STATIC void
        !          13729: AscWriteLramByte(
        !          13730:                     PortAddr iop_base,
        !          13731:                     ushort addr,
        !          13732:                     uchar byte_val
        !          13733: )
        !          13734: {
        !          13735:     ushort              word_data;
        !          13736: 
        !          13737:     if (isodd_word(addr)) {
        !          13738:         addr--;
        !          13739:         word_data = AscReadLramWord(iop_base, addr);
        !          13740:         word_data &= 0x00FF;
        !          13741:         word_data |= (((ushort) byte_val << 8) & 0xFF00);
        !          13742:     } else {
        !          13743:         word_data = AscReadLramWord(iop_base, addr);
        !          13744:         word_data &= 0xFF00;
        !          13745:         word_data |= ((ushort) byte_val & 0x00FF);
        !          13746:     }
        !          13747:     AscWriteLramWord(iop_base, addr, word_data);
        !          13748:     return;
        !          13749: }
        !          13750: 
        !          13751: STATIC void
        !          13752: AscMemWordCopyToLram(
        !          13753:                         PortAddr iop_base,
        !          13754:                         ushort s_addr,
        !          13755:                         ushort * s_buffer,
        !          13756:                         int words
        !          13757: )
        !          13758: {
        !          13759:     AscSetChipLramAddr(iop_base, s_addr);
        !          13760:     DvcOutPortWords(iop_base + IOP_RAM_DATA, s_buffer, words);
        !          13761:     return;
        !          13762: }
        !          13763: 
        !          13764: STATIC void
        !          13765: AscMemDWordCopyToLram(
        !          13766:                          PortAddr iop_base,
        !          13767:                          ushort s_addr,
        !          13768:                          ulong * s_buffer,
        !          13769:                          int dwords
        !          13770: )
        !          13771: {
        !          13772:     AscSetChipLramAddr(iop_base, s_addr);
        !          13773:     DvcOutPortDWords(iop_base + IOP_RAM_DATA, s_buffer, dwords);
        !          13774:     return;
        !          13775: }
        !          13776: 
        !          13777: STATIC void
        !          13778: AscMemWordCopyFromLram(
        !          13779:                           PortAddr iop_base,
        !          13780:                           ushort s_addr,
        !          13781:                           ushort * d_buffer,
        !          13782:                           int words
        !          13783: )
        !          13784: {
        !          13785:     AscSetChipLramAddr(iop_base, s_addr);
        !          13786:     DvcInPortWords(iop_base + IOP_RAM_DATA, d_buffer, words);
        !          13787:     return;
        !          13788: }
        !          13789: 
        !          13790: STATIC ulong
        !          13791: AscMemSumLramWord(
        !          13792:                      PortAddr iop_base,
        !          13793:                      ushort s_addr,
        !          13794:                      rint words
        !          13795: )
        !          13796: {
        !          13797:     ulong               sum;
        !          13798:     int                 i;
        !          13799: 
        !          13800:     sum = 0L;
        !          13801:     for (i = 0; i < words; i++, s_addr += 2) {
        !          13802:         sum += AscReadLramWord(iop_base, s_addr);
        !          13803:     }
        !          13804:     return (sum);
        !          13805: }
        !          13806: 
        !          13807: STATIC void
        !          13808: AscMemWordSetLram(
        !          13809:                      PortAddr iop_base,
        !          13810:                      ushort s_addr,
        !          13811:                      ushort set_wval,
        !          13812:                      rint words
        !          13813: )
        !          13814: {
        !          13815:     rint             i;
        !          13816: 
        !          13817:     AscSetChipLramAddr(iop_base, s_addr);
        !          13818:     for (i = 0; i < words; i++) {
        !          13819:         AscSetChipLramData(iop_base, set_wval);
        !          13820:     }
        !          13821:     return;
        !          13822: }
        !          13823: 
        !          13824: 
        !          13825: /*
        !          13826:  * --- Adv Library Functions
        !          13827:  */
        !          13828: 
        !          13829: /* a_qswap.h */
        !          13830: STATIC unsigned char _adv_mcode_buf[] ASC_INITDATA = {
        !          13831:   0x9C,  0xF0,  0x80,  0x01,  0x00,  0xF0,  0x44,  0x0A,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
        !          13832:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
        !          13833:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x72,  0x01,  0xD6,  0x11,  0x00,  0x00,  0x70,  0x01,
        !          13834:   0x30,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x90,  0x10,  0x2D,  0x03,  0x00,  0x00,  0x00,  0x00,
        !          13835:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
        !          13836:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
        !          13837:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
        !          13838:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
        !          13839:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
        !          13840:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
        !          13841:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
        !          13842:   0x48,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
        !          13843:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
        !          13844:   0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,
        !          13845:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
        !          13846:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
        !          13847:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
        !          13848:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
        !          13849:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x78,  0x56,  0x34,  0x12,
        !          13850:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
        !          13851:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
        !          13852:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
        !          13853:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
        !          13854:   0x00,  0x00,  0x04,  0xF7,  0x70,  0x01,  0x0C,  0x1C,  0x06,  0xF7,  0x02,  0x00,  0x00,  0xF2,  0xD6,  0x0A,
        !          13855:   0x04,  0xF7,  0x70,  0x01,  0x06,  0xF7,  0x02,  0x00,  0x3E,  0x57,  0x3C,  0x56,  0x0C,  0x1C,  0x00,  0xFC,
        !          13856:   0xA6,  0x00,  0x01,  0x58,  0xAA,  0x13,  0x20,  0xF0,  0xA6,  0x03,  0x06,  0xEC,  0xB9,  0x00,  0x0E,  0x47,
        !          13857:   0x03,  0xE6,  0x10,  0x00,  0xCE,  0x45,  0x02,  0x13,  0x3E,  0x57,  0x06,  0xEA,  0xB9,  0x00,  0x47,  0x4B,
        !          13858:   0x03,  0xF6,  0xE0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x01,  0x48,  0x4E,  0x12,  0x03,  0xF6,  0xC0,  0x00,
        !          13859:   0x00,  0xF2,  0x68,  0x0A,  0x41,  0x58,  0x03,  0xF6,  0xD0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x49,  0x44,
        !          13860:   0x59,  0xF0,  0x0A,  0x02,  0x03,  0xF6,  0xE0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x44,  0x58,  0x00,  0xF2,
        !          13861:   0xE2,  0x0D,  0x02,  0xCC,  0x4A,  0xE4,  0x01,  0x00,  0x55,  0xF0,  0x08,  0x03,  0x45,  0xF4,  0x02,  0x00,
        !          13862:   0x83,  0x5A,  0x04,  0xCC,  0x01,  0x4A,  0x12,  0x12,  0x00,  0xF2,  0xE2,  0x0D,  0x00,  0xCD,  0x48,  0xE4,
        !          13863:   0x01,  0x00,  0xE9,  0x13,  0x00,  0xF2,  0xC6,  0x0F,  0xFA,  0x10,  0x0E,  0x47,  0x03,  0xE6,  0x10,  0x00,
        !          13864:   0xCE,  0x45,  0x02,  0x13,  0x3E,  0x57,  0xCE,  0x47,  0x97,  0x13,  0x04,  0xEC,  0xB4,  0x00,  0x00,  0xF2,
        !          13865:   0xE2,  0x0D,  0x00,  0xCD,  0x48,  0xE4,  0x00,  0x00,  0x12,  0x12,  0x3E,  0x57,  0x06,  0xCC,  0x45,  0xF4,
        !          13866:   0x02,  0x00,  0x83,  0x5A,  0x00,  0xCC,  0x00,  0xEA,  0xB4,  0x00,  0x92,  0x10,  0x00,  0xF0,  0x8C,  0x01,
        !          13867:   0x43,  0xF0,  0x5C,  0x02,  0x44,  0xF0,  0x60,  0x02,  0x45,  0xF0,  0x64,  0x02,  0x46,  0xF0,  0x68,  0x02,
        !          13868:   0x47,  0xF0,  0x6E,  0x02,  0x48,  0xF0,  0x9E,  0x02,  0xB9,  0x54,  0x62,  0x10,  0x00,  0x1C,  0x5A,  0x10,
        !          13869:   0x02,  0x1C,  0x56,  0x10,  0x1E,  0x1C,  0x52,  0x10,  0x00,  0xF2,  0x1E,  0x11,  0x50,  0x10,  0x06,  0xFC,
        !          13870:   0xA8,  0x00,  0x03,  0xF6,  0xBE,  0x00,  0x00,  0xF2,  0x4E,  0x0A,  0x8C,  0x10,  0x01,  0xF6,  0x01,  0x00,
        !          13871:   0x01,  0xFA,  0xA8,  0x00,  0x00,  0xF2,  0x2C,  0x0B,  0x06,  0x10,  0xB9,  0x54,  0x01,  0xFA,  0xA8,  0x00,
        !          13872:   0x03,  0xF6,  0xBE,  0x00,  0x00,  0xF2,  0x58,  0x0A,  0x01,  0xFC,  0xA8,  0x00,  0x20,  0x10,  0x58,  0x1C,
        !          13873:   0x00,  0xF2,  0x1C,  0x0B,  0x5A,  0x1C,  0x01,  0xF6,  0x01,  0x00,  0x38,  0x54,  0x00,  0xFA,  0xA6,  0x00,
        !          13874:   0x01,  0xFA,  0xA8,  0x00,  0x20,  0x1C,  0x00,  0xF0,  0x72,  0x01,  0x01,  0xF6,  0x01,  0x00,  0x38,  0x54,
        !          13875:   0x00,  0xFA,  0xA6,  0x00,  0x01,  0xFA,  0xA8,  0x00,  0x20,  0x1C,  0x00,  0xF0,  0x80,  0x01,  0x03,  0xF6,
        !          13876:   0xE0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x01,  0x48,  0x0A,  0x13,  0x00,  0xF2,  0x38,  0x10,  0x00,  0xF2,
        !          13877:   0x54,  0x0F,  0x24,  0x10,  0x03,  0xF6,  0xC0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x02,  0xF6,  0xD0,  0x00,
        !          13878:   0x02,  0x57,  0x03,  0x59,  0x01,  0xCC,  0x49,  0x44,  0x5B,  0xF0,  0x04,  0x03,  0x00,  0xF2,  0x9C,  0x0F,
        !          13879:   0x00,  0xF0,  0x80,  0x01,  0x00,  0xF2,  0x14,  0x10,  0x0C,  0x1C,  0x02,  0x4B,  0xBF,  0x57,  0x9E,  0x43,
        !          13880:   0x77,  0x57,  0x07,  0x4B,  0x20,  0xF0,  0xA6,  0x03,  0x40,  0x1C,  0x1E,  0xF0,  0x30,  0x03,  0x26,  0xF0,
        !          13881:   0x2C,  0x03,  0xA0,  0xF0,  0x1A,  0x03,  0x11,  0xF0,  0xA6,  0x03,  0x12,  0x10,  0x9F,  0xF0,  0x3E,  0x03,
        !          13882:   0x46,  0x1C,  0x82,  0xE7,  0x05,  0x00,  0x9E,  0xE7,  0x11,  0x00,  0x00,  0xF0,  0x06,  0x0A,  0x0C,  0x1C,
        !          13883:   0x48,  0x1C,  0x46,  0x1C,  0x38,  0x54,  0x00,  0xEC,  0xBA,  0x00,  0x08,  0x44,  0x00,  0xEA,  0xBA,  0x00,
        !          13884:   0x03,  0xF6,  0xC0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x08,  0x44,  0x00,  0x4C,  0x82,  0xE7,  0x02,  0x00,
        !          13885:   0x00,  0xF2,  0x12,  0x11,  0x00,  0xF2,  0x12,  0x11,  0x85,  0xF0,  0x70,  0x03,  0x00,  0xF2,  0x60,  0x0B,
        !          13886:   0x06,  0xF0,  0x80,  0x03,  0x09,  0xF0,  0x24,  0x09,  0x1E,  0xF0,  0xFC,  0x09,  0x00,  0xF0,  0x02,  0x0A,
        !          13887:   0x00,  0xFC,  0xBE,  0x00,  0x98,  0x57,  0x55,  0xF0,  0xAC,  0x04,  0x01,  0xE6,  0x0C,  0x00,  0x00,  0xF2,
        !          13888:   0x4E,  0x0D,  0x00,  0xF2,  0x12,  0x11,  0x00,  0xF2,  0xBC,  0x11,  0x00,  0xF2,  0xC8,  0x11,  0x01,  0xF0,
        !          13889:   0x7C,  0x02,  0x00,  0xF0,  0x8A,  0x02,  0x46,  0x1C,  0x0C,  0x1C,  0x67,  0x1B,  0xBF,  0x57,  0x77,  0x57,
        !          13890:   0x02,  0x4B,  0x48,  0x1C,  0x32,  0x1C,  0x00,  0xF2,  0x92,  0x0D,  0x30,  0x1C,  0x96,  0xF0,  0xBC,  0x03,
        !          13891:   0xB1,  0xF0,  0xC0,  0x03,  0x1E,  0xF0,  0xFC,  0x09,  0x85,  0xF0,  0x02,  0x0A,  0x00,  0xFC,  0xBE,  0x00,
        !          13892:   0x98,  0x57,  0x14,  0x12,  0x01,  0xE6,  0x0C,  0x00,  0x00,  0xF2,  0x4E,  0x0D,  0x00,  0xF2,  0x12,  0x11,
        !          13893:   0x01,  0xF0,  0x7C,  0x02,  0x00,  0xF0,  0x8A,  0x02,  0x03,  0xF6,  0xE0,  0x00,  0x00,  0xF2,  0x68,  0x0A,
        !          13894:   0x01,  0x48,  0x55,  0xF0,  0x98,  0x04,  0x03,  0x82,  0x03,  0xFC,  0xA0,  0x00,  0x9B,  0x57,  0x40,  0x12,
        !          13895:   0x69,  0x18,  0x00,  0xF2,  0x12,  0x11,  0x85,  0xF0,  0x42,  0x04,  0x69,  0x08,  0x00,  0xF2,  0x12,  0x11,
        !          13896:   0x85,  0xF0,  0x02,  0x0A,  0x68,  0x08,  0x4C,  0x44,  0x28,  0x12,  0x44,  0x48,  0x03,  0xF6,  0xE0,  0x00,
        !          13897:   0x00,  0xF2,  0x68,  0x0A,  0x45,  0x58,  0x00,  0xF2,  0xF6,  0x0D,  0x00,  0xCC,  0x01,  0x48,  0x55,  0xF0,
        !          13898:   0x98,  0x04,  0x4C,  0x44,  0xEF,  0x13,  0x00,  0xF2,  0xC6,  0x0F,  0x00,  0xF2,  0x14,  0x10,  0x08,  0x10,
        !          13899:   0x68,  0x18,  0x45,  0x5A,  0x00,  0xF2,  0xF6,  0x0D,  0x04,  0x80,  0x18,  0xE4,  0x10,  0x00,  0x28,  0x12,
        !          13900:   0x01,  0xE6,  0x06,  0x00,  0x04,  0x80,  0x18,  0xE4,  0x01,  0x00,  0x04,  0x12,  0x01,  0xE6,  0x0D,  0x00,
        !          13901:   0x00,  0xF2,  0x4E,  0x0D,  0x00,  0xF2,  0x12,  0x11,  0x04,  0xE6,  0x02,  0x00,  0x9E,  0xE7,  0x15,  0x00,
        !          13902:   0x01,  0xF0,  0x1C,  0x0A,  0x00,  0xF0,  0x02,  0x0A,  0x69,  0x08,  0x05,  0x80,  0x48,  0xE4,  0x00,  0x00,
        !          13903:   0x0C,  0x12,  0x00,  0xE6,  0x11,  0x00,  0x00,  0xEA,  0xB8,  0x00,  0x00,  0xF2,  0xB6,  0x10,  0x82,  0xE7,
        !          13904:   0x02,  0x00,  0x1C,  0x90,  0x40,  0x5C,  0x00,  0x16,  0x01,  0xE6,  0x06,  0x00,  0x00,  0xF2,  0x4E,  0x0D,
        !          13905:   0x01,  0xF0,  0x80,  0x01,  0x1E,  0xF0,  0x80,  0x01,  0x00,  0xF0,  0xA0,  0x04,  0x42,  0x5B,  0x06,  0xF7,
        !          13906:   0x03,  0x00,  0x46,  0x59,  0xBF,  0x57,  0x77,  0x57,  0x01,  0xE6,  0x80,  0x00,  0x07,  0x80,  0x31,  0x44,
        !          13907:   0x04,  0x80,  0x18,  0xE4,  0x20,  0x00,  0x56,  0x13,  0x20,  0x80,  0x48,  0xE4,  0x03,  0x00,  0x4E,  0x12,
        !          13908:   0x00,  0xFC,  0xA2,  0x00,  0x98,  0x57,  0x55,  0xF0,  0x1C,  0x05,  0x31,  0xE4,  0x40,  0x00,  0x00,  0xFC,
        !          13909:   0xA0,  0x00,  0x98,  0x57,  0x36,  0x12,  0x4C,  0x1C,  0x00,  0xF2,  0x12,  0x11,  0x89,  0x48,  0x00,  0xF2,
        !          13910:   0x12,  0x11,  0x86,  0xF0,  0x2E,  0x05,  0x82,  0xE7,  0x06,  0x00,  0x1B,  0x80,  0x48,  0xE4,  0x22,  0x00,
        !          13911:   0x5B,  0xF0,  0x0C,  0x05,  0x48,  0xE4,  0x20,  0x00,  0x59,  0xF0,  0x10,  0x05,  0x00,  0xE6,  0x20,  0x00,
        !          13912:   0x09,  0x48,  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0x2E,  0x05,  0x83,  0x80,  0x04,  0x10,  0x00,  0xF2,
        !          13913:   0xA2,  0x0D,  0x00,  0xE6,  0x01,  0x00,  0x00,  0xEA,  0x26,  0x01,  0x01,  0xEA,  0x27,  0x01,  0x04,  0x80,
        !          13914:   0x18,  0xE4,  0x10,  0x00,  0x36,  0x12,  0xB9,  0x54,  0x00,  0xF2,  0xF6,  0x0E,  0x01,  0xE6,  0x06,  0x00,
        !          13915:   0x04,  0x80,  0x18,  0xE4,  0x01,  0x00,  0x04,  0x12,  0x01,  0xE6,  0x0D,  0x00,  0x00,  0xF2,  0x4E,  0x0D,
        !          13916:   0x00,  0xF2,  0x12,  0x11,  0x00,  0xF2,  0xBC,  0x11,  0x00,  0xF2,  0xC8,  0x11,  0x04,  0xE6,  0x02,  0x00,
        !          13917:   0x9E,  0xE7,  0x15,  0x00,  0x01,  0xF0,  0x1C,  0x0A,  0x00,  0xF0,  0x02,  0x0A,  0x00,  0xFC,  0x20,  0x01,
        !          13918:   0x98,  0x57,  0x34,  0x12,  0x00,  0xFC,  0x24,  0x01,  0x98,  0x57,  0x2C,  0x13,  0xB9,  0x54,  0x00,  0xF2,
        !          13919:   0xF6,  0x0E,  0x86,  0xF0,  0xA8,  0x05,  0x03,  0xF6,  0x01,  0x00,  0x00,  0xF2,  0x8C,  0x0E,  0x85,  0xF0,
        !          13920:   0x9E,  0x05,  0x82,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x60,  0x0B,  0x82,  0xE7,  0x02,  0x00,  0x00,  0xFC,
        !          13921:   0x24,  0x01,  0xB0,  0x57,  0x00,  0xFA,  0x24,  0x01,  0x00,  0xFC,  0x9E,  0x00,  0x98,  0x57,  0x5A,  0x12,
        !          13922:   0x00,  0xFC,  0xB6,  0x00,  0x98,  0x57,  0x52,  0x13,  0x03,  0xE6,  0x0C,  0x00,  0x00,  0xFC,  0x9C,  0x00,
        !          13923:   0x98,  0x57,  0x04,  0x13,  0x03,  0xE6,  0x19,  0x00,  0x05,  0xE6,  0x08,  0x00,  0x00,  0xF6,  0x00,  0x01,
        !          13924:   0x00,  0x57,  0x00,  0x57,  0x03,  0x58,  0x00,  0xDC,  0x18,  0xF4,  0x00,  0x80,  0x04,  0x13,  0x05,  0xE6,
        !          13925:   0x0F,  0x00,  0xB9,  0x54,  0x00,  0xF2,  0xF6,  0x0E,  0x86,  0xF0,  0x0A,  0x06,  0x00,  0xF2,  0xBA,  0x0E,
        !          13926:   0x85,  0xF0,  0x00,  0x06,  0x82,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x60,  0x0B,  0x82,  0xE7,  0x02,  0x00,
        !          13927:   0x00,  0xFC,  0xB6,  0x00,  0xB0,  0x57,  0x00,  0xFA,  0xB6,  0x00,  0x01,  0xF6,  0x01,  0x00,  0x00,  0xF2,
        !          13928:   0xF6,  0x0E,  0x9C,  0x32,  0x4E,  0x1C,  0x32,  0x1C,  0x00,  0xF2,  0x92,  0x0D,  0x30,  0x1C,  0x82,  0xE7,
        !          13929:   0x04,  0x00,  0xB1,  0xF0,  0x22,  0x06,  0x0A,  0xF0,  0x3E,  0x06,  0x05,  0xF0,  0xD6,  0x06,  0x06,  0xF0,
        !          13930:   0xDC,  0x06,  0x09,  0xF0,  0x24,  0x09,  0x1E,  0xF0,  0xFC,  0x09,  0x00,  0xF0,  0x02,  0x0A,  0x04,  0x80,
        !          13931:   0x18,  0xE4,  0x20,  0x00,  0x30,  0x12,  0x09,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x21,  0x80,
        !          13932:   0x18,  0xE4,  0xE0,  0x00,  0x09,  0x48,  0x00,  0xF2,  0x12,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF2,
        !          13933:   0x12,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x99,  0xA4,  0x00,  0xF2,  0x12,  0x11,
        !          13934:   0x09,  0xE7,  0x00,  0x00,  0x9A,  0x10,  0x04,  0x80,  0x18,  0xE4,  0x02,  0x00,  0x34,  0x12,  0x09,  0xE7,
        !          13935:   0x1B,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x21,  0x80,  0x18,  0xE4,  0xE0,  0x00,  0x09,  0x48,  0x00,  0xF2,
        !          13936:   0x12,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF2,
        !          13937:   0x12,  0x11,  0x09,  0xE7,  0x01,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF0,
        !          13938:   0x0C,  0x09,  0xBB,  0x55,  0x9A,  0x81,  0x03,  0xF7,  0x20,  0x00,  0x09,  0x6F,  0x93,  0x45,  0x55,  0xF0,
        !          13939:   0xE2,  0x06,  0xB1,  0xF0,  0xC2,  0x06,  0x0A,  0xF0,  0xBA,  0x06,  0x09,  0xF0,  0x24,  0x09,  0x1E,  0xF0,
        !          13940:   0xFC,  0x09,  0x00,  0xF0,  0x02,  0x0A,  0x00,  0xF2,  0x60,  0x0B,  0x47,  0x10,  0x09,  0xE7,  0x08,  0x00,
        !          13941:   0x41,  0x10,  0x05,  0x80,  0x48,  0xE4,  0x00,  0x00,  0x1E,  0x12,  0x00,  0xE6,  0x11,  0x00,  0x00,  0xEA,
        !          13942:   0xB8,  0x00,  0x00,  0xF2,  0xB6,  0x10,  0x2C,  0x90,  0xAE,  0x90,  0x08,  0x50,  0x8A,  0x50,  0x38,  0x54,
        !          13943:   0x1F,  0x40,  0x00,  0xF2,  0xB4,  0x0D,  0x08,  0x10,  0x08,  0x90,  0x8A,  0x90,  0x30,  0x50,  0xB2,  0x50,
        !          13944:   0x9C,  0x32,  0x0C,  0x92,  0x8E,  0x92,  0x38,  0x54,  0x04,  0x80,  0x30,  0xE4,  0x08,  0x00,  0x04,  0x40,
        !          13945:   0x0C,  0x1C,  0x00,  0xF6,  0x03,  0x00,  0xB1,  0xF0,  0x26,  0x07,  0x9E,  0xF0,  0x3A,  0x07,  0x01,  0x48,
        !          13946:   0x55,  0xF0,  0xFC,  0x09,  0x0C,  0x1C,  0x10,  0x44,  0xED,  0x10,  0x0B,  0xF0,  0x5E,  0x07,  0x0C,  0xF0,
        !          13947:   0x62,  0x07,  0x05,  0xF0,  0x52,  0x07,  0x06,  0xF0,  0x58,  0x07,  0x09,  0xF0,  0x24,  0x09,  0x00,  0xF0,
        !          13948:   0x02,  0x0A,  0x00,  0xF2,  0x60,  0x0B,  0xCF,  0x10,  0x09,  0xE7,  0x08,  0x00,  0xC9,  0x10,  0x2E,  0x1C,
        !          13949:   0x02,  0x10,  0x2C,  0x1C,  0xAA,  0xF0,  0x64,  0x07,  0xAC,  0xF0,  0x72,  0x07,  0x40,  0x10,  0x34,  0x1C,
        !          13950:   0xF3,  0x10,  0xAD,  0xF0,  0x7C,  0x07,  0xC8,  0x10,  0x36,  0x1C,  0xE9,  0x10,  0x2B,  0xF0,  0x82,  0x08,
        !          13951:   0x6B,  0x18,  0x18,  0xF4,  0x00,  0xFE,  0x20,  0x12,  0x01,  0x58,  0xD2,  0xF0,  0x82,  0x08,  0x76,  0x18,
        !          13952:   0x18,  0xF4,  0x03,  0x00,  0xEC,  0x12,  0x00,  0xFC,  0x22,  0x01,  0x18,  0xF4,  0x01,  0x00,  0xE2,  0x12,
        !          13953:   0x0B,  0xF0,  0x64,  0x07,  0x0C,  0xF0,  0x64,  0x07,  0x36,  0x1C,  0x34,  0x1C,  0xB7,  0x10,  0x38,  0x54,
        !          13954:   0xB9,  0x54,  0x84,  0x80,  0x19,  0xE4,  0x20,  0x00,  0xB2,  0x13,  0x85,  0x80,  0x81,  0x48,  0x66,  0x12,
        !          13955:   0x04,  0x80,  0x18,  0xE4,  0x08,  0x00,  0x58,  0x13,  0x1F,  0x80,  0x08,  0x44,  0xC8,  0x44,  0x9F,  0x12,
        !          13956:   0x1F,  0x40,  0x34,  0x91,  0xB6,  0x91,  0x44,  0x55,  0xE5,  0x55,  0x02,  0xEC,  0xB8,  0x00,  0x02,  0x49,
        !          13957:   0xBB,  0x55,  0x82,  0x81,  0xC0,  0x55,  0x48,  0xF4,  0x0F,  0x00,  0x5A,  0xF0,  0x1A,  0x08,  0x4A,  0xE4,
        !          13958:   0x17,  0x00,  0xD5,  0xF0,  0xFA,  0x07,  0x02,  0xF6,  0x0F,  0x00,  0x02,  0xF4,  0x02,  0x00,  0x02,  0xEA,
        !          13959:   0xB8,  0x00,  0x04,  0x91,  0x86,  0x91,  0x02,  0x4B,  0x2C,  0x90,  0x08,  0x50,  0x2E,  0x90,  0x0A,  0x50,
        !          13960:   0x2C,  0x51,  0xAE,  0x51,  0x00,  0xF2,  0xB6,  0x10,  0x38,  0x54,  0x00,  0xF2,  0xB4,  0x0D,  0x56,  0x10,
        !          13961:   0x34,  0x91,  0xB6,  0x91,  0x0C,  0x10,  0x04,  0x80,  0x18,  0xE4,  0x08,  0x00,  0x41,  0x12,  0x0C,  0x91,
        !          13962:   0x8E,  0x91,  0x04,  0x80,  0x18,  0xE4,  0xF7,  0x00,  0x04,  0x40,  0x30,  0x90,  0xB2,  0x90,  0x36,  0x10,
        !          13963:   0x02,  0x80,  0x48,  0xE4,  0x10,  0x00,  0x31,  0x12,  0x82,  0xE7,  0x10,  0x00,  0x84,  0x80,  0x19,  0xE4,
        !          13964:   0x20,  0x00,  0x10,  0x13,  0x0C,  0x90,  0x8E,  0x90,  0x5D,  0xF0,  0x78,  0x07,  0x0C,  0x58,  0x8D,  0x58,
        !          13965:   0x00,  0xF0,  0x64,  0x07,  0x38,  0x54,  0xB9,  0x54,  0x19,  0x80,  0xF1,  0x10,  0x3A,  0x55,  0x19,  0x81,
        !          13966:   0xBB,  0x55,  0x10,  0x90,  0x92,  0x90,  0x10,  0x58,  0x91,  0x58,  0x14,  0x59,  0x95,  0x59,  0x00,  0xF0,
        !          13967:   0x64,  0x07,  0x04,  0x80,  0x18,  0xE4,  0x20,  0x00,  0x06,  0x12,  0x6C,  0x19,  0x19,  0x41,  0x7C,  0x10,
        !          13968:   0x6C,  0x19,  0x0C,  0x51,  0xED,  0x19,  0x8E,  0x51,  0x6B,  0x18,  0x18,  0xF4,  0x00,  0xFF,  0x02,  0x13,
        !          13969:   0x6A,  0x10,  0x01,  0x58,  0xD2,  0xF0,  0xC0,  0x08,  0x76,  0x18,  0x18,  0xF4,  0x03,  0x00,  0x0A,  0x12,
        !          13970:   0x00,  0xFC,  0x22,  0x01,  0x18,  0xF4,  0x01,  0x00,  0x06,  0x13,  0x9E,  0xE7,  0x16,  0x00,  0x4C,  0x10,
        !          13971:   0xD1,  0xF0,  0xCA,  0x08,  0x9E,  0xE7,  0x17,  0x00,  0x42,  0x10,  0xD0,  0xF0,  0xD4,  0x08,  0x9E,  0xE7,
        !          13972:   0x19,  0x00,  0x38,  0x10,  0xCF,  0xF0,  0xDE,  0x08,  0x9E,  0xE7,  0x20,  0x00,  0x2E,  0x10,  0xCE,  0xF0,
        !          13973:   0xE8,  0x08,  0x9E,  0xE7,  0x21,  0x00,  0x24,  0x10,  0xCD,  0xF0,  0xF2,  0x08,  0x9E,  0xE7,  0x22,  0x00,
        !          13974:   0x1A,  0x10,  0xCC,  0xF0,  0x04,  0x09,  0x84,  0x80,  0x19,  0xE4,  0x04,  0x00,  0x06,  0x12,  0x9E,  0xE7,
        !          13975:   0x12,  0x00,  0x08,  0x10,  0xCB,  0xF0,  0x0C,  0x09,  0x9E,  0xE7,  0x24,  0x00,  0xB1,  0xF0,  0x0C,  0x09,
        !          13976:   0x05,  0xF0,  0x1E,  0x09,  0x09,  0xF0,  0x24,  0x09,  0x1E,  0xF0,  0xFC,  0x09,  0xE4,  0x10,  0x00,  0xF2,
        !          13977:   0x60,  0x0B,  0xE9,  0x10,  0x9C,  0x32,  0x82,  0xE7,  0x20,  0x00,  0x32,  0x1C,  0xE9,  0x09,  0x00,  0xF2,
        !          13978:   0x12,  0x11,  0x85,  0xF0,  0x02,  0x0A,  0x69,  0x08,  0x01,  0xF0,  0x44,  0x09,  0x1E,  0xF0,  0xFC,  0x09,
        !          13979:   0x00,  0xF0,  0x38,  0x09,  0x30,  0x44,  0x06,  0x12,  0x9E,  0xE7,  0x42,  0x00,  0xB8,  0x10,  0x04,  0xF6,
        !          13980:   0x01,  0x00,  0xB3,  0x45,  0x74,  0x12,  0x04,  0x80,  0x18,  0xE4,  0x20,  0x00,  0x22,  0x13,  0x4B,  0xE4,
        !          13981:   0x02,  0x00,  0x36,  0x12,  0x4B,  0xE4,  0x28,  0x00,  0xAC,  0x13,  0x00,  0xF2,  0xBC,  0x11,  0x00,  0xF2,
        !          13982:   0xC8,  0x11,  0x03,  0xF6,  0xD0,  0x00,  0xFA,  0x14,  0x82,  0xE7,  0x01,  0x00,  0x00,  0xF0,  0x80,  0x01,
        !          13983:   0x9E,  0xE7,  0x44,  0x00,  0x4B,  0xE4,  0x02,  0x00,  0x06,  0x12,  0x03,  0xE6,  0x02,  0x00,  0x76,  0x10,
        !          13984:   0x00,  0xF2,  0xA2,  0x0D,  0x03,  0xE6,  0x02,  0x00,  0x6C,  0x10,  0x00,  0xF2,  0xA2,  0x0D,  0x19,  0x82,
        !          13985:   0x34,  0x46,  0x0A,  0x13,  0x03,  0xE6,  0x02,  0x00,  0x9E,  0xE7,  0x43,  0x00,  0x68,  0x10,  0x04,  0x80,
        !          13986:   0x30,  0xE4,  0x20,  0x00,  0x04,  0x40,  0x00,  0xF2,  0xBC,  0x11,  0x00,  0xF2,  0xC8,  0x11,  0x82,  0xE7,
        !          13987:   0x01,  0x00,  0x06,  0xF7,  0x02,  0x00,  0x00,  0xF0,  0x08,  0x03,  0x04,  0x80,  0x18,  0xE4,  0x20,  0x00,
        !          13988:   0x06,  0x12,  0x03,  0xE6,  0x02,  0x00,  0x3E,  0x10,  0x04,  0x80,  0x18,  0xE4,  0x02,  0x00,  0x3A,  0x12,
        !          13989:   0x04,  0x80,  0x18,  0xE4,  0xFD,  0x00,  0x04,  0x40,  0x1C,  0x1C,  0x9D,  0xF0,  0xEA,  0x09,  0x1C,  0x1C,
        !          13990:   0x9D,  0xF0,  0xF0,  0x09,  0xC1,  0x10,  0x9E,  0xE7,  0x13,  0x00,  0x0A,  0x10,  0x9E,  0xE7,  0x41,  0x00,
        !          13991:   0x04,  0x10,  0x9E,  0xE7,  0x24,  0x00,  0x00,  0xFC,  0xBE,  0x00,  0x98,  0x57,  0xD5,  0xF0,  0x8A,  0x02,
        !          13992:   0x04,  0xE6,  0x04,  0x00,  0x06,  0x10,  0x04,  0xE6,  0x04,  0x00,  0x9D,  0x41,  0x1C,  0x42,  0x9F,  0xE7,
        !          13993:   0x00,  0x00,  0x06,  0xF7,  0x02,  0x00,  0x03,  0xF6,  0xE0,  0x00,  0x3C,  0x14,  0x44,  0x58,  0x45,  0x58,
        !          13994:   0x00,  0xF2,  0xF6,  0x0D,  0x00,  0xF2,  0x7E,  0x10,  0x00,  0xF2,  0xC6,  0x0F,  0x3C,  0x14,  0x1E,  0x1C,
        !          13995:   0x00,  0xF0,  0x80,  0x01,  0x12,  0x1C,  0x22,  0x1C,  0xD2,  0x14,  0x00,  0xF0,  0x72,  0x01,  0x83,  0x59,
        !          13996:   0x03,  0xDC,  0x73,  0x57,  0x80,  0x5D,  0x00,  0x16,  0x83,  0x59,  0x03,  0xDC,  0x38,  0x54,  0x70,  0x57,
        !          13997:   0x33,  0x54,  0x3B,  0x54,  0x80,  0x5D,  0x00,  0x16,  0x03,  0x57,  0x83,  0x59,  0x38,  0x54,  0x00,  0xCC,
        !          13998:   0x00,  0x16,  0x03,  0x57,  0x83,  0x59,  0x00,  0x4C,  0x00,  0x16,  0x02,  0x80,  0x48,  0xE4,  0x01,  0x00,
        !          13999:   0x0E,  0x12,  0x48,  0xE4,  0x05,  0x00,  0x08,  0x12,  0x00,  0xF2,  0xBC,  0x11,  0x00,  0xF2,  0xC8,  0x11,
        !          14000:   0xC1,  0x5A,  0x3A,  0x55,  0x02,  0xEC,  0xB5,  0x00,  0x45,  0x59,  0x00,  0xF2,  0xF6,  0x0D,  0x83,  0x58,
        !          14001:   0x30,  0xE7,  0x00,  0x00,  0x10,  0x4D,  0x30,  0xE7,  0x40,  0x00,  0x10,  0x4F,  0x38,  0x90,  0xBA,  0x90,
        !          14002:   0x10,  0x5C,  0x80,  0x5C,  0x83,  0x5A,  0x10,  0x4E,  0x04,  0xEA,  0xB5,  0x00,  0x43,  0x5B,  0x03,  0xF4,
        !          14003:   0xE0,  0x00,  0x83,  0x59,  0x04,  0xCC,  0x01,  0x4A,  0x0A,  0x12,  0x45,  0x5A,  0x00,  0xF2,  0xF6,  0x0D,
        !          14004:   0x00,  0xF2,  0x38,  0x10,  0x00,  0x16,  0x08,  0x1C,  0x00,  0xFC,  0xAC,  0x00,  0x06,  0x58,  0x67,  0x18,
        !          14005:   0x18,  0xF4,  0x8F,  0xE1,  0x01,  0xFC,  0xAE,  0x00,  0x19,  0xF4,  0x70,  0x1E,  0xB0,  0x54,  0x07,  0x58,
        !          14006:   0x00,  0xFC,  0xB0,  0x00,  0x08,  0x58,  0x00,  0xFC,  0xB2,  0x00,  0x09,  0x58,  0x0A,  0x1C,  0x00,  0xE6,
        !          14007:   0x0F,  0x00,  0x00,  0xEA,  0xB9,  0x00,  0x38,  0x54,  0x00,  0xFA,  0x24,  0x01,  0x00,  0xFA,  0xB6,  0x00,
        !          14008:   0x18,  0x1C,  0x14,  0x1C,  0x10,  0x1C,  0x32,  0x1C,  0x12,  0x1C,  0x00,  0x16,  0x3E,  0x57,  0x0C,  0x14,
        !          14009:   0x0E,  0x47,  0x07,  0xE6,  0x10,  0x00,  0xCE,  0x47,  0xF5,  0x13,  0x00,  0x16,  0x00,  0xF2,  0xA2,  0x0D,
        !          14010:   0x02,  0x4B,  0x03,  0xF6,  0xE0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x01,  0x48,  0x20,  0x12,  0x44,  0x58,
        !          14011:   0x45,  0x58,  0x9E,  0xE7,  0x15,  0x00,  0x9C,  0xE7,  0x04,  0x00,  0x00,  0xF2,  0xF6,  0x0D,  0x00,  0xF2,
        !          14012:   0x7E,  0x10,  0x00,  0xF2,  0xC6,  0x0F,  0x00,  0xF2,  0x7A,  0x0A,  0x1E,  0x1C,  0xD5,  0x10,  0x00,  0x16,
        !          14013:   0x69,  0x08,  0x48,  0xE4,  0x04,  0x00,  0x64,  0x12,  0x48,  0xE4,  0x02,  0x00,  0x20,  0x12,  0x48,  0xE4,
        !          14014:   0x03,  0x00,  0x1A,  0x12,  0x48,  0xE4,  0x08,  0x00,  0x14,  0x12,  0x48,  0xE4,  0x01,  0x00,  0xF0,  0x12,
        !          14015:   0x48,  0xE4,  0x07,  0x00,  0x12,  0x12,  0x01,  0xE6,  0x07,  0x00,  0x00,  0xF2,  0x4E,  0x0D,  0x00,  0xF2,
        !          14016:   0x12,  0x11,  0x05,  0xF0,  0x60,  0x0B,  0x00,  0x16,  0x00,  0xE6,  0x01,  0x00,  0x00,  0xEA,  0x99,  0x00,
        !          14017:   0x02,  0x80,  0x48,  0xE4,  0x03,  0x00,  0xE7,  0x12,  0x48,  0xE4,  0x06,  0x00,  0xE1,  0x12,  0x01,  0xE6,
        !          14018:   0x06,  0x00,  0x00,  0xF2,  0x4E,  0x0D,  0x00,  0xF2,  0x12,  0x11,  0x04,  0xE6,  0x02,  0x00,  0x9E,  0xE7,
        !          14019:   0x15,  0x00,  0x01,  0xF0,  0x1C,  0x0A,  0x00,  0xF0,  0x02,  0x0A,  0x00,  0x16,  0x02,  0x80,  0x48,  0xE4,
        !          14020:   0x10,  0x00,  0x1C,  0x12,  0x82,  0xE7,  0x08,  0x00,  0x3C,  0x56,  0x03,  0x82,  0x00,  0xF2,  0xE2,  0x0D,
        !          14021:   0x30,  0xE7,  0x08,  0x00,  0x04,  0xF7,  0x70,  0x01,  0x06,  0xF7,  0x02,  0x00,  0x00,  0xF0,  0x80,  0x01,
        !          14022:   0x6C,  0x19,  0xED,  0x19,  0x5D,  0xF0,  0xD4,  0x0B,  0x44,  0x55,  0xE5,  0x55,  0x59,  0xF0,  0x52,  0x0C,
        !          14023:   0x04,  0x55,  0xA5,  0x55,  0x1F,  0x80,  0x01,  0xEC,  0xB8,  0x00,  0x82,  0x48,  0x82,  0x80,  0x49,  0x44,
        !          14024:   0x2E,  0x13,  0x01,  0xEC,  0xB8,  0x00,  0x41,  0xE4,  0x02,  0x00,  0x01,  0xEA,  0xB8,  0x00,  0x49,  0xE4,
        !          14025:   0x11,  0x00,  0x59,  0xF0,  0x2E,  0x0C,  0x01,  0xE6,  0x17,  0x00,  0x01,  0xEA,  0xB8,  0x00,  0x02,  0x4B,
        !          14026:   0x88,  0x90,  0xAC,  0x50,  0x8A,  0x90,  0xAE,  0x50,  0x01,  0xEC,  0xB8,  0x00,  0x82,  0x48,  0x82,  0x80,
        !          14027:   0x10,  0x44,  0x02,  0x4B,  0x1F,  0x40,  0xC0,  0x44,  0x00,  0xF2,  0xB4,  0x0D,  0x04,  0x55,  0xA5,  0x55,
        !          14028:   0x9F,  0x10,  0x0C,  0x51,  0x8E,  0x51,  0x30,  0x90,  0xB2,  0x90,  0x00,  0x56,  0xA1,  0x56,  0x30,  0x50,
        !          14029:   0xB2,  0x50,  0x34,  0x90,  0xB6,  0x90,  0x40,  0x56,  0xE1,  0x56,  0x34,  0x50,  0xB6,  0x50,  0x65,  0x10,
        !          14030:   0xB1,  0xF0,  0x70,  0x0C,  0x85,  0xF0,  0xCA,  0x0B,  0xE9,  0x09,  0x4B,  0xE4,  0x03,  0x00,  0x78,  0x12,
        !          14031:   0x4B,  0xE4,  0x02,  0x00,  0x01,  0x13,  0xB1,  0xF0,  0x86,  0x0C,  0x85,  0xF0,  0xCA,  0x0B,  0x69,  0x08,
        !          14032:   0x48,  0xE4,  0x03,  0x00,  0xD5,  0xF0,  0x86,  0x0B,  0x00,  0xF2,  0x12,  0x11,  0x85,  0xF0,  0xCA,  0x0B,
        !          14033:   0xE8,  0x09,  0x3C,  0x56,  0x00,  0xFC,  0x20,  0x01,  0x98,  0x57,  0x02,  0x13,  0xBB,  0x45,  0x4B,  0xE4,
        !          14034:   0x00,  0x00,  0x08,  0x12,  0x03,  0xE6,  0x01,  0x00,  0x04,  0xF6,  0x00,  0x80,  0xA8,  0x14,  0xD2,  0x14,
        !          14035:   0x30,  0x1C,  0x02,  0x80,  0x48,  0xE4,  0x03,  0x00,  0x10,  0x13,  0x00,  0xFC,  0xB6,  0x00,  0x98,  0x57,
        !          14036:   0x02,  0x13,  0x4C,  0x1C,  0x3E,  0x1C,  0x00,  0xF0,  0x8E,  0x0B,  0x00,  0xFC,  0x24,  0x01,  0xB0,  0x57,
        !          14037:   0x00,  0xFA,  0x24,  0x01,  0x4C,  0x1C,  0x3E,  0x1C,  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0x8E,  0x0B,
        !          14038:   0x00,  0xF2,  0x8C,  0x0E,  0x00,  0xF0,  0x8E,  0x0B,  0xB1,  0xF0,  0xF8,  0x0C,  0x85,  0xF0,  0x86,  0x0B,
        !          14039:   0x69,  0x08,  0x48,  0xE4,  0x01,  0x00,  0xD5,  0xF0,  0x86,  0x0B,  0xFC,  0x14,  0x42,  0x58,  0x6C,  0x14,
        !          14040:   0x80,  0x14,  0x30,  0x1C,  0x4A,  0xF4,  0x02,  0x00,  0x55,  0xF0,  0x86,  0x0B,  0x4A,  0xF4,  0x01,  0x00,
        !          14041:   0x0E,  0x12,  0x02,  0x80,  0x48,  0xE4,  0x03,  0x00,  0x06,  0x13,  0x3E,  0x1C,  0x00,  0xF0,  0x8E,  0x0B,
        !          14042:   0x00,  0xFC,  0xB6,  0x00,  0xB0,  0x57,  0x00,  0xFA,  0xB6,  0x00,  0x4C,  0x1C,  0x3E,  0x1C,  0x00,  0xF2,
        !          14043:   0x12,  0x11,  0x86,  0xF0,  0x8E,  0x0B,  0x00,  0xF2,  0xBA,  0x0E,  0x00,  0xF0,  0x8E,  0x0B,  0x4C,  0x1C,
        !          14044:   0xB1,  0xF0,  0x50,  0x0D,  0x85,  0xF0,  0x5C,  0x0D,  0x69,  0x08,  0xF3,  0x10,  0x86,  0xF0,  0x64,  0x0D,
        !          14045:   0x4E,  0x1C,  0x89,  0x48,  0x00,  0x16,  0x00,  0xF6,  0x00,  0x01,  0x00,  0x57,  0x00,  0x57,  0x03,  0x58,
        !          14046:   0x00,  0xDC,  0x18,  0xF4,  0xFF,  0x7F,  0x30,  0x56,  0x00,  0x5C,  0x00,  0x16,  0x00,  0xF6,  0x00,  0x01,
        !          14047:   0x00,  0x57,  0x00,  0x57,  0x03,  0x58,  0x00,  0xDC,  0x18,  0xF4,  0x00,  0x80,  0x30,  0x56,  0x00,  0x5C,
        !          14048:   0x00,  0x16,  0x00,  0xF6,  0x00,  0x01,  0x00,  0x57,  0x00,  0x57,  0x03,  0x58,  0x00,  0xDC,  0x0B,  0x58,
        !          14049:   0x00,  0x16,  0x03,  0xF6,  0x24,  0x01,  0x00,  0xF2,  0x58,  0x0A,  0x03,  0xF6,  0xB6,  0x00,  0x00,  0xF2,
        !          14050:   0x58,  0x0A,  0x00,  0x16,  0x02,  0xEC,  0xB8,  0x00,  0x02,  0x49,  0x18,  0xF4,  0xFF,  0x00,  0x00,  0x54,
        !          14051:   0x00,  0x54,  0x00,  0x54,  0x00,  0xF4,  0x08,  0x00,  0xE1,  0x18,  0x80,  0x54,  0x03,  0x58,  0x00,  0xDD,
        !          14052:   0x01,  0xDD,  0x02,  0xDD,  0x03,  0xDC,  0x02,  0x4B,  0x30,  0x50,  0xB2,  0x50,  0x34,  0x51,  0xB6,  0x51,
        !          14053:   0x00,  0x16,  0x45,  0x5A,  0x1D,  0xF4,  0xFF,  0x00,  0x85,  0x56,  0x85,  0x56,  0x85,  0x56,  0x05,  0xF4,
        !          14054:   0x02,  0x12,  0x83,  0x5A,  0x00,  0x16,  0x1D,  0xF4,  0xFF,  0x00,  0x85,  0x56,  0x85,  0x56,  0x85,  0x56,
        !          14055:   0x05,  0xF4,  0x00,  0x12,  0x83,  0x5A,  0x00,  0x16,  0x38,  0x54,  0xBB,  0x55,  0x3C,  0x56,  0xBD,  0x56,
        !          14056:   0x00,  0xF2,  0x12,  0x11,  0x85,  0xF0,  0x82,  0x0E,  0xE9,  0x09,  0xC1,  0x59,  0x00,  0xF2,  0x12,  0x11,
        !          14057:   0x85,  0xF0,  0x82,  0x0E,  0xE8,  0x0A,  0x83,  0x55,  0x83,  0x55,  0x4B,  0xF4,  0x90,  0x01,  0x5C,  0xF0,
        !          14058:   0x36,  0x0E,  0xBD,  0x56,  0x40,  0x10,  0x4B,  0xF4,  0x30,  0x00,  0x59,  0xF0,  0x48,  0x0E,  0x01,  0xF6,
        !          14059:   0x0C,  0x00,  0x00,  0xF6,  0x01,  0x00,  0x2E,  0x10,  0x02,  0xFC,  0x9C,  0x00,  0x9A,  0x57,  0x14,  0x13,
        !          14060:   0x4B,  0xF4,  0x64,  0x00,  0x59,  0xF0,  0x64,  0x0E,  0x03,  0xF6,  0x64,  0x00,  0x01,  0xF6,  0x19,  0x00,
        !          14061:   0x00,  0xF6,  0x01,  0x00,  0x43,  0xF4,  0x33,  0x00,  0x56,  0xF0,  0x76,  0x0E,  0x04,  0xF4,  0x00,  0x01,
        !          14062:   0x43,  0xF4,  0x19,  0x00,  0xF3,  0x10,  0xB4,  0x56,  0xC3,  0x58,  0x02,  0xFC,  0x9E,  0x00,  0x9A,  0x57,
        !          14063:   0x08,  0x13,  0x3C,  0x56,  0x00,  0xF6,  0x02,  0x00,  0x00,  0x16,  0x00,  0x16,  0x09,  0xE7,  0x01,  0x00,
        !          14064:   0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0xB8,  0x0E,  0x09,  0xE7,  0x02,  0x00,  0x00,  0xF2,  0x12,  0x11,
        !          14065:   0x86,  0xF0,  0xB8,  0x0E,  0x09,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0xB8,  0x0E,
        !          14066:   0x4E,  0x1C,  0x89,  0x49,  0x00,  0xF2,  0x12,  0x11,  0x00,  0x16,  0x09,  0xE7,  0x01,  0x00,  0x00,  0xF2,
        !          14067:   0x12,  0x11,  0x86,  0xF0,  0xF2,  0x0E,  0x09,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,
        !          14068:   0xF2,  0x0E,  0x09,  0xE7,  0x01,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0xF2,  0x0E,  0x89,  0x49,
        !          14069:   0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0xF2,  0x0E,  0x4E,  0x1C,  0x89,  0x4A,  0x00,  0xF2,  0x12,  0x11,
        !          14070:   0x00,  0x16,  0x3C,  0x56,  0x00,  0x16,  0x00,  0xEC,  0x26,  0x01,  0x48,  0xE4,  0x01,  0x00,  0x1E,  0x13,
        !          14071:   0x38,  0x44,  0x00,  0xEA,  0x26,  0x01,  0x49,  0xF4,  0x00,  0x00,  0x04,  0x12,  0x4E,  0x1C,  0x02,  0x10,
        !          14072:   0x4C,  0x1C,  0x01,  0xEC,  0x27,  0x01,  0x89,  0x48,  0x00,  0xF2,  0x12,  0x11,  0x02,  0x14,  0x00,  0x16,
        !          14073:   0x85,  0xF0,  0x52,  0x0F,  0x38,  0x54,  0x00,  0xEA,  0x99,  0x00,  0x00,  0xF2,  0x60,  0x0B,  0x02,  0x80,
        !          14074:   0x48,  0xE4,  0x06,  0x00,  0x1C,  0x13,  0x00,  0xEC,  0x99,  0x00,  0x48,  0xE4,  0x01,  0x00,  0x0A,  0x12,
        !          14075:   0x04,  0x80,  0x30,  0xE4,  0x01,  0x00,  0x04,  0x40,  0x08,  0x10,  0x04,  0x80,  0x18,  0xE4,  0xFE,  0x00,
        !          14076:   0x04,  0x40,  0x00,  0x16,  0x02,  0xF6,  0xE0,  0x00,  0x02,  0x57,  0x03,  0x59,  0x01,  0xCC,  0x81,  0x48,
        !          14077:   0x22,  0x12,  0x00,  0x4E,  0x83,  0x5A,  0x90,  0x4C,  0x20,  0xE7,  0x00,  0x00,  0xC3,  0x58,  0x1B,  0xF4,
        !          14078:   0xFF,  0x00,  0x83,  0x55,  0x83,  0x55,  0x83,  0x55,  0x03,  0xF4,  0x00,  0x12,  0x8B,  0x55,  0x83,  0x59,
        !          14079:   0x00,  0x4E,  0x00,  0x16,  0x00,  0x4E,  0x02,  0xF6,  0xF0,  0x00,  0x02,  0x57,  0x03,  0x59,  0x00,  0x4E,
        !          14080:   0x83,  0x5A,  0x30,  0xE7,  0x00,  0x00,  0x20,  0xE7,  0x00,  0x00,  0x00,  0x16,  0x02,  0xF6,  0xF0,  0x00,
        !          14081:   0x02,  0x57,  0x03,  0x59,  0x01,  0xCC,  0x00,  0x4E,  0x83,  0x5A,  0x30,  0xE7,  0x00,  0x00,  0x80,  0x4C,
        !          14082:   0xC3,  0x58,  0x1B,  0xF4,  0xFF,  0x00,  0x83,  0x55,  0x83,  0x55,  0x83,  0x55,  0x03,  0xF4,  0x00,  0x12,
        !          14083:   0x83,  0x59,  0x00,  0x4E,  0x00,  0x16,  0x03,  0xF6,  0xE0,  0x00,  0x03,  0x57,  0x83,  0x59,  0x3A,  0x55,
        !          14084:   0x02,  0xCC,  0x45,  0x5A,  0x00,  0xF2,  0xF6,  0x0D,  0xC0,  0x5A,  0x40,  0x5C,  0x38,  0x54,  0x00,  0xCD,
        !          14085:   0x01,  0xCC,  0x4A,  0x46,  0x0A,  0x13,  0x83,  0x59,  0x00,  0x4C,  0x01,  0x48,  0x16,  0x13,  0x0C,  0x10,
        !          14086:   0xC5,  0x58,  0x00,  0xF2,  0xF6,  0x0D,  0x00,  0x4C,  0x01,  0x48,  0x08,  0x13,  0x05,  0xF6,  0xF0,  0x00,
        !          14087:   0x05,  0x57,  0x08,  0x10,  0x45,  0x58,  0x00,  0xF2,  0xF6,  0x0D,  0x8D,  0x56,  0x83,  0x5A,  0x80,  0x4C,
        !          14088:   0x05,  0x17,  0x00,  0x16,  0x02,  0x4B,  0x06,  0xF7,  0x04,  0x00,  0x62,  0x0B,  0x03,  0x82,  0x00,  0xF2,
        !          14089:   0xE2,  0x0D,  0x02,  0x80,  0x00,  0x4C,  0x45,  0xF4,  0x02,  0x00,  0x52,  0x14,  0x06,  0xF7,  0x02,  0x00,
        !          14090:   0x06,  0x14,  0x00,  0xF2,  0x54,  0x0F,  0x00,  0x16,  0x02,  0x4B,  0x01,  0xF6,  0xFF,  0x00,  0x38,  0x1C,
        !          14091:   0x05,  0xF4,  0x04,  0x00,  0x83,  0x5A,  0x18,  0xDF,  0x19,  0xDF,  0x1D,  0xF7,  0x3C,  0x00,  0xB8,  0xF0,
        !          14092:   0x4E,  0x10,  0x9C,  0x14,  0x01,  0x48,  0x1C,  0x13,  0x0E,  0xF7,  0x3C,  0x00,  0x03,  0xF7,  0x04,  0x00,
        !          14093:   0xAF,  0x19,  0x03,  0x42,  0x45,  0xF4,  0x02,  0x00,  0x83,  0x5A,  0x02,  0xCC,  0x02,  0x41,  0x45,  0xF4,
        !          14094:   0x02,  0x00,  0x00,  0x16,  0x91,  0x44,  0xD5,  0xF0,  0x3E,  0x10,  0x00,  0xF0,  0x9E,  0x02,  0x01,  0xF6,
        !          14095:   0xFF,  0x00,  0x38,  0x1C,  0x05,  0xF4,  0x04,  0x00,  0x83,  0x5A,  0x18,  0xDF,  0x19,  0xDF,  0x0E,  0xF7,
        !          14096:   0x3C,  0x00,  0x03,  0xF7,  0x04,  0x00,  0x0F,  0x79,  0x1C,  0xF7,  0x3C,  0x00,  0xB8,  0xF0,  0x9C,  0x10,
        !          14097:   0x4E,  0x14,  0x01,  0x48,  0x06,  0x13,  0x45,  0xF4,  0x04,  0x00,  0x00,  0x16,  0x91,  0x44,  0xD5,  0xF0,
        !          14098:   0x82,  0x10,  0x00,  0xF0,  0x9E,  0x02,  0x02,  0xF6,  0xFF,  0x00,  0x38,  0x1C,  0x2C,  0xBC,  0xAE,  0xBC,
        !          14099:   0xE2,  0x08,  0x00,  0xEC,  0xB8,  0x00,  0x02,  0x48,  0x1D,  0xF7,  0x80,  0x00,  0xB8,  0xF0,  0xCC,  0x10,
        !          14100:   0x1E,  0x14,  0x01,  0x48,  0x0E,  0x13,  0x0E,  0xF7,  0x80,  0x00,  0x38,  0x54,  0x03,  0x58,  0xAF,  0x19,
        !          14101:   0x82,  0x48,  0x00,  0x16,  0x82,  0x48,  0x12,  0x45,  0xD5,  0xF0,  0xBA,  0x10,  0x00,  0xF0,  0x9E,  0x02,
        !          14102:   0x39,  0xF0,  0xF8,  0x10,  0x38,  0x44,  0x00,  0x16,  0x7E,  0x18,  0x18,  0xF4,  0x03,  0x00,  0x04,  0x13,
        !          14103:   0x61,  0x18,  0x00,  0x16,  0x38,  0x1C,  0x00,  0xFC,  0x22,  0x01,  0x18,  0xF4,  0x01,  0x00,  0xF1,  0x12,
        !          14104:   0xE3,  0x10,  0x30,  0x44,  0x30,  0x44,  0x30,  0x44,  0xB1,  0xF0,  0x18,  0x11,  0x00,  0x16,  0x3E,  0x57,
        !          14105:   0x03,  0xF6,  0xE0,  0x00,  0x03,  0x57,  0x83,  0x59,  0x04,  0xCC,  0x01,  0x4A,  0x6A,  0x12,  0x45,  0x5A,
        !          14106:   0x00,  0xF2,  0xF6,  0x0D,  0x02,  0x4B,  0x70,  0x14,  0x34,  0x13,  0x02,  0x80,  0x48,  0xE4,  0x08,  0x00,
        !          14107:   0x18,  0x12,  0x9C,  0xE7,  0x02,  0x00,  0x9E,  0xE7,  0x15,  0x00,  0x00,  0xF2,  0xC6,  0x0F,  0x00,  0xF2,
        !          14108:   0x7A,  0x0A,  0x1E,  0x1C,  0x01,  0xF6,  0x01,  0x00,  0x00,  0x16,  0x30,  0xE4,  0x10,  0x00,  0x04,  0x40,
        !          14109:   0x00,  0xF2,  0xE2,  0x0D,  0x20,  0xE7,  0x01,  0x00,  0x01,  0xF6,  0x01,  0x00,  0x00,  0x16,  0x04,  0xDC,
        !          14110:   0x01,  0x4A,  0x24,  0x12,  0x45,  0x5A,  0x00,  0xF2,  0xF6,  0x0D,  0x43,  0x5B,  0x06,  0xEC,  0x98,  0x00,
        !          14111:   0x00,  0xF2,  0x38,  0x10,  0xC6,  0x59,  0x20,  0x14,  0x0A,  0x13,  0x00,  0xF2,  0xC6,  0x0F,  0x00,  0xF2,
        !          14112:   0x14,  0x10,  0xA7,  0x10,  0x83,  0x5A,  0xD7,  0x10,  0x0E,  0x47,  0x07,  0xE6,  0x10,  0x00,  0xCE,  0x47,
        !          14113:   0x5A,  0xF0,  0x20,  0x11,  0xB9,  0x54,  0x00,  0x16,  0x14,  0x90,  0x96,  0x90,  0x02,  0xFC,  0xA8,  0x00,
        !          14114:   0x03,  0xFC,  0xAA,  0x00,  0x48,  0x55,  0x02,  0x13,  0xC9,  0x55,  0x00,  0x16,  0x00,  0xEC,  0xBA,  0x00,
        !          14115:   0x10,  0x44,  0x00,  0xEA,  0xBA,  0x00,  0x00,  0x16,  0x03,  0xF6,  0xC0,  0x00,  0x00,  0xF2,  0x68,  0x0A,
        !          14116:   0x10,  0x44,  0x00,  0x4C,  0x00,  0x16
        !          14117: };
        !          14118: 
        !          14119: unsigned short _adv_mcode_size ASC_INITDATA =
        !          14120:     sizeof(_adv_mcode_buf); /* 0x11D6 */
        !          14121: unsigned long  _adv_mcode_chksum ASC_INITDATA = 0x03494981UL;
        !          14122: 
        !          14123: /* a_init.c */
        !          14124: /*
        !          14125:  * EEPROM Configuration.
        !          14126:  *
        !          14127:  * All drivers should use this structure to set the default EEPROM
        !          14128:  * configuration. The BIOS now uses this structure when it is built.
        !          14129:  * Additional structure information can be found in a_condor.h where
        !          14130:  * the structure is defined.
        !          14131:  */
        !          14132: STATIC ADVEEP_CONFIG
        !          14133: Default_EEPROM_Config ASC_INITDATA = {
        !          14134:     ADV_EEPROM_BIOS_ENABLE,     /* cfg_msw */
        !          14135:     0x0000,                     /* cfg_lsw */
        !          14136:     0xFFFF,                     /* disc_enable */
        !          14137:     0xFFFF,                     /* wdtr_able */
        !          14138:     0xFFFF,                     /* sdtr_able */
        !          14139:     0xFFFF,                     /* start_motor */
        !          14140:     0xFFFF,                     /* tagqng_able */
        !          14141:     0xFFFF,                     /* bios_scan */
        !          14142:     0,                          /* scam_tolerant */
        !          14143:     7,                          /* adapter_scsi_id */
        !          14144:     0,                          /* bios_boot_delay */
        !          14145:     3,                          /* scsi_reset_delay */
        !          14146:     0,                          /* bios_id_lun */
        !          14147:     0,                          /* termination */
        !          14148:     0,                          /* reserved1 */
        !          14149:     0xFFEF,                     /* bios_ctrl */
        !          14150:     0xFFFF,                     /* ultra_able */
        !          14151:     0,                          /* reserved2 */
        !          14152:     ASC_DEF_MAX_HOST_QNG,       /* max_host_qng */
        !          14153:     ASC_DEF_MAX_DVC_QNG,        /* max_dvc_qng */
        !          14154:     0,                          /* dvc_cntl */
        !          14155:     0,                          /* bug_fix */
        !          14156:     0,                          /* serial_number_word1 */
        !          14157:     0,                          /* serial_number_word2 */
        !          14158:     0,                          /* serial_number_word3 */
        !          14159:     0,                          /* check_sum */
        !          14160:     { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* oem_name[16] */
        !          14161:     0,                          /* dvc_err_code */
        !          14162:     0,                          /* adv_err_code */
        !          14163:     0,                          /* adv_err_addr */
        !          14164:     0,                          /* saved_dvc_err_code */
        !          14165:     0,                          /* saved_adv_err_code */
        !          14166:     0,                          /* saved_adv_err_addr */
        !          14167:     0                           /* num_of_err */
        !          14168: };
        !          14169: 
        !          14170: /*
        !          14171:  * Initialize the ADV_DVC_VAR structure.
        !          14172:  *
        !          14173:  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
        !          14174:  *
        !          14175:  * For a non-fatal error return a warning code. If there are no warnings
        !          14176:  * then 0 is returned.
        !          14177:  */
        !          14178: ASC_INITFUNC(
        !          14179: int
        !          14180: AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
        !          14181: )
        !          14182: {
        !          14183:     ushort      warn_code;
        !          14184:     AdvPortAddr iop_base;
        !          14185:     uchar       pci_cmd_reg;
        !          14186:     int         status;
        !          14187: 
        !          14188:     warn_code = 0;
        !          14189:     asc_dvc->err_code = 0;
        !          14190:     iop_base = asc_dvc->iop_base;
        !          14191: 
        !          14192:     /*
        !          14193:      * PCI Command Register
        !          14194:      */
        !          14195: 
        !          14196:     if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc,
        !          14197:                             AscPCIConfigCommandRegister))
        !          14198:          & AscPCICmdRegBits_BusMastering)
        !          14199:         != AscPCICmdRegBits_BusMastering)
        !          14200:     {
        !          14201:         pci_cmd_reg |= AscPCICmdRegBits_BusMastering;
        !          14202: 
        !          14203:         DvcAdvWritePCIConfigByte(asc_dvc,
        !          14204:                 AscPCIConfigCommandRegister, pci_cmd_reg);
        !          14205: 
        !          14206:         if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister))
        !          14207:              & AscPCICmdRegBits_BusMastering)
        !          14208:             != AscPCICmdRegBits_BusMastering)
        !          14209:         {
        !          14210:             warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
        !          14211:         }
        !          14212:     }
        !          14213: 
        !          14214:     /*
        !          14215:      * PCI Latency Timer
        !          14216:      *
        !          14217:      * If the "latency timer" register is 0x20 or above, then we don't need
        !          14218:      * to change it.  Otherwise, set it to 0x20 (i.e. set it to 0x20 if it
        !          14219:      * comes up less than 0x20).
        !          14220:      */
        !          14221:     if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) {
        !          14222:         DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer, 0x20);
        !          14223:         if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20)
        !          14224:         {
        !          14225:             warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
        !          14226:         }
        !          14227:     }
        !          14228: 
        !          14229:     /*
        !          14230:      * Save the state of the PCI Configuration Command Register
        !          14231:      * "Parity Error Response Control" Bit. If the bit is clear (0),
        !          14232:      * in AdvInitAsc3550Driver() tell the microcode to ignore DMA
        !          14233:      * parity errors.
        !          14234:      */
        !          14235:     asc_dvc->cfg->control_flag = 0;
        !          14236:     if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister)
        !          14237:          & AscPCICmdRegBits_ParErrRespCtrl)) == 0)
        !          14238:     {
        !          14239:         asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
        !          14240:     }
        !          14241: 
        !          14242:     asc_dvc->cur_host_qng = 0;
        !          14243: 
        !          14244:     asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
        !          14245:       ADV_LIB_VERSION_MINOR;
        !          14246:     asc_dvc->cfg->chip_version =
        !          14247:       AdvGetChipVersion(iop_base, asc_dvc->bus_type);
        !          14248: 
        !          14249:     /*
        !          14250:      * Reset the chip to start and allow register writes.
        !          14251:      */
        !          14252:     if (AdvFindSignature(iop_base) == 0)
        !          14253:     {
        !          14254:         asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
        !          14255:         return ADV_ERROR;
        !          14256:     }
        !          14257:     else {
        !          14258: 
        !          14259:         AdvResetChip(asc_dvc);
        !          14260: 
        !          14261:         if ((status = AdvInitFromEEP(asc_dvc)) == ADV_ERROR)
        !          14262:         {
        !          14263:             return ADV_ERROR;
        !          14264:         }
        !          14265:         warn_code |= status;
        !          14266: 
        !          14267:         /*
        !          14268:          * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
        !          14269:          * Resets should be performed.
        !          14270:          */
        !          14271:         if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
        !          14272:         {
        !          14273:             AdvResetSCSIBus(asc_dvc);
        !          14274:         }
        !          14275:     }
        !          14276: 
        !          14277:     return warn_code;
        !          14278: }
        !          14279: 
        !          14280: /*
        !          14281:  * Initialize the ASC3550.
        !          14282:  *
        !          14283:  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
        !          14284:  *
        !          14285:  * For a non-fatal error return a warning code. If there are no warnings
        !          14286:  * then 0 is returned.
        !          14287:  */
        !          14288: ASC_INITFUNC(
        !          14289: int
        !          14290: AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
        !          14291: )
        !          14292: {
        !          14293:     AdvPortAddr iop_base;
        !          14294:     ushort      warn_code;
        !          14295:     ulong       sum;
        !          14296:     int         begin_addr;
        !          14297:     int         end_addr;
        !          14298:     int         code_sum;
        !          14299:     int         word;
        !          14300:     int         rql_addr;                   /* RISC Queue List address */
        !          14301:     int         i;
        !          14302:     ushort      scsi_cfg1;
        !          14303:     uchar       biosmem[ASC_MC_BIOSLEN];    /* BIOS RISC Memory 0x40-0x8F. */
        !          14304: 
        !          14305:     /* If there is already an error, don't continue. */
        !          14306:     if (asc_dvc->err_code != 0)
        !          14307:     {
        !          14308:         return ADV_ERROR;
        !          14309:     }
        !          14310: 
        !          14311:     warn_code = 0;
        !          14312:     iop_base = asc_dvc->iop_base;
        !          14313: 
        !          14314:     /*
        !          14315:      * Save the RISC memory BIOS region before writing the microcode.
        !          14316:      * The BIOS may already be loaded and using its RISC LRAM region
        !          14317:      * so its region must be saved and restored.
        !          14318:      *
        !          14319:      * Note: This code makes the assumption, which is currently true,
        !          14320:      * that a chip reset does not clear RISC LRAM.
        !          14321:      */
        !          14322:     for (i = 0; i < ASC_MC_BIOSLEN; i++)
        !          14323:     {
        !          14324:         AdvReadByteLram(iop_base, ASC_MC_BIOSMEM + i, biosmem[i]);
        !          14325:     }
        !          14326: 
        !          14327:     /*
        !          14328:      * Load the Microcode
        !          14329:      *
        !          14330:      * Write the microcode image to RISC memory starting at address 0.
        !          14331:      */
        !          14332:     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
        !          14333:     for (word = 0; word < _adv_mcode_size; word += 2)
        !          14334:     {
        !          14335:         AdvWriteWordAutoIncLram(iop_base,
        !          14336:             *((ushort *) (&_adv_mcode_buf[word])));
        !          14337:     }
        !          14338: 
        !          14339:     /*
        !          14340:      * Clear the rest of Condor's Internal RAM (8KB).
        !          14341:      */
        !          14342:     for (; word < ADV_CONDOR_MEMSIZE; word += 2)
        !          14343:     {
        !          14344:         AdvWriteWordAutoIncLram(iop_base, 0);
        !          14345:     }
        !          14346: 
        !          14347:     /*
        !          14348:      * Verify the microcode checksum.
        !          14349:      */
        !          14350:     sum = 0;
        !          14351:     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
        !          14352:     for (word = 0; word < _adv_mcode_size; word += 2)
        !          14353:     {
        !          14354:         sum += AdvReadWordAutoIncLram(iop_base);
        !          14355:     }
        !          14356: 
        !          14357:     if (sum != _adv_mcode_chksum)
        !          14358:     {
        !          14359:         asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
        !          14360:         return ADV_ERROR;
        !          14361:     }
        !          14362: 
        !          14363:     /*
        !          14364:      * Restore the RISC memory BIOS region.
        !          14365:      */
        !          14366:     for (i = 0; i < ASC_MC_BIOSLEN; i++)
        !          14367:     {
        !          14368:         AdvWriteByteLram(iop_base, ASC_MC_BIOSMEM + i, biosmem[i]);
        !          14369:     }
        !          14370: 
        !          14371:     /*
        !          14372:      * Calculate and write the microcode code checksum to the microcode
        !          14373:      * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).  
        !          14374:      */
        !          14375:     AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
        !          14376:     AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
        !          14377:     code_sum = 0;
        !          14378:     for (word = begin_addr; word < end_addr; word += 2)
        !          14379:     {
        !          14380:         code_sum += *((ushort *) (&_adv_mcode_buf[word]));
        !          14381:     }
        !          14382:     AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
        !          14383: 
        !          14384:     /*
        !          14385:      * Read microcode version and date.
        !          14386:      */
        !          14387:     AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
        !          14388:     AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
        !          14389: 
        !          14390:     /*
        !          14391:      * Initialize microcode operating variables
        !          14392:      */
        !          14393:     AdvWriteWordLram(iop_base, ASC_MC_ADAPTER_SCSI_ID,
        !          14394:                        asc_dvc->chip_scsi_id);
        !          14395: 
        !          14396:     /*
        !          14397:      * If the PCI Configuration Command Register "Parity Error Response
        !          14398:      * Control" Bit was clear (0), then set the microcode variable
        !          14399:      * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
        !          14400:      * to ignore DMA parity errors.
        !          14401:      */
        !          14402:     if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
        !          14403:     {
        !          14404:         /* 
        !          14405:          * Note: Don't remove the use of a temporary variable in
        !          14406:          * the following code, otherwise the Microsoft C compiler
        !          14407:          * will turn the following lines into a no-op.
        !          14408:          */
        !          14409:         AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
        !          14410:         word |= CONTROL_FLAG_IGNORE_PERR;
        !          14411:         AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
        !          14412:     }
        !          14413: 
        !          14414:     /*
        !          14415:      * Set default microcode operating variables for WDTR, SDTR, and
        !          14416:      * command tag queuing based on the EEPROM configuration values.
        !          14417:      *
        !          14418:      * These ADV_DVC_VAR fields and the microcode variables will be
        !          14419:      * changed in AdvInquiryHandling() if it is found a device is
        !          14420:      * incapable of a particular feature.
        !          14421:      */
        !          14422: 
        !          14423:     /*
        !          14424:      * Set the microcode ULTRA target mask from EEPROM value. The
        !          14425:      * SDTR target mask overrides the ULTRA target mask in the
        !          14426:      * microcode so it is safe to set this value without determining
        !          14427:      * whether the device supports SDTR.
        !          14428:      * 
        !          14429:      * Note: There is no way to know whether a device supports ULTRA
        !          14430:      * speed without attempting a SDTR ULTRA speed negotiation with
        !          14431:      * the device. The device will reject the speed if it does not
        !          14432:      * support it by responding with an SDTR message containing a
        !          14433:      * slower speed.
        !          14434:      */
        !          14435:     AdvWriteWordLram(iop_base, ASC_MC_ULTRA_ABLE, asc_dvc->ultra_able);
        !          14436:     AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
        !          14437: 
        !          14438: 
        !          14439:     /*
        !          14440:      * Set SCSI_CFG0 Microcode Default Value.
        !          14441:      *
        !          14442:      * The microcode will set the SCSI_CFG0 register using this value
        !          14443:      * after it is started below.
        !          14444:      */
        !          14445:     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
        !          14446:         PARITY_EN | SEL_TMO_LONG | OUR_ID_EN | asc_dvc->chip_scsi_id);
        !          14447:   
        !          14448:     /*
        !          14449:      * Determine SCSI_CFG1 Microcode Default Value.
        !          14450:      *
        !          14451:      * The microcode will set the SCSI_CFG1 register using this value
        !          14452:      * after it is started below.
        !          14453:      */
        !          14454: 
        !          14455:     /* Read current SCSI_CFG1 Register value. */
        !          14456:     scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
        !          14457: 
        !          14458:     /*
        !          14459:      * If all three connectors are in use, return an error.
        !          14460:      */
        !          14461:     if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
        !          14462:         (scsi_cfg1 & CABLE_ILLEGAL_B) == 0)
        !          14463:     {
        !          14464:         asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
        !          14465:         return ADV_ERROR;
        !          14466:     }
        !          14467: 
        !          14468:     /*
        !          14469:      * If the internal narrow cable is reversed all of the SCSI_CTRL
        !          14470:      * register signals will be set. Check for and return an error if
        !          14471:      * this condition is found.
        !          14472:      */
        !          14473:     if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
        !          14474:     {
        !          14475:         asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
        !          14476:         return ADV_ERROR;
        !          14477:     }
        !          14478: 
        !          14479:     /*
        !          14480:      * If this is a differential board and a single-ended device
        !          14481:      * is attached to one of the connectors, return an error.
        !          14482:      */
        !          14483:     if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0)
        !          14484:     {
        !          14485:         asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
        !          14486:         return ADV_ERROR;
        !          14487:     }
        !          14488: 
        !          14489:     /*
        !          14490:      * If automatic termination control is enabled, then set the
        !          14491:      * termination value based on a table listed in a_condor.h.
        !          14492:      *
        !          14493:      * If manual termination was specified with an EEPROM setting
        !          14494:      * then 'termination' was set-up in AdvInitFromEEP() and
        !          14495:      * is ready to be 'ored' into SCSI_CFG1.
        !          14496:      */
        !          14497:     if (asc_dvc->cfg->termination == 0)
        !          14498:     {
        !          14499:         /*
        !          14500:          * The software always controls termination by setting TERM_CTL_SEL.
        !          14501:          * If TERM_CTL_SEL were set to 0, the hardware would set termination.
        !          14502:          */
        !          14503:         asc_dvc->cfg->termination |= TERM_CTL_SEL;
        !          14504: 
        !          14505:         switch(scsi_cfg1 & CABLE_DETECT)
        !          14506:         {
        !          14507:             /* TERM_CTL_H: on, TERM_CTL_L: on */
        !          14508:             case 0x3: case 0x7: case 0xB: case 0xD: case 0xE: case 0xF:
        !          14509:                 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
        !          14510:                 break;
        !          14511: 
        !          14512:             /* TERM_CTL_H: on, TERM_CTL_L: off */
        !          14513:             case 0x1: case 0x5: case 0x9: case 0xA: case 0xC:
        !          14514:                 asc_dvc->cfg->termination |= TERM_CTL_H;
        !          14515:                 break;
        !          14516: 
        !          14517:             /* TERM_CTL_H: off, TERM_CTL_L: off */
        !          14518:             case 0x2: case 0x6:
        !          14519:                 break;
        !          14520:         }
        !          14521:     }
        !          14522: 
        !          14523:     /*
        !          14524:      * Clear any set TERM_CTL_H and TERM_CTL_L bits.
        !          14525:      */
        !          14526:     scsi_cfg1 &= ~TERM_CTL;
        !          14527: 
        !          14528:     /*
        !          14529:      * Invert the TERM_CTL_H and TERM_CTL_L bits and then
        !          14530:      * set 'scsi_cfg1'. The TERM_POL bit does not need to be
        !          14531:      * referenced, because the hardware internally inverts
        !          14532:      * the Termination High and Low bits if TERM_POL is set.
        !          14533:      */
        !          14534:     scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
        !          14535: 
        !          14536:     /*
        !          14537:      * Set SCSI_CFG1 Microcode Default Value
        !          14538:      *
        !          14539:      * Set filter value and possibly modified termination control
        !          14540:      * bits in the Microcode SCSI_CFG1 Register Value.
        !          14541:      *
        !          14542:      * The microcode will set the SCSI_CFG1 register using this value
        !          14543:      * after it is started below.
        !          14544:      */
        !          14545:     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
        !          14546:                        FLTR_11_TO_20NS | scsi_cfg1);
        !          14547: 
        !          14548:     /*
        !          14549:      * Set SEL_MASK Microcode Default Value
        !          14550:      *
        !          14551:      * The microcode will set the SEL_MASK register using this value
        !          14552:      * after it is started below.
        !          14553:      */
        !          14554:     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
        !          14555:                         ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
        !          14556: 
        !          14557:     /*
        !          14558:      * Link all the RISC Queue Lists together in a doubly-linked
        !          14559:      * NULL terminated list.
        !          14560:      *
        !          14561:      * Skip the NULL (0) queue which is not used.
        !          14562:      */
        !          14563:     for (i = 1, rql_addr = ASC_MC_RISC_Q_LIST_BASE + ASC_MC_RISC_Q_LIST_SIZE;
        !          14564:          i < ASC_MC_RISC_Q_TOTAL_CNT;
        !          14565:          i++, rql_addr += ASC_MC_RISC_Q_LIST_SIZE)
        !          14566:     {
        !          14567:         /*
        !          14568:          * Set the current RISC Queue List's RQL_FWD and RQL_BWD pointers
        !          14569:          * in a one word write and set the state (RQL_STATE) to free.
        !          14570:          */
        !          14571:         AdvWriteWordLram(iop_base, rql_addr, ((i + 1) + ((i - 1) << 8)));
        !          14572:         AdvWriteByteLram(iop_base, rql_addr + RQL_STATE, ASC_MC_QS_FREE);
        !          14573:     }
        !          14574: 
        !          14575:     /*
        !          14576:      * Set the Host and RISC Queue List pointers.
        !          14577:      *
        !          14578:      * Both sets of pointers are initialized with the same values:
        !          14579:      * ASC_MC_RISC_Q_FIRST(0x01) and ASC_MC_RISC_Q_LAST (0xFF).
        !          14580:      */
        !          14581:     AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_READY, ASC_MC_RISC_Q_FIRST);
        !          14582:     AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_DONE, ASC_MC_RISC_Q_LAST);
        !          14583: 
        !          14584:     AdvWriteByteLram(iop_base, ASC_MC_RISC_NEXT_READY, ASC_MC_RISC_Q_FIRST);
        !          14585:     AdvWriteByteLram(iop_base, ASC_MC_RISC_NEXT_DONE, ASC_MC_RISC_Q_LAST);
        !          14586: 
        !          14587:     /*
        !          14588:      * Finally, set up the last RISC Queue List (255) with
        !          14589:      * a NULL forward pointer.
        !          14590:      */
        !          14591:     AdvWriteWordLram(iop_base, rql_addr, (ASC_MC_NULL_Q + ((i - 1) << 8)));
        !          14592:     AdvWriteByteLram(iop_base, rql_addr + RQL_STATE, ASC_MC_QS_FREE);
        !          14593: 
        !          14594:     AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
        !          14595:          (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
        !          14596: 
        !          14597:     /* 
        !          14598:      * Note: Don't remove the use of a temporary variable in
        !          14599:      * the following code, otherwise the Microsoft C compiler
        !          14600:      * will turn the following lines into a no-op.
        !          14601:      */
        !          14602:     AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
        !          14603:     AdvWriteWordRegister(iop_base, IOPW_PC, word);
        !          14604: 
        !          14605:     /* finally, finally, gentlemen, start your engine */
        !          14606:     AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
        !          14607:  
        !          14608:     return warn_code;
        !          14609: }
        !          14610: 
        !          14611: /*
        !          14612:  * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
        !          14613:  * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
        !          14614:  * all of this is done.
        !          14615:  *
        !          14616:  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
        !          14617:  *
        !          14618:  * For a non-fatal error return a warning code. If there are no warnings
        !          14619:  * then 0 is returned.
        !          14620:  *
        !          14621:  * Note: Chip is stopped on entry.
        !          14622:  */
        !          14623: ASC_INITFUNC(
        !          14624: STATIC int
        !          14625: AdvInitFromEEP(ADV_DVC_VAR *asc_dvc)
        !          14626: )
        !          14627: {
        !          14628:     AdvPortAddr         iop_base;
        !          14629:     ushort              warn_code;
        !          14630:     ADVEEP_CONFIG       eep_config;
        !          14631:     int                 i;
        !          14632: 
        !          14633:     iop_base = asc_dvc->iop_base;
        !          14634: 
        !          14635:     warn_code = 0;
        !          14636: 
        !          14637:     /*
        !          14638:      * Read the board's EEPROM configuration.
        !          14639:      *
        !          14640:      * Set default values if a bad checksum is found.
        !          14641:      */
        !          14642:     if (AdvGetEEPConfig(iop_base, &eep_config) != eep_config.check_sum)
        !          14643:     {
        !          14644:         warn_code |= ASC_WARN_EEPROM_CHKSUM;
        !          14645: 
        !          14646:         /*
        !          14647:          * Set EEPROM default values.
        !          14648:          */
        !          14649:         for (i = 0; i < sizeof(ADVEEP_CONFIG); i++)
        !          14650:         {
        !          14651:             *((uchar *) &eep_config + i) =
        !          14652:                 *((uchar *) &Default_EEPROM_Config + i);
        !          14653:         }
        !          14654: 
        !          14655:         /*
        !          14656:          * Assume the 6 byte board serial number that was read
        !          14657:          * from EEPROM is correct even if the EEPROM checksum
        !          14658:          * failed.
        !          14659:          */
        !          14660:         eep_config.serial_number_word3 =
        !          14661:             AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 1);
        !          14662:         eep_config.serial_number_word2 =
        !          14663:             AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 2);
        !          14664:         eep_config.serial_number_word1 =
        !          14665:             AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 3);
        !          14666:         AdvSetEEPConfig(iop_base, &eep_config);
        !          14667:     }
        !          14668: 
        !          14669:     /*
        !          14670:      * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
        !          14671:      * EEPROM configuration that was read.
        !          14672:      *
        !          14673:      * This is the mapping of EEPROM fields to Adv Library fields.
        !          14674:      */
        !          14675:     asc_dvc->wdtr_able = eep_config.wdtr_able;
        !          14676:     asc_dvc->sdtr_able = eep_config.sdtr_able;
        !          14677:     asc_dvc->ultra_able = eep_config.ultra_able;
        !          14678:     asc_dvc->tagqng_able = eep_config.tagqng_able;
        !          14679:     asc_dvc->cfg->disc_enable = eep_config.disc_enable;
        !          14680:     asc_dvc->max_host_qng = eep_config.max_host_qng;
        !          14681:     asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
        !          14682:     asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
        !          14683:     asc_dvc->start_motor = eep_config.start_motor;
        !          14684:     asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
        !          14685:     asc_dvc->cfg->bios_boot_wait = eep_config.bios_boot_delay;
        !          14686:     asc_dvc->bios_ctrl = eep_config.bios_ctrl;
        !          14687:     asc_dvc->no_scam = eep_config.scam_tolerant;
        !          14688:     asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
        !          14689:     asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
        !          14690:     asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
        !          14691: 
        !          14692:     /*
        !          14693:      * Set the host maximum queuing (max. 253, min. 16) and the per device
        !          14694:      * maximum queuing (max. 63, min. 4).
        !          14695:      */
        !          14696:     if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
        !          14697:     {
        !          14698:         eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
        !          14699:     } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
        !          14700:     {
        !          14701:         /* If the value is zero, assume it is uninitialized. */
        !          14702:         if (eep_config.max_host_qng == 0)
        !          14703:         {
        !          14704:             eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
        !          14705:         } else
        !          14706:         {
        !          14707:             eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
        !          14708:         }
        !          14709:     }
        !          14710: 
        !          14711:     if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
        !          14712:     {
        !          14713:         eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
        !          14714:     } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
        !          14715:     {
        !          14716:         /* If the value is zero, assume it is uninitialized. */
        !          14717:         if (eep_config.max_dvc_qng == 0)
        !          14718:         {
        !          14719:             eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
        !          14720:         } else
        !          14721:         {
        !          14722:             eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
        !          14723:         }
        !          14724:     }
        !          14725: 
        !          14726:     /*
        !          14727:      * If 'max_dvc_qng' is greater than 'max_host_qng', then
        !          14728:      * set 'max_dvc_qng' to 'max_host_qng'.
        !          14729:      */
        !          14730:     if (eep_config.max_dvc_qng > eep_config.max_host_qng)
        !          14731:     {
        !          14732:         eep_config.max_dvc_qng = eep_config.max_host_qng;
        !          14733:     }
        !          14734: 
        !          14735:     /*
        !          14736:      * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_CFG 'max_dvc_qng'
        !          14737:      * values based on possibly adjusted EEPROM values.
        !          14738:      */
        !          14739:     asc_dvc->max_host_qng = eep_config.max_host_qng;
        !          14740:     asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
        !          14741: 
        !          14742: 
        !          14743:     /*
        !          14744:      * If the EEPROM 'termination' field is set to automatic (0), then set
        !          14745:      * the ADV_DVC_CFG 'termination' field to automatic also.
        !          14746:      *
        !          14747:      * If the termination is specified with a non-zero 'termination'
        !          14748:      * value check that a legal value is set and set the ADV_DVC_CFG
        !          14749:      * 'termination' field appropriately.
        !          14750:      */
        !          14751:     if (eep_config.termination == 0)
        !          14752:     {
        !          14753:         asc_dvc->cfg->termination = 0;    /* auto termination */
        !          14754:     } else
        !          14755:     {
        !          14756:         /* Enable manual control with low off / high off. */
        !          14757:         if (eep_config.termination == 1)
        !          14758:         {
        !          14759:             asc_dvc->cfg->termination = TERM_CTL_SEL;
        !          14760: 
        !          14761:         /* Enable manual control with low off / high on. */
        !          14762:         } else if (eep_config.termination == 2)
        !          14763:         {
        !          14764:             asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
        !          14765: 
        !          14766:         /* Enable manual control with low on / high on. */
        !          14767:         } else if (eep_config.termination == 3)
        !          14768:         {
        !          14769:             asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
        !          14770:         } else
        !          14771:         {
        !          14772:             /*
        !          14773:              * The EEPROM 'termination' field contains a bad value. Use
        !          14774:              * automatic termination instead.
        !          14775:              */
        !          14776:             asc_dvc->cfg->termination = 0;
        !          14777:             warn_code |= ASC_WARN_EEPROM_TERMINATION;
        !          14778:         }
        !          14779:     }
        !          14780: 
        !          14781:     return warn_code;
        !          14782: }
        !          14783: 
        !          14784: /*
        !          14785:  * Read EEPROM configuration into the specified buffer.
        !          14786:  *
        !          14787:  * Return a checksum based on the EEPROM configuration read.
        !          14788:  */
        !          14789: ASC_INITFUNC(
        !          14790: STATIC ushort
        !          14791: AdvGetEEPConfig(AdvPortAddr iop_base, ADVEEP_CONFIG *cfg_buf)
        !          14792: )
        !          14793: {
        !          14794:     ushort              wval, chksum;
        !          14795:     ushort              *wbuf;
        !          14796:     int                 eep_addr;
        !          14797: 
        !          14798:     wbuf = (ushort *) cfg_buf;
        !          14799:     chksum = 0;
        !          14800: 
        !          14801:     for (eep_addr = ASC_EEP_DVC_CFG_BEGIN;
        !          14802:          eep_addr < ASC_EEP_DVC_CFG_END;
        !          14803:          eep_addr++, wbuf++)
        !          14804:     {
        !          14805:         wval = AdvReadEEPWord(iop_base, eep_addr);
        !          14806:         chksum += wval;
        !          14807:         *wbuf = wval;
        !          14808:     }
        !          14809:     *wbuf = AdvReadEEPWord(iop_base, eep_addr);
        !          14810:     wbuf++;
        !          14811:     for (eep_addr = ASC_EEP_DVC_CTL_BEGIN;
        !          14812:          eep_addr < ASC_EEP_MAX_WORD_ADDR;
        !          14813:          eep_addr++, wbuf++)
        !          14814:     {
        !          14815:         *wbuf = AdvReadEEPWord(iop_base, eep_addr);
        !          14816:     }
        !          14817:     return chksum;
        !          14818: }
        !          14819: 
        !          14820: /*
        !          14821:  * Read the EEPROM from specified location
        !          14822:  */
        !          14823: ASC_INITFUNC(
        !          14824: STATIC ushort
        !          14825: AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
        !          14826: )
        !          14827: {
        !          14828:     AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
        !          14829:         ASC_EEP_CMD_READ | eep_word_addr);
        !          14830:     AdvWaitEEPCmd(iop_base);
        !          14831:     return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
        !          14832: }
        !          14833: 
        !          14834: /*
        !          14835:  * Wait for EEPROM command to complete
        !          14836:  */
        !          14837: ASC_INITFUNC(
        !          14838: STATIC void
        !          14839: AdvWaitEEPCmd(AdvPortAddr iop_base)
        !          14840: )
        !          14841: {
        !          14842:     int eep_delay_ms;
        !          14843: 
        !          14844:     for (eep_delay_ms = 0; eep_delay_ms < ASC_EEP_DELAY_MS; eep_delay_ms++)
        !          14845:     {
        !          14846:         if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE)
        !          14847:         {
        !          14848:             break;
        !          14849:         }
        !          14850:         DvcSleepMilliSecond(1);
        !          14851:     }
        !          14852:     if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) == 0)
        !          14853:     {
        !          14854:         ADV_ASSERT(0);
        !          14855:     }
        !          14856:     return;
        !          14857: }
        !          14858: 
        !          14859: /*
        !          14860:  * Write the EEPROM from 'cfg_buf'.
        !          14861:  */
        !          14862: ASC_INITFUNC(
        !          14863: STATIC void
        !          14864: AdvSetEEPConfig(AdvPortAddr iop_base, ADVEEP_CONFIG *cfg_buf)
        !          14865: )
        !          14866: {
        !          14867:     ushort       *wbuf;
        !          14868:     ushort       addr, chksum;
        !          14869: 
        !          14870:     wbuf = (ushort *) cfg_buf;
        !          14871:     chksum = 0;
        !          14872: 
        !          14873:     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
        !          14874:     AdvWaitEEPCmd(iop_base);
        !          14875: 
        !          14876:     /*
        !          14877:      * Write EEPROM from word 0 to word 15
        !          14878:      */
        !          14879:     for (addr = ASC_EEP_DVC_CFG_BEGIN;
        !          14880:          addr < ASC_EEP_DVC_CFG_END; addr++, wbuf++)
        !          14881:     {
        !          14882:         chksum += *wbuf;
        !          14883:         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf);
        !          14884:         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
        !          14885:         AdvWaitEEPCmd(iop_base);
        !          14886:         DvcSleepMilliSecond(ASC_EEP_DELAY_MS);
        !          14887:     }
        !          14888: 
        !          14889:     /*
        !          14890:      * Write EEPROM checksum at word 18
        !          14891:      */
        !          14892:     AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
        !          14893:     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
        !          14894:     AdvWaitEEPCmd(iop_base);
        !          14895:     wbuf++;        /* skip over check_sum */
        !          14896: 
        !          14897:     /*
        !          14898:      * Write EEPROM OEM name at words 19 to 26 
        !          14899:      */
        !          14900:     for (addr = ASC_EEP_DVC_CTL_BEGIN;
        !          14901:          addr < ASC_EEP_MAX_WORD_ADDR; addr++, wbuf++)
        !          14902:     {
        !          14903:         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf);
        !          14904:         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
        !          14905:         AdvWaitEEPCmd(iop_base);
        !          14906:     }
        !          14907:     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
        !          14908:     AdvWaitEEPCmd(iop_base);
        !          14909:     return;
        !          14910: }
        !          14911: 
        !          14912: /*
        !          14913:  * This function resets the chip and SCSI bus
        !          14914:  *
        !          14915:  * It is up to the caller to add a delay to let the bus settle after
        !          14916:  * calling this function.
        !          14917:  *
        !          14918:  * The SCSI_CFG0, SCSI_CFG1, and MEM_CFG registers are set-up in
        !          14919:  * AdvInitAsc3550Driver(). Here when doing a write to one of these
        !          14920:  * registers read first and then write.
        !          14921:  *
        !          14922:  * Note: A SCSI Bus Reset can not be done until after the EEPROM
        !          14923:  * configuration is read to determine whether SCSI Bus Resets
        !          14924:  * should be performed.
        !          14925:  */
        !          14926: ASC_INITFUNC(
        !          14927: STATIC void
        !          14928: AdvResetChip(ADV_DVC_VAR *asc_dvc)
        !          14929: )
        !          14930: {
        !          14931:     AdvPortAddr    iop_base;
        !          14932:     ushort         word;
        !          14933:     uchar          byte;
        !          14934: 
        !          14935:     iop_base = asc_dvc->iop_base;
        !          14936: 
        !          14937:     /*
        !          14938:      * Reset Chip.
        !          14939:      */
        !          14940:     AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
        !          14941:     DvcSleepMilliSecond(100);
        !          14942:     AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_WR_IO_REG);
        !          14943: 
        !          14944:     /*
        !          14945:      * Initialize Chip registers.
        !          14946:      * 
        !          14947:      * Note: Don't remove the use of a temporary variable in the following
        !          14948:      * code, otherwise the Microsoft C compiler will turn the following lines
        !          14949:      * into a no-op.
        !          14950:      */
        !          14951:     byte = AdvReadByteRegister(iop_base, IOPB_MEM_CFG);
        !          14952:     byte |= RAM_SZ_8KB;
        !          14953:     AdvWriteByteRegister(iop_base, IOPB_MEM_CFG, byte);
        !          14954: 
        !          14955:     word = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
        !          14956:     word &= ~BIG_ENDIAN;
        !          14957:     AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, word);
        !          14958: 
        !          14959:     /*
        !          14960:      * Setting the START_CTL_EMFU 3:2 bits sets a FIFO threshold
        !          14961:      * of 128 bytes. This register is only accessible to the host.
        !          14962:      */
        !          14963:     AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
        !          14964:         START_CTL_EMFU | READ_CMD_MRM);
        !          14965: }
        !          14966: 
        !          14967: /* a_advlib.c */
        !          14968: /*
        !          14969:  * Description:
        !          14970:  *      Send a SCSI request to the ASC3550 chip
        !          14971:  *
        !          14972:  * If there is no SG list for the request, set 'sg_entry_cnt' to 0.
        !          14973:  *
        !          14974:  * If 'sg_real_addr' is non-zero on entry, AscGetSGList() will not be
        !          14975:  * called. It is assumed the caller has already initialized 'sg_real_addr'.
        !          14976:  *
        !          14977:  * Return:
        !          14978:  *      ADV_SUCCESS(1) - the request is in the mailbox
        !          14979:  *      ADV_BUSY(0) - total request count > 253, try later
        !          14980:  *      ADV_ERROR(-1) - invalid scsi request Q
        !          14981:  */
        !          14982: STATIC int
        !          14983: AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc,
        !          14984:                 ADV_SCSI_REQ_Q *scsiq)
        !          14985: {
        !          14986:     if (scsiq == (ADV_SCSI_REQ_Q *) 0L)
        !          14987:     {
        !          14988:         /* 'scsiq' should never be NULL. */
        !          14989:         ADV_ASSERT(0);
        !          14990:         return ADV_ERROR;
        !          14991:     }
        !          14992: 
        !          14993:     return AdvSendScsiCmd(asc_dvc, scsiq);
        !          14994: }
        !          14995: 
        !          14996: /*
        !          14997:  * Reset SCSI Bus and purge all outstanding requests.
        !          14998:  *
        !          14999:  * Return Value:
        !          15000:  *      ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
        !          15001:  *
        !          15002:  * Note: Should always return ADV_TRUE.
        !          15003:  */
        !          15004: STATIC int
        !          15005: AdvResetSB(ADV_DVC_VAR *asc_dvc)
        !          15006: {
        !          15007:     int         status;
        !          15008: 
        !          15009:     status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET, 0L, 0);
        !          15010: 
        !          15011:     AdvResetSCSIBus(asc_dvc);
        !          15012: 
        !          15013:     return status;
        !          15014: }
        !          15015: 
        !          15016: /*
        !          15017:  * Reset SCSI Bus and delay.
        !          15018:  */
        !          15019: STATIC void
        !          15020: AdvResetSCSIBus(ADV_DVC_VAR *asc_dvc)
        !          15021: {
        !          15022:     AdvPortAddr    iop_base;
        !          15023:     ushort         scsi_ctrl;
        !          15024: 
        !          15025:     iop_base = asc_dvc->iop_base;
        !          15026: 
        !          15027:     /*
        !          15028:      * The microcode currently sets the SCSI Bus Reset signal while
        !          15029:      * handling the AscSendIdleCmd() IDLE_CMD_SCSI_RESET command above.
        !          15030:      * But the SCSI Bus Reset Hold Time in the microcode is not deterministic
        !          15031:      * (it may in fact be for less than the SCSI Spec. minimum of 25 us).
        !          15032:      * Therefore on return the Adv Library sets the SCSI Bus Reset signal
        !          15033:      * for ASC_SCSI_RESET_HOLD_TIME_US, which is defined to be greater
        !          15034:      * than 25 us.
        !          15035:      */
        !          15036:     scsi_ctrl = AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL);
        !          15037:     AdvWriteWordRegister(iop_base, IOPW_SCSI_CTRL,
        !          15038:         scsi_ctrl | ADV_SCSI_CTRL_RSTOUT);
        !          15039:     DvcDelayMicroSecond(asc_dvc, (ushort) ASC_SCSI_RESET_HOLD_TIME_US);
        !          15040:     AdvWriteWordRegister(iop_base, IOPW_SCSI_CTRL,
        !          15041:         scsi_ctrl & ~ADV_SCSI_CTRL_RSTOUT);
        !          15042: 
        !          15043:     DvcSleepMilliSecond((ulong) asc_dvc->scsi_reset_wait * 1000);
        !          15044: }
        !          15045: 
        !          15046: 
        !          15047: /*
        !          15048:  * Adv Library Interrupt Service Routine
        !          15049:  *
        !          15050:  *  This function is called by a driver's interrupt service routine.
        !          15051:  *  The function disables and re-enables interrupts.
        !          15052:  *
        !          15053:  *  When a microcode idle command is completed, the ADV_DVC_VAR
        !          15054:  *  'idle_cmd_done' field is set to ADV_TRUE.
        !          15055:  *
        !          15056:  *  Note: AdvISR() can be called when interrupts are disabled or even
        !          15057:  *  when there is no hardware interrupt condition present. It will
        !          15058:  *  always check for completed idle commands and microcode requests.
        !          15059:  *  This is an important feature that shouldn't be changed because it
        !          15060:  *  allows commands to be completed from polling mode loops.
        !          15061:  *
        !          15062:  * Return:
        !          15063:  *   ADV_TRUE(1) - interrupt was pending
        !          15064:  *   ADV_FALSE(0) - no interrupt was pending
        !          15065:  */
        !          15066: STATIC int
        !          15067: AdvISR(ADV_DVC_VAR *asc_dvc)
        !          15068: {
        !          15069:     AdvPortAddr                 iop_base;
        !          15070:     uchar                       int_stat;
        !          15071:     ushort                      next_done_loc, target_bit;
        !          15072:     int                         completed_q;
        !          15073:     int                         flags;
        !          15074:     ADV_SCSI_REQ_Q              *scsiq;
        !          15075:     ASC_REQ_SENSE               *sense_data;
        !          15076:     int                         ret;
        !          15077: 
        !          15078:     flags = DvcEnterCritical();
        !          15079:     iop_base = asc_dvc->iop_base;
        !          15080: 
        !          15081:     if (AdvIsIntPending(iop_base))
        !          15082:     {
        !          15083:         ret = ADV_TRUE;
        !          15084:     } else
        !          15085:     {
        !          15086:         ret = ADV_FALSE;
        !          15087:     }
        !          15088: 
        !          15089:     /* Reading the register clears the interrupt. */
        !          15090:     int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
        !          15091: 
        !          15092:     if (int_stat & ADV_INTR_STATUS_INTRB)
        !          15093:     {
        !          15094:         asc_dvc->idle_cmd_done = ADV_TRUE;
        !          15095:     }
        !          15096: 
        !          15097:     /*
        !          15098:      * Notify the driver of a hardware detected SCSI Bus Reset.
        !          15099:      */
        !          15100:     if (int_stat & ADV_INTR_STATUS_INTRC)
        !          15101:     {
        !          15102:         if (asc_dvc->sbreset_callback != 0)
        !          15103:         {
        !          15104:             (*(ADV_SBRESET_CALLBACK) asc_dvc->sbreset_callback)(asc_dvc);
        !          15105:         }
        !          15106:     }
        !          15107: 
        !          15108:     /*
        !          15109:      * ASC_MC_HOST_NEXT_DONE (0x129) is actually the last completed RISC
        !          15110:      * Queue List request. Its forward pointer (RQL_FWD) points to the
        !          15111:      * current completed RISC Queue List request.
        !          15112:      */
        !          15113:     AdvReadByteLram(iop_base, ASC_MC_HOST_NEXT_DONE, next_done_loc);
        !          15114:     next_done_loc = ASC_MC_RISC_Q_LIST_BASE +
        !          15115:         (next_done_loc * ASC_MC_RISC_Q_LIST_SIZE) + RQL_FWD;
        !          15116: 
        !          15117:     AdvReadByteLram(iop_base, next_done_loc, completed_q);
        !          15118: 
        !          15119:     /* Loop until all completed Q's are processed. */
        !          15120:     while (completed_q != ASC_MC_NULL_Q)
        !          15121:     {
        !          15122:         AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_DONE, completed_q);
        !          15123: 
        !          15124:         next_done_loc = ASC_MC_RISC_Q_LIST_BASE +
        !          15125:           (completed_q * ASC_MC_RISC_Q_LIST_SIZE);
        !          15126: 
        !          15127:         /*
        !          15128:          * Read the ADV_SCSI_REQ_Q virtual address pointer from
        !          15129:          * the RISC list entry. The microcode has changed the
        !          15130:          * ADV_SCSI_REQ_Q physical address to its virtual address.
        !          15131:          *
        !          15132:          * Refer to comments at the end of AdvSendScsiCmd() for
        !          15133:          * more information on the RISC list structure.
        !          15134:          */
        !          15135:         {
        !          15136:             ushort lsw, msw;
        !          15137:             AdvReadWordLram(iop_base, next_done_loc + RQL_PHYADDR, lsw);
        !          15138:             AdvReadWordLram(iop_base, next_done_loc + RQL_PHYADDR + 2, msw);
        !          15139: 
        !          15140:             scsiq = (ADV_SCSI_REQ_Q *) (((ulong) msw << 16) | lsw);
        !          15141:         }
        !          15142:         ADV_ASSERT(scsiq != NULL);
        !          15143: 
        !          15144:         target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
        !          15145: 
        !          15146:         /*
        !          15147:          * Clear request microcode control flag.
        !          15148:          */
        !          15149:         scsiq->cntl = 0;
        !          15150: 
        !          15151:         /*
        !          15152:          * Check Condition handling
        !          15153:          */
        !          15154:         if ((scsiq->done_status == QD_WITH_ERROR) &&
        !          15155:             (scsiq->scsi_status == SS_CHK_CONDITION) &&
        !          15156:             (sense_data = (ASC_REQ_SENSE *) scsiq->vsense_addr) != 0 &&
        !          15157:             (scsiq->orig_sense_len - scsiq->sense_len) >= ASC_MIN_SENSE_LEN)
        !          15158:         {
        !          15159:             /*
        !          15160:              * Command returned with a check condition and valid
        !          15161:              * sense data.
        !          15162:              */
        !          15163:         }
        !          15164:         /*
        !          15165:          * If the command that completed was a SCSI INQUIRY and
        !          15166:          * LUN 0 was sent the command, then process the INQUIRY
        !          15167:          * command information for the device.
        !          15168:          */
        !          15169:         else if (scsiq->done_status == QD_NO_ERROR &&
        !          15170:                    scsiq->cdb[0] == SCSICMD_Inquiry &&
        !          15171:                    scsiq->target_lun == 0)
        !          15172:         {
        !          15173:             AdvInquiryHandling(asc_dvc, scsiq);
        !          15174:         }
        !          15175: 
        !          15176:         
        !          15177:         /* Change the RISC Queue List state to free. */
        !          15178:         AdvWriteByteLram(iop_base, next_done_loc + RQL_STATE, ASC_MC_QS_FREE);
        !          15179: 
        !          15180:         /* Get the RISC Queue List forward pointer. */
        !          15181:         AdvReadByteLram(iop_base, next_done_loc + RQL_FWD, completed_q);
        !          15182: 
        !          15183:         /*
        !          15184:          * Notify the driver of the completed request by passing
        !          15185:          * the ADV_SCSI_REQ_Q pointer to its callback function.
        !          15186:          */
        !          15187:         ADV_ASSERT(asc_dvc->cur_host_qng > 0);
        !          15188:         asc_dvc->cur_host_qng--;
        !          15189:         scsiq->a_flag |= ADV_SCSIQ_DONE;
        !          15190:         (*(ADV_ISR_CALLBACK) asc_dvc->isr_callback)(asc_dvc, scsiq);
        !          15191:         /*
        !          15192:          * Note: After the driver callback function is called, 'scsiq'
        !          15193:          * can no longer be referenced.
        !          15194:          *
        !          15195:          * Fall through and continue processing other completed
        !          15196:          * requests...
        !          15197:          */
        !          15198: 
        !          15199:         /*
        !          15200:          * Disable interrupts again in case the driver inadvertently
        !          15201:          * enabled interrupts in its callback function.
        !          15202:          *
        !          15203:          * The DvcEnterCritical() return value is ignored, because
        !          15204:          * the 'flags' saved when AdvISR() was first entered will be
        !          15205:          * used to restore the interrupt flag on exit.
        !          15206:          */
        !          15207:         (void) DvcEnterCritical();
        !          15208:     }
        !          15209:     DvcLeaveCritical(flags);
        !          15210:     return ret;
        !          15211: }
        !          15212: 
        !          15213: /*
        !          15214:  * Send an idle command to the chip and wait for completion.
        !          15215:  *
        !          15216:  * Interrupts do not have to be enabled on entry.
        !          15217:  *
        !          15218:  * Return Values:
        !          15219:  *   ADV_TRUE - command completed successfully
        !          15220:  *   ADV_FALSE - command failed
        !          15221:  */
        !          15222: STATIC int
        !          15223: AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
        !          15224:                ushort idle_cmd,
        !          15225:                ulong idle_cmd_parameter,
        !          15226:                int flags)
        !          15227: {
        !          15228:     int         last_int_level;
        !          15229:     ulong       i;
        !          15230:     AdvPortAddr iop_base;
        !          15231:     int         ret;
        !          15232: 
        !          15233:     asc_dvc->idle_cmd_done = 0;
        !          15234: 
        !          15235:     last_int_level = DvcEnterCritical();
        !          15236:     iop_base = asc_dvc->iop_base;
        !          15237: 
        !          15238:     /*
        !          15239:      * Write the idle command value after the idle command parameter
        !          15240:      * has been written to avoid a race condition. If the order is not
        !          15241:      * followed, the microcode may process the idle command before the
        !          15242:      * parameters have been written to LRAM.
        !          15243:      */
        !          15244:     AdvWriteDWordLram(iop_base, ASC_MC_IDLE_PARA_STAT, idle_cmd_parameter);
        !          15245:     AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
        !          15246:     DvcLeaveCritical(last_int_level);
        !          15247: 
        !          15248:     /*
        !          15249:      * If the 'flags' argument contains the ADV_NOWAIT flag, then
        !          15250:      * return with success.
        !          15251:      */
        !          15252:     if (flags & ADV_NOWAIT)
        !          15253:     {
        !          15254:         return ADV_TRUE;
        !          15255:     }
        !          15256: 
        !          15257:     for (i = 0; i < SCSI_WAIT_10_SEC * SCSI_MS_PER_SEC; i++)
        !          15258:     {
        !          15259:         /*
        !          15260:          * 'idle_cmd_done' is set by AdvISR().
        !          15261:          */
        !          15262:         if (asc_dvc->idle_cmd_done)
        !          15263:         {
        !          15264:             break;
        !          15265:         }
        !          15266:         DvcSleepMilliSecond(1);
        !          15267: 
        !          15268:         /*
        !          15269:          * If interrupts were disabled on entry to AdvSendIdleCmd(),
        !          15270:          * then they will still be disabled here. Call AdvISR() to
        !          15271:          * check for the idle command completion.
        !          15272:          */
        !          15273:         (void) AdvISR(asc_dvc);
        !          15274:     }
        !          15275: 
        !          15276:     last_int_level = DvcEnterCritical();
        !          15277: 
        !          15278:     if (asc_dvc->idle_cmd_done == ADV_FALSE)
        !          15279:     {
        !          15280:         ADV_ASSERT(0); /* The idle command should never timeout. */
        !          15281:         return ADV_FALSE;
        !          15282:     } else
        !          15283:     {
        !          15284:         AdvReadWordLram(iop_base, ASC_MC_IDLE_PARA_STAT, ret);
        !          15285:         return ret;
        !          15286:     }
        !          15287: }
        !          15288: 
        !          15289: /*
        !          15290:  * Send the SCSI request block to the adapter
        !          15291:  *
        !          15292:  * Each of the 255 Adv Library/Microcode RISC Lists or mailboxes has the
        !          15293:  * following structure:
        !          15294:  *
        !          15295:  * 0: RQL_FWD - RISC list forward pointer (1 byte)
        !          15296:  * 1: RQL_BWD - RISC list backward pointer (1 byte)
        !          15297:  * 2: RQL_STATE - RISC list state byte - free, ready, done, aborted (1 byte)
        !          15298:  * 3: RQL_TID - request target id (1 byte)
        !          15299:  * 4: RQL_PHYADDR - ADV_SCSI_REQ_Q physical pointer (4 bytes)
        !          15300:  *
        !          15301:  * Return:
        !          15302:  *      ADV_SUCCESS(1) - the request is in the mailbox
        !          15303:  *      ADV_BUSY(0) - total request count > 253, try later
        !          15304:  */
        !          15305: STATIC int
        !          15306: AdvSendScsiCmd(
        !          15307:     ADV_DVC_VAR *asc_dvc,
        !          15308:     ADV_SCSI_REQ_Q  *scsiq)
        !          15309: {
        !          15310:     ushort                 next_ready_loc;
        !          15311:     uchar                  next_ready_loc_fwd;
        !          15312:     int                    last_int_level;
        !          15313:     AdvPortAddr            iop_base;
        !          15314:     long                   req_size;
        !          15315:     ulong                  q_phy_addr;
        !          15316: 
        !          15317:     /*
        !          15318:      * The ADV_SCSI_REQ_Q 'target_id' field should never be equal
        !          15319:      * to the host adapter ID or exceed ADV_MAX_TID.
        !          15320:      */
        !          15321:     if (scsiq->target_id == asc_dvc->chip_scsi_id ||
        !          15322:         scsiq->target_id > ADV_MAX_TID)
        !          15323:     {
        !          15324:         scsiq->host_status = QHSTA_M_INVALID_DEVICE;
        !          15325:         scsiq->done_status = QD_WITH_ERROR;
        !          15326:         return ADV_ERROR;
        !          15327:     }
        !          15328: 
        !          15329:     iop_base = asc_dvc->iop_base;
        !          15330: 
        !          15331:     last_int_level = DvcEnterCritical();
        !          15332: 
        !          15333:     if (asc_dvc->cur_host_qng >= asc_dvc->max_host_qng)
        !          15334:     {
        !          15335:         DvcLeaveCritical(last_int_level);
        !          15336:         return ADV_BUSY;
        !          15337:     } else
        !          15338:     {
        !          15339:         ADV_ASSERT(asc_dvc->cur_host_qng < ASC_MC_RISC_Q_TOTAL_CNT);
        !          15340:         asc_dvc->cur_host_qng++;
        !          15341:     }
        !          15342: 
        !          15343:     /*
        !          15344:      * Clear the ADV_SCSI_REQ_Q done flag.
        !          15345:      */
        !          15346:     scsiq->a_flag &= ~ADV_SCSIQ_DONE;
        !          15347: 
        !          15348:     /*
        !          15349:      * Save the original sense buffer length.
        !          15350:      *
        !          15351:      * After the request completes 'sense_len' will be set to the residual
        !          15352:      * byte count of the Auto-Request Sense if a command returns CHECK
        !          15353:      * CONDITION and the Sense Data is valid indicated by 'host_status' not
        !          15354:      * being set to QHSTA_M_AUTO_REQ_SENSE_FAIL. To determine the valid
        !          15355:      * Sense Data Length subtract 'sense_len' from 'orig_sense_len'.
        !          15356:      */
        !          15357:     scsiq->orig_sense_len = scsiq->sense_len;
        !          15358: 
        !          15359:     AdvReadByteLram(iop_base, ASC_MC_HOST_NEXT_READY, next_ready_loc);
        !          15360:     next_ready_loc = ASC_MC_RISC_Q_LIST_BASE +
        !          15361:         (next_ready_loc * ASC_MC_RISC_Q_LIST_SIZE);
        !          15362: 
        !          15363:     /*
        !          15364:      * Write the physical address of the Q to the mailbox.
        !          15365:      * We need to skip the first four bytes, because the microcode
        !          15366:      * uses them internally for linking Q's together.
        !          15367:      */
        !          15368:     req_size = sizeof(ADV_SCSI_REQ_Q);
        !          15369:     q_phy_addr = DvcGetPhyAddr(asc_dvc, scsiq,
        !          15370:                     (uchar *) scsiq, &req_size,
        !          15371:                     ADV_IS_SCSIQ_FLAG);
        !          15372:     ADV_ASSERT(ADV_DWALIGN(q_phy_addr) == q_phy_addr);
        !          15373:     ADV_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
        !          15374: 
        !          15375:     scsiq->scsiq_ptr = (ADV_SCSI_REQ_Q *) scsiq;
        !          15376: 
        !          15377:     /*
        !          15378:      * The RISC list structure, which 'next_ready_loc' is a pointer
        !          15379:      * to in microcode LRAM, has the format detailed in the comment
        !          15380:      * header for this function.
        !          15381:      *
        !          15382:      * Write the ADV_SCSI_REQ_Q physical pointer to 'next_ready_loc' request.
        !          15383:      */
        !          15384:     AdvWriteDWordLram(iop_base, next_ready_loc + RQL_PHYADDR, q_phy_addr);
        !          15385: 
        !          15386:     /* Write target_id to 'next_ready_loc' request. */
        !          15387:     AdvWriteByteLram(iop_base, next_ready_loc + RQL_TID, scsiq->target_id);
        !          15388: 
        !          15389:     /*
        !          15390:      * Set the ASC_MC_HOST_NEXT_READY (0x128) microcode variable to
        !          15391:      * the 'next_ready_loc' request forward pointer.
        !          15392:      *
        !          15393:      * Do this *before* changing the 'next_ready_loc' queue to QS_READY.
        !          15394:      * After the state is changed to QS_READY 'RQL_FWD' will be changed
        !          15395:      * by the microcode.
        !          15396:      *
        !          15397:      * NOTE: The temporary variable 'next_ready_loc_fwd' is required to
        !          15398:      * prevent some compilers from optimizing out 'AdvReadByteLram()' if
        !          15399:      * it were used as the 3rd argument to 'AdvWriteByteLram()'.
        !          15400:      */
        !          15401:     AdvReadByteLram(iop_base, next_ready_loc + RQL_FWD, next_ready_loc_fwd);
        !          15402:     AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_READY, next_ready_loc_fwd);
        !          15403: 
        !          15404:     /*
        !          15405:      * Change the state of 'next_ready_loc' request from QS_FREE to
        !          15406:      * QS_READY which will cause the microcode to pick it up and
        !          15407:      * execute it.
        !          15408:      *
        !          15409:      * Can't reference 'next_ready_loc' after changing the request
        !          15410:      * state to QS_READY. The microcode now owns the request.
        !          15411:      */
        !          15412:     AdvWriteByteLram(iop_base, next_ready_loc + RQL_STATE, ASC_MC_QS_READY);
        !          15413: 
        !          15414:     DvcLeaveCritical(last_int_level);
        !          15415:     return ADV_SUCCESS;
        !          15416: }
        !          15417: 
        !          15418: /*
        !          15419:  * Inquiry Information Byte 7 Handling
        !          15420:  *
        !          15421:  * Handle SCSI Inquiry Command information for a device by setting
        !          15422:  * microcode operating variables that affect WDTR, SDTR, and Tag 
        !          15423:  * Queuing.
        !          15424:  */
        !          15425: STATIC void
        !          15426: AdvInquiryHandling(
        !          15427:     ADV_DVC_VAR          *asc_dvc,
        !          15428:     ADV_SCSI_REQ_Q       *scsiq)
        !          15429: {
        !          15430:     AdvPortAddr          iop_base;
        !          15431:     uchar                tid;
        !          15432:     ASC_SCSI_INQUIRY     *inq;
        !          15433:     ushort               tidmask;
        !          15434:     ushort               cfg_word;
        !          15435: 
        !          15436:     /*
        !          15437:      * AdvInquiryHandling() requires up to INQUIRY information Byte 7
        !          15438:      * to be available.
        !          15439:      *
        !          15440:      * If less than 8 bytes of INQUIRY information were requested or less
        !          15441:      * than 8 bytes were transferred, then return. cdb[4] is the request
        !          15442:      * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the
        !          15443:      * microcode to the transfer residual count.
        !          15444:      */
        !          15445:     if (scsiq->cdb[4] < 8 || (scsiq->cdb[4] - scsiq->data_cnt) < 8)
        !          15446:     {
        !          15447:         return;
        !          15448:     }
        !          15449: 
        !          15450:     iop_base = asc_dvc->iop_base;
        !          15451:     tid = scsiq->target_id;
        !          15452:     inq = (ASC_SCSI_INQUIRY *) scsiq->vdata_addr;
        !          15453: 
        !          15454:     /*
        !          15455:      * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
        !          15456:      */
        !          15457:     if (inq->byte3.rsp_data_fmt < 2 && inq->byte2.ansi_apr_ver < 2)
        !          15458:     {
        !          15459:         return;
        !          15460:     } else
        !          15461:     {
        !          15462:         /*
        !          15463:          * INQUIRY Byte 7 Handling
        !          15464:          *
        !          15465:          * Use a device's INQUIRY byte 7 to determine whether it
        !          15466:          * supports WDTR, SDTR, and Tag Queuing. If the feature
        !          15467:          * is enabled in the EEPROM and the device supports the
        !          15468:          * feature, then enable it in the microcode.
        !          15469:          */
        !          15470: 
        !          15471:         tidmask = ADV_TID_TO_TIDMASK(tid);
        !          15472: 
        !          15473:         /*
        !          15474:          * Wide Transfers
        !          15475:          *
        !          15476:          * If the EEPROM enabled WDTR for the device and the device
        !          15477:          * supports wide bus (16 bit) transfers, then turn on the
        !          15478:          * device's 'wdtr_able' bit and write the new value to the
        !          15479:          * microcode.
        !          15480:          */
        !          15481:         if ((asc_dvc->wdtr_able & tidmask) && inq->byte7.WBus16)
        !          15482:         {
        !          15483:             AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
        !          15484:             if ((cfg_word & tidmask) == 0)
        !          15485:             {
        !          15486:                 cfg_word |= tidmask;
        !          15487:                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
        !          15488: 
        !          15489:                 /*
        !          15490:                  * Clear the microcode "WDTR negotiation" done indicator
        !          15491:                  * for the target to cause it to negotiate with the new
        !          15492:                  * setting set above.
        !          15493:                  */
        !          15494:                 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
        !          15495:                 cfg_word &= ~tidmask;
        !          15496:                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
        !          15497:             }
        !          15498:         }
        !          15499: 
        !          15500:         /*
        !          15501:          * Synchronous Transfers
        !          15502:          *
        !          15503:          * If the EEPROM enabled SDTR for the device and the device
        !          15504:          * supports synchronous transfers, then turn on the device's
        !          15505:          * 'sdtr_able' bit. Write the new value to the microcode.
        !          15506:          */
        !          15507:         if ((asc_dvc->sdtr_able & tidmask) && inq->byte7.Sync)
        !          15508:         {
        !          15509:             AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
        !          15510:             if ((cfg_word & tidmask) == 0)
        !          15511:             {
        !          15512:                 cfg_word |= tidmask;
        !          15513:                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
        !          15514: 
        !          15515:                 /*
        !          15516:                  * Clear the microcode "SDTR negotiation" done indicator
        !          15517:                  * for the target to cause it to negotiate with the new
        !          15518:                  * setting set above.
        !          15519:                  */
        !          15520:                 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
        !          15521:                 cfg_word &= ~tidmask;
        !          15522:                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
        !          15523:             }
        !          15524:         }
        !          15525: 
        !          15526:         /*
        !          15527:          * If the EEPROM enabled Tag Queuing for device and the
        !          15528:          * device supports Tag Queuing, then turn on the device's
        !          15529:          * 'tagqng_enable' bit in the microcode and set the microcode
        !          15530:          * maximum command count to the ADV_DVC_VAR 'max_dvc_qng'
        !          15531:          * value.
        !          15532:          *
        !          15533:          * Tag Queuing is disabled for the BIOS which runs in polled
        !          15534:          * mode and would see no benefit from Tag Queuing. Also by
        !          15535:          * disabling Tag Queuing in the BIOS devices with Tag Queuing
        !          15536:          * bugs will at least work with the BIOS.
        !          15537:          */
        !          15538:         if ((asc_dvc->tagqng_able & tidmask) && inq->byte7.CmdQue)
        !          15539:         {
        !          15540:             AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
        !          15541:             cfg_word |= tidmask;
        !          15542:             AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
        !          15543:             AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
        !          15544:                 asc_dvc->max_dvc_qng);
        !          15545:         }
        !          15546:     }
        !          15547: }

unix.superglobalmegacorp.com

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