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