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

1.1.1.2 ! root        1: /* $Id: advansys.c,v 1.1.4.1 2005/06/02 18:52:38 ams Exp $ */
1.1       root        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);
1.1.1.2 ! root     2036: STATIC long      DvcEnterCritical(void);
        !          2037: STATIC void      DvcLeaveCritical(long);
1.1       root     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:  */
1.1.1.2 ! root     2873: STATIC long  DvcEnterCritical(void);
        !          2874: STATIC void  DvcLeaveCritical(long);
1.1       root     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:  */
1.1.1.2 ! root     3139: STATIC ADVEEP_CONFIG Default_EEPROM_Config;
1.1       root     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;
1.1.1.2 ! root     3259: #define REQPNEXT(reqp)       ((reqp)->host_scribble)
1.1       root     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;
1.1.1.2 ! root     5403:     long                flags;
1.1       root     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;
1.1.1.2 ! root     5498:     long                flags;
1.1       root     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;
1.1.1.2 ! root     5737:     long                 flags;
1.1       root     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);
1.1.1.2 ! root     6018:             for (tscp = done_scp; tscp; tscp = (REQP) REQPNEXT(tscp)) {
1.1       root     6019:                 tscp->result = HOST_BYTE(DID_RESET);
                   6020:             }
                   6021:         } else {
                   6022:             ASC_ASSERT(last_scp != NULL);
1.1.1.2 ! root     6023:             REQPNEXT(last_scp) =
        !          6024:              (unsigned char *) asc_dequeue_list(&boardp->active,
        !          6025:                                                 &new_last_scp, target);
        !          6026:             if (new_last_scp != (Scsi_Cmnd *) NULL) {
        !          6027:                ASC_ASSERT((REQP) REQPNEXT(last_scp) != NULL);
        !          6028:                 for (tscp = (Scsi_Cmnd *) REQPNEXT(last_scp);
        !          6029:                     tscp;
        !          6030:                     tscp = (Scsi_Cmnd *) REQPNEXT(tscp)) {
1.1       root     6031:                     tscp->result = HOST_BYTE(DID_RESET);
                   6032:                 }
                   6033:                 last_scp = new_last_scp;
                   6034:             }
                   6035:         }
                   6036: 
                   6037:         /*
                   6038:          * Add waiting requests to 'done_scp' and set the request status
                   6039:          * to DID_RESET.
                   6040:          */
                   6041:         if (done_scp == NULL) {
                   6042:             done_scp = asc_dequeue_list(&boardp->waiting, &last_scp, target);
1.1.1.2 ! root     6043:             for (tscp = done_scp; tscp; tscp = (REQP) REQPNEXT(tscp)) {
1.1       root     6044:                 tscp->result = HOST_BYTE(DID_RESET);
                   6045:             }
                   6046:         } else {
                   6047:             ASC_ASSERT(last_scp != NULL);
1.1.1.2 ! root     6048:             REQPNEXT(last_scp) =
        !          6049:              (unsigned char *) asc_dequeue_list(&boardp->waiting,
        !          6050:                                                 &new_last_scp, target);
1.1       root     6051:             if (new_last_scp != NULL) {
1.1.1.2 ! root     6052:                ASC_ASSERT((REQP) REQPNEXT(last_scp) != NULL);
        !          6053:                 for (tscp = (REQP) REQPNEXT(last_scp);
        !          6054:                     tscp;
        !          6055:                     tscp = (REQP) REQPNEXT(tscp)) {
1.1       root     6056:                     tscp->result = HOST_BYTE(DID_RESET);
                   6057:                 }
                   6058:                 last_scp = new_last_scp;
                   6059:             }
                   6060:         }
                   6061: 
                   6062:         /* Save the time of the most recently completed reset. */
                   6063:         boardp->last_reset = jiffies;
                   6064: 
                   6065:         /* Clear reset flag. */
                   6066:         boardp->flags &= ~ASC_HOST_IN_RESET;
                   6067: 
                   6068:         /*
                   6069:          * Start any waiting commands for the board.
                   6070:          */
                   6071:         if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
                   6072:             ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
                   6073:             asc_execute_queue(&boardp->waiting);
                   6074:         }
                   6075:         ret = SCSI_RESET_SUCCESS;
                   6076:     }
                   6077: 
                   6078:     /* Interrupts could be enabled here. */
                   6079: 
                   6080:     ASC_ASSERT(do_scsi_done != ASC_ERROR);
                   6081:     ASC_ASSERT(scp_found != ASC_ERROR);
                   6082:     if (do_scsi_done == ASC_TRUE) {
                   6083:         if (scp->scsi_done == NULL) {
                   6084:             ASC_PRINT1(
                   6085: "advansys_reset: reset request scsi_done() is NULL, %x\n",
                   6086:                 (unsigned) scp);
                   6087:         } else {
                   6088:             if (scp_found == ASC_FALSE) {
                   6089:                 ASC_PRINT1(
                   6090: "advansys_reset: reset request not active or waiting, completing anyway %x\n",
                   6091:                     (unsigned) scp);
                   6092:             }
                   6093:             ASC_STATS(scp->host, done);
                   6094:             scp->scsi_done(scp);
                   6095:         }
                   6096:     }
                   6097: 
                   6098:     /*
                   6099:      * It is possible for the request done function to re-enable
                   6100:      * interrupts without confusing the driver. But here interrupts
                   6101:      * aren't enabled until requests have been completed.
                   6102:      */
                   6103:     if (done_scp != NULL) {
                   6104:         asc_scsi_done_list(done_scp);
                   6105:     }
                   6106: 
                   6107:     ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
                   6108: 
                   6109:     /* Re-enable interrupts, if they were enabled on entry. */
                   6110:     restore_flags(flags);
                   6111: 
                   6112:     ASC_ASSERT(ret != ASC_ERROR);
                   6113:     return ret;
                   6114: }
                   6115: 
                   6116: /*
                   6117:  * advansys_biosparam()
                   6118:  *
                   6119:  * Translate disk drive geometry if the "BIOS greater than 1 GB"
                   6120:  * support is enabled for a drive.
                   6121:  *
                   6122:  * ip (information pointer) is an int array with the following definition:
                   6123:  * ip[0]: heads
                   6124:  * ip[1]: sectors
                   6125:  * ip[2]: cylinders
                   6126:  */
                   6127: int
                   6128: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
                   6129: advansys_biosparam(Disk *dp, int dep, int ip[])
                   6130: #else /* version >= v1.3.0 */
                   6131: advansys_biosparam(Disk *dp, kdev_t dep, int ip[])
                   6132: #endif /* version >= v1.3.0 */
                   6133: {
                   6134:     asc_board_t     *boardp;
                   6135: 
                   6136:     ASC_DBG(1, "advansys_biosparam: begin\n");
                   6137:     ASC_STATS(dp->device->host, biosparam);
                   6138:     boardp = ASC_BOARDP(dp->device->host);
                   6139:     if (ASC_NARROW_BOARD(boardp)) {
                   6140:         if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
                   6141:              ASC_CNTL_BIOS_GT_1GB) && dp->capacity > 0x200000) {
                   6142:                 ip[0] = 255;
                   6143:                 ip[1] = 63;
                   6144:         } else {
                   6145:                 ip[0] = 64;
                   6146:                 ip[1] = 32;
                   6147:         }
                   6148:     } else {
                   6149:         if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
                   6150:              BIOS_CTRL_EXTENDED_XLAT) && dp->capacity > 0x200000) {
                   6151:                 ip[0] = 255;
                   6152:                 ip[1] = 63;
                   6153:         } else {
                   6154:                 ip[0] = 64;
                   6155:                 ip[1] = 32;
                   6156:         }
                   6157:     }
                   6158:     ip[2] = dp->capacity / (ip[0] * ip[1]);
                   6159:     ASC_DBG(1, "advansys_biosparam: end\n");
                   6160:     return 0;
                   6161: }
                   6162: 
                   6163: /*
                   6164:  * advansys_setup()
                   6165:  *
                   6166:  * This function is called from init/main.c at boot time.
                   6167:  * It it passed LILO parameters that can be set from the
                   6168:  * LILO command line or in /etc/lilo.conf.
                   6169:  *
                   6170:  * It is used by the AdvanSys driver to either disable I/O
                   6171:  * port scanning or to limit scanning to 1 - 4 I/O ports.
                   6172:  * Regardless of the option setting EISA and PCI boards
                   6173:  * will still be searched for and detected. This option
                   6174:  * only affects searching for ISA and VL boards.
                   6175:  *
                   6176:  * If ADVANSYS_DEBUG is defined the driver debug level may
                   6177:  * be set using the 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port.
                   6178:  *
                   6179:  * Examples:
                   6180:  * 1. Eliminate I/O port scanning:
                   6181:  *         boot: linux advansys=
                   6182:  *       or
                   6183:  *         boot: linux advansys=0x0
                   6184:  * 2. Limit I/O port scanning to one I/O port:
                   6185:  *        boot: linux advansys=0x110
                   6186:  * 3. Limit I/O port scanning to four I/O ports:
                   6187:  *        boot: linux advansys=0x110,0x210,0x230,0x330
                   6188:  * 4. If ADVANSYS_DEBUG, limit I/O port scanning to four I/O ports and
                   6189:  *    set the driver debug level to 2.
                   6190:  *        boot: linux advansys=0x110,0x210,0x230,0x330,0xdeb2
                   6191:  *
                   6192:  * ints[0] - number of arguments
                   6193:  * ints[1] - first argument
                   6194:  * ints[2] - second argument
                   6195:  * ...
                   6196:  */
                   6197: ASC_INITFUNC(
                   6198: void
                   6199: advansys_setup(char *str, int *ints)
                   6200: )
                   6201: {
                   6202:     int    i;
                   6203: 
                   6204:     if (asc_iopflag == ASC_TRUE) {
                   6205:         printk("AdvanSys SCSI: 'advansys' LILO option may appear only once\n");
                   6206:         return;
                   6207:     }
                   6208: 
                   6209:     asc_iopflag = ASC_TRUE;
                   6210: 
                   6211:     if (ints[0] > ASC_NUM_IOPORT_PROBE) {
                   6212: #ifdef ADVANSYS_DEBUG
                   6213:         if ((ints[0] == ASC_NUM_IOPORT_PROBE + 1) &&
                   6214:             (ints[ASC_NUM_IOPORT_PROBE + 1] >> 4 == 0xdeb)) {
                   6215:             asc_dbglvl = ints[ASC_NUM_IOPORT_PROBE + 1] & 0xf;
                   6216:         } else {
                   6217: #endif /* ADVANSYS_DEBUG */
                   6218:             printk("AdvanSys SCSI: only %d I/O ports accepted\n",
                   6219:                 ASC_NUM_IOPORT_PROBE);
                   6220: #ifdef ADVANSYS_DEBUG
                   6221:         }
                   6222: #endif /* ADVANSYS_DEBUG */
                   6223:     }
                   6224: 
                   6225: #ifdef ADVANSYS_DEBUG
                   6226:     ASC_DBG1(1, "advansys_setup: ints[0] %d\n", ints[0]);
                   6227:     for (i = 1; i < ints[0]; i++) {
                   6228:         ASC_DBG2(1, " ints[%d] %x", i, ints[i]);
                   6229:     }
                   6230:     ASC_DBG(1, "\n");
                   6231: #endif /* ADVANSYS_DEBUG */
                   6232: 
                   6233:     for (i = 1; i <= ints[0] && i <= ASC_NUM_IOPORT_PROBE; i++) {
                   6234:         asc_ioport[i-1] = ints[i];
                   6235:         ASC_DBG2(1, "advansys_setup: asc_ioport[%d] %x\n",
                   6236:             i - 1, asc_ioport[i-1]);
                   6237:     }
                   6238: }
                   6239: 
                   6240: 
                   6241: /*
                   6242:  * --- Loadable Driver Support
                   6243:  */
                   6244: 
                   6245: #ifdef MODULE
                   6246: Scsi_Host_Template driver_template = ADVANSYS;
                   6247: # include "scsi_module.c"
                   6248: #endif /* MODULE */
                   6249: 
                   6250: 
                   6251: /*
                   6252:  * --- Miscellaneous Driver Functions
                   6253:  */
                   6254: 
                   6255: /*
                   6256:  * First-level interrupt handler.
                   6257:  *
                   6258:  * For versions > v1.3.70, 'dev_id' is a pointer to the interrupting
                   6259:  * adapter's asc_board_t. Because all boards are currently checked
                   6260:  * for interrupts on each interrupt, 'dev_id' is not referenced. 'dev_id'
                   6261:  * could be used to identify an interrupt passed to the AdvanSys driver,
                   6262:  * which is for a device sharing an interrupt with an AdvanSys adapter.
                   6263:  */
                   6264: STATIC void
                   6265: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
                   6266: advansys_interrupt(int irq, struct pt_regs *regs)
                   6267: #else /* version >= v1.3.70 */
                   6268: advansys_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                   6269: #endif /* version >= v1.3.70 */
                   6270: {
                   6271: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,95)
1.1.1.2 ! root     6272:     long            flags;
1.1       root     6273: #else /* version >= v2.1.95 */
                   6274:     unsigned long   flags;
                   6275: #endif /* version >= v2.1.95 */
                   6276:     int             i;
                   6277:     asc_board_t     *boardp;
                   6278:     Scsi_Cmnd       *done_scp = NULL, *last_scp = NULL;
                   6279:     Scsi_Cmnd       *new_last_scp;
                   6280: 
                   6281: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,95)
                   6282:     /* Disable interrupts, if they aren't already disabled. */
                   6283:     save_flags(flags);
                   6284:     cli();
                   6285: #else /* version >= v2.1.95 */
                   6286:     /*
                   6287:      * Disable interrupts, if they aren't already disabled and acquire
                   6288:      * the I/O spinlock.
                   6289:      */
                   6290:     spin_lock_irqsave(&io_request_lock, flags);
                   6291: #endif /* version >= v2.1.95 */
                   6292: 
                   6293:     ASC_DBG(1, "advansys_interrupt: begin\n");
                   6294: 
                   6295:     /*
                   6296:      * Check for interrupts on all boards.
                   6297:      * AscISR() will call asc_isr_callback().
                   6298:      */
                   6299:     for (i = 0; i < asc_board_count; i++) {
                   6300:         boardp = ASC_BOARDP(asc_host[i]);
                   6301:         ASC_DBG2(2, "advansys_interrupt: i %d, boardp %lx\n",
                   6302:             i, (ulong) boardp)            
                   6303:         if (ASC_NARROW_BOARD(boardp)) {
                   6304:             /*
                   6305:              * Narrow Board
                   6306:              */
                   6307:             if (AscIsIntPending(asc_host[i]->io_port)) {
                   6308:                 ASC_STATS(asc_host[i], interrupt);
                   6309:                 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
                   6310:                 AscISR(&boardp->dvc_var.asc_dvc_var);
                   6311:             }
                   6312:         } else {
                   6313:             /*
                   6314:              * Wide Board
                   6315:              */
                   6316:             ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
                   6317:             if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
                   6318:                 ASC_STATS(asc_host[i], interrupt);
                   6319:             }
                   6320:         }
                   6321: 
                   6322:         /*
                   6323:          * Start waiting requests and create a list of completed requests.
                   6324:          * 
                   6325:          * If a reset or abort request is being performed for the board,
                   6326:          * the reset or abort handler will complete pending requests after
                   6327:          * it has completed.
                   6328:          */
                   6329:         if ((boardp->flags & (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) == 0) {
                   6330:             ASC_DBG2(1, "advansys_interrupt: done_scp %lx, last_scp %lx\n",
                   6331:                 (ulong) done_scp, (ulong) last_scp);
                   6332: 
                   6333:             /* Start any waiting commands for the board. */
                   6334:             if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
                   6335:                 ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
                   6336:                 asc_execute_queue(&boardp->waiting);
                   6337:             }
                   6338: 
                   6339:              /*
                   6340:               * Add to the list of requests that must be completed.
                   6341:               *
                   6342:               * 'done_scp' will always be NULL on the first iteration
                   6343:               * of this loop. 'last_scp' is set at the same time as
                   6344:               * 'done_scp'.
                   6345:               */
                   6346:             if (done_scp == NULL) {
                   6347:                 done_scp = asc_dequeue_list(&boardp->done, &last_scp,
                   6348:                     ASC_TID_ALL);
                   6349:             } else {
                   6350:                 ASC_ASSERT(last_scp != NULL);
1.1.1.2 ! root     6351:                 REQPNEXT(last_scp) =
        !          6352:                  (unsigned char *) asc_dequeue_list(&boardp->done,
        !          6353:                                                     &new_last_scp,
        !          6354:                                                     ASC_TID_ALL);
1.1       root     6355:                 if (new_last_scp != NULL) {
                   6356:                     ASC_ASSERT(REQPNEXT(last_scp) != NULL);
                   6357:                     last_scp = new_last_scp;
                   6358:                 }
                   6359:             }
                   6360:         }
                   6361:     }
                   6362: 
                   6363:     /* Interrupts could be enabled here. */
                   6364: 
                   6365:     /*
                   6366:      * It is possible for the request done function to re-enable
                   6367:      * interrupts without confusing the driver. But here the
                   6368:      * original flags aren't restored until all requests have been
                   6369:      * completed.
                   6370:      */
                   6371:     asc_scsi_done_list(done_scp);
                   6372: 
                   6373: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,95)
                   6374:     /*
                   6375:      * Restore the original flags which will enable interrupts
                   6376:      * if and only if they were enabled on entry.
                   6377:      */
                   6378:     restore_flags(flags);
                   6379: #else /* version >= v2.1.95 */
                   6380:     /*
                   6381:      * Release the I/O spinlock and restore the original flags
                   6382:      * which will enable interrupts if and only if they were
                   6383:      * enabled on entry.
                   6384:      */
                   6385:     spin_unlock_irqrestore(&io_request_lock, flags);
                   6386: #endif /* version >= v2.1.95 */
                   6387: 
                   6388:     ASC_DBG(1, "advansys_interrupt: end\n");
                   6389:     return;
                   6390: }
                   6391: 
                   6392: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
                   6393: /*
                   6394:  * Set the number of commands to queue per device for the
                   6395:  * specified host adapter.
                   6396:  */
                   6397: STATIC void
                   6398: advansys_select_queue_depths(struct Scsi_Host *shp, Scsi_Device *devicelist)
                   6399: {
                   6400:     Scsi_Device        *device;
                   6401:     asc_board_t        *boardp;
                   6402: 
                   6403:     boardp = ASC_BOARDP(shp);
                   6404:     boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
                   6405:     for (device = devicelist; device != NULL; device = device->next) {
                   6406:         if (device->host != shp) {
                   6407:             continue;
                   6408:         }
                   6409:         /*
                   6410:          * Save a pointer to the device and set its initial/maximum
                   6411:          * queue depth.
                   6412:          */
                   6413:         boardp->device[device->id] = device;
                   6414:         if (ASC_NARROW_BOARD(boardp)) {
                   6415:             device->queue_depth =
                   6416:                 boardp->dvc_var.asc_dvc_var.max_dvc_qng[device->id];
                   6417:         } else {
                   6418:             device->queue_depth =
                   6419:                 boardp->dvc_var.adv_dvc_var.max_dvc_qng;
                   6420:         }
                   6421:         ASC_DBG3(1, "advansys_select_queue_depths: shp %x, id %d, depth %d\n",
                   6422:             (unsigned) shp, device->id, device->queue_depth);
                   6423:     }
                   6424: }
                   6425: #endif /* version >= v1.3.89 */
                   6426: 
                   6427: /*
                   6428:  * Function used only with polled I/O requests that are initiated by
                   6429:  * advansys_command().
                   6430:  */
                   6431: STATIC void
                   6432: advansys_command_done(Scsi_Cmnd *scp)
                   6433: {
                   6434:     ASC_DBG1(1, "advansys_command_done: scp %x\n", (unsigned) scp);
                   6435:     scp->SCp.Status = 1;
                   6436: }
                   6437: 
                   6438: /*
                   6439:  * Complete all requests on the singly linked list pointed
                   6440:  * to by 'scp'.
                   6441:  *
                   6442:  * Interrupts can be enabled on entry.
                   6443:  */
                   6444: STATIC void
                   6445: asc_scsi_done_list(Scsi_Cmnd *scp)
                   6446: {
                   6447:     Scsi_Cmnd    *tscp;
                   6448: 
                   6449:     ASC_DBG(2, "asc_scsi_done_list: begin\n");
                   6450:     while (scp != NULL) {
                   6451:         ASC_DBG1(3, "asc_scsi_done_list: scp %x\n", (unsigned) scp);
1.1.1.2 ! root     6452:         tscp = (REQP) REQPNEXT(scp);
1.1       root     6453:         REQPNEXT(scp) = NULL;
                   6454:         ASC_STATS(scp->host, done);
                   6455:         ASC_ASSERT(scp->scsi_done != NULL);
                   6456:         scp->scsi_done(scp);
                   6457:         scp = tscp;
                   6458:     }
                   6459:     ASC_DBG(2, "asc_scsi_done_list: done\n");
                   6460:     return;
                   6461: }
                   6462: 
                   6463: /*
                   6464:  * Execute a single 'Scsi_Cmnd'.
                   6465:  *
                   6466:  * The function 'done' is called when the request has been completed.
                   6467:  *
                   6468:  * Scsi_Cmnd:
                   6469:  *
                   6470:  *  host - board controlling device
                   6471:  *  device - device to send command
                   6472:  *  target - target of device
                   6473:  *  lun - lun of device
                   6474:  *  cmd_len - length of SCSI CDB
                   6475:  *  cmnd - buffer for SCSI 8, 10, or 12 byte CDB
                   6476:  *  use_sg - if non-zero indicates scatter-gather request with use_sg elements
                   6477:  *
                   6478:  *  if (use_sg == 0) {
                   6479:  *    request_buffer - buffer address for request
                   6480:  *    request_bufflen - length of request buffer
                   6481:  *  } else {
                   6482:  *    request_buffer - pointer to scatterlist structure
                   6483:  *  }
                   6484:  *
                   6485:  *  sense_buffer - sense command buffer
                   6486:  *
                   6487:  *  result (4 bytes of an int):
                   6488:  *    Byte Meaning
                   6489:  *    0 SCSI Status Byte Code
                   6490:  *    1 SCSI One Byte Message Code
                   6491:  *    2 Host Error Code
                   6492:  *    3 Mid-Level Error Code
                   6493:  *
                   6494:  *  host driver fields:
                   6495:  *    SCp - Scsi_Pointer used for command processing status
                   6496:  *    scsi_done - used to save caller's done function
                   6497:  *    host_scribble - used for pointer to another Scsi_Cmnd
                   6498:  *
                   6499:  * If this function returns ASC_NOERROR or ASC_ERROR the request
                   6500:  * has been enqueued on the board's 'done' queue and must be
                   6501:  * completed by the caller.
                   6502:  *
                   6503:  * If ASC_BUSY is returned the request must be enqueued by the
                   6504:  * caller and re-tried later.
                   6505:  */
                   6506: STATIC int
                   6507: asc_execute_scsi_cmnd(Scsi_Cmnd *scp)
                   6508: {
                   6509:     asc_board_t        *boardp;
                   6510:     ASC_DVC_VAR        *asc_dvc_varp;
                   6511:     ADV_DVC_VAR        *adv_dvc_varp;
                   6512:     ADV_SCSI_REQ_Q     *adv_scsiqp;
                   6513:     Scsi_Device        *device;
                   6514:     int                ret;
                   6515: 
                   6516:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
                   6517:     ASC_DBG2(1, "asc_execute_scsi_cmnd: scp %x, done %x\n",
                   6518:         (unsigned) scp, (unsigned) scp->scsi_done);
                   6519: 
                   6520:     boardp = ASC_BOARDP(scp->host);
                   6521:     device = boardp->device[scp->target];
                   6522: 
                   6523:     if (ASC_NARROW_BOARD(boardp)) {
                   6524:         /*
                   6525:          * Build and execute Narrow Board request.
                   6526:          */
                   6527: 
                   6528:         asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
                   6529: 
                   6530:         /*
                   6531:          * Build Asc Library request structure using the
                   6532:          * global structures 'asc_scsi_req' and 'asc_sg_head'.
                   6533:          *
                   6534:          * asc_build_req() can not return ASC_BUSY.
                   6535:          */
                   6536:         if (asc_build_req(boardp, scp) == ASC_ERROR) {
                   6537:             ASC_STATS(scp->host, build_error);
                   6538:             return ASC_ERROR;
                   6539:         }
                   6540: 
                   6541:         /*
                   6542:          * Execute the command. If there is no error, add the command
                   6543:          * to the active queue.
                   6544:          */
                   6545:         switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
                   6546:         case ASC_NOERROR:
                   6547:             ASC_STATS(scp->host, exe_noerror);
                   6548:             /*
                   6549:              * Increment monotonically increasing per device successful
                   6550:              * request counter. Wrapping doesn't matter.
                   6551:              */
                   6552:             boardp->reqcnt[scp->target]++;
                   6553: 
                   6554: #if ASC_QUEUE_FLOW_CONTROL
                   6555:             /*
                   6556:              * Conditionally increment the device queue depth.
                   6557:              *
                   6558:              * If no error occurred and there have been 100 consecutive
                   6559:              * successful requests and the current queue depth is less
                   6560:              * than the maximum queue depth, then increment the current
                   6561:              * queue depth.
                   6562:              */
                   6563:             if (boardp->nerrcnt[scp->target]++ > 100) {
                   6564:                 boardp->nerrcnt[scp->target] = 0;
                   6565:                 if (device != NULL &&
                   6566:                     (device->queue_curr_depth < device->queue_depth) &&
                   6567:                     (!(boardp->queue_full &
                   6568:                        ADV_TID_TO_TIDMASK(scp->target)) ||
                   6569:                      (boardp->queue_full_cnt[scp->target] >
                   6570:                       device->queue_curr_depth))) {
                   6571:                     device->queue_curr_depth++;
                   6572:                 }
                   6573:             }
                   6574: #endif /* ASC_QUEUE_FLOW_CONTROL */
                   6575:             asc_enqueue(&boardp->active, scp, ASC_BACK);
                   6576:             ASC_DBG(1,
                   6577:                 "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
                   6578:             break;
                   6579:         case ASC_BUSY:
                   6580:             /* Caller must enqueue request and retry later. */
                   6581:             ASC_STATS(scp->host, exe_busy);
                   6582: #if ASC_QUEUE_FLOW_CONTROL
                   6583:             /*
                   6584:              * Clear consecutive no error counter and if possible decrement
                   6585:              * queue depth.
                   6586:              */
                   6587:             boardp->nerrcnt[scp->target] = 0;
                   6588:             if (device != NULL && device->queue_curr_depth > 1) {
                   6589:                 device->queue_curr_depth--;
                   6590:             }
                   6591: #endif /* ASC_QUEUE_FLOW_CONTROL */
                   6592:             break;
                   6593:         case ASC_ERROR:
                   6594:             ASC_PRINT2(
                   6595: "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code %x\n",
                   6596:                 boardp->id, asc_dvc_varp->err_code);
                   6597:             ASC_STATS(scp->host, exe_error);
                   6598: #if ASC_QUEUE_FLOW_CONTROL
                   6599:             /* Clear consecutive no error counter. */
                   6600:             boardp->nerrcnt[scp->target] = 0;
                   6601: #endif /* ASC_QUEUE_FLOW_CONTROL */
                   6602:             scp->result = HOST_BYTE(DID_ERROR);
                   6603:             asc_enqueue(&boardp->done, scp, ASC_BACK);
                   6604:             break;
                   6605:         default:
                   6606:             ASC_PRINT2(
                   6607: "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code %x\n",
                   6608:                 boardp->id, asc_dvc_varp->err_code);
                   6609:             ASC_STATS(scp->host, exe_unknown);
                   6610: #if ASC_QUEUE_FLOW_CONTROL
                   6611:             /* Clear consecutive no error counter. */
                   6612:             boardp->nerrcnt[scp->target] = 0;
                   6613: #endif /* ASC_QUEUE_FLOW_CONTROL */
                   6614:             scp->result = HOST_BYTE(DID_ERROR);
                   6615:             asc_enqueue(&boardp->done, scp, ASC_BACK);
                   6616:             break;
                   6617:         }
                   6618:     } else {
                   6619:         /*
                   6620:          * Build and execute Wide Board request.
                   6621:          */
                   6622:         adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
                   6623: 
                   6624:         /*
                   6625:          * Build and get a pointer to an Adv Library request structure.
                   6626:          *
                   6627:          * If the request is successfully built then send  it below,
                   6628:          * otherwise return with an error.
                   6629:          */
                   6630:         switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
                   6631:         case ASC_NOERROR:
                   6632:             ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
                   6633:             break;
                   6634:         case ASC_BUSY:
                   6635:             ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
                   6636:             return ASC_BUSY;
                   6637:         case ASC_ERROR:
                   6638:         default:
                   6639:             ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
                   6640:             ASC_STATS(scp->host, build_error);
                   6641:             return ASC_ERROR;
                   6642:         }
                   6643:     
                   6644:         /*
                   6645:          * Execute the command. If there is no error, add the command
                   6646:          * to the active queue.
                   6647:          */
                   6648:         switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
                   6649:         case ASC_NOERROR:
                   6650:             ASC_STATS(scp->host, exe_noerror);
                   6651:             /*
                   6652:              * Increment monotonically increasing per device successful
                   6653:              * request counter. Wrapping doesn't matter.
                   6654:              */
                   6655:             boardp->reqcnt[scp->target]++;
                   6656:             asc_enqueue(&boardp->active, scp, ASC_BACK);
                   6657:             ASC_DBG(1,
                   6658:                 "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
                   6659:             break;
                   6660:         case ASC_BUSY:
                   6661:             /* Caller must enqueue request and retry later. */
                   6662:             ASC_STATS(scp->host, exe_busy);
                   6663:             break;
                   6664:         case ASC_ERROR:
                   6665:             ASC_PRINT2(
                   6666: "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code %x\n",
                   6667:                 boardp->id, adv_dvc_varp->err_code);
                   6668:             ASC_STATS(scp->host, exe_error);
                   6669:             scp->result = HOST_BYTE(DID_ERROR);
                   6670:             asc_enqueue(&boardp->done, scp, ASC_BACK);
                   6671:             break;
                   6672:         default:
                   6673:             ASC_PRINT2(
                   6674: "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code %x\n",
                   6675:                 boardp->id, adv_dvc_varp->err_code);
                   6676:             ASC_STATS(scp->host, exe_unknown);
                   6677:             scp->result = HOST_BYTE(DID_ERROR);
                   6678:             asc_enqueue(&boardp->done, scp, ASC_BACK);
                   6679:             break;
                   6680:         }
                   6681:     }
                   6682: 
                   6683:     ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
                   6684:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
                   6685:     return ret;
                   6686: }
                   6687: 
                   6688: /*
                   6689:  * Build a request structure for the Asc Library (Narrow Board).
                   6690:  *
                   6691:  * The global structures 'asc_scsi_q' and 'asc_sg_head' are
                   6692:  * used to build the request.
                   6693:  *
                   6694:  * If an error occurs, then return ASC_ERROR.
                   6695:  */
                   6696: STATIC int
                   6697: asc_build_req(asc_board_t *boardp, Scsi_Cmnd *scp)
                   6698: {
                   6699:     /*
                   6700:      * Mutually exclusive access is required to 'asc_scsi_q' and
                   6701:      * 'asc_sg_head' until after the request is started.
                   6702:      */
                   6703:     memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
                   6704: 
                   6705:     /*
                   6706:      * Point the ASC_SCSI_Q to the 'Scsi_Cmnd'.
                   6707:      */
                   6708:     asc_scsi_q.q2.srb_ptr = (ulong) scp;
                   6709: 
                   6710:     /*
                   6711:      * Build the ASC_SCSI_Q request.
                   6712:      */
                   6713:     ASC_ASSERT(scp->cmd_len <= ASC_MAX_CDB_LEN);
                   6714:     if (scp->cmd_len > ASC_MAX_CDB_LEN) {
                   6715:         scp->cmd_len = ASC_MAX_CDB_LEN;
                   6716:     }
                   6717:     asc_scsi_q.cdbptr = &scp->cmnd[0];
                   6718:     asc_scsi_q.q2.cdb_len = scp->cmd_len;
                   6719:     asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->target);
                   6720:     asc_scsi_q.q1.target_lun = scp->lun;
                   6721:     asc_scsi_q.q2.target_ix = ASC_TIDLUN_TO_IX(scp->target, scp->lun);
                   6722: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
                   6723:     asc_scsi_q.q1.sense_addr = (ulong) &scp->sense_buffer[0];
                   6724: #else /* version >= v2.0.0 */
                   6725:     asc_scsi_q.q1.sense_addr = virt_to_bus(&scp->sense_buffer[0]);
                   6726: #endif /* version >= v2.0.0 */
                   6727:     asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
                   6728: 
                   6729:     /*
                   6730:      * If there are any outstanding requests for the current target,
                   6731:      * then every 255th request send an ORDERED request. This heuristic
                   6732:      * tries to retain the benefit of request sorting while preventing
                   6733:      * request starvation. 255 is the max number of tags or pending commands
                   6734:      * a device may have outstanding.
                   6735:      *
                   6736:      * The request count is incremented below for every successfully
                   6737:      * started request.
                   6738:      * 
                   6739:      */
                   6740:     if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->target] > 0) &&
                   6741:         (boardp->reqcnt[scp->target] % 255) == 0) {
                   6742:         asc_scsi_q.q2.tag_code = M2_QTAG_MSG_ORDERED;
                   6743:     } else {
                   6744:         asc_scsi_q.q2.tag_code = M2_QTAG_MSG_SIMPLE;
                   6745:     }
                   6746: 
                   6747:     /*
                   6748:      * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
                   6749:      * buffer command.
                   6750:      */
                   6751:     if (scp->use_sg == 0) {
                   6752:         /*
                   6753:          * CDB request of single contiguous buffer.
                   6754:          */
                   6755:         ASC_STATS(scp->host, cont_cnt);
                   6756: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
                   6757:         asc_scsi_q.q1.data_addr = (ulong) scp->request_buffer;
                   6758: #else /* version >= v2.0.0 */
                   6759:         asc_scsi_q.q1.data_addr = virt_to_bus(scp->request_buffer);
                   6760: #endif /* version >= v2.0.0 */
                   6761:         asc_scsi_q.q1.data_cnt = scp->request_bufflen;
                   6762:         ASC_STATS_ADD(scp->host, cont_xfer,
                   6763:                       ASC_CEILING(scp->request_bufflen, 512));
                   6764:         asc_scsi_q.q1.sg_queue_cnt = 0;
                   6765:         asc_scsi_q.sg_head = NULL;
                   6766:     } else {
                   6767:         /*
                   6768:          * CDB scatter-gather request list.
                   6769:          */
                   6770:         int                     sgcnt;
                   6771:         struct scatterlist      *slp;
                   6772: 
                   6773:         if (scp->use_sg > scp->host->sg_tablesize) {
                   6774:             ASC_PRINT3(
                   6775: "asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
                   6776:                 boardp->id, scp->use_sg, scp->host->sg_tablesize);
                   6777:             scp->result = HOST_BYTE(DID_ERROR);
                   6778:             asc_enqueue(&boardp->done, scp, ASC_BACK);
                   6779:             return ASC_ERROR;
                   6780:         }
                   6781: 
                   6782:         ASC_STATS(scp->host, sg_cnt);
                   6783: 
                   6784:         /*
                   6785:          * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
                   6786:          * structure to point to it.
                   6787:          */
                   6788:         memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
                   6789: 
                   6790:         asc_scsi_q.q1.cntl |= QC_SG_HEAD;
                   6791:         asc_scsi_q.sg_head = &asc_sg_head;
                   6792:         asc_scsi_q.q1.data_cnt = 0;
                   6793:         asc_scsi_q.q1.data_addr = 0;
                   6794:         asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = scp->use_sg;
                   6795:         ASC_STATS_ADD(scp->host, sg_elem, asc_sg_head.entry_cnt);
                   6796: 
                   6797:         /*
                   6798:          * Convert scatter-gather list into ASC_SG_HEAD list.
                   6799:          */
                   6800:         slp = (struct scatterlist *) scp->request_buffer;
                   6801:         for (sgcnt = 0; sgcnt < scp->use_sg; sgcnt++, slp++) {
                   6802: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
                   6803:             asc_sg_head.sg_list[sgcnt].addr = (ulong) slp->address;
                   6804: #else /* version >= v2.0.0 */
                   6805:             asc_sg_head.sg_list[sgcnt].addr = virt_to_bus(slp->address);
                   6806: #endif /* version >= v2.0.0 */
                   6807:             asc_sg_head.sg_list[sgcnt].bytes = slp->length;
                   6808:             ASC_STATS_ADD(scp->host, sg_xfer, ASC_CEILING(slp->length, 512));
                   6809:         }
                   6810:     }
                   6811: 
                   6812:     ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
                   6813:     ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
                   6814: 
                   6815:     return ASC_NOERROR;
                   6816: }
                   6817: 
                   6818: /*
                   6819:  * Build a request structure for the Adv Library (Wide Board).
                   6820:  *
                   6821:  * If an adv_req_t can not be allocated to issue the request,
                   6822:  * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
                   6823:  */
                   6824: STATIC int
                   6825: adv_build_req(asc_board_t *boardp, Scsi_Cmnd *scp,
                   6826:     ADV_SCSI_REQ_Q **adv_scsiqpp)
                   6827: {
                   6828:     adv_req_t           *reqp;
                   6829:     ADV_SCSI_REQ_Q      *scsiqp;
                   6830:     int                 i;
                   6831: 
                   6832:     /*
                   6833:      * Allocate an adv_req_t structure from the board to execute
                   6834:      * the command.
                   6835:      */
                   6836:     if (boardp->adv_reqp == NULL) {
                   6837:         ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
                   6838:         ASC_STATS(scp->host, adv_build_noreq);
                   6839:         return ASC_BUSY;
                   6840:     } else {
                   6841:         reqp = boardp->adv_reqp;
                   6842:         boardp->adv_reqp = reqp->next_reqp;
                   6843:         reqp->next_reqp = NULL;
                   6844:     }
                   6845: 
                   6846:     /*
                   6847:      * Get 4-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
                   6848:      */
                   6849:     scsiqp = (ADV_SCSI_REQ_Q *) ADV_DWALIGN(&reqp->scsi_req_q);
                   6850:     memset(scsiqp, 0, sizeof(ADV_SCSI_REQ_Q));
                   6851: 
                   6852:     /*
                   6853:      * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
                   6854:      */
                   6855:     scsiqp->srb_ptr = (ulong) reqp;
                   6856: 
                   6857:     /*
                   6858:      * Set the adv_req_t 'cmndp' to point to the Scsi_Cmnd structure.
                   6859:      */
                   6860:     reqp->cmndp = scp;
                   6861: 
                   6862:     /*
                   6863:      * Build the ADV_SCSI_REQ_Q request.
                   6864:      */
                   6865: 
                   6866:     /*
                   6867:      * Set CDB length and copy it to the request structure.
                   6868:      */
                   6869:     ASC_ASSERT(scp->cmd_len <= ASC_MAX_CDB_LEN);
                   6870:     if (scp->cmd_len > ASC_MAX_CDB_LEN) {
                   6871:         scp->cmd_len = ASC_MAX_CDB_LEN;
                   6872:     }
                   6873:     scsiqp->cdb_len = scp->cmd_len;
                   6874:     for (i = 0; i < scp->cmd_len; i++) {
                   6875:         scsiqp->cdb[i] = scp->cmnd[i];
                   6876:     }
                   6877: 
                   6878:     scsiqp->target_id = scp->target;
                   6879:     scsiqp->target_lun = scp->lun;
                   6880: 
                   6881:     scsiqp->vsense_addr = (ulong) &scp->sense_buffer[0];
                   6882: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
                   6883:     scsiqp->sense_addr = (ulong) &scp->sense_buffer[0];
                   6884: #else /* version >= v2.0.0 */
                   6885:     scsiqp->sense_addr = virt_to_bus(&scp->sense_buffer[0]);
                   6886: #endif /* version >= v2.0.0 */
                   6887:     scsiqp->sense_len = sizeof(scp->sense_buffer);
                   6888: 
                   6889:     /*
                   6890:      * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
                   6891:      * buffer command.
                   6892:      */
                   6893:     scsiqp->data_cnt = scp->request_bufflen;
                   6894:     scsiqp->vdata_addr = (ulong) scp->request_buffer;
                   6895: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
                   6896:     scsiqp->data_addr = (ulong) scp->request_buffer;
                   6897: #else /* version >= v2.0.0 */
                   6898:     scsiqp->data_addr = virt_to_bus(scp->request_buffer);
                   6899: #endif /* version >= v2.0.0 */
                   6900: 
                   6901:     if (scp->use_sg == 0) {
                   6902:         /*
                   6903:          * CDB request of single contiguous buffer.
                   6904:          */
                   6905:         reqp->sgblkp = NULL;
                   6906:         scsiqp->sg_list_ptr = NULL;
                   6907:         ASC_STATS(scp->host, cont_cnt);
                   6908:         ASC_STATS_ADD(scp->host, cont_xfer,
                   6909:                       ASC_CEILING(scp->request_bufflen, 512));
                   6910:     } else {
                   6911:         /*
                   6912:          * CDB scatter-gather request list.
                   6913:          */
                   6914:         if (scp->use_sg > ADV_MAX_SG_LIST) {
                   6915:             ASC_PRINT3(
                   6916: "adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
                   6917:                 boardp->id, scp->use_sg, scp->host->sg_tablesize);
                   6918:             scp->result = HOST_BYTE(DID_ERROR);
                   6919:             asc_enqueue(&boardp->done, scp, ASC_BACK);
                   6920: 
                   6921:             /*
                   6922:              * Free the 'adv_req_t' structure by adding it back to the
                   6923:              * board free list.
                   6924:              */
                   6925:             reqp->next_reqp = boardp->adv_reqp;
                   6926:             boardp->adv_reqp = reqp;
                   6927: 
                   6928:             return ASC_ERROR;
                   6929:         }
                   6930: 
                   6931:         /*
                   6932:          * Allocate an 'adv_sgblk_t' structure from the board to
                   6933:          * execute the command.
                   6934:          */
                   6935:         if (boardp->adv_sgblkp == NULL) {
                   6936:             ASC_DBG(1, "adv_build_req: no free adv_sgblk_t\n");
                   6937:             ASC_STATS(scp->host, adv_build_nosg);
                   6938:             /*
                   6939:              * Free the 'adv_req_t' structure by adding it back to the
                   6940:              * board free list.
                   6941:              */
                   6942:             reqp->next_reqp = boardp->adv_reqp;
                   6943:             boardp->adv_reqp = reqp;
                   6944:             return ASC_BUSY;
                   6945:         } else {
                   6946:             reqp->sgblkp = boardp->adv_sgblkp;
                   6947:             boardp->adv_sgblkp = reqp->sgblkp->next_sgblkp;
                   6948:             reqp->sgblkp->next_sgblkp = NULL;
                   6949:         }
                   6950: 
                   6951:         /*
                   6952:          * Build scatter-gather list.
                   6953:          */
                   6954:         scsiqp->sg_list_ptr = (ADV_SG_BLOCK *)
                   6955:             ADV_DWALIGN(&reqp->sgblkp->sg_block[0]);
                   6956: 
                   6957:         memset(scsiqp->sg_list_ptr, 0, sizeof(ADV_SG_BLOCK) *
                   6958:             (ADV_NUM_SG_BLOCK + ADV_NUM_PAGE_CROSSING));
                   6959:          
                   6960:         if (adv_get_sglist(&boardp->dvc_var.adv_dvc_var, scsiqp, scp) ==
                   6961:             ADV_ERROR) {
                   6962: 
                   6963:             /*
                   6964:              * Free the adv_sgblk_t structure, if any, by adding it back
                   6965:              * to the board free list.
                   6966:              */
                   6967:             ASC_ASSERT(reqp->sgblkp != NULL);
                   6968:             reqp->sgblkp->next_sgblkp = boardp->adv_sgblkp;
                   6969:             boardp->adv_sgblkp = reqp->sgblkp;
                   6970: 
                   6971:             /*
                   6972:              * Free the adv_req_t structure by adding it back to the
                   6973:              * board free list.
                   6974:              */
                   6975:             reqp->next_reqp = boardp->adv_reqp;
                   6976:             boardp->adv_reqp = reqp;
                   6977: 
                   6978:             return ADV_ERROR;
                   6979:         }
                   6980: 
                   6981:         ASC_STATS(scp->host, sg_cnt);
                   6982:         ASC_STATS_ADD(scp->host, sg_elem, scp->use_sg);
                   6983:     }
                   6984: 
                   6985:     ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
                   6986:     ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
                   6987: 
                   6988:     *adv_scsiqpp = scsiqp;
                   6989: 
                   6990:     return ASC_NOERROR;
                   6991: }
                   6992: 
                   6993: /*
                   6994:  * Build scatter-gather list for Adv Library (Wide Board).
                   6995:  *
                   6996:  * Return:
                   6997:  *      ADV_SUCCESS(1) - SG List successfully created
                   6998:  *      ADV_ERROR(-1) - SG List creation failed
                   6999:  */
                   7000: STATIC int
                   7001: adv_get_sglist(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp,
                   7002:     Scsi_Cmnd *scp)
                   7003: {
                   7004:     ADV_SG_BLOCK        *sg_block;              /* virtual address of a SG */
                   7005:     ulong               sg_block_next_addr;     /* block and its next */
                   7006:     ulong               sg_block_physical_addr;
                   7007:     int                 sg_block_index, i;      /* how many SG entries */
                   7008:     struct scatterlist  *slp;
                   7009:     int                 sg_elem_cnt;
                   7010: 
                   7011:     slp = (struct scatterlist *) scp->request_buffer;
                   7012:     sg_elem_cnt = scp->use_sg;
                   7013: 
                   7014:     sg_block = scsiqp->sg_list_ptr;
                   7015:     sg_block_next_addr = (ulong) sg_block;    /* allow math operation */
                   7016:     sg_block_physical_addr =
                   7017: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
                   7018:         (ulong) scsiqp->sg_list_ptr;
                   7019: #else /* version >= v2.0.0 */
                   7020:         virt_to_bus(scsiqp->sg_list_ptr);
                   7021: #endif /* version >= v2.0.0 */
                   7022:     ADV_ASSERT(ADV_DWALIGN(sg_block_physical_addr) ==
                   7023:                    sg_block_physical_addr);
                   7024:     scsiqp->sg_real_addr = sg_block_physical_addr;
                   7025: 
                   7026:     sg_block_index = 0;
                   7027:     do
                   7028:     {
                   7029:         sg_block->first_entry_no = sg_block_index;
                   7030:         for (i = 0; i < NO_OF_SG_PER_BLOCK; i++)
                   7031:         {
                   7032:             sg_block->sg_list[i].sg_addr =
                   7033: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
                   7034:                 (ulong) slp->address;
                   7035: #else /* version >= v2.0.0 */
                   7036:                 virt_to_bus(slp->address);
                   7037: #endif /* version >= v2.0.0 */
                   7038:             sg_block->sg_list[i].sg_count = slp->length;
                   7039:             ASC_STATS_ADD(scp->host, sg_xfer, ASC_CEILING(slp->length, 512));
                   7040: 
                   7041:             if (--sg_elem_cnt == 0)
                   7042:             {   /* last entry, get out */
                   7043:                 scsiqp->sg_entry_cnt = sg_block_index + i + 1;
                   7044:                 sg_block->last_entry_no = sg_block_index + i;
                   7045:                 sg_block->sg_ptr = 0L;    /* next link = NULL */
                   7046:                 return ADV_SUCCESS;
                   7047:             }
                   7048:             slp++;
                   7049:         } 
                   7050:         sg_block_next_addr += sizeof(ADV_SG_BLOCK);
                   7051:         sg_block_physical_addr += sizeof(ADV_SG_BLOCK);
                   7052:         ADV_ASSERT(ADV_DWALIGN(sg_block_physical_addr) ==
                   7053:                        sg_block_physical_addr);
                   7054: 
                   7055:         sg_block_index += NO_OF_SG_PER_BLOCK;
                   7056:         sg_block->sg_ptr = (ADV_SG_BLOCK *) sg_block_physical_addr;
                   7057:         sg_block->last_entry_no = sg_block_index - 1;
                   7058:         sg_block = (ADV_SG_BLOCK *) sg_block_next_addr; /* virtual addr */
                   7059:     }
                   7060:     while (1);
                   7061:     /* NOTREACHED */
                   7062: }
                   7063: 
                   7064: /*
                   7065:  * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
                   7066:  *
                   7067:  * Interrupt callback function for the Narrow SCSI Asc Library.
                   7068:  */
                   7069: STATIC void
                   7070: asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
                   7071: {
                   7072:     asc_board_t         *boardp;
                   7073:     Scsi_Cmnd           *scp;
                   7074:     struct Scsi_Host    *shp;
                   7075:     int                 underrun = ASC_FALSE;
                   7076:     int                 i;
                   7077: 
                   7078:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
                   7079:     ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp %x, qdonep %x\n",
                   7080:         (unsigned) asc_dvc_varp, (unsigned) qdonep);
                   7081:     ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
                   7082: 
                   7083:     /*
                   7084:      * Get the Scsi_Cmnd structure and Scsi_Host structure for the
                   7085:      * command that has been completed.
                   7086:      */
                   7087:     scp = (Scsi_Cmnd *) qdonep->d2.srb_ptr;
                   7088:     ASC_DBG1(1, "asc_isr_callback: scp %x\n", (unsigned) scp);
                   7089: 
                   7090:     if (scp == NULL) {
                   7091:         ASC_PRINT("asc_isr_callback: scp is NULL\n");
                   7092:         return;
                   7093:     }
                   7094:     ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
                   7095: 
                   7096:     /*
                   7097:      * If the request's host pointer is not valid, display a
                   7098:      * message and return.
                   7099:      */
                   7100:     shp = scp->host;
                   7101:     for (i = 0; i < asc_board_count; i++) {
                   7102:         if (asc_host[i] == shp) {
                   7103:             break;
                   7104:         }
                   7105:     }
                   7106:     if (i == asc_board_count) {
                   7107:         ASC_PRINT2("asc_isr_callback: scp %x has bad host pointer, host %x\n",
                   7108:             (unsigned) scp, (unsigned) shp);
                   7109:         return;
                   7110:     }
                   7111: 
                   7112:     ASC_STATS(shp, callback);
                   7113:     ASC_DBG1(1, "asc_isr_callback: shp %x\n", (unsigned) shp);
                   7114: 
                   7115:     /*
                   7116:      * If the request isn't found on the active queue, it may
                   7117:      * have been removed to handle a reset or abort request.
                   7118:      * Display a message and return.
                   7119:      */
                   7120:     boardp = ASC_BOARDP(shp);
                   7121:     ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
                   7122:     if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
                   7123:         ASC_PRINT2("asc_isr_callback: board %d: scp %x not on active queue\n",
                   7124:             boardp->id, (unsigned) scp);
                   7125:         return;
                   7126:     }
                   7127: 
                   7128:     /*
                   7129:      * Check for an underrun condition.
                   7130:      */
                   7131:     if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 && 
                   7132:         qdonep->remain_bytes <= scp->request_bufflen != 0) {
                   7133:         ASC_DBG1(1, "asc_isr_callback: underrun condition %u bytes\n",
                   7134:         (unsigned) qdonep->remain_bytes);
                   7135:         underrun = ASC_TRUE;
                   7136:     }
                   7137: 
                   7138:     /*
                   7139:      * 'qdonep' contains the command's ending status.
                   7140:      */
                   7141:     switch (qdonep->d3.done_stat) {
                   7142:     case QD_NO_ERROR:
                   7143:         ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
                   7144:         switch (qdonep->d3.host_stat) {
                   7145:         case QHSTA_NO_ERROR:
                   7146:             scp->result = 0;
                   7147:             break;
                   7148:         default:
                   7149:             /* QHSTA error occurred */
                   7150:             scp->result = HOST_BYTE(DID_ERROR);
                   7151:             break;
                   7152:         }
                   7153: 
                   7154:         /*
                   7155:          * If an INQUIRY command completed successfully, then call
                   7156:          * the AscInquiryHandling() function to set-up the device.
                   7157:          */
                   7158:         if (scp->cmnd[0] == SCSICMD_Inquiry && scp->lun == 0 &&
                   7159:             (scp->request_bufflen - qdonep->remain_bytes) >= 8)
                   7160:         {
                   7161:             AscInquiryHandling(asc_dvc_varp, scp->target & 0x7,
                   7162:                 (ASC_SCSI_INQUIRY *) scp->request_buffer);
                   7163:         }
                   7164: 
                   7165:         /*
                   7166:          * If there was an underrun without any other error,
                   7167:          * set DID_ERROR to indicate the underrun error.
                   7168:          *
                   7169:          * Note: There is no way yet to indicate the number
                   7170:          * of underrun bytes.
                   7171:          */
                   7172:         if (scp->result == 0 && underrun == ASC_TRUE) {
                   7173:             scp->result = HOST_BYTE(DID_UNDERRUN);
                   7174:         }
                   7175:         break;
                   7176: 
                   7177:     case QD_WITH_ERROR:
                   7178:         ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
                   7179:         switch (qdonep->d3.host_stat) {
                   7180:         case QHSTA_NO_ERROR:
                   7181:             if (qdonep->d3.scsi_stat == SS_CHK_CONDITION) {
                   7182:                 ASC_DBG(2, "asc_isr_callback: SS_CHK_CONDITION\n");
                   7183:                 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
                   7184:                     sizeof(scp->sense_buffer));
                   7185:                 /*
                   7186:                  * Note: The 'status_byte()' macro used by target drivers
                   7187:                  * defined in scsi.h shifts the status byte returned by
                   7188:                  * host drivers right by 1 bit. This is why target drivers
                   7189:                  * also use right shifted status byte definitions. For
                   7190:                  * instance target drivers use CHECK_CONDITION, defined to
                   7191:                  * 0x1, instead of the SCSI defined check condition value
                   7192:                  * of 0x2. Host drivers are supposed to return the status
                   7193:                  * byte as it is defined by SCSI.
                   7194:                  */
                   7195:                 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
                   7196:                     STATUS_BYTE(qdonep->d3.scsi_stat); 
                   7197:             } else {
                   7198:                 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat); 
                   7199:             }
                   7200:             break;
                   7201: 
                   7202:         default:
                   7203:             /* QHSTA error occurred */
                   7204:             ASC_DBG1(1, "asc_isr_callback: host_stat %x\n",
                   7205:                 qdonep->d3.host_stat);
                   7206:             scp->result = HOST_BYTE(DID_BAD_TARGET);
                   7207:             break;
                   7208:         }
                   7209:         break;
                   7210: 
                   7211:     case QD_ABORTED_BY_HOST:
                   7212:         ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
                   7213:         scp->result = HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.scsi_msg) |
                   7214:                 STATUS_BYTE(qdonep->d3.scsi_stat);
                   7215:         break;
                   7216: 
                   7217:     default:
                   7218:         ASC_DBG1(1, "asc_isr_callback: done_stat %x\n", qdonep->d3.done_stat);
                   7219:         scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.scsi_msg) |
                   7220:                 STATUS_BYTE(qdonep->d3.scsi_stat);
                   7221:         break;
                   7222:     }
                   7223: 
                   7224:     /*
                   7225:      * If the 'init_tidmask' bit isn't already set for the target and the
                   7226:      * current request finished normally, then set the bit for the target
                   7227:      * to indicate that a device is present.
                   7228:      */
                   7229:     if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->target)) == 0 &&
                   7230:         qdonep->d3.done_stat == QD_NO_ERROR &&
                   7231:         qdonep->d3.host_stat == QHSTA_NO_ERROR) {
                   7232:         boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target);
                   7233:     }
                   7234: 
                   7235:     /* 
                   7236:      * Because interrupts may be enabled by the 'Scsi_Cmnd' done
                   7237:      * function, add the command to the end of the board's done queue.
                   7238:      * The done function for the command will be called from
                   7239:      * advansys_interrupt().
                   7240:      */
                   7241:     asc_enqueue(&boardp->done, scp, ASC_BACK);
                   7242: 
                   7243:     return;
                   7244: }
                   7245: 
                   7246: /*
                   7247:  * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
                   7248:  *
                   7249:  * Callback function for the Wide SCSI Adv Library.
                   7250:  */
                   7251: STATIC void
                   7252: adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
                   7253: {
                   7254:     asc_board_t         *boardp;
                   7255:     adv_req_t           *reqp;
                   7256:     Scsi_Cmnd           *scp;
                   7257:     struct Scsi_Host    *shp;
                   7258:     int                 underrun = ASC_FALSE;
                   7259:     int                 i;
                   7260: 
                   7261:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
                   7262:     ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp %x, scsiqp %x\n",
                   7263:         (unsigned) adv_dvc_varp, (unsigned) scsiqp);
                   7264:     ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
                   7265: 
                   7266:     /*
                   7267:      * Get the adv_req_t structure for the command that has been
                   7268:      * completed. The adv_req_t structure actually contains the
                   7269:      * completed ADV_SCSI_REQ_Q structure.
                   7270:      */
                   7271:     reqp = (adv_req_t *) scsiqp->srb_ptr;
                   7272:     ASC_DBG1(1, "adv_isr_callback: reqp %x\n", (unsigned) reqp);
                   7273:     if (reqp == NULL) {
                   7274:         ASC_PRINT("adv_isr_callback: reqp is NULL\n");
                   7275:         return;
                   7276:     }
                   7277: 
                   7278:     /*
                   7279:      * Get the Scsi_Cmnd structure and Scsi_Host structure for the
                   7280:      * command that has been completed.
                   7281:      *
                   7282:      * Note: The adv_req_t request structure and adv_sgblk_t structure,
                   7283:      * if any, * dropped, because a board structure pointer can not be
                   7284:      * determined.
                   7285:      */
                   7286:     scp = reqp->cmndp;
                   7287:     ASC_DBG1(1, "adv_isr_callback: scp %x\n", (unsigned) scp);
                   7288:     if (scp == NULL) {
                   7289:         ASC_PRINT("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
                   7290:         return;
                   7291:     }
                   7292:     ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
                   7293: 
                   7294:     /*
                   7295:      * If the request's host pointer is not valid, display a message
                   7296:      * and return.
                   7297:      */
                   7298:     shp = scp->host;
                   7299:     for (i = 0; i < asc_board_count; i++) {
                   7300:         if (asc_host[i] == shp) {
                   7301:             break;
                   7302:         }
                   7303:     }
                   7304:     /*
                   7305:      * Note: If the host structure is not found, the adv_req_t request
                   7306:      * structure and adv_sgblk_t structure, if any, is dropped.
                   7307:      */
                   7308:     if (i == asc_board_count) {
                   7309:         ASC_PRINT2("adv_isr_callback: scp %x has bad host pointer, host %x\n",
                   7310:             (unsigned) scp, (unsigned) shp);
                   7311:         return;
                   7312:     }
                   7313: 
                   7314:     ASC_STATS(shp, callback);
                   7315:     ASC_DBG1(1, "adv_isr_callback: shp %x\n", (unsigned) shp);
                   7316: 
                   7317:     /*
                   7318:      * If the request isn't found on the active queue, it may have been
                   7319:      * removed to handle a reset or abort request. Display a message and
                   7320:      * return.
                   7321:      *
                   7322:      * Note: Because the structure may still be in use don't attempt
                   7323:      * to free the adv_req_t and adv_sgblk_t, if any, structures.
                   7324:      */
                   7325:     boardp = ASC_BOARDP(shp);
                   7326:     ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
                   7327:     if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
                   7328:         ASC_PRINT2("adv_isr_callback: board %d: scp %x not on active queue\n",
                   7329:             boardp->id, (unsigned) scp);
                   7330:         return;
                   7331:     }
                   7332: 
                   7333:     /*
                   7334:      * Check for an underrun condition.
                   7335:      */
                   7336:     if (scp->request_bufflen != 0 && scsiqp->data_cnt != 0) {
                   7337:         ASC_DBG1(1, "adv_isr_callback: underrun condition %lu bytes\n",
                   7338:         scsiqp->data_cnt);
                   7339:         underrun = ASC_TRUE;
                   7340:     }
                   7341: 
                   7342:     /*
                   7343:      * 'done_status' contains the command's ending status.
                   7344:      */
                   7345:     switch (scsiqp->done_status) {
                   7346:     case QD_NO_ERROR:
                   7347:         ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
                   7348:         switch (scsiqp->host_status) {
                   7349:         case QHSTA_NO_ERROR:
                   7350:             scp->result = 0;
                   7351:             break;
                   7352:         default:
                   7353:             /* QHSTA error occurred. */
                   7354:             ASC_DBG1(2, "adv_isr_callback: host_status %x\n",
                   7355:                 scsiqp->host_status);
                   7356:             scp->result = HOST_BYTE(DID_ERROR);
                   7357:             break;
                   7358:         }
                   7359:         /*
                   7360:          * If there was an underrun without any other error,
                   7361:          * set DID_ERROR to indicate the underrun error.
                   7362:          *
                   7363:          * Note: There is no way yet to indicate the number
                   7364:          * of underrun bytes.
                   7365:          */
                   7366:         if (scp->result == 0 && underrun == ASC_TRUE) {
                   7367:                 scp->result = HOST_BYTE(DID_UNDERRUN);
                   7368:         }
                   7369:         break;
                   7370: 
                   7371:     case QD_WITH_ERROR:
                   7372:         ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
                   7373:         switch (scsiqp->host_status) {
                   7374:         case QHSTA_NO_ERROR:
                   7375:             if (scsiqp->scsi_status == SS_CHK_CONDITION) {
                   7376:                 ASC_DBG(2, "adv_isr_callback: SS_CHK_CONDITION\n");
                   7377:                 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
                   7378:                     sizeof(scp->sense_buffer));
                   7379:                 /*
                   7380:                  * Note: The 'status_byte()' macro used by target drivers
                   7381:                  * defined in scsi.h shifts the status byte returned by
                   7382:                  * host drivers right by 1 bit. This is why target drivers
                   7383:                  * also use right shifted status byte definitions. For
                   7384:                  * instance target drivers use CHECK_CONDITION, defined to
                   7385:                  * 0x1, instead of the SCSI defined check condition value
                   7386:                  * of 0x2. Host drivers are supposed to return the status
                   7387:                  * byte as it is defined by SCSI.
                   7388:                  */
                   7389:                 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
                   7390:                     STATUS_BYTE(scsiqp->scsi_status);
                   7391:             } else {
                   7392:                 scp->result = STATUS_BYTE(scsiqp->scsi_status);
                   7393:             }
                   7394:             break;
                   7395: 
                   7396:         default:
                   7397:             /* Some other QHSTA error occurred. */
                   7398:             ASC_DBG1(1, "adv_isr_callback: host_status %x\n",
                   7399:                 scsiqp->host_status);
                   7400:             scp->result = HOST_BYTE(DID_BAD_TARGET);
                   7401:             break;
                   7402:         }
                   7403:         break;
                   7404: 
                   7405:     case QD_ABORTED_BY_HOST:
                   7406:         ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
                   7407:         scp->result = HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
                   7408:         break;
                   7409: 
                   7410:     default:
                   7411:         ASC_DBG1(1, "adv_isr_callback: done_status %x\n", scsiqp->done_status);
                   7412:         scp->result = HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
                   7413:         break;
                   7414:     }
                   7415: 
                   7416:     /*
                   7417:      * If the 'init_tidmask' bit isn't already set for the target and the
                   7418:      * current request finished normally, then set the bit for the target
                   7419:      * to indicate that a device is present.
                   7420:      */
                   7421:     if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->target)) == 0 &&
                   7422:         scsiqp->done_status == QD_NO_ERROR &&
                   7423:         scsiqp->host_status == QHSTA_NO_ERROR) {
                   7424:         boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target);
                   7425:     }
                   7426: 
                   7427:     /* 
                   7428:      * Because interrupts may be enabled by the 'Scsi_Cmnd' done
                   7429:      * function, add the command to the end of the board's done queue.
                   7430:      * The done function for the command will be called from
                   7431:      * advansys_interrupt().
                   7432:      */
                   7433:     asc_enqueue(&boardp->done, scp, ASC_BACK);
                   7434: 
                   7435:     /*
                   7436:      * Free the adv_sgblk_t structure, if any, by adding it back
                   7437:      * to the board free list.
                   7438:      */
                   7439:     if (reqp->sgblkp != NULL) {
                   7440:         reqp->sgblkp->next_sgblkp = boardp->adv_sgblkp;
                   7441:         boardp->adv_sgblkp = reqp->sgblkp;
                   7442:     }
                   7443: 
                   7444:     /*
                   7445:      * Free the adv_req_t structure used with the command by adding
                   7446:      * it back to the board free list.
                   7447:      */
                   7448:     reqp->next_reqp = boardp->adv_reqp;
                   7449:     boardp->adv_reqp = reqp;
                   7450: 
                   7451:     ASC_DBG(1, "adv_isr_callback: done\n");
                   7452: 
                   7453:     return;
                   7454: }
                   7455: 
                   7456: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
                   7457: #ifdef ASC_CONFIG_PCI
                   7458: /*
                   7459:  * Search for an AdvanSys PCI device in the PCI configuration space.
                   7460:  */
                   7461: ASC_INITFUNC(
                   7462: STATIC int
                   7463: asc_srch_pci_dev(PCI_DEVICE *pciDevice)
                   7464: )
                   7465: {
                   7466:     int                        ret = PCI_DEVICE_NOT_FOUND;
                   7467: 
                   7468:     ASC_DBG(2, "asc_srch_pci_dev: begin\n");
                   7469: 
                   7470:     if (pci_scan_method == -1) {
                   7471:         pci_scan_method = asc_scan_method();
                   7472:     }
                   7473:     pciDevice->type = pci_scan_method;
                   7474:     ASC_DBG1(2, "asc_srch_pci_dev: type %d\n", pciDevice->type);
                   7475: 
                   7476:     ret = asc_pci_find_dev(pciDevice);
                   7477:     ASC_DBG1(2, "asc_srch_pci_dev: asc_pci_find_dev() return %d\n", ret);
                   7478:     if (ret == PCI_DEVICE_FOUND) {
                   7479:         pciDevice->slotNumber = pciDevice->slotFound + 1;
                   7480:         pciDevice->startSlot = pciDevice->slotFound + 1;
                   7481:     } else {
                   7482:         if (pciDevice->bridge > pciDevice->busNumber) {
                   7483:             ASC_DBG2(2, "asc_srch_pci_dev: bridge %x, busNumber %x\n",
                   7484:                 pciDevice->bridge, pciDevice->busNumber);
                   7485:             pciDevice->busNumber++;
                   7486:             pciDevice->slotNumber = 0;
                   7487:             pciDevice->startSlot = 0;
                   7488:             pciDevice->endSlot = 0x0f;
                   7489:             ret = asc_srch_pci_dev(pciDevice);
                   7490:             ASC_DBG1(2, "asc_srch_pci_dev: recursive call return %d\n", ret);
                   7491:         }
                   7492:     }
                   7493: 
                   7494:     ASC_DBG1(2, "asc_srch_pci_dev: return %d\n", ret);
                   7495:     return ret;
                   7496: }
                   7497: 
                   7498: /*
                   7499:  * Determine the access method to be used for 'pciDevice'.
                   7500:  */
                   7501: ASC_INITFUNC(
                   7502: STATIC uchar
                   7503: asc_scan_method(void)
                   7504: )
                   7505: {
                   7506:     ushort      data;
                   7507:     PCI_DATA    pciData;
                   7508:     uchar       type;
                   7509:     uchar       slot;
                   7510: 
                   7511:     ASC_DBG(2, "asc_scan_method: begin\n");
                   7512:     memset(&pciData, 0, sizeof(pciData));
                   7513:     for (type = 1; type < 3; type++) {
                   7514:         pciData.type = type;
                   7515:         for (slot = 0; slot < PCI_MAX_SLOT; slot++) {
                   7516:             pciData.slot = slot;
                   7517:             data = asc_get_cfg_word(&pciData);
                   7518:             if ((data != 0xFFFF) && (data != 0x0000)) {
                   7519:                 ASC_DBG2(4, "asc_scan_method: data %x, type %d\n", data, type);
                   7520:                 return (type);
                   7521:             }
                   7522:         }
                   7523:     }
                   7524:     ASC_DBG1(4, "asc_scan_method: type %d\n", type);
                   7525:     return (type);
                   7526: }
                   7527: 
                   7528: /*
                   7529:  * Check for an AdvanSys PCI device in 'pciDevice'.
                   7530:  *
                   7531:  * Return PCI_DEVICE_FOUND if found, otherwise return PCI_DEVICE_NOT_FOUND.
                   7532:  */
                   7533: ASC_INITFUNC(
                   7534: STATIC int
                   7535: asc_pci_find_dev(PCI_DEVICE *pciDevice)
                   7536: )
                   7537: {
                   7538:     PCI_DATA    pciData;
                   7539:     ushort      vendorid, deviceid;
                   7540:     uchar       classcode, subclass;
                   7541:     uchar       lslot;
                   7542: 
                   7543:     ASC_DBG(3, "asc_pci_find_dev: begin\n");
                   7544:     pciData.type = pciDevice->type;
                   7545:     pciData.bus = pciDevice->busNumber;
                   7546:     pciData.func = pciDevice->devFunc;
                   7547:     lslot = pciDevice->startSlot;
                   7548:     for (; lslot < pciDevice->endSlot; lslot++) {
                   7549:         pciData.slot = lslot;
                   7550:         pciData.offset = VENDORID_OFFSET;
                   7551:         vendorid = asc_get_cfg_word(&pciData);
                   7552:         ASC_DBG1(3, "asc_pci_find_dev: vendorid %x\n", vendorid);
                   7553:         if (vendorid != 0xffff) {
                   7554:             pciData.offset = DEVICEID_OFFSET;
                   7555:             deviceid = asc_get_cfg_word(&pciData);
                   7556:             ASC_DBG1(3, "asc_pci_find_dev: deviceid %x\n", deviceid);
                   7557:             if ((vendorid == ASC_PCI_VENDORID) &&
                   7558:                 ((deviceid == ASC_PCI_DEVICE_ID_1100) ||
                   7559:                  (deviceid == ASC_PCI_DEVICE_ID_1200) ||
                   7560:                  (deviceid == ASC_PCI_DEVICE_ID_1300) ||
                   7561:                  (deviceid == ASC_PCI_DEVICE_ID_2300))) {
                   7562:                 pciDevice->slotFound = lslot;
                   7563:                 ASC_DBG(3, "asc_pci_find_dev: PCI_DEVICE_FOUND\n");
                   7564:                 return PCI_DEVICE_FOUND;
                   7565:             } else {
                   7566:                 pciData.offset = SUBCLASS_OFFSET;
                   7567:                 subclass = asc_get_cfg_byte(&pciData);
                   7568:                 pciData.offset = CLASSCODE_OFFSET;
                   7569:                 classcode = asc_get_cfg_byte(&pciData);
                   7570:                 if ((classcode & PCI_BASE_CLASS_BRIDGE_DEVICE) &&
                   7571:                     (subclass & PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER)) {
                   7572:                     pciDevice->bridge++;
                   7573:                 }
                   7574:                 ASC_DBG2(3, "asc_pci_find_dev: subclass %x, classcode %x\n",
                   7575:                     subclass, classcode);
                   7576:             }
                   7577:         }
                   7578:     }
                   7579:     return PCI_DEVICE_NOT_FOUND;
                   7580: }
                   7581: 
                   7582: /*
                   7583:  * Read PCI configuration data into 'pciConfig'.
                   7584:  */
                   7585: ASC_INITFUNC(
                   7586: STATIC void
                   7587: asc_get_pci_cfg(PCI_DEVICE *pciDevice, PCI_CONFIG_SPACE *pciConfig)
                   7588: )
                   7589: {
                   7590:     PCI_DATA    pciData;
                   7591:     uchar       counter;
                   7592:     uchar       *localConfig;
                   7593: 
                   7594:     ASC_DBG1(4, "asc_get_pci_cfg: slotFound %d\n ",
                   7595:         pciDevice->slotFound);
                   7596: 
                   7597:     pciData.type = pciDevice->type;
                   7598:     pciData.bus = pciDevice->busNumber;
                   7599:     pciData.slot = pciDevice->slotFound;
                   7600:     pciData.func = pciDevice->devFunc;
                   7601:     localConfig = (uchar *) pciConfig;
                   7602: 
                   7603:     for (counter = 0; counter < sizeof(PCI_CONFIG_SPACE); counter++) {
                   7604:         pciData.offset = counter;
                   7605:         *localConfig = asc_get_cfg_byte(&pciData);
                   7606:         ASC_DBG1(4, "asc_get_pci_cfg: byte %x\n", *localConfig);
                   7607:         localConfig++;
                   7608:     }
                   7609:     ASC_DBG1(4, "asc_get_pci_cfg: counter %d\n", counter);
                   7610: }
                   7611: 
                   7612: /*
                   7613:  * Read a word (16 bits) from the PCI configuration space.
                   7614:  *
                   7615:  * The configuration mechanism is checked for the correct access method.
                   7616:  */
                   7617: ASC_INITFUNC(
                   7618: STATIC ushort
                   7619: asc_get_cfg_word(PCI_DATA *pciData)
                   7620: )
                   7621: {
                   7622:     ushort   tmp;
                   7623:     ulong    address;
                   7624:     ulong    lbus = pciData->bus;
                   7625:     ulong    lslot = pciData->slot;
                   7626:     ulong    lfunc = pciData->func;
                   7627:     uchar    t2CFA, t2CF8;
                   7628:     ulong    t1CF8, t1CFC;
                   7629: 
                   7630:     ASC_DBG4(4, "asc_get_cfg_word: type %d, bus %lu, slot %lu, func %lu\n",
                   7631:         pciData->type, lbus, lslot, lfunc);
                   7632: 
                   7633:     /*
                   7634:      * Check type of configuration mechanism.
                   7635:      */
                   7636:     if (pciData->type == 2) {
                   7637:         /*
                   7638:          * Save registers to be restored later.
                   7639:          */
                   7640:         t2CFA = inp(0xCFA);    /* save PCI bus register */
                   7641:         t2CF8 = inp(0xCF8);    /* save config space enable register */
                   7642: 
                   7643:         /*
                   7644:          * Write the bus and enable registers.
                   7645:          */
                   7646:         /* set for type 1 cycle, if needed */
                   7647:         outp(0xCFA, pciData->bus);
                   7648:         /* set the function number */
                   7649:         outp(0xCF8, 0x10 | (pciData->func << 1)) ;
                   7650: 
                   7651:         /*
                   7652:          * Read the configuration space type 2 locations.
                   7653:          */
                   7654:         tmp = (ushort) inpw(0xC000 | ((pciData->slot << 8) + pciData->offset));
                   7655: 
                   7656:         outp(0xCFA, t2CFA);    /* save PCI bus register */
                   7657:         outp(0xCF8, t2CF8);    /* save config space enable register */
                   7658:     } else {
                   7659:         /*
                   7660:          * Type 1 or 3 configuration mechanism.
                   7661:          *
                   7662:          * Save the CONFIG_ADDRESS and CONFIG_DATA register values.
                   7663:          */
                   7664:         t1CF8 = inpl(0xCF8);
                   7665:         t1CFC = inpl(0xCFC);
                   7666: 
                   7667:         /*
                   7668:          * enable <31>, bus = <23:16>, slot = <15:11>,
                   7669:          * func = <10:8>, reg = <7:2>
                   7670:          */
                   7671:         address = (ulong) ((lbus << 16) | (lslot << 11) |
                   7672:             (lfunc << 8) | (pciData->offset & 0xFC) | 0x80000000L);
                   7673: 
                   7674:         /*
                   7675:          * Write out the address to CONFIG_ADDRESS.
                   7676:          */
                   7677:         outpl(0xCF8, address);
                   7678: 
                   7679:         /*
                   7680:          * Read in word from CONFIG_DATA.
                   7681:          */
                   7682:         tmp = (ushort) ((inpl(0xCFC) >>
                   7683:                  ((pciData->offset & 2) * 8)) & 0xFFFF);
                   7684: 
                   7685:         /*
                   7686:          * Restore registers.
                   7687:          */
                   7688:         outpl(0xCF8, t1CF8);
                   7689:         outpl(0xCFC, t1CFC);
                   7690:     }
                   7691:     ASC_DBG1(4, "asc_get_cfg_word: config data: %x\n", tmp);
                   7692:     return tmp;
                   7693: }
                   7694: 
                   7695: /*
                   7696:  * Reads a byte from the PCI configuration space.
                   7697:  *
                   7698:  * The configuration mechanism is checked for the correct access method.
                   7699:  */
                   7700: ASC_INITFUNC(
                   7701: STATIC uchar
                   7702: asc_get_cfg_byte(PCI_DATA *pciData)
                   7703: )
                   7704: {
                   7705:     uchar tmp;
                   7706:     ulong address;
                   7707:     ulong lbus = pciData->bus, lslot = pciData->slot, lfunc = pciData->func;
                   7708:     uchar t2CFA, t2CF8;
                   7709:     ulong t1CF8, t1CFC;
                   7710: 
                   7711:     ASC_DBG1(4, "asc_get_cfg_byte: type: %d\n", pciData->type);
                   7712: 
                   7713:     /*
                   7714:      * Check type of configuration mechanism.
                   7715:      */
                   7716:     if (pciData->type == 2) {
                   7717:         /*
                   7718:          * Save registers to be restored later.
                   7719:          */
                   7720:         t2CFA = inp(0xCFA);    /* save PCI bus register */
                   7721:         t2CF8 = inp(0xCF8);    /* save config space enable register */
                   7722: 
                   7723:         /*
                   7724:          * Write the bus and enable registers.
                   7725:          */
                   7726:         /* set for type 1 cycle, if needed */
                   7727:         outp(0xCFA, pciData->bus);
                   7728:         /* set the function number */
                   7729:         outp(0xCF8, 0x10 | (pciData->func << 1));
                   7730: 
                   7731:         /*
                   7732:          * Read configuration space type 2 locations.
                   7733:          */
                   7734:         tmp = inp(0xC000 | ((pciData->slot << 8) + pciData->offset));
                   7735: 
                   7736:         /*
                   7737:          * Restore registers.
                   7738:          */
                   7739:         outp(0xCF8, t2CF8);    /* restore the enable register */
                   7740:         outp(0xCFA, t2CFA);    /* restore PCI bus register */
                   7741:     } else {
                   7742:         /*
                   7743:          * Type 1 or 3 configuration mechanism.
                   7744:          *
                   7745:          * Save CONFIG_ADDRESS and CONFIG_DATA register values.
                   7746:          */
                   7747:         t1CF8 = inpl(0xCF8);
                   7748:         t1CFC = inpl(0xCFC);
                   7749: 
                   7750:         /*
                   7751:          * enable <31>, bus = <23:16>, slot = <15:11>, func = <10:8>,
                   7752:          * reg = <7:2>
                   7753:          */
                   7754:         address = (ulong) ((lbus << 16) | (lslot << 11) |
                   7755:             (lfunc << 8) | (pciData->offset & 0xFC) | 0x80000000L);
                   7756: 
                   7757:         /*
                   7758:          * Write out address to CONFIG_ADDRESS.
                   7759:          */
                   7760:         outpl(0xCF8, address);
                   7761: 
                   7762:         /*
                   7763:          * Read in word from CONFIG_DATA.
                   7764:          */
                   7765:         tmp = (uchar) ((inpl(0xCFC) >> ((pciData->offset & 3) * 8)) & 0xFF);
                   7766: 
                   7767:         /*
                   7768:          * Restore registers.
                   7769:          */
                   7770:         outpl(0xCF8, t1CF8);
                   7771:         outpl(0xCFC, t1CFC);
                   7772:     }
                   7773:     ASC_DBG1(4, "asc_get_cfg_byte: config data: %x\n", tmp);
                   7774:     return tmp;
                   7775: }
                   7776: 
                   7777: /*
                   7778:  * Write a byte to the PCI configuration space.
                   7779:  */
                   7780: ASC_INITFUNC(
                   7781: STATIC void
                   7782: asc_put_cfg_byte(PCI_DATA *pciData, uchar byte_data)
                   7783: )
                   7784: {
                   7785:     ulong tmpl;
                   7786:     ulong address;
                   7787:     ulong lbus = pciData->bus, lslot = pciData->slot, lfunc = pciData->func;
                   7788:     uchar t2CFA, t2CF8;
                   7789:     ulong t1CF8, t1CFC;
                   7790: 
                   7791:     ASC_DBG2(4, "asc_put_cfg_byte: type: %d, byte_data %x\n",
                   7792:         pciData->type, byte_data);
                   7793: 
                   7794:     /*
                   7795:      * Check type of configuration mechanism.
                   7796:      */
                   7797:     if (pciData->type == 2) {
                   7798: 
                   7799:         /*
                   7800:          * Save registers to be restored later.
                   7801:          */
                   7802:         t2CFA = inp(0xCFA);    /* save PCI bus register */
                   7803:         t2CF8 = inp(0xCF8);    /* save config space enable register */
                   7804: 
                   7805:         /*
                   7806:          * Write bus and enable registers.
                   7807:          */
                   7808:         outp(0xCFA, pciData->bus);
                   7809: 
                   7810:         /*
                   7811:          * Set the function number.
                   7812:          */
                   7813:         outp(0xCF8, 0x10 | (pciData->func << 1));
                   7814: 
                   7815:         /*
                   7816:          * Write the configuration space type 2 locations.
                   7817:          */
                   7818:         outp(0xC000 | ((pciData->slot << 8) + pciData->offset), byte_data);
                   7819: 
                   7820:         /*
                   7821:          * Restore registers.
                   7822:          */
                   7823:         outp(0xCF8, t2CF8);    /* restore the enable register */
                   7824:         outp(0xCFA, t2CFA);    /* restore PCI bus register    */
                   7825:     } else {
                   7826: 
                   7827:         /*
                   7828:          * Type 1 or 3 configuration mechanism.
                   7829:          *
                   7830:          * Save the CONFIG_ADDRESS and CONFIG_DATA register values.
                   7831:          */
                   7832:         t1CF8 = inpl(0xCF8);
                   7833:         t1CFC = inpl(0xCFC);
                   7834: 
                   7835:         /*
                   7836:          * enable <31>, bus = <23:16>, slot = <15:11>, func = <10:8>,
                   7837:          * reg = <7:2>
                   7838:          */
                   7839:         address = (ulong) ((lbus << 16) | (lslot << 11) | (lfunc << 8) |
                   7840:                 (pciData->offset & 0xFC) | 0x80000000L);
                   7841:         /*
                   7842:          * Write out address to CONFIG_ADDRESS.
                   7843:          */
                   7844:         outpl(0xCF8, address);
                   7845: 
                   7846:         /*
                   7847:          * Write double word to CONFIG_DATA preserving the bytes
                   7848:          * in the double not written.
                   7849:          */
                   7850:         tmpl = inpl(0xCFC) & ~(0xFF << ((pciData->offset & 3) * 8));
                   7851:         outpl(0xCFC, tmpl | (byte_data << ((pciData->offset & 3) * 8)));
                   7852: 
                   7853:         /*
                   7854:          * Restore registers.
                   7855:          */
                   7856:         outpl(0xCF8, t1CF8);
                   7857:         outpl(0xCFC, t1CFC);
                   7858:     }
                   7859:     ASC_DBG(4, "asc_put_cfg_byte: end\n");
                   7860: }
                   7861: #endif /* ASC_CONFIG_PCI */
                   7862: #endif /* version < v2.1.93 */
                   7863: 
                   7864: /*
                   7865:  * Add a 'REQP' to the end of specified queue. Set 'tidmask'
                   7866:  * to indicate a command is queued for the device.
                   7867:  *
                   7868:  * 'flag' may be either ASC_FRONT or ASC_BACK.
                   7869:  *
                   7870:  * 'REQPNEXT(reqp)' returns reqp's next pointer.
                   7871:  */
                   7872: STATIC void
                   7873: asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
                   7874: {
                   7875:     int        tid;
                   7876: 
                   7877:     ASC_DBG3(3, "asc_enqueue: ascq %x, reqp %x, flag %d\n",
                   7878:         (unsigned) ascq, (unsigned) reqp, flag);
                   7879:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
                   7880:     ASC_ASSERT(reqp != NULL);
                   7881:     ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
                   7882:     tid = REQPTID(reqp);
                   7883:     ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
                   7884:     if (flag == ASC_FRONT) {
1.1.1.2 ! root     7885:         REQPNEXT(reqp) = (unsigned char *) ascq->q_first[tid];
1.1       root     7886:         ascq->q_first[tid] = reqp;
                   7887:         /* If the queue was empty, set the last pointer. */
                   7888:         if (ascq->q_last[tid] == NULL) {
                   7889:             ascq->q_last[tid] = reqp;
                   7890:         }
                   7891:     } else { /* ASC_BACK */
                   7892:         if (ascq->q_last[tid] != NULL) {
1.1.1.2 ! root     7893:             REQPNEXT(ascq->q_last[tid]) = (unsigned char *) reqp;
1.1       root     7894:         }
                   7895:         ascq->q_last[tid] = reqp;
                   7896:         REQPNEXT(reqp) = NULL;
                   7897:         /* If the queue was empty, set the first pointer. */
                   7898:         if (ascq->q_first[tid] == NULL) {
                   7899:             ascq->q_first[tid] = reqp;
                   7900:         }
                   7901:     }
                   7902:     /* The queue has at least one entry, set its bit. */
                   7903:     ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
                   7904: #ifdef ADVANSYS_STATS
                   7905:     /* Maintain request queue statistics. */
                   7906:     ascq->q_tot_cnt[tid]++;
                   7907:     ascq->q_cur_cnt[tid]++;
                   7908:     if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
                   7909:         ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
                   7910:         ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
                   7911:             tid, ascq->q_max_cnt[tid]);
                   7912:     }
                   7913:     REQPTIME(reqp) = REQTIMESTAMP();
                   7914: #endif /* ADVANSYS_STATS */
                   7915:     ASC_DBG1(3, "asc_enqueue: reqp %x\n", (unsigned) reqp);
                   7916:     return;
                   7917: }
                   7918: 
                   7919: /*
                   7920:  * Return first queued 'REQP' on the specified queue for
                   7921:  * the specified target device. Clear the 'tidmask' bit for
                   7922:  * the device if no more commands are left queued for it.
                   7923:  *
                   7924:  * 'REQPNEXT(reqp)' returns reqp's next pointer.
                   7925:  */
                   7926: STATIC REQP
                   7927: asc_dequeue(asc_queue_t *ascq, int tid)
                   7928: {
                   7929:     REQP    reqp;
                   7930: 
                   7931:     ASC_DBG2(3, "asc_dequeue: ascq %x, tid %d\n", (unsigned) ascq, tid);
                   7932:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
                   7933:     ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
                   7934:     if ((reqp = ascq->q_first[tid]) != NULL) {
                   7935:         ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
1.1.1.2 ! root     7936:         ascq->q_first[tid] = (REQP) REQPNEXT(reqp);
1.1       root     7937:         /* If the queue is empty, clear its bit and the last pointer. */
                   7938:         if (ascq->q_first[tid] == NULL) {
                   7939:             ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
                   7940:             ASC_ASSERT(ascq->q_last[tid] == reqp);
                   7941:             ascq->q_last[tid] = NULL;
                   7942:         }
                   7943: #ifdef ADVANSYS_STATS
                   7944:         /* Maintain request queue statistics. */
                   7945:         ascq->q_cur_cnt[tid]--;
                   7946:         ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
                   7947:         REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
                   7948: #endif /* ADVANSYS_STATS */
                   7949:     }
                   7950:     ASC_DBG1(3, "asc_dequeue: reqp %x\n", (unsigned) reqp);
                   7951:     return reqp;
                   7952: }
                   7953: 
                   7954: /*
                   7955:  * Return a pointer to a singly linked list of all the requests queued
                   7956:  * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
                   7957:  *
                   7958:  * If 'lastpp' is not NULL, '*lastpp' will be set to point to the 
                   7959:  * the last request returned in the singly linked list.
                   7960:  *
                   7961:  * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
                   7962:  * then all queued requests are concatenated into one list and
                   7963:  * returned.
                   7964:  *
                   7965:  * Note: If 'lastpp' is used to append a new list to the end of
                   7966:  * an old list, only change the old list last pointer if '*lastpp'
                   7967:  * (or the function return value) is not NULL, i.e. use a temporary
                   7968:  * variable for 'lastpp' and check its value after the function return
                   7969:  * before assigning it to the list last pointer.
                   7970:  *
                   7971:  * Unfortunately collecting queuing time statistics adds overhead to
                   7972:  * the function that isn't inherent to the function's algorithm.
                   7973:  */
                   7974: STATIC REQP
                   7975: asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
                   7976: {
                   7977:     REQP    firstp, lastp;
                   7978:     int     i;
                   7979: 
                   7980:     ASC_DBG2(3, "asc_dequeue_list: ascq %x, tid %d\n", (unsigned) ascq, tid);
                   7981:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
                   7982:     ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
                   7983: 
                   7984:     /*
                   7985:      * If 'tid' is not ASC_TID_ALL, return requests only for
                   7986:      * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
                   7987:      * requests for all tids.
                   7988:      */
                   7989:     if (tid != ASC_TID_ALL) {
                   7990:         /* Return all requests for the specified 'tid'. */
                   7991:         if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
                   7992:             /* List is empty; Set first and last return pointers to NULL. */
                   7993:             firstp = lastp = NULL;
                   7994:         } else {
                   7995:             firstp = ascq->q_first[tid];
                   7996:             lastp = ascq->q_last[tid];
                   7997:             ascq->q_first[tid] = ascq->q_last[tid] = NULL;
                   7998:             ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
                   7999: #ifdef ADVANSYS_STATS
                   8000:             {
                   8001:                 REQP reqp;
                   8002:                 ascq->q_cur_cnt[tid] = 0;
1.1.1.2 ! root     8003:                 for (reqp = firstp; reqp; reqp = (REQP) REQPNEXT(reqp)) {
1.1       root     8004:                     REQTIMESTAT("asc_dequeue_list", ascq, reqp, tid);
                   8005:                 }
                   8006:             }
                   8007: #endif /* ADVANSYS_STATS */
                   8008:         }
                   8009:     } else {
                   8010:         /* Return all requests for all tids. */
                   8011:         firstp = lastp = NULL;
                   8012:         for (i = 0; i <= ADV_MAX_TID; i++) {
                   8013:             if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
                   8014:                 if (firstp == NULL) {
                   8015:                     firstp = ascq->q_first[i];
                   8016:                     lastp = ascq->q_last[i];
                   8017:                 } else {
                   8018:                     ASC_ASSERT(lastp != NULL);
1.1.1.2 ! root     8019:                     REQPNEXT(lastp) = (unsigned char *) ascq->q_first[i];
1.1       root     8020:                     lastp = ascq->q_last[i];
                   8021:                 }
                   8022:                 ascq->q_first[i] = ascq->q_last[i] = NULL;
                   8023:                 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
                   8024: #ifdef ADVANSYS_STATS
                   8025:                 ascq->q_cur_cnt[i] = 0;
                   8026: #endif /* ADVANSYS_STATS */
                   8027:             }
                   8028:         }
                   8029: #ifdef ADVANSYS_STATS
                   8030:         {
                   8031:             REQP reqp;
1.1.1.2 ! root     8032:             for (reqp = firstp; reqp; reqp = (REQP) REQPNEXT(reqp)) {
1.1       root     8033:                 REQTIMESTAT("asc_dequeue_list", ascq, reqp, reqp->target);
                   8034:             }
                   8035:         }
                   8036: #endif /* ADVANSYS_STATS */
                   8037:     }
                   8038:     if (lastpp) {
                   8039:         *lastpp = lastp;
                   8040:     }
                   8041:     ASC_DBG1(3, "asc_dequeue_list: firstp %x\n", (unsigned) firstp);
                   8042:     return firstp;
                   8043: }
                   8044: 
                   8045: /*
                   8046:  * Remove the specified 'REQP' from the specified queue for
                   8047:  * the specified target device. Clear the 'tidmask' bit for the
                   8048:  * device if no more commands are left queued for it.
                   8049:  *
                   8050:  * 'REQPNEXT(reqp)' returns reqp's the next pointer.
                   8051:  *
                   8052:  * Return ASC_TRUE if the command was found and removed,
                   8053:  * otherwise return ASC_FALSE.
                   8054:  */
                   8055: STATIC int
                   8056: asc_rmqueue(asc_queue_t *ascq, REQP reqp)
                   8057: {
                   8058:     REQP        currp, prevp;
                   8059:     int         tid;
                   8060:     int         ret = ASC_FALSE;
                   8061: 
                   8062:     ASC_DBG2(3, "asc_rmqueue: ascq %x, reqp %x\n",
                   8063:         (unsigned) ascq, (unsigned) reqp);
                   8064:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
                   8065:     ASC_ASSERT(reqp != NULL);
                   8066: 
                   8067:     tid = REQPTID(reqp);
                   8068:     ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
                   8069: 
                   8070:     /*
                   8071:      * Handle the common case of 'reqp' being the first
                   8072:      * entry on the queue.
                   8073:      */
                   8074:     if (reqp == ascq->q_first[tid]) {
                   8075:         ret = ASC_TRUE;
1.1.1.2 ! root     8076:         ascq->q_first[tid] = (REQP) REQPNEXT(reqp);
1.1       root     8077:         /* If the queue is now empty, clear its bit and the last pointer. */
                   8078:         if (ascq->q_first[tid] == NULL) {
                   8079:             ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
                   8080:             ASC_ASSERT(ascq->q_last[tid] == reqp);
                   8081:             ascq->q_last[tid] = NULL;
                   8082:         }
                   8083:     } else if (ascq->q_first[tid] != NULL) {
                   8084:         ASC_ASSERT(ascq->q_last[tid] != NULL);
                   8085:         /*
                   8086:          * Because the case of 'reqp' being the first entry has been
                   8087:          * handled above and it is known the queue is not empty, if
                   8088:          * 'reqp' is found on the queue it is guaranteed the queue will
                   8089:          * not become empty and that 'q_first[tid]' will not be changed.
                   8090:          *
                   8091:          * Set 'prevp' to the first entry, 'currp' to the second entry,
                   8092:          * and search for 'reqp'.
                   8093:          */
1.1.1.2 ! root     8094:         for (prevp = ascq->q_first[tid], currp = (REQP) REQPNEXT(prevp);
        !          8095:              currp; prevp = currp, currp = (REQP) REQPNEXT(currp)) {
1.1       root     8096:             if (currp == reqp) {
                   8097:                 ret = ASC_TRUE;
                   8098:                 REQPNEXT(prevp) = REQPNEXT(currp);
                   8099:                 REQPNEXT(reqp) = NULL;
                   8100:                 if (ascq->q_last[tid] == reqp) {
                   8101:                     ascq->q_last[tid] = prevp;
                   8102:                 }
                   8103:                 break;
                   8104:             }
                   8105:         }
                   8106:     }
                   8107: #ifdef ADVANSYS_STATS
                   8108:     /* Maintain request queue statistics. */
                   8109:     if (ret == ASC_TRUE) {
                   8110:         ascq->q_cur_cnt[tid]--;
                   8111:         REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
                   8112:     }
                   8113:     ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
                   8114: #endif /* ADVANSYS_STATS */
                   8115:     ASC_DBG2(3, "asc_rmqueue: reqp %x, ret %d\n", (unsigned) reqp, ret);
                   8116:     return ret;
                   8117: }
                   8118: 
                   8119: /*
                   8120:  * If the specified 'REQP' is queued on the specified queue for
                   8121:  * the specified target device, return ASC_TRUE.
                   8122:  */
                   8123: STATIC int
                   8124: asc_isqueued(asc_queue_t *ascq, REQP reqp)
                   8125: {
                   8126:     REQP        treqp;
                   8127:     int            tid;
                   8128:     int            ret = ASC_FALSE;
                   8129: 
                   8130:     ASC_DBG2(3, "asc_isqueued: ascq %x, reqp %x\n",
                   8131:         (unsigned) ascq, (unsigned) reqp);
                   8132:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
                   8133:     ASC_ASSERT(reqp != NULL);
                   8134: 
                   8135:     tid = REQPTID(reqp);
                   8136:     ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
                   8137: 
1.1.1.2 ! root     8138:     for (treqp = ascq->q_first[tid]; treqp; treqp = (REQP) REQPNEXT(treqp)) {
1.1       root     8139:         ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
                   8140:         if (treqp == reqp) {
                   8141:             ret = ASC_TRUE;
                   8142:             break;
                   8143:         }
                   8144:     }
                   8145:     ASC_DBG1(3, "asc_isqueued: ret %x\n", ret);
                   8146:     return ret;
                   8147: }
                   8148: 
                   8149: /*
                   8150:  * Execute as many queued requests as possible for the specified queue.
                   8151:  *
                   8152:  * Calls asc_execute_scsi_cmnd() to execute a REQP/Scsi_Cmnd.
                   8153:  */
                   8154: STATIC void
                   8155: asc_execute_queue(asc_queue_t *ascq)
                   8156: {
                   8157:     ADV_SCSI_BIT_ID_TYPE    scan_tidmask;
                   8158:     REQP                    reqp;
                   8159:     int                     i;
                   8160: 
                   8161:     ASC_DBG1(1, "asc_execute_queue: ascq %x\n", (unsigned) ascq);
                   8162:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
                   8163:     /*
                   8164:      * Execute queued commands for devices attached to
                   8165:      * the current board in round-robin fashion.
                   8166:      */
                   8167:     scan_tidmask = ascq->q_tidmask;
                   8168:     do {
                   8169:         for (i = 0; i <= ADV_MAX_TID; i++) {
                   8170:             if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
                   8171:                 if ((reqp = asc_dequeue(ascq, i)) == NULL) {
                   8172:                     scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
                   8173:                 } else if (asc_execute_scsi_cmnd((Scsi_Cmnd *) reqp)
                   8174:                             == ASC_BUSY) {
                   8175:                     scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
                   8176:                     /* Put the request back at front of the list. */
                   8177:                     asc_enqueue(ascq, reqp, ASC_FRONT);
                   8178:                 }
                   8179:             }
                   8180:         }
                   8181:     } while (scan_tidmask);
                   8182:     return;
                   8183: }
                   8184: 
                   8185: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
                   8186: /*
                   8187:  * asc_prt_board_devices()
                   8188:  *
                   8189:  * Print driver information for devices attached to the board.
                   8190:  *
                   8191:  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
                   8192:  * cf. asc_prt_line().
                   8193:  *
                   8194:  * Return the number of characters copied into 'cp'. No more than
                   8195:  * 'cplen' characters will be copied to 'cp'.
                   8196:  */
                   8197: STATIC int
                   8198: asc_prt_board_devices(struct Scsi_Host *shp, char *cp, int cplen)
                   8199: {
                   8200:     asc_board_t        *boardp;
                   8201:     int                leftlen;
                   8202:     int                totlen;
                   8203:     int                len;
                   8204:     int                chip_scsi_id;
                   8205:     int                i;
                   8206: 
                   8207:     boardp = ASC_BOARDP(shp);
                   8208:     leftlen = cplen;
                   8209:     totlen = len = 0;
                   8210: 
                   8211:     len = asc_prt_line(cp, leftlen,
                   8212: "\nDevice Information for AdvanSys SCSI Host %d:\n", shp->host_no);
                   8213:     ASC_PRT_NEXT();
                   8214: 
                   8215:     if (ASC_NARROW_BOARD(boardp)) {
                   8216:         chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
                   8217:     } else {
                   8218:         chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
                   8219:     }
                   8220: 
                   8221:     len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
                   8222:     ASC_PRT_NEXT();
                   8223:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   8224:         if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
                   8225:             len = asc_prt_line(cp, leftlen, " %X,", i);
                   8226:             ASC_PRT_NEXT();
                   8227:         }
                   8228:     }
                   8229:     len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
                   8230:     ASC_PRT_NEXT();
                   8231: 
                   8232:     return totlen;
                   8233: }
                   8234: 
                   8235: /*
                   8236:  * Display Wide Board BIOS Information.
                   8237:  */
                   8238: STATIC int
                   8239: asc_prt_adv_bios(struct Scsi_Host *shp, char *cp, int cplen)
                   8240: {
                   8241:     asc_board_t        *boardp;
                   8242:     int                leftlen;
                   8243:     int                totlen;
                   8244:     int                len;
                   8245:     int                upgrade = ASC_FALSE;
                   8246:     ushort             major, minor, letter;
                   8247: 
                   8248:     boardp = ASC_BOARDP(shp);
                   8249:     leftlen = cplen;
                   8250:     totlen = len = 0;
                   8251: 
                   8252:     len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
                   8253:     ASC_PRT_NEXT();
                   8254: 
                   8255:     /*
                   8256:      * If the BIOS saved a valid signature, then fill in
                   8257:      * the BIOS code segment base address.
                   8258:      */
                   8259:     if (boardp->bios_signature != 0x55AA) {
                   8260:         len = asc_prt_line(cp, leftlen, "Pre-3.1\n");
                   8261:         ASC_PRT_NEXT();
                   8262:         upgrade = ASC_TRUE;
                   8263:     } else {
                   8264:         major = (boardp->bios_version >> 12) & 0xF;
                   8265:         minor = (boardp->bios_version >> 8) & 0xF;
                   8266:         letter = (boardp->bios_version & 0xFF);
                   8267: 
                   8268:         len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
                   8269:             major, minor, letter >= 26 ? '?' : letter + 'A');
                   8270:         ASC_PRT_NEXT();
                   8271: 
                   8272:         /* Current available ROM BIOS release is 3.1C. */
                   8273:         if (major < 3 || (major <= 3 && minor < 1) ||
                   8274:             (major <= 3 && minor <= 1 && letter < ('C'- 'A'))) {
                   8275:             upgrade = ASC_TRUE;
                   8276:         }
                   8277:     }
                   8278:     if (upgrade == ASC_TRUE) {
                   8279:         len = asc_prt_line(cp, leftlen,
                   8280: "Newer version of ROM BIOS available: ftp://ftp.advansys.com/pub\n");
                   8281:             ASC_PRT_NEXT();
                   8282:     }
                   8283: 
                   8284:     return totlen;
                   8285: }
                   8286: 
                   8287: /*
                   8288:  * Add serial number to information bar if signature AAh
                   8289:  * is found in at bit 15-9 (7 bits) of word 1.
                   8290:  *
                   8291:  * Serial Number consists fo 12 alpha-numeric digits.
                   8292:  *
                   8293:  *       1 - Product type (A,B,C,D..)  Word0: 15-13 (3 bits)
                   8294:  *       2 - MFG Location (A,B,C,D..)  Word0: 12-10 (3 bits)
                   8295:  *     3-4 - Product ID (0-99)         Word0: 9-0 (10 bits)
                   8296:  *       5 - Product revision (A-J)    Word0:  "         "
                   8297:  *
                   8298:  *           Signature                 Word1: 15-9 (7 bits)
                   8299:  *       6 - Year (0-9)                Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
                   8300:  *     7-8 - Week of the year (1-52)   Word1: 5-0 (6 bits)
                   8301:  *
                   8302:  *    9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
                   8303:  *
                   8304:  * Note 1: Only production cards will have a serial number.
                   8305:  *
                   8306:  * Note 2: Signature is most significant 7 bits (0xFE).
                   8307:  *
                   8308:  * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
                   8309:  */
                   8310: STATIC int
                   8311: asc_get_eeprom_string(ushort *serialnum, uchar *cp)
                   8312: {
                   8313:     ushort      w, num;
                   8314: 
                   8315:     if ((serialnum[1] & 0xFE00) != ((ushort) 0xAA << 8)) {
                   8316:         return ASC_FALSE;
                   8317:     } else {
                   8318:         /*
                   8319:          * First word - 6 digits.
                   8320:          */
                   8321:         w = serialnum[0];
                   8322: 
                   8323:         /* Product type - 1st digit. */
                   8324:         if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
                   8325:             /* Product type is P=Prototype */
                   8326:             *cp += 0x8;
                   8327:         }
                   8328:         cp++;
                   8329: 
                   8330:         /* Manufacturing location - 2nd digit. */
                   8331:         *cp++ = 'A' + ((w & 0x1C00) >> 10);
                   8332: 
                   8333:         /* Product ID - 3rd, 4th digits. */
                   8334:         num = w & 0x3FF;
                   8335:         *cp++ = '0' + (num / 100);
                   8336:         num %= 100;
                   8337:         *cp++ = '0' + (num / 10);
                   8338: 
                   8339:         /* Product revision - 5th digit. */
                   8340:         *cp++ = 'A' + (num % 10);
                   8341: 
                   8342:         /*
                   8343:          * Second word
                   8344:          */
                   8345:         w = serialnum[1];
                   8346: 
                   8347:         /*
                   8348:          * Year - 6th digit.
                   8349:          *
                   8350:          * If bit 15 of third word is set, then the
                   8351:          * last digit of the year is greater than 7.
                   8352:          */
                   8353:         if (serialnum[2] & 0x8000) {
                   8354:             *cp++ = '8' + ((w & 0x1C0) >> 6);
                   8355:         } else {
                   8356:             *cp++ = '0' + ((w & 0x1C0) >> 6);
                   8357:         }
                   8358: 
                   8359:         /* Week of year - 7th, 8th digits. */
                   8360:         num = w & 0x003F;
                   8361:         *cp++ = '0' + num / 10;
                   8362:         num %= 10;
                   8363:         *cp++ = '0' + num;
                   8364: 
                   8365:         /*
                   8366:          * Third word
                   8367:          */
                   8368:         w = serialnum[2] & 0x7FFF;
                   8369: 
                   8370:         /* Serial number - 9th digit. */
                   8371:         *cp++ = 'A' + (w / 1000);
                   8372: 
                   8373:         /* 10th, 11th, 12th digits. */
                   8374:         num = w % 1000;
                   8375:         *cp++ = '0' + num / 100;
                   8376:         num %= 100;
                   8377:         *cp++ = '0' + num / 10;
                   8378:         num %= 10;
                   8379:         *cp++ = '0' + num;
                   8380: 
                   8381:         *cp = '\0';     /* Null Terminate the string. */
                   8382:         return ASC_TRUE;
                   8383:     }
                   8384: }
                   8385: 
                   8386: /*
                   8387:  * asc_prt_asc_board_eeprom()
                   8388:  *
                   8389:  * Print board EEPROM configuration.
                   8390:  *
                   8391:  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
                   8392:  * cf. asc_prt_line().
                   8393:  *
                   8394:  * Return the number of characters copied into 'cp'. No more than
                   8395:  * 'cplen' characters will be copied to 'cp'.
                   8396:  */
                   8397: STATIC int
                   8398: asc_prt_asc_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
                   8399: {
                   8400:     asc_board_t        *boardp;
                   8401:     ASC_DVC_VAR        *asc_dvc_varp;
                   8402:     int                leftlen;
                   8403:     int                totlen;
                   8404:     int                len;
                   8405:     ASCEEP_CONFIG      *ep;
                   8406:     int                i;
                   8407:     int                isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
                   8408:     uchar              serialstr[13];
                   8409: 
                   8410:     boardp = ASC_BOARDP(shp);
                   8411:     asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
                   8412:     ep = &boardp->eep_config.asc_eep;
                   8413: 
                   8414:     leftlen = cplen;
                   8415:     totlen = len = 0;
                   8416: 
                   8417:     len = asc_prt_line(cp, leftlen,
                   8418: "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
                   8419:     ASC_PRT_NEXT();
                   8420: 
                   8421:     if (asc_get_eeprom_string((ushort *) &ep->adapter_info[0], serialstr) ==
                   8422:         ASC_TRUE) {
                   8423:         len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
                   8424:         ASC_PRT_NEXT();
                   8425:     } else {
                   8426:         if (ep->adapter_info[5] == 0xBB) {
                   8427:             len = asc_prt_line(cp, leftlen,
                   8428:                 " Default Settings Used for EEPROM-less Adapter.\n");
                   8429:             ASC_PRT_NEXT();
                   8430:         } else {
                   8431:             len = asc_prt_line(cp, leftlen,
                   8432:                 " Serial Number Signature Not Present.\n");
                   8433:             ASC_PRT_NEXT();
                   8434:         }
                   8435:     }
                   8436: 
                   8437:     len = asc_prt_line(cp, leftlen,
                   8438: " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
                   8439:         ep->chip_scsi_id, ep->max_total_qng, ep->max_tag_qng);
                   8440:     ASC_PRT_NEXT();
                   8441: 
                   8442:     len = asc_prt_line(cp, leftlen,
                   8443: " cntl %x, no_scam %x\n",
                   8444:         ep->cntl, ep->no_scam);
                   8445:     ASC_PRT_NEXT();
                   8446: 
                   8447:     len = asc_prt_line(cp, leftlen,
                   8448: " Target ID:           ");
                   8449:     ASC_PRT_NEXT();
                   8450:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   8451:         len = asc_prt_line(cp, leftlen, " %d", i);
                   8452:         ASC_PRT_NEXT();
                   8453:     }
                   8454:     len = asc_prt_line(cp, leftlen, "\n");
                   8455:     ASC_PRT_NEXT();
                   8456: 
                   8457:     len = asc_prt_line(cp, leftlen,
                   8458: " Disconnects:         ");
                   8459:     ASC_PRT_NEXT();
                   8460:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   8461:         len = asc_prt_line(cp, leftlen, " %c",
                   8462:             (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   8463:         ASC_PRT_NEXT();
                   8464:     }
                   8465:     len = asc_prt_line(cp, leftlen, "\n");
                   8466:     ASC_PRT_NEXT();
                   8467: 
                   8468:     len = asc_prt_line(cp, leftlen,
                   8469: " Command Queuing:     ");
                   8470:     ASC_PRT_NEXT();
                   8471:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   8472:         len = asc_prt_line(cp, leftlen, " %c",
                   8473:             (ep->use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   8474:         ASC_PRT_NEXT();
                   8475:     }
                   8476:     len = asc_prt_line(cp, leftlen, "\n");
                   8477:     ASC_PRT_NEXT();
                   8478: 
                   8479:     len = asc_prt_line(cp, leftlen,
                   8480: " Start Motor:         ");
                   8481:     ASC_PRT_NEXT();
                   8482:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   8483:         len = asc_prt_line(cp, leftlen, " %c",
                   8484:             (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   8485:         ASC_PRT_NEXT();
                   8486:     }
                   8487:     len = asc_prt_line(cp, leftlen, "\n");
                   8488:     ASC_PRT_NEXT();
                   8489: 
                   8490:     len = asc_prt_line(cp, leftlen,
                   8491: " Synchronous Transfer:");
                   8492:     ASC_PRT_NEXT();
                   8493:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   8494:         len = asc_prt_line(cp, leftlen, " %c",
                   8495:             (ep->init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   8496:         ASC_PRT_NEXT();
                   8497:     }
                   8498:     len = asc_prt_line(cp, leftlen, "\n");
                   8499:     ASC_PRT_NEXT();
                   8500: 
                   8501:     if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
                   8502:         len = asc_prt_line(cp, leftlen,
                   8503: " Host ISA DMA speed:   %d MB/S\n",
                   8504:             isa_dma_speed[ep->isa_dma_speed]);
                   8505:         ASC_PRT_NEXT();
                   8506:     }
                   8507: 
                   8508:      return totlen;
                   8509: }
                   8510: 
                   8511: /*
                   8512:  * asc_prt_adv_board_eeprom()
                   8513:  *
                   8514:  * Print board EEPROM configuration.
                   8515:  *
                   8516:  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
                   8517:  * cf. asc_prt_line().
                   8518:  *
                   8519:  * Return the number of characters copied into 'cp'. No more than
                   8520:  * 'cplen' characters will be copied to 'cp'.
                   8521:  */
                   8522: STATIC int
                   8523: asc_prt_adv_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
                   8524: {
                   8525:     asc_board_t        *boardp;
                   8526:     ADV_DVC_VAR        *adv_dvc_varp;
                   8527:     int                leftlen;
                   8528:     int                totlen;
                   8529:     int                len;
                   8530:     int                i;
                   8531:     char               *termstr;
                   8532:     uchar              serialstr[13];
                   8533:     ADVEEP_CONFIG      *ep;
                   8534: 
                   8535:     boardp = ASC_BOARDP(shp);
                   8536:     adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
                   8537:     ep = &boardp->eep_config.adv_eep;
                   8538: 
                   8539:     leftlen = cplen;
                   8540:     totlen = len = 0;
                   8541: 
                   8542:     len = asc_prt_line(cp, leftlen,
                   8543: "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
                   8544:     ASC_PRT_NEXT();
                   8545: 
                   8546:     if (asc_get_eeprom_string(&ep->serial_number_word1, serialstr) ==
                   8547:         ASC_TRUE) {
                   8548:         len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
                   8549:         ASC_PRT_NEXT();
                   8550:     } else {
                   8551:         len = asc_prt_line(cp, leftlen,
                   8552:             " Serial Number Signature Not Present.\n");
                   8553:         ASC_PRT_NEXT();
                   8554:     }
                   8555: 
                   8556:     len = asc_prt_line(cp, leftlen,
                   8557: " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
                   8558:         ep->adapter_scsi_id, ep->max_host_qng, ep->max_dvc_qng);
                   8559:     ASC_PRT_NEXT();
                   8560: 
                   8561:     switch (ep->termination) {
                   8562:         case 1:
                   8563:             termstr = "Low Off/High Off";
                   8564:             break;
                   8565:         case 2:
                   8566:             termstr = "Low Off/High On";
                   8567:             break;
                   8568:         case 3:
                   8569:             termstr = "Low On/High On";
                   8570:             break;
                   8571:         default:
                   8572:         case 0:
                   8573:             termstr = "Automatic";
                   8574:             break;
                   8575:     }
                   8576: 
                   8577:     len = asc_prt_line(cp, leftlen,
                   8578: " termination: %u (%s), bios_ctrl: %x\n",
                   8579:         ep->termination, termstr, ep->bios_ctrl);
                   8580:     ASC_PRT_NEXT();
                   8581: 
                   8582:     len = asc_prt_line(cp, leftlen,
                   8583: " Target ID:           ");
                   8584:     ASC_PRT_NEXT();
                   8585:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   8586:         len = asc_prt_line(cp, leftlen, " %X", i);
                   8587:         ASC_PRT_NEXT();
                   8588:     }
                   8589:     len = asc_prt_line(cp, leftlen, "\n");
                   8590:     ASC_PRT_NEXT();
                   8591: 
                   8592:     len = asc_prt_line(cp, leftlen,
                   8593: " Disconnects:         ");
                   8594:     ASC_PRT_NEXT();
                   8595:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   8596:         len = asc_prt_line(cp, leftlen, " %c",
                   8597:             (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   8598:         ASC_PRT_NEXT();
                   8599:     }
                   8600:     len = asc_prt_line(cp, leftlen, "\n");
                   8601:     ASC_PRT_NEXT();
                   8602: 
                   8603:     len = asc_prt_line(cp, leftlen,
                   8604: " Command Queuing:     ");
                   8605:     ASC_PRT_NEXT();
                   8606:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   8607:         len = asc_prt_line(cp, leftlen, " %c",
                   8608:             (ep->tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   8609:         ASC_PRT_NEXT();
                   8610:     }
                   8611:     len = asc_prt_line(cp, leftlen, "\n");
                   8612:     ASC_PRT_NEXT();
                   8613: 
                   8614:     len = asc_prt_line(cp, leftlen,
                   8615: " Start Motor:         ");
                   8616:     ASC_PRT_NEXT();
                   8617:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   8618:         len = asc_prt_line(cp, leftlen, " %c",
                   8619:             (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   8620:         ASC_PRT_NEXT();
                   8621:     }
                   8622:     len = asc_prt_line(cp, leftlen, "\n");
                   8623:     ASC_PRT_NEXT();
                   8624: 
                   8625:     len = asc_prt_line(cp, leftlen,
                   8626: " Synchronous Transfer:");
                   8627:     ASC_PRT_NEXT();
                   8628:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   8629:         len = asc_prt_line(cp, leftlen, " %c",
                   8630:             (ep->sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   8631:         ASC_PRT_NEXT();
                   8632:     }
                   8633:     len = asc_prt_line(cp, leftlen, "\n");
                   8634:     ASC_PRT_NEXT();
                   8635: 
                   8636:     len = asc_prt_line(cp, leftlen,
                   8637: " Ultra Transfer:      ");
                   8638:     ASC_PRT_NEXT();
                   8639:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   8640:         len = asc_prt_line(cp, leftlen, " %c",
                   8641:             (ep->ultra_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   8642:         ASC_PRT_NEXT();
                   8643:     }
                   8644:     len = asc_prt_line(cp, leftlen, "\n");
                   8645:     ASC_PRT_NEXT();
                   8646: 
                   8647:     len = asc_prt_line(cp, leftlen,
                   8648: " Wide Transfer:       ");
                   8649:     ASC_PRT_NEXT();
                   8650:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   8651:         len = asc_prt_line(cp, leftlen, " %c",
                   8652:             (ep->wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   8653:         ASC_PRT_NEXT();
                   8654:     }
                   8655:     len = asc_prt_line(cp, leftlen, "\n");
                   8656:     ASC_PRT_NEXT();
                   8657: 
                   8658:     return totlen;
                   8659: }
                   8660: 
                   8661: /*
                   8662:  * asc_prt_driver_conf()
                   8663:  *
                   8664:  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
                   8665:  * cf. asc_prt_line().
                   8666:  *
                   8667:  * Return the number of characters copied into 'cp'. No more than
                   8668:  * 'cplen' characters will be copied to 'cp'.
                   8669:  */
                   8670: STATIC int
                   8671: asc_prt_driver_conf(struct Scsi_Host *shp, char *cp, int cplen)
                   8672: {
                   8673:     asc_board_t            *boardp;
                   8674:     int                    leftlen;
                   8675:     int                    totlen;
                   8676:     int                    len;
                   8677:     int                    chip_scsi_id;
                   8678: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
                   8679:     int                    i;
                   8680: #endif /* version >= v1.3.89 */
                   8681: 
                   8682:     boardp = ASC_BOARDP(shp);
                   8683: 
                   8684:     leftlen = cplen;
                   8685:     totlen = len = 0;
                   8686: 
                   8687:     len = asc_prt_line(cp, leftlen,
                   8688: "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
                   8689:         shp->host_no);
                   8690:     ASC_PRT_NEXT();
                   8691: 
                   8692:     len = asc_prt_line(cp, leftlen,
                   8693: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89)
                   8694: " host_busy %u, last_reset %u, max_id %u, max_lun %u\n",
                   8695:         shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun);
                   8696: #else /* version >= v1.3.89 */
                   8697: " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
                   8698:         shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun,
                   8699:         shp->max_channel);
                   8700: #endif /* version >= v1.3.89 */
                   8701:     ASC_PRT_NEXT();
                   8702:     
                   8703:     len = asc_prt_line(cp, leftlen,
                   8704: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,57)
                   8705: " can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
                   8706:         shp->can_queue, shp->this_id, shp->sg_tablesize, shp->cmd_per_lun);
                   8707: #else /* version >= v1.3.57 */
                   8708: " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
                   8709:         shp->unique_id, shp->can_queue, shp->this_id, shp->sg_tablesize,
                   8710:         shp->cmd_per_lun);
                   8711: #endif /* version >= v1.3.57 */
                   8712:     ASC_PRT_NEXT();
                   8713: 
                   8714:     len = asc_prt_line(cp, leftlen,
                   8715: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,57)
                   8716: " unchecked_isa_dma %d, loaded_as_module %d\n",
                   8717:         shp->unchecked_isa_dma, shp->loaded_as_module);
                   8718: #else /* version >= v1.3.57 */
                   8719: " unchecked_isa_dma %d, use_clustering %d, loaded_as_module %d\n",
                   8720:         shp->unchecked_isa_dma, shp->use_clustering, shp->loaded_as_module);
                   8721: #endif /* version >= v1.3.57 */
                   8722:     ASC_PRT_NEXT();
                   8723: 
                   8724:     len = asc_prt_line(cp, leftlen, " flags %x, last_reset %x, jiffies %x\n",
                   8725:         boardp->flags, boardp->last_reset, jiffies);
                   8726:     ASC_PRT_NEXT();
                   8727: 
                   8728:     if (ASC_NARROW_BOARD(boardp)) {
                   8729:         chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
                   8730:     } else {
                   8731:         chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
                   8732:     }
                   8733: 
                   8734: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
                   8735:     if (boardp->flags & ASC_SELECT_QUEUE_DEPTHS) {
                   8736:         len = asc_prt_line(cp, leftlen, " queue_depth:");
                   8737:         ASC_PRT_NEXT();
                   8738:         for (i = 0; i <= ADV_MAX_TID; i++) {
                   8739:             if ((chip_scsi_id == i) ||
                   8740:                 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   8741:                 continue;
                   8742:             }
                   8743:             if (boardp->device[i] == NULL) {
                   8744:                 continue;
                   8745:             }
                   8746:             len = asc_prt_line(cp, leftlen, " %X:%d",
                   8747:                 i, boardp->device[i]->queue_depth);
                   8748:             ASC_PRT_NEXT();
                   8749:         }
                   8750:         len = asc_prt_line(cp, leftlen, "\n");
                   8751:         ASC_PRT_NEXT();
                   8752:     }
                   8753: #endif /* version >= v1.3.89 */
                   8754: 
                   8755: #if ASC_QUEUE_FLOW_CONTROL
                   8756:     if (ASC_NARROW_BOARD(boardp)) {
                   8757:         len = asc_prt_line(cp, leftlen, " queue_curr_depth:");
                   8758:         ASC_PRT_NEXT();
                   8759:         /* Use ASC_MAX_TID for Narrow Board. */
                   8760:         for (i = 0; i <= ASC_MAX_TID; i++) {
                   8761:             if ((boardp->asc_dvc_cfg.chip_scsi_id == i) ||
                   8762:                 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   8763:                 continue;
                   8764:             }
                   8765:             if (boardp->device[i] == NULL) {
                   8766:                 continue;
                   8767:             }
                   8768:             len = asc_prt_line(cp, leftlen, " %d:%d",
                   8769:                 i, boardp->device[i]->queue_curr_depth);
                   8770:             ASC_PRT_NEXT();
                   8771:         }
                   8772:         len = asc_prt_line(cp, leftlen, "\n");
                   8773:         ASC_PRT_NEXT();
                   8774: 
                   8775:         len = asc_prt_line(cp, leftlen, " queue_count:");
                   8776:         ASC_PRT_NEXT();
                   8777:         /* Use ASC_MAX_TID for Narrow Board. */
                   8778:         for (i = 0; i <= ASC_MAX_TID; i++) {
                   8779:             if ((boardp->asc_dvc_cfg.chip_scsi_id == i) ||
                   8780:                 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   8781:                 continue;
                   8782:             }
                   8783:             if (boardp->device[i] == NULL) {
                   8784:                 continue;
                   8785:             }
                   8786:             len = asc_prt_line(cp, leftlen, " %d:%d",
                   8787:                 i, boardp->device[i]->queue_count);
                   8788:             ASC_PRT_NEXT();
                   8789:         }
                   8790:         len = asc_prt_line(cp, leftlen, "\n");
                   8791:         ASC_PRT_NEXT();
                   8792:     }
                   8793: #endif /* ASC_QUEUE_FLOW_CONTROL */
                   8794: 
                   8795:     return totlen;
                   8796: }
                   8797: 
                   8798: /*
                   8799:  * asc_prt_asc_board_info()
                   8800:  *
                   8801:  * Print dynamic board configuration information.
                   8802:  *
                   8803:  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
                   8804:  * cf. asc_prt_line().
                   8805:  *
                   8806:  * Return the number of characters copied into 'cp'. No more than
                   8807:  * 'cplen' characters will be copied to 'cp'.
                   8808:  */
                   8809: STATIC int
                   8810: asc_prt_asc_board_info(struct Scsi_Host *shp, char *cp, int cplen)
                   8811: {
                   8812:     asc_board_t            *boardp;
                   8813:     int                    leftlen;
                   8814:     int                    totlen;
                   8815:     int                    len;
                   8816:     ASC_DVC_VAR            *v;
                   8817:     ASC_DVC_CFG            *c;
                   8818:     int                    i;
                   8819: 
                   8820:     boardp = ASC_BOARDP(shp);
                   8821:     v = &boardp->dvc_var.asc_dvc_var;
                   8822:     c = &boardp->dvc_cfg.asc_dvc_cfg;
                   8823: 
                   8824:     leftlen = cplen;
                   8825:     totlen = len = 0;
                   8826: 
                   8827:     len = asc_prt_line(cp, leftlen,
                   8828: "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
                   8829:     shp->host_no);
                   8830:     ASC_PRT_NEXT();
                   8831: 
                   8832:     len = asc_prt_line(cp, leftlen,
                   8833: " chip_version %u, lib_version %x, lib_serial_no %u, mcode_date %x\n",
                   8834:         c->chip_version, c->lib_version, c->lib_serial_no, c->mcode_date);
                   8835:     ASC_PRT_NEXT();
                   8836: 
                   8837:     len = asc_prt_line(cp, leftlen,
                   8838: " mcode_version %x, err_code %u\n",
                   8839:          c->mcode_version, v->err_code);
                   8840:     ASC_PRT_NEXT();
                   8841: 
                   8842:     /* Current number of commands waiting for the host. */
                   8843:     len = asc_prt_line(cp, leftlen,
                   8844: " Total Command Pending: %d\n", v->cur_total_qng);
                   8845:     ASC_PRT_NEXT();
                   8846: 
                   8847:     len = asc_prt_line(cp, leftlen,
                   8848: " Command Queuing:");
                   8849:     ASC_PRT_NEXT();
                   8850:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   8851:         if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
                   8852:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   8853:             continue;
                   8854:         }
                   8855:         len = asc_prt_line(cp, leftlen, " %d:%c",
                   8856:             i, (v->use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   8857:         ASC_PRT_NEXT();
                   8858:     }
                   8859:     len = asc_prt_line(cp, leftlen, "\n");
                   8860:     ASC_PRT_NEXT();
                   8861: 
                   8862:     /* Current number of commands waiting for a device. */
                   8863:     len = asc_prt_line(cp, leftlen,
                   8864: " Command Queue Pending:");
                   8865:     ASC_PRT_NEXT();
                   8866:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   8867:         if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
                   8868:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   8869:             continue;
                   8870:         }
                   8871:         len = asc_prt_line(cp, leftlen, " %d:%u", i, v->cur_dvc_qng[i]);
                   8872:         ASC_PRT_NEXT();
                   8873:     }
                   8874:     len = asc_prt_line(cp, leftlen, "\n");
                   8875:     ASC_PRT_NEXT();
                   8876: 
                   8877:     /* Current limit on number of commands that can be sent to a device. */
                   8878:     len = asc_prt_line(cp, leftlen,
                   8879: " Command Queue Limit:");
                   8880:     ASC_PRT_NEXT();
                   8881:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   8882:         if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
                   8883:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   8884:             continue;
                   8885:         }
                   8886:         len = asc_prt_line(cp, leftlen, " %d:%u", i, v->max_dvc_qng[i]);
                   8887:         ASC_PRT_NEXT();
                   8888:     }
                   8889:     len = asc_prt_line(cp, leftlen, "\n");
                   8890:     ASC_PRT_NEXT();
                   8891: 
                   8892:     /* Indicate whether the device has returned queue full status. */
                   8893:     len = asc_prt_line(cp, leftlen,
                   8894: " Command Queue Full:");
                   8895:     ASC_PRT_NEXT();
                   8896:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   8897:         if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
                   8898:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   8899:             continue;
                   8900:         }
                   8901:         if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
                   8902:             len = asc_prt_line(cp, leftlen, " %d:Y-%d",
                   8903:                 i, boardp->queue_full_cnt[i]);
                   8904:         } else {
                   8905:             len = asc_prt_line(cp, leftlen, " %d:N", i);
                   8906:         }
                   8907:         ASC_PRT_NEXT();
                   8908:     }
                   8909:     len = asc_prt_line(cp, leftlen, "\n");
                   8910:     ASC_PRT_NEXT();
                   8911: 
                   8912:     len = asc_prt_line(cp, leftlen,
                   8913: " Synchronous Transfer:");
                   8914:     ASC_PRT_NEXT();
                   8915:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   8916:         if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
                   8917:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   8918:             continue;
                   8919:         }
                   8920:         len = asc_prt_line(cp, leftlen, " %d:%c",
                   8921:             i, (v->sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   8922:         ASC_PRT_NEXT();
                   8923:     }
                   8924:     len = asc_prt_line(cp, leftlen, "\n");
                   8925:     ASC_PRT_NEXT();
                   8926: 
                   8927:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   8928:         uchar syn_period_ix;
                   8929: 
                   8930:         if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
                   8931:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   8932:             continue;
                   8933:         }
                   8934:         if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
                   8935:             continue;
                   8936:         }
                   8937:         syn_period_ix = (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index - 1);
                   8938:         len = asc_prt_line(cp, leftlen, "  %d:", i);
                   8939:         ASC_PRT_NEXT();
                   8940: 
                   8941:         len = asc_prt_line(cp, leftlen,
                   8942:             " Transfer Period Factor: %d (%d.%d Mhz),",
                   8943:             v->sdtr_period_tbl[syn_period_ix],
                   8944:             250 / v->sdtr_period_tbl[syn_period_ix],
                   8945:             ASC_TENTHS(250, v->sdtr_period_tbl[syn_period_ix]));
                   8946:         ASC_PRT_NEXT();
                   8947: 
                   8948:         len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d\n",
                   8949:             boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET);
                   8950:         ASC_PRT_NEXT();
                   8951:     }
                   8952: 
                   8953:     return totlen;
                   8954: }
                   8955: 
                   8956: /*
                   8957:  * asc_prt_adv_board_info()
                   8958:  *
                   8959:  * Print dynamic board configuration information.
                   8960:  *
                   8961:  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
                   8962:  * cf. asc_prt_line().
                   8963:  *
                   8964:  * Return the number of characters copied into 'cp'. No more than
                   8965:  * 'cplen' characters will be copied to 'cp'.
                   8966:  */
                   8967: STATIC int
                   8968: asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen)
                   8969: {
                   8970:     asc_board_t            *boardp;
                   8971:     int                    leftlen;
                   8972:     int                    totlen;
                   8973:     int                    len;
                   8974:     int                    i;
                   8975:     ADV_DVC_VAR            *v;
                   8976:     ADV_DVC_CFG            *c;
                   8977:     AdvPortAddr            iop_base;
                   8978:     ushort                 chip_scsi_id;
                   8979:     ushort                 lramword;
                   8980:     uchar                  lrambyte;
                   8981:     ushort                 sdtr_able;
                   8982:     ushort                 period;
                   8983: 
                   8984:     boardp = ASC_BOARDP(shp);
                   8985:     v = &boardp->dvc_var.adv_dvc_var;
                   8986:     c = &boardp->dvc_cfg.adv_dvc_cfg;
                   8987:     iop_base = v->iop_base;
                   8988:     chip_scsi_id = v->chip_scsi_id;
                   8989: 
                   8990:     leftlen = cplen;
                   8991:     totlen = len = 0;
                   8992: 
                   8993:     len = asc_prt_line(cp, leftlen,
                   8994: "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
                   8995:     shp->host_no);
                   8996:     ASC_PRT_NEXT();
                   8997: 
                   8998:     len = asc_prt_line(cp, leftlen,
                   8999: " iop_base %lx, cable_detect: %X, err_code %u, idle_cmd_done %u\n",
                   9000:          v->iop_base,
                   9001:          AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1) & CABLE_DETECT,
                   9002:          v->err_code, v->idle_cmd_done);
                   9003:     ASC_PRT_NEXT();
                   9004: 
                   9005:     len = asc_prt_line(cp, leftlen,
                   9006: " chip_version %u, lib_version %x, mcode_date %x, mcode_version %x\n",
                   9007:         c->chip_version, c->lib_version, c->mcode_date, c->mcode_version);
                   9008:     ASC_PRT_NEXT();
                   9009: 
                   9010:     AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, lramword);
                   9011:     len = asc_prt_line(cp, leftlen,
                   9012: " Queuing Enabled:");
                   9013:     ASC_PRT_NEXT();
                   9014:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   9015:         if ((chip_scsi_id == i) ||
                   9016:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   9017:             continue;
                   9018:         }
                   9019: 
                   9020:         len = asc_prt_line(cp, leftlen, " %X:%c",
                   9021:             i, (lramword & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   9022:         ASC_PRT_NEXT();
                   9023:     }
                   9024:     len = asc_prt_line(cp, leftlen, "\n");
                   9025:     ASC_PRT_NEXT();
                   9026: 
                   9027:     len = asc_prt_line(cp, leftlen,
                   9028: " Queue Limit:");
                   9029:     ASC_PRT_NEXT();
                   9030:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   9031:         if ((chip_scsi_id == i) ||
                   9032:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   9033:             continue;
                   9034:         }
                   9035: 
                   9036:         AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i, lrambyte);
                   9037: 
                   9038:         len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
                   9039:         ASC_PRT_NEXT();
                   9040:     }
                   9041:     len = asc_prt_line(cp, leftlen, "\n");
                   9042:     ASC_PRT_NEXT();
                   9043: 
                   9044:     len = asc_prt_line(cp, leftlen,
                   9045: " Command Pending:");
                   9046:     ASC_PRT_NEXT();
                   9047:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   9048:         if ((chip_scsi_id == i) ||
                   9049:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   9050:             continue;
                   9051:         }
                   9052: 
                   9053:         AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i, lrambyte);
                   9054: 
                   9055:         len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
                   9056:         ASC_PRT_NEXT();
                   9057:     }
                   9058:     len = asc_prt_line(cp, leftlen, "\n");
                   9059:     ASC_PRT_NEXT();
                   9060: 
                   9061:     AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, lramword);
                   9062:     len = asc_prt_line(cp, leftlen,
                   9063: " Wide Enabled:");
                   9064:     ASC_PRT_NEXT();
                   9065:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   9066:         if ((chip_scsi_id == i) ||
                   9067:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   9068:             continue;
                   9069:         }
                   9070: 
                   9071:         len = asc_prt_line(cp, leftlen, " %X:%c",
                   9072:             i, (lramword & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   9073:         ASC_PRT_NEXT();
                   9074:     }
                   9075:     len = asc_prt_line(cp, leftlen, "\n");
                   9076:     ASC_PRT_NEXT();
                   9077: 
                   9078:     len = asc_prt_line(cp, leftlen,
                   9079: " Transfer Bit Width:");
                   9080:     ASC_PRT_NEXT();
                   9081:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   9082:         if ((chip_scsi_id == i) ||
                   9083:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   9084:             continue;
                   9085:         }
                   9086: 
                   9087:         AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
                   9088:             lramword);
                   9089:         len = asc_prt_line(cp, leftlen, " %X:%d",
                   9090:             i, (lramword & 0x8000) ? 16 : 8);
                   9091:         ASC_PRT_NEXT();
                   9092:     }
                   9093:     len = asc_prt_line(cp, leftlen, "\n");
                   9094:     ASC_PRT_NEXT();
                   9095: 
                   9096:     AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
                   9097:     len = asc_prt_line(cp, leftlen,
                   9098: " Synchronous Enabled:");
                   9099:     ASC_PRT_NEXT();
                   9100:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   9101:         if ((chip_scsi_id == i) ||
                   9102:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   9103:             continue;
                   9104:         }
                   9105: 
                   9106:         len = asc_prt_line(cp, leftlen, " %X:%c",
                   9107:             i, (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   9108:         ASC_PRT_NEXT();
                   9109:     }
                   9110:     len = asc_prt_line(cp, leftlen, "\n");
                   9111:     ASC_PRT_NEXT();
                   9112: 
                   9113:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   9114: 
                   9115:         AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
                   9116:             lramword);
                   9117:         lramword &= ~0x8000;
                   9118: 
                   9119:         if ((chip_scsi_id == i) ||
                   9120:             ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0) ||
                   9121:             (lramword == 0)) {
                   9122:             continue;
                   9123:         }
                   9124: 
                   9125:         len = asc_prt_line(cp, leftlen, "  %X:", i);
                   9126:         ASC_PRT_NEXT();
                   9127:         
                   9128:         period = (((lramword >> 8) * 25) + 50)/4;
                   9129: 
                   9130:         len = asc_prt_line(cp, leftlen,
                   9131:             " Transfer Period Factor: %d (%d.%d Mhz),",
                   9132:             period, 250/period, ASC_TENTHS(250, period));
                   9133:         ASC_PRT_NEXT();
                   9134: 
                   9135:         len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d\n",
                   9136:             lramword & 0x1F);
                   9137:         ASC_PRT_NEXT();
                   9138:     }
                   9139: 
                   9140:     return totlen;
                   9141: }
                   9142: 
                   9143: /*
                   9144:  * asc_proc_copy() 
                   9145:  *
                   9146:  * Copy proc information to a read buffer taking into account the current
                   9147:  * read offset in the file and the remaining space in the read buffer.
                   9148:  */
                   9149: STATIC int
                   9150: asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
                   9151:               char *cp, int cplen)
                   9152: {
                   9153:     int cnt = 0;
                   9154:     
                   9155:     ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
                   9156:             (unsigned) offset, (unsigned) advoffset, cplen);
                   9157:     if (offset <= advoffset) {
                   9158:         /* Read offset below current offset, copy everything. */
                   9159:         cnt = ASC_MIN(cplen, 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:     } else if (offset < advoffset + cplen) {
                   9164:         /* Read offset within current range, partial copy. */
                   9165:         cnt = (advoffset + cplen) - offset;
                   9166:         cp = (cp + cplen) - cnt;
                   9167:         cnt = ASC_MIN(cnt, leftlen);
                   9168:         ASC_DBG3(2, "asc_proc_copy: curbuf %x, cp %x, cnt %d\n",
                   9169:                 (unsigned) curbuf, (unsigned) cp, cnt);
                   9170:         memcpy(curbuf, cp, cnt);
                   9171:     }
                   9172:     return cnt;
                   9173: }
                   9174: 
                   9175: /*
                   9176:  * asc_prt_line()
                   9177:  *
                   9178:  * If 'cp' is NULL print to the console, otherwise print to a buffer.
                   9179:  *
                   9180:  * Return 0 if printing to the console, otherwise return the number of
                   9181:  * bytes written to the buffer.
                   9182:  *
                   9183:  * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
                   9184:  * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
                   9185:  */
                   9186: STATIC int
                   9187: asc_prt_line(char *buf, int buflen, char *fmt, ...)
                   9188: {
                   9189:     va_list        args;
                   9190:     int            ret;
                   9191:     char        s[ASC_PRTLINE_SIZE];
                   9192: 
                   9193:     va_start(args, fmt);
                   9194:     ret = vsprintf(s, fmt, args);
                   9195:     ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
                   9196:     if (buf == NULL) {
1.1.1.2 ! root     9197:         (void) printk("%s", s);
1.1       root     9198:         ret = 0;
                   9199:     } else {
                   9200:         ret = ASC_MIN(buflen, ret);
                   9201:         memcpy(buf, s, ret);
                   9202:     }
                   9203:     va_end(args);
                   9204:     return ret;
                   9205: }
                   9206: #endif /* version >= v1.3.0 */
                   9207: 
                   9208: 
                   9209: /*
                   9210:  * --- Functions Required by the Asc Library
                   9211:  */
                   9212: 
                   9213: /*
                   9214:  * Delay for 'n' milliseconds. Don't use the 'jiffies'
                   9215:  * global variable which is incremented once every 5 ms
                   9216:  * from a timer interrupt, because this function may be
                   9217:  * called when interrupts are disabled.
                   9218:  */
                   9219: STATIC void
                   9220: DvcSleepMilliSecond(ulong n)
                   9221: {
                   9222:     ulong i;
                   9223: 
                   9224:     ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", n);
                   9225:     for (i = 0; i < n; i++) {
                   9226:         udelay(1000);
                   9227:     }
                   9228: }
                   9229: 
1.1.1.2 ! root     9230: STATIC long
1.1       root     9231: DvcEnterCritical(void)
                   9232: {
1.1.1.2 ! root     9233:     long   flags;
1.1       root     9234: 
                   9235:     save_flags(flags);
                   9236:     cli();
                   9237:     return flags;
                   9238: }
                   9239: 
                   9240: STATIC void
1.1.1.2 ! root     9241: DvcLeaveCritical(long flags)
1.1       root     9242: {
                   9243:     restore_flags(flags);
                   9244: }
                   9245: 
                   9246: STATIC ulong
                   9247: DvcGetSGList(ASC_DVC_VAR *asc_dvc_sg, uchar *buf_addr, ulong buf_len,
                   9248:              ASC_SG_HEAD *asc_sg_head_ptr)
                   9249: {
                   9250:     ulong buf_size;
                   9251: 
                   9252:     buf_size = buf_len;
                   9253:     asc_sg_head_ptr->entry_cnt = 1;
                   9254: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
                   9255:     asc_sg_head_ptr->sg_list[0].addr = (ulong) buf_addr;
                   9256: #else /* version >= v2.0.0 */
                   9257:     asc_sg_head_ptr->sg_list[0].addr = virt_to_bus(buf_addr);
                   9258: #endif /* version >= v2.0.0 */
                   9259:     asc_sg_head_ptr->sg_list[0].bytes = buf_size;
                   9260:     return buf_size;
                   9261: }
                   9262: 
                   9263: /*
                   9264:  * void
                   9265:  * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, ushort *outbuf, int words)
                   9266:  *
                   9267:  * Calling/Exit State:
                   9268:  *    none
                   9269:  *
                   9270:  * Description:
                   9271:  *     Output an ASC_SCSI_Q structure to the chip
                   9272:  */
                   9273: STATIC void
                   9274: DvcPutScsiQ(PortAddr iop_base, ushort s_addr, ushort *outbuf, int words)
                   9275: {
                   9276:     int    i;
                   9277: 
                   9278:     ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", (uchar *) outbuf, 2 * words);
                   9279:     AscSetChipLramAddr(iop_base, s_addr);
                   9280:     for (i = 0; i < words; i++, outbuf++) {
                   9281:         if (i == 2 || i == 10) {
                   9282:             continue;
                   9283:         }
                   9284:         AscSetChipLramDataNoSwap(iop_base, *outbuf);
                   9285:     }
                   9286: }
                   9287: 
                   9288: /*
                   9289:  * void
                   9290:  * DvcGetQinfo(PortAddr iop_base, ushort s_addr, ushort *inbuf, int words)
                   9291:  *
                   9292:  * Calling/Exit State:
                   9293:  *    none
                   9294:  *
                   9295:  * Description:
                   9296:  *     Input an ASC_QDONE_INFO structure from the chip
                   9297:  */
                   9298: STATIC void
                   9299: DvcGetQinfo(PortAddr iop_base, ushort s_addr, ushort *inbuf, int words)
                   9300: {
                   9301:     int    i;
                   9302: 
                   9303:     AscSetChipLramAddr(iop_base, s_addr);
                   9304:     for (i = 0; i < words; i++, inbuf++) {
                   9305:         if (i == 5) {
                   9306:             continue;
                   9307:         }
                   9308:         *inbuf = AscGetChipLramDataNoSwap(iop_base);
                   9309:     }
                   9310:     ASC_DBG_PRT_HEX(2, "DvcGetQinfo", (uchar *) inbuf, 2 * words);
                   9311: }
                   9312: 
                   9313: /*
                   9314:  * void    DvcOutPortWords(ushort iop_base, ushort &outbuf, int words)
                   9315:  *
                   9316:  * Calling/Exit State:
                   9317:  *    none
                   9318:  *
                   9319:  * Description:
                   9320:  *     output a buffer to an i/o port address
                   9321:  */
                   9322: STATIC void
                   9323: DvcOutPortWords(ushort iop_base, ushort *outbuf, int words)
                   9324: {
                   9325:     int    i;
                   9326: 
                   9327:     for (i = 0; i < words; i++, outbuf++)
                   9328:         outpw(iop_base, *outbuf);
                   9329: }
                   9330: 
                   9331: /*
                   9332:  * void    DvcInPortWords(ushort iop_base, ushort &outbuf, int words)
                   9333:  *
                   9334:  * Calling/Exit State:
                   9335:  *    none
                   9336:  *
                   9337:  * Description:
                   9338:  *     input a buffer from an i/o port address
                   9339:  */
                   9340: STATIC void
                   9341: DvcInPortWords(ushort iop_base, ushort *inbuf, int words)
                   9342: {
                   9343:     int    i;
                   9344: 
                   9345:     for (i = 0; i < words; i++, inbuf++)
                   9346:         *inbuf = inpw(iop_base);
                   9347: }
                   9348: 
                   9349: /*
                   9350:  * void DvcOutPortDWords(PortAddr port, ulong *pdw, int dwords)
                   9351:  *
                   9352:  * Calling/Exit State:
                   9353:  *    none
                   9354:  *
                   9355:  * Description:
                   9356:  *     output a buffer of 32-bit integers to an i/o port address in
                   9357:  *  16 bit integer units
                   9358:  */
                   9359: STATIC void  
                   9360: DvcOutPortDWords(PortAddr port, ulong *pdw, int dwords)
                   9361: {
                   9362:     int        i;
                   9363:     int        words;
                   9364:     ushort    *pw;
                   9365: 
                   9366:     pw = (ushort *) pdw;
                   9367:     words = dwords << 1;
                   9368:     for(i = 0; i < words; i++, pw++) {
                   9369:         outpw(port, *pw);
                   9370:     }
                   9371:     return;
                   9372: }
                   9373: 
                   9374: /*
                   9375:  * Read a PCI configuration byte.
                   9376:  */
                   9377: ASC_INITFUNC(
                   9378: STATIC uchar
                   9379: DvcReadPCIConfigByte(
                   9380:         ASC_DVC_VAR asc_ptr_type *asc_dvc, 
                   9381:         ushort offset)
                   9382: )
                   9383: {
                   9384: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
                   9385: #ifdef ASC_CONFIG_PCI
                   9386:     PCI_DATA    pciData;
                   9387: 
                   9388:     pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
                   9389:     pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
                   9390:     pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
                   9391:     pciData.offset = offset;
                   9392:     pciData.type = pci_scan_method;
                   9393:     return asc_get_cfg_byte(&pciData);
                   9394: #else /* ASC_CONFIG_PCI */
                   9395:     return 0;
                   9396: #endif /* ASC_CONFIG_PCI */
                   9397: #else /* version >= v2.1.93 */ 
                   9398: #ifdef CONFIG_PCI
                   9399:     uchar byte_data;
                   9400:     pcibios_read_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
                   9401:         PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
                   9402:             ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
                   9403:         offset, &byte_data);
                   9404:     return byte_data;
                   9405: #else /* CONFIG_PCI */
                   9406:     return 0;
                   9407: #endif /* CONFIG_PCI */
                   9408: #endif /* version >= v2.1.93 */ 
                   9409: }
                   9410: 
                   9411: /*
                   9412:  * Write a PCI configuration byte.
                   9413:  */
                   9414: ASC_INITFUNC(
                   9415: STATIC void
                   9416: DvcWritePCIConfigByte(
                   9417:         ASC_DVC_VAR asc_ptr_type *asc_dvc, 
                   9418:         ushort offset, 
                   9419:         uchar  byte_data)
                   9420: )
                   9421: {
                   9422: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
                   9423: #ifdef ASC_CONFIG_PCI
                   9424:     PCI_DATA    pciData;
                   9425: 
                   9426:     pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
                   9427:     pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
                   9428:     pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
                   9429:     pciData.offset = offset;
                   9430:     pciData.type = pci_scan_method;
                   9431:     asc_put_cfg_byte(&pciData, byte_data);
                   9432: #endif /* ASC_CONFIG_PCI */
                   9433: #else /* version >= v2.1.93 */ 
                   9434: #ifdef CONFIG_PCI
                   9435:     pcibios_write_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
                   9436:         PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
                   9437:             ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
                   9438:         offset, byte_data);
                   9439: #endif /* CONFIG_PCI */
                   9440: #endif /* version >= v2.1.93 */ 
                   9441: }
                   9442: 
                   9443: /*
                   9444:  * Return the BIOS address of the adapter at the specified
                   9445:  * I/O port and with the specified bus type.
                   9446:  */
                   9447: ASC_INITFUNC(
                   9448: STATIC ushort
                   9449: AscGetChipBiosAddress(
                   9450:         PortAddr iop_base,
                   9451:         ushort bus_type
                   9452: )
                   9453: )
                   9454: {
                   9455:     ushort  cfg_lsw ;
                   9456:     ushort  bios_addr ;
                   9457: 
                   9458:     /*
                   9459:      * The PCI BIOS is re-located by the motherboard BIOS. Because
                   9460:      * of this the driver can not determine where a PCI BIOS is
                   9461:      * loaded and executes.
                   9462:      */
                   9463:     if (bus_type & ASC_IS_PCI)
                   9464:     {
                   9465:         return(0);
                   9466:     }
                   9467: 
                   9468:     if((bus_type & ASC_IS_EISA) != 0)
                   9469:     {
                   9470:         cfg_lsw = AscGetEisaChipCfg(iop_base) ;
                   9471:         cfg_lsw &= 0x000F ;
                   9472:         bios_addr = (ushort)(ASC_BIOS_MIN_ADDR  +
                   9473:                                 (cfg_lsw * ASC_BIOS_BANK_SIZE)) ;
                   9474:         return(bios_addr) ;
                   9475:     }/* if */
                   9476: 
                   9477:     cfg_lsw = AscGetChipCfgLsw(iop_base) ;
                   9478: 
                   9479:     /*
                   9480:     *  ISA PnP uses the top bit as the 32K BIOS flag
                   9481:     */
                   9482:     if (bus_type == ASC_IS_ISAPNP)
                   9483:     {
                   9484:         cfg_lsw &= 0x7FFF;
                   9485:     }/* if */
                   9486: 
                   9487:     bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) +
                   9488:             ASC_BIOS_MIN_ADDR) ;
                   9489:     return(bios_addr) ;
                   9490: }
                   9491: 
                   9492: 
                   9493: /*
                   9494:  * --- Functions Required by the Adv Library
                   9495:  */
                   9496: 
                   9497: /*
                   9498:  * DvcGetPhyAddr()
                   9499:  *
                   9500:  * Return the physical address of 'vaddr' and set '*lenp' to the
                   9501:  * number of physically contiguous bytes that follow 'vaddr'.
                   9502:  * 'flag' indicates the type of structure whose physical address
                   9503:  * is being translated.
                   9504:  *
                   9505:  * Note: Because Linux currently doesn't page the kernel and all
                   9506:  * kernel buffers are physically contiguous, leave '*lenp' unchanged.
                   9507:  */
                   9508: ulong
                   9509: DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
                   9510:         uchar *vaddr, long *lenp, int flag)
                   9511: {
                   9512:     ulong                paddr;
                   9513: 
                   9514: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
                   9515:     paddr = (ulong) vaddr;
                   9516: #else /* version >= v2.0.0 */
                   9517:     paddr = virt_to_bus(vaddr);
                   9518: #endif /* version >= v2.0.0 */
                   9519: 
                   9520:     ASC_DBG4(4,
                   9521:         "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n", 
                   9522:         (ulong) vaddr, (ulong) lenp, (ulong) *((ulong *) lenp), paddr);
                   9523: 
                   9524:     return paddr;
                   9525: }
                   9526: 
                   9527: /*
                   9528:  * Read a PCI configuration byte.
                   9529:  */
                   9530: ASC_INITFUNC(
                   9531: STATIC uchar
                   9532: DvcAdvReadPCIConfigByte(
                   9533:         ADV_DVC_VAR *asc_dvc, 
                   9534:         ushort offset)
                   9535: )
                   9536: {
                   9537: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
                   9538: #ifdef ASC_CONFIG_PCI
                   9539:     PCI_DATA    pciData;
                   9540: 
                   9541:     pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
                   9542:     pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
                   9543:     pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
                   9544:     pciData.offset = offset;
                   9545:     pciData.type = pci_scan_method;
                   9546:     return asc_get_cfg_byte(&pciData);
                   9547: #else /* ASC_CONFIG_PCI */
                   9548:     return 0;
                   9549: #endif /* ASC_CONFIG_PCI */
                   9550: #else /* version >= v2.1.93 */ 
                   9551: #ifdef CONFIG_PCI
                   9552:     uchar byte_data;
                   9553:     pcibios_read_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
                   9554:         PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
                   9555:             ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
                   9556:         offset, &byte_data);
                   9557:     return byte_data;
                   9558: #else /* CONFIG_PCI */
                   9559:     return 0;
                   9560: #endif /* CONFIG_PCI */
                   9561: #endif /* version >= v2.1.93 */ 
                   9562: }
                   9563: 
                   9564: /*
                   9565:  * Write a PCI configuration byte.
                   9566:  */
                   9567: ASC_INITFUNC(
                   9568: STATIC void
                   9569: DvcAdvWritePCIConfigByte(
                   9570:         ADV_DVC_VAR *asc_dvc, 
                   9571:         ushort offset, 
                   9572:         uchar  byte_data)
                   9573: )
                   9574: {
                   9575: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
                   9576: #ifdef ASC_CONFIG_PCI
                   9577:     PCI_DATA    pciData;
                   9578: 
                   9579:     pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
                   9580:     pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
                   9581:     pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
                   9582:     pciData.offset = offset;
                   9583:     pciData.type = pci_scan_method;
                   9584:     asc_put_cfg_byte(&pciData, byte_data);
                   9585: #endif /* ASC_CONFIG_PCI */
                   9586: #else /* version >= v2.1.93 */ 
                   9587: #ifdef CONFIG_PCI
                   9588:     pcibios_write_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
                   9589:         PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
                   9590:             ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
                   9591:         offset, byte_data);
                   9592: #endif /* CONFIG_PCI */
                   9593: #endif /* version >= v2.1.93 */ 
                   9594: }
                   9595: 
                   9596: /*
                   9597:  * --- Tracing and Debugging Functions
                   9598:  */
                   9599: 
                   9600: #ifdef ADVANSYS_STATS
                   9601: /*
                   9602:  * asc_prt_board_stats()
                   9603:  *
                   9604:  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
                   9605:  * cf. asc_prt_line().
                   9606:  *
                   9607:  * Return the number of characters copied into 'cp'. No more than
                   9608:  * 'cplen' characters will be copied to 'cp'.
                   9609:  */
                   9610: STATIC int
                   9611: asc_prt_board_stats(struct Scsi_Host *shp, char *cp, int cplen)
                   9612: {
                   9613:     int                    leftlen;
                   9614:     int                    totlen;
                   9615:     int                    len;
                   9616:     struct asc_stats       *s;
                   9617:     int                    i;
                   9618:     ushort                 chip_scsi_id;
                   9619:     asc_board_t            *boardp;
                   9620:     asc_queue_t            *active;
                   9621:     asc_queue_t            *waiting;
                   9622: 
                   9623:     leftlen = cplen;
                   9624:     totlen = len = 0;
                   9625: 
                   9626:     boardp = ASC_BOARDP(shp);
                   9627:     s = &boardp->asc_stats;
                   9628: 
                   9629:     len = asc_prt_line(cp, leftlen,
                   9630: "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", shp->host_no);
                   9631:     ASC_PRT_NEXT();
                   9632:     
                   9633:     len = asc_prt_line(cp, leftlen,
                   9634: " command %lu, queuecommand %lu, abort %lu, reset %lu, biosparam %lu\n",
                   9635:         s->command, s->queuecommand, s->abort, s->reset, s->biosparam);
                   9636:     ASC_PRT_NEXT();
                   9637: 
                   9638:     len = asc_prt_line(cp, leftlen,
                   9639: " interrupt %lu, callback %lu, done %lu\n",
                   9640:         s->interrupt, s->callback, s->done);
                   9641:     ASC_PRT_NEXT();
                   9642: 
                   9643:     len = asc_prt_line(cp, leftlen,
                   9644: " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
                   9645:         s->exe_noerror, s->exe_busy, s->exe_error, s->exe_unknown);
                   9646:     ASC_PRT_NEXT();
                   9647: 
                   9648:     if (ASC_NARROW_BOARD(boardp)) {
                   9649:         len = asc_prt_line(cp, leftlen,
                   9650: " build_error %lu\n",
                   9651:          s->build_error);
                   9652:     } else {
                   9653:         len = asc_prt_line(cp, leftlen,
                   9654: " build_error %lu, build_noreq %lu, build_nosg %lu\n",
                   9655:          s->build_error, s->adv_build_noreq, s->adv_build_nosg);
                   9656:     }
                   9657:     ASC_PRT_NEXT();
                   9658: 
                   9659:     /*
                   9660:      * Display data transfer statistics.
                   9661:      */
                   9662:     if (s->cont_cnt > 0) {
                   9663:         len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
                   9664:         ASC_PRT_NEXT();
                   9665: 
                   9666:         len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
                   9667:                     s->cont_xfer/2,
                   9668:                     ASC_TENTHS(s->cont_xfer, 2));
                   9669:         ASC_PRT_NEXT();
                   9670: 
                   9671:         /* Contiguous transfer average size */
                   9672:         len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
                   9673:                     (s->cont_xfer/2)/s->cont_cnt,
                   9674:                     ASC_TENTHS((s->cont_xfer/2), s->cont_cnt));
                   9675:         ASC_PRT_NEXT();
                   9676:     }
                   9677: 
                   9678:     if (s->sg_cnt > 0) {
                   9679: 
                   9680:         len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
                   9681:                     s->sg_cnt, s->sg_elem);
                   9682:         ASC_PRT_NEXT();
                   9683: 
                   9684:         len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
                   9685:                     s->sg_xfer/2,
                   9686:                     ASC_TENTHS(s->sg_xfer, 2));
                   9687:         ASC_PRT_NEXT();
                   9688: 
                   9689:         /* Scatter gather transfer statistics */
                   9690:         len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
                   9691:                     s->sg_elem/s->sg_cnt,
                   9692:                     ASC_TENTHS(s->sg_elem, s->sg_cnt));
                   9693:         ASC_PRT_NEXT();
                   9694: 
                   9695:         len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
                   9696:                     (s->sg_xfer/2)/s->sg_elem,
                   9697:                     ASC_TENTHS((s->sg_xfer/2), s->sg_elem));
                   9698:         ASC_PRT_NEXT();
                   9699: 
                   9700:         len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
                   9701:                     (s->sg_xfer/2)/s->sg_cnt,
                   9702:                     ASC_TENTHS((s->sg_xfer/2), s->sg_cnt));
                   9703:         ASC_PRT_NEXT();
                   9704:     }
                   9705: 
                   9706:     /*
                   9707:      * Display request queuing statistics.
                   9708:      */
                   9709:     len = asc_prt_line(cp, leftlen,
                   9710: " Active and Waiting Request Queues (Time Unit: %d HZ):\n", HZ);
                   9711:     ASC_PRT_NEXT();
                   9712: 
                   9713:     active = &ASC_BOARDP(shp)->active;
                   9714:     waiting = &ASC_BOARDP(shp)->waiting;
                   9715: 
                   9716:     if (ASC_NARROW_BOARD(boardp)) {
                   9717:         chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
                   9718:     } else {
                   9719:         chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
                   9720:     }
                   9721: 
                   9722:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   9723: 
                   9724:         if ((chip_scsi_id == i) ||
                   9725:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   9726:             continue;
                   9727:         }
                   9728: 
                   9729:         if (active->q_tot_cnt[i] > 0 || waiting->q_tot_cnt[i] > 0) {
                   9730:             len = asc_prt_line(cp, leftlen, " target %d\n", i);
                   9731:             ASC_PRT_NEXT();
                   9732: 
                   9733:             len = asc_prt_line(cp, leftlen,
                   9734: "   active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
                   9735:                 active->q_cur_cnt[i], active->q_max_cnt[i],
                   9736:                 active->q_tot_cnt[i],
                   9737:                 active->q_min_tim[i], active->q_max_tim[i],
                   9738:                 (active->q_tot_cnt[i] == 0) ? 0 :
                   9739:                 (active->q_tot_tim[i]/active->q_tot_cnt[i]),
                   9740:                 (active->q_tot_cnt[i] == 0) ? 0 :
                   9741:                 ASC_TENTHS(active->q_tot_tim[i], active->q_tot_cnt[i]));
                   9742:             ASC_PRT_NEXT();
                   9743: 
                   9744:             len = asc_prt_line(cp, leftlen,
                   9745: "   waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
                   9746:                 waiting->q_cur_cnt[i], waiting->q_max_cnt[i],
                   9747:                 waiting->q_tot_cnt[i],
                   9748:                 waiting->q_min_tim[i], waiting->q_max_tim[i],
                   9749:                 (waiting->q_tot_cnt[i] == 0) ? 0 :
                   9750:                 (waiting->q_tot_tim[i]/waiting->q_tot_cnt[i]),
                   9751:                 (waiting->q_tot_cnt[i] == 0) ? 0 :
                   9752:                 ASC_TENTHS(waiting->q_tot_tim[i], waiting->q_tot_cnt[i]));
                   9753:             ASC_PRT_NEXT();
                   9754:         }
                   9755:     }
                   9756: 
                   9757:      return totlen;
                   9758: }
                   9759: #endif /* ADVANSYS_STATS */
                   9760: 
                   9761: #ifdef ADVANSYS_DEBUG
                   9762: /*
                   9763:  * asc_prt_scsi_host()
                   9764:  */
                   9765: STATIC void 
                   9766: asc_prt_scsi_host(struct Scsi_Host *s)
                   9767: {
                   9768:     asc_board_t         *boardp;
                   9769: 
                   9770:     boardp = ASC_BOARDP(s);
                   9771: 
                   9772:     printk("Scsi_Host at addr %x\n", (unsigned) s);
                   9773:     printk(
                   9774: " next %x, extra_bytes %u, host_busy %u, host_no %d, last_reset %d,\n",
                   9775:         (unsigned) s->next, s->extra_bytes, s->host_busy, s->host_no,
                   9776:         (unsigned) s->last_reset);
                   9777: 
                   9778:     printk(
                   9779: " host_wait %x, host_queue %x, hostt %x, block %x,\n",
                   9780:         (unsigned) s->host_wait, (unsigned) s->host_queue,
                   9781:         (unsigned) s->hostt, (unsigned) s->block);
                   9782: 
                   9783:     printk(
                   9784: " wish_block %d, base %x, io_port %d, n_io_port %d, irq %d, dma_channel %d,\n",
                   9785:         s->wish_block, (unsigned) s->base, s->io_port, s->n_io_port,
                   9786:         s->irq, s->dma_channel);
                   9787: 
                   9788:     printk(
                   9789: " this_id %d, can_queue %d,\n", s->this_id, s->can_queue);
                   9790: 
                   9791:     printk(
                   9792: " cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d, loaded_as_module %d\n",
                   9793:         s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma,
                   9794:         s->loaded_as_module);
                   9795: 
                   9796:     if (ASC_NARROW_BOARD(boardp)) {
                   9797:         asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
                   9798:         asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
                   9799:     } else {
                   9800:         asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
                   9801:         asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
                   9802:     }
                   9803: }
                   9804: 
                   9805: /*
                   9806:  * asc_prt_scsi_cmnd()
                   9807:  */
                   9808: STATIC void 
                   9809: asc_prt_scsi_cmnd(Scsi_Cmnd *s)
                   9810: {
                   9811:     printk("Scsi_Cmnd at addr %x\n", (unsigned) s);
                   9812: 
                   9813: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
                   9814:     printk(
                   9815: " host %x, device %x, target %u, lun %u\n",
                   9816:         (unsigned) s->host, (unsigned) s->device, s->target, s->lun);
                   9817: #else /* version >= v1.3.0 */
                   9818:     printk(
                   9819: " host %x, device %x, target %u, lun %u, channel %u,\n",
                   9820:         (unsigned) s->host, (unsigned) s->device, s->target, s->lun,
                   9821:         s->channel);
                   9822: #endif /* version >= v1.3.0 */
                   9823: 
                   9824:     asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
                   9825: 
                   9826:     printk(
                   9827: " use_sg %u, sglist_len %u, abort_reason %x\n",
                   9828:         s->use_sg, s->sglist_len, s->abort_reason);
                   9829: 
                   9830: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89)
                   9831:     printk(
                   9832: " retries %d, allowed %d\n",
                   9833:          s->retries, s->allowed);
                   9834: #else /* version >= v1.3.89 */
                   9835:     printk(
                   9836: " serial_number %x, serial_number_at_timeout %x, retries %d, allowed %d\n",
                   9837:         (unsigned) s->serial_number, (unsigned) s->serial_number_at_timeout,
                   9838:          s->retries, s->allowed);
                   9839: #endif /* version >= v1.3.89 */
                   9840: 
                   9841:     printk(
                   9842: " timeout_per_command %d, timeout_total %d, timeout %d\n",
                   9843:         s->timeout_per_command, s->timeout_total, s->timeout);
                   9844: 
                   9845:     printk(
                   9846: " internal_timeout %u, flags %u, this_count %d\n",
                   9847:         s->internal_timeout, s->flags, s->this_count);
                   9848: 
                   9849:     printk(
                   9850: " scsi_done %x, done %x, host_scribble %x, result %x\n",
                   9851:         (unsigned) s->scsi_done, (unsigned) s->done,
                   9852:         (unsigned) s->host_scribble, s->result);
                   9853: 
                   9854:     printk(
                   9855: " tag %u, pid %u\n",
                   9856:         (unsigned) s->tag, (unsigned) s->pid);
                   9857: }
                   9858: 
                   9859: /*
                   9860:  * asc_prt_asc_dvc_var()
                   9861:  */
                   9862: STATIC void 
                   9863: asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
                   9864: {
                   9865:     printk("ASC_DVC_VAR at addr %x\n", (unsigned) h);
                   9866: 
                   9867:     printk(
                   9868: " iop_base %x, err_code %x, dvc_cntl %x, bug_fix_cntl %d,\n",
                   9869:         h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
                   9870: 
                   9871:     printk(
                   9872: " bus_type %d, isr_callback %x, exe_callback %x, init_sdtr %x,\n",
                   9873:         h->bus_type, (unsigned) h->isr_callback, (unsigned) h->exe_callback,
                   9874:         (unsigned) h->init_sdtr);
                   9875: 
                   9876:     printk(
                   9877: " sdtr_done %x, use_tagged_qng %x, unit_not_ready %x, chip_no %x,\n",
                   9878:         (unsigned) h->sdtr_done, (unsigned) h->use_tagged_qng,
                   9879:         (unsigned) h->unit_not_ready, (unsigned) h->chip_no);
                   9880:         
                   9881:     printk(
                   9882: " queue_full_or_busy %x, start_motor %x, scsi_reset_wait %x, irq_no %x,\n",
                   9883:         (unsigned) h->queue_full_or_busy, (unsigned) h->start_motor,
                   9884:         (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
                   9885: 
                   9886:     printk(
                   9887: " is_in_int %x, max_total_qng %x, cur_total_qng %x, in_critical_cnt %x,\n",
                   9888:         (unsigned) h->is_in_int, (unsigned) h->max_total_qng,
                   9889:         (unsigned) h->cur_total_qng, (unsigned) h->in_critical_cnt);
                   9890: 
                   9891:     printk(
                   9892: " last_q_shortage %x, init_state %x, no_scam %x, pci_fix_asyn_xfer %x,\n",
                   9893:         (unsigned) h->last_q_shortage, (unsigned) h->init_state,
                   9894:         (unsigned) h->no_scam, (unsigned) h->pci_fix_asyn_xfer);
                   9895: 
                   9896:     printk(
                   9897: " cfg %x, saved_ptr2func %x\n",
                   9898:         (unsigned) h->cfg, (unsigned) h->saved_ptr2func);
                   9899: }
                   9900: 
                   9901: /*
                   9902:  * asc_prt_asc_dvc_cfg()
                   9903:  */
                   9904: STATIC void 
                   9905: asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
                   9906: {
                   9907:     printk("ASC_DVC_CFG at addr %x\n", (unsigned) h);
                   9908: 
                   9909:     printk(
                   9910: " can_tagged_qng %x, cmd_qng_enabled %x, disc_enable %x, sdtr_enable %x,\n",
                   9911:             h->can_tagged_qng, h->cmd_qng_enabled, h->disc_enable,
                   9912:             h->sdtr_enable);
                   9913: 
                   9914:     printk(
                   9915: " chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
                   9916:              h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
                   9917:              h->chip_version);
                   9918: 
                   9919:     printk(
                   9920: " pci_device_id %d, lib_serial_no %x, lib_version %x, mcode_date %x,\n",
                   9921:           h->pci_device_id, h->lib_serial_no, h->lib_version, h->mcode_date);
                   9922: 
                   9923:     printk(
                   9924: " mcode_version %d, overrun_buf %x\n",
                   9925:             h->mcode_version, (unsigned) h->overrun_buf);
                   9926: }
                   9927: 
                   9928: /*
                   9929:  * asc_prt_asc_scsi_q()
                   9930:  */
                   9931: STATIC void 
                   9932: asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
                   9933: {
                   9934:     ASC_SG_HEAD    *sgp;
                   9935:     int i;
                   9936: 
                   9937:     printk("ASC_SCSI_Q at addr %x\n", (unsigned) q);
                   9938: 
                   9939:     printk(
                   9940: " target_ix %u, target_lun %u, srb_ptr %x, tag_code %u,\n",
                   9941:             q->q2.target_ix, q->q1.target_lun,
                   9942:             (unsigned) q->q2.srb_ptr, q->q2.tag_code);
                   9943: 
                   9944:     printk(
                   9945: " data_addr %x, data_cnt %lu, sense_addr %x, sense_len %u,\n",
                   9946:             (unsigned) q->q1.data_addr, q->q1.data_cnt,
                   9947:             (unsigned) q->q1.sense_addr, q->q1.sense_len);
                   9948: 
                   9949:     printk(
                   9950: " cdbptr %x, cdb_len %u, sg_head %x, sg_queue_cnt %u\n",
                   9951:             (unsigned) q->cdbptr, q->q2.cdb_len,
                   9952:             (unsigned) q->sg_head, q->q1.sg_queue_cnt);
                   9953: 
                   9954:     if (q->sg_head) {
                   9955:         sgp = q->sg_head;
                   9956:         printk("ASC_SG_HEAD at addr %x\n", (unsigned) sgp);
                   9957:         printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, sgp->queue_cnt);
                   9958:         for (i = 0; i < sgp->entry_cnt; i++) {
                   9959:             printk(" [%u]: addr %x, bytes %lu\n",
                   9960:                 i, (unsigned) sgp->sg_list[i].addr, sgp->sg_list[i].bytes);
                   9961:         }
                   9962: 
                   9963:     }
                   9964: }
                   9965: 
                   9966: /*
                   9967:  * asc_prt_asc_qdone_info()
                   9968:  */
                   9969: STATIC void 
                   9970: asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
                   9971: {
                   9972:     printk("ASC_QDONE_INFO at addr %x\n", (unsigned) q);
                   9973:     printk(
                   9974: " srb_ptr %x, target_ix %u, cdb_len %u, tag_code %u, done_stat %x\n",
                   9975:             (unsigned) q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
                   9976:             q->d2.tag_code, q->d3.done_stat);
                   9977:     printk(
                   9978: " host_stat %x, scsi_stat %x, scsi_msg %x\n",
                   9979:             q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
                   9980: }
                   9981: 
                   9982: /*
                   9983:  * asc_prt_adv_dvc_var()
                   9984:  *
                   9985:  * Display an ADV_DVC_VAR structure.
                   9986:  */
                   9987: STATIC void 
                   9988: asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
                   9989: {
                   9990:     printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong) h);
                   9991: 
                   9992:     printk(
                   9993: "  iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
                   9994:         (ulong) h->iop_base, h->err_code, (unsigned) h->ultra_able);
                   9995: 
                   9996:     printk(
                   9997: "  isr_callback 0x%x, sdtr_able 0x%x, wdtr_able 0x%x\n",
                   9998:         (unsigned) h->isr_callback, (unsigned) h->wdtr_able,
                   9999:         (unsigned) h->sdtr_able);
                   10000: 
                   10001:     printk(
                   10002: "  start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
                   10003:         (unsigned) h->start_motor,
                   10004:         (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
                   10005: 
                   10006:     printk(
                   10007: "  max_host_qng 0x%x, cur_host_qng 0x%x, max_dvc_qng 0x%x\n",
                   10008:         (unsigned) h->max_host_qng, (unsigned) h->cur_host_qng,
                   10009:         (unsigned) h->max_dvc_qng);
                   10010: 
                   10011:     printk(
                   10012: "  no_scam 0x%x, tagqng_able 0x%x, chip_scsi_id 0x%x, cfg 0x%lx\n",
                   10013:         (unsigned) h->no_scam, (unsigned) h->tagqng_able,
                   10014:         (unsigned) h->chip_scsi_id, (ulong) h->cfg);
                   10015: 
                   10016: }
                   10017: 
                   10018: /*
                   10019:  * asc_prt_adv_dvc_cfg()
                   10020:  *
                   10021:  * Display an ADV_DVC_CFG structure.
                   10022:  */
                   10023: STATIC void 
                   10024: asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
                   10025: {
                   10026:     printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong) h);
                   10027: 
                   10028:     printk(
                   10029: "  disc_enable 0x%x, termination 0x%x\n",
                   10030:         h->disc_enable, h->termination);
                   10031: 
                   10032:     printk(
                   10033: "  chip_version 0x%x, mcode_date 0x%x\n",
                   10034:         h->chip_version, h->mcode_date);
                   10035: 
                   10036:     printk(
                   10037: "  mcode_version 0x%x, pci_device_id 0x%x, lib_version 0x%x\n",
                   10038:        h->mcode_version, h->pci_device_id, h->lib_version);
                   10039: 
                   10040:     printk(
                   10041: "  control_flag 0x%x, pci_slot_info 0x%x\n",
                   10042:        h->control_flag, h->pci_slot_info);
                   10043: }
                   10044: 
                   10045: /*
                   10046:  * asc_prt_adv_scsi_req_q()
                   10047:  *
                   10048:  * Display an ADV_SCSI_REQ_Q structure.
                   10049:  */
                   10050: STATIC void 
                   10051: asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
                   10052: {
                   10053:     int                 i;
                   10054:     struct asc_sg_block *sg_ptr;
                   10055: 
                   10056:     printk("ADV_SCSI_REQ_Q at addr %x\n", (unsigned) q);
                   10057: 
                   10058:     printk(
                   10059: "  target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
                   10060:             q->target_id, q->target_lun, q->srb_ptr, q->a_flag);
                   10061: 
                   10062:     printk("  cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
                   10063:             q->cntl, q->data_addr, q->vdata_addr);
                   10064: 
                   10065:     printk(
                   10066: "  data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
                   10067:             q->data_cnt, q->sense_addr, q->sense_len);
                   10068: 
                   10069:     printk(
                   10070: "  cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
                   10071:             q->cdb_len, q->done_status, q->host_status, q->scsi_status);
                   10072: 
                   10073:     printk(
                   10074: "  vsense_addr 0x%lx, scsiq_ptr 0x%lx, ux_wk_data_cnt %lu\n",
                   10075:             (ulong) q->vsense_addr, (ulong) q->scsiq_ptr,
                   10076:             (ulong) q->ux_wk_data_cnt);
                   10077: 
                   10078:     printk(
                   10079: "  sg_list_ptr 0x%lx, sg_real_addr 0x%lx, sg_entry_cnt %u\n",
                   10080:             (ulong) q->sg_list_ptr, (ulong) q->sg_real_addr, q->sg_entry_cnt);
                   10081: 
                   10082:     printk(
                   10083: "  ux_sg_ix %u, orig_sense_len %u\n",
                   10084:             q->ux_sg_ix, q->orig_sense_len);
                   10085: 
                   10086:     /* Display the request's ADV_SG_BLOCK structures. */
                   10087:     for (sg_ptr = q->sg_list_ptr, i = 0; sg_ptr != NULL;
                   10088:         sg_ptr = sg_ptr->sg_ptr, i++) {
                   10089:         /*
                   10090:          * 'sg_ptr' is a physical address. Convert it to a virtual
                   10091:          * address by indexing 'i' into the virtual address array
                   10092:          * 'sg_list_ptr'.
                   10093:          *
                   10094:          * At the end of the each iteration of the loop 'sg_ptr' is
                   10095:          * converted back into a physical address by setting 'sg_ptr'
                   10096:          *  to the next pointer 'sg_ptr->sg_ptr'.
                   10097:          */
                   10098:         sg_ptr = &(((ADV_SG_BLOCK *) (q->sg_list_ptr))[i]);
                   10099:         asc_prt_adv_sgblock(i, sg_ptr);
                   10100:     }
                   10101: }
                   10102: 
                   10103: /*
                   10104:  * asc_prt_adv_sgblock()
                   10105:  *
                   10106:  * Display an ADV_SG_BLOCK structure.
                   10107:  */
                   10108: STATIC void
                   10109: asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
                   10110: {
                   10111:     int i, s;
                   10112: 
                   10113:     /* Calculate starting entry number for the current block. */
                   10114:     s = sgblockno * NO_OF_SG_PER_BLOCK;
                   10115: 
                   10116:     printk(" ADV_SG_BLOCK at addr 0x%lx (sgblockno %lu)\n",
                   10117:         (ulong) b, (ulong) sgblockno);
                   10118:     printk(
                   10119: "  first_entry_no %lu, last_entry_no %lu, sg_ptr 0x%lx\n",
                   10120:         (ulong) b->first_entry_no, (ulong) b->last_entry_no, (ulong) b->sg_ptr);
                   10121:     ASC_ASSERT(b->first_entry_no - s >= 0);
                   10122:     ASC_ASSERT(b->last_entry_no - s >= 0);
                   10123:     ASC_ASSERT(b->last_entry_no - s <= NO_OF_SG_PER_BLOCK);
                   10124:     ASC_ASSERT(b->first_entry_no - s <= NO_OF_SG_PER_BLOCK);
                   10125:     ASC_ASSERT(b->first_entry_no - s <= NO_OF_SG_PER_BLOCK);
                   10126:     ASC_ASSERT(b->first_entry_no - s <= b->last_entry_no - s);
                   10127:     for (i = b->first_entry_no - s; i <= b->last_entry_no - s; i++) {
                   10128:         printk("  [%lu]: sg_addr 0x%lx, sg_count 0x%lx\n",
                   10129:             (ulong) i, (ulong) b->sg_list[i].sg_addr,
                   10130:             (ulong) b->sg_list[i].sg_count);
                   10131:     }
                   10132: }
                   10133: 
                   10134: /*
                   10135:  * asc_prt_hex()
                   10136:  *
                   10137:  * Print hexadecimal output in 4 byte groupings 32 bytes 
                   10138:  * or 8 double-words per line.
                   10139:  */
                   10140: STATIC void 
                   10141: asc_prt_hex(char *f, uchar *s, int l)
                   10142: {
                   10143:     int            i;
                   10144:     int            j;
                   10145:     int            k;
                   10146:     int            m;
                   10147: 
                   10148:     printk("%s: (%d bytes)\n", f, l);
                   10149: 
                   10150:     for (i = 0; i < l; i += 32) {
                   10151:         
                   10152:         /* Display a maximum of 8 double-words per line. */
                   10153:         if ((k = (l - i) / 4) >= 8) {
                   10154:             k = 8;
                   10155:             m = 0;
                   10156:         } else {
                   10157:             m = (l - i) % 4 ;
                   10158:         }
                   10159: 
                   10160:         for (j = 0; j < k; j++) {
                   10161:             printk(" %2.2X%2.2X%2.2X%2.2X",
                   10162:                 (unsigned) s[i+(j*4)], (unsigned) s[i+(j*4)+1],
                   10163:                 (unsigned) s[i+(j*4)+2], (unsigned) s[i+(j*4)+3]);
                   10164:         }
                   10165: 
                   10166:         switch (m) {
                   10167:         case 0:
                   10168:         default:
                   10169:             break;
                   10170:         case 1:
                   10171:             printk(" %2.2X",
                   10172:                 (unsigned) s[i+(j*4)]);
                   10173:             break;
                   10174:         case 2:
                   10175:             printk(" %2.2X%2.2X",
                   10176:                 (unsigned) s[i+(j*4)],
                   10177:                 (unsigned) s[i+(j*4)+1]);
                   10178:             break;
                   10179:         case 3:
                   10180:             printk(" %2.2X%2.2X%2.2X",
                   10181:                 (unsigned) s[i+(j*4)+1],
                   10182:                 (unsigned) s[i+(j*4)+2],
                   10183:                 (unsigned) s[i+(j*4)+3]);
                   10184:             break;
                   10185:         }
                   10186: 
                   10187:         printk("\n");
                   10188:     }
                   10189: }
                   10190: #endif /* ADVANSYS_DEBUG */
                   10191: 
                   10192: #ifdef ADVANSYS_ASSERT
                   10193: /*
                   10194:  * interrupts_enabled()
                   10195:  *
                   10196:  * Return 1 if interrupts are enabled, otherwise return 0.
                   10197:  */
                   10198: STATIC int
                   10199: interrupts_enabled(void)
                   10200: {
1.1.1.2 ! root     10201:     long flags;
1.1       root     10202: 
                   10203:     save_flags(flags);
                   10204:     if (flags & 0x0200) {
                   10205:         return ASC_TRUE;
                   10206:     } else {
                   10207:         return ASC_FALSE;
                   10208:     }
                   10209: }
                   10210: #endif /* ADVANSYS_ASSERT */
                   10211: 
                   10212: 
                   10213: /*
                   10214:  * --- Asc Library Functions
                   10215:  */
                   10216: 
                   10217: ASC_INITFUNC(
                   10218: STATIC ushort
                   10219: AscGetEisaChipCfg(
                   10220:                      PortAddr iop_base
                   10221: )
                   10222: )
                   10223: {
                   10224:     PortAddr            eisa_cfg_iop;
                   10225: 
                   10226:     eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
                   10227:       (PortAddr) (ASC_EISA_CFG_IOP_MASK);
                   10228:     return (inpw(eisa_cfg_iop));
                   10229: }
                   10230: 
                   10231: ASC_INITFUNC(
                   10232: STATIC uchar
                   10233: AscSetChipScsiID(
                   10234:                     PortAddr iop_base,
                   10235:                     uchar new_host_id
                   10236: )
                   10237: )
                   10238: {
                   10239:     ushort              cfg_lsw;
                   10240: 
                   10241:     if (AscGetChipScsiID(iop_base) == new_host_id) {
                   10242:         return (new_host_id);
                   10243:     }
                   10244:     cfg_lsw = AscGetChipCfgLsw(iop_base);
                   10245:     cfg_lsw &= 0xF8FF;
                   10246:     cfg_lsw |= (ushort) ((new_host_id & ASC_MAX_TID) << 8);
                   10247:     AscSetChipCfgLsw(iop_base, cfg_lsw);
                   10248:     return (AscGetChipScsiID(iop_base));
                   10249: }
                   10250: 
                   10251: ASC_INITFUNC(
                   10252: STATIC uchar
                   10253: AscGetChipScsiCtrl(
                   10254:                       PortAddr iop_base
                   10255: )
                   10256: )
                   10257: {
                   10258:     uchar               sc;
                   10259: 
                   10260:     AscSetBank(iop_base, 1);
                   10261:     sc = inp(iop_base + IOP_REG_SC);
                   10262:     AscSetBank(iop_base, 0);
                   10263:     return (sc);
                   10264: }
                   10265: 
                   10266: ASC_INITFUNC(
                   10267: STATIC uchar
                   10268: AscGetChipVersion(
                   10269:                      PortAddr iop_base,
                   10270:                      ushort bus_type
                   10271: )
                   10272: )
                   10273: {
                   10274:     if ((bus_type & ASC_IS_EISA) != 0) {
                   10275:         PortAddr            eisa_iop;
                   10276:         uchar               revision;
                   10277:         eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
                   10278:           (PortAddr) ASC_EISA_REV_IOP_MASK;
                   10279:         revision = inp(eisa_iop);
                   10280:         return ((uchar) ((ASC_CHIP_MIN_VER_EISA - 1) + revision));
                   10281:     }
                   10282:     return (AscGetChipVerNo(iop_base));
                   10283: }
                   10284: 
                   10285: ASC_INITFUNC(
                   10286: STATIC ushort
                   10287: AscGetChipBusType(
                   10288:                      PortAddr iop_base
                   10289: )
                   10290: )
                   10291: {
                   10292:     ushort              chip_ver;
                   10293: 
                   10294:     chip_ver = AscGetChipVerNo(iop_base);
                   10295:     if (
                   10296:            (chip_ver >= ASC_CHIP_MIN_VER_VL)
                   10297:            && (chip_ver <= ASC_CHIP_MAX_VER_VL)
                   10298: ) {
                   10299:         if (
                   10300:                ((iop_base & 0x0C30) == 0x0C30)
                   10301:                || ((iop_base & 0x0C50) == 0x0C50)
                   10302: ) {
                   10303:             return (ASC_IS_EISA);
                   10304:         }
                   10305:         return (ASC_IS_VL);
                   10306:     }
                   10307:     if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
                   10308:         (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
                   10309:         if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
                   10310:             return (ASC_IS_ISAPNP);
                   10311:         }
                   10312:         return (ASC_IS_ISA);
                   10313:     } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
                   10314:                (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
                   10315:         return (ASC_IS_PCI);
                   10316:     }
                   10317:     return (0);
                   10318: }
                   10319: 
                   10320: ASC_INITFUNC(
                   10321: STATIC ulong
                   10322: AscLoadMicroCode(
                   10323:                     PortAddr iop_base,
                   10324:                     ushort s_addr,
                   10325:                     ushort *mcode_buf,
                   10326:                     ushort mcode_size
                   10327: )
                   10328: )
                   10329: {
                   10330:     ulong               chksum;
                   10331:     ushort              mcode_word_size;
                   10332:     ushort              mcode_chksum;
                   10333: 
                   10334:     mcode_word_size = (ushort) (mcode_size >> 1);
                   10335:     AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
                   10336:     AscMemWordCopyToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
                   10337:     chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
                   10338:     mcode_chksum = (ushort) AscMemSumLramWord(iop_base,
                   10339:                                               (ushort) ASC_CODE_SEC_BEG,
                   10340:           (ushort) ((mcode_size - s_addr - (ushort) ASC_CODE_SEC_BEG) / 2));
                   10341:     AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
                   10342:     AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
                   10343:     return (chksum);
                   10344: }
                   10345: 
                   10346: ASC_INITFUNC(
                   10347: STATIC int
                   10348: AscFindSignature(
                   10349:                     PortAddr iop_base
                   10350: )
                   10351: )
                   10352: {
                   10353:     ushort              sig_word;
                   10354: 
                   10355:     if (AscGetChipSignatureByte(iop_base) == (uchar) ASC_1000_ID1B) {
                   10356:         sig_word = AscGetChipSignatureWord(iop_base);
                   10357:         if ((sig_word == (ushort) ASC_1000_ID0W) ||
                   10358:             (sig_word == (ushort) ASC_1000_ID0W_FIX)) {
                   10359:             return (1);
                   10360:         }
                   10361:     }
                   10362:     return (0);
                   10363: }
                   10364: 
                   10365: STATIC uchar _isa_pnp_inited ASC_INITDATA = 0;
                   10366: STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] ASC_INITDATA =
                   10367: {
                   10368:     0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
                   10369:     ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
                   10370: };
                   10371: 
                   10372: ASC_INITFUNC(
                   10373: STATIC PortAddr
                   10374: AscSearchIOPortAddr(
                   10375:                        PortAddr iop_beg,
                   10376:                        ushort bus_type
                   10377: )
                   10378: )
                   10379: {
                   10380:     if (bus_type & ASC_IS_VL) {
                   10381:         while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
                   10382:             if (AscGetChipVersion(iop_beg, bus_type) <= ASC_CHIP_MAX_VER_VL) {
                   10383:                 return (iop_beg);
                   10384:             }
                   10385:         }
                   10386:         return (0);
                   10387:     }
                   10388:     if (bus_type & ASC_IS_ISA) {
                   10389:         if (_isa_pnp_inited == 0) {
                   10390:             AscSetISAPNPWaitForKey();
                   10391:             _isa_pnp_inited++;
                   10392:         }
                   10393:         while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
                   10394:             if ((AscGetChipVersion(iop_beg, bus_type) & ASC_CHIP_VER_ISA_BIT) != 0) {
                   10395:                 return (iop_beg);
                   10396:             }
                   10397:         }
                   10398:         return (0);
                   10399:     }
                   10400:     if (bus_type & ASC_IS_EISA) {
                   10401:         if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) {
                   10402:             return (iop_beg);
                   10403:         }
                   10404:         return (0);
                   10405:     }
                   10406:     return (0);
                   10407: }
                   10408: 
                   10409: ASC_INITFUNC(
                   10410: STATIC PortAddr
                   10411: AscSearchIOPortAddr11(
                   10412:                          PortAddr s_addr
                   10413: )
                   10414: )
                   10415: {
                   10416:     int                 i;
                   10417:     PortAddr            iop_base;
                   10418: 
                   10419:     for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) {
                   10420:         if (_asc_def_iop_base[i] > s_addr) {
                   10421:             break;
                   10422:         }
                   10423:     }
                   10424:     for (; i < ASC_IOADR_TABLE_MAX_IX; i++) {
                   10425:         iop_base = _asc_def_iop_base[i];
                   10426:         if (check_region(iop_base, ASC_IOADR_GAP) != 0) {
                   10427:             ASC_DBG1(1,
                   10428:                "AscSearchIOPortAddr11: check_region() failed I/O port %x\n",
                   10429:                      iop_base);
                   10430:             continue;
                   10431:         }
                   10432:         ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port %x\n", iop_base);
                   10433:         if (AscFindSignature(iop_base)) {
                   10434:             return (iop_base);
                   10435:         }
                   10436:     }
                   10437:     return (0);
                   10438: }
                   10439: 
                   10440: ASC_INITFUNC(
                   10441: STATIC void
                   10442: AscToggleIRQAct(
                   10443:                    PortAddr iop_base
                   10444: )
                   10445: )
                   10446: {
                   10447:     AscSetChipStatus(iop_base, CIW_IRQ_ACT);
                   10448:     AscSetChipStatus(iop_base, 0);
                   10449:     return;
                   10450: }
                   10451: 
                   10452: ASC_INITFUNC(
                   10453: STATIC void
                   10454: AscSetISAPNPWaitForKey(
                   10455:     void)
                   10456: )
                   10457: {
                   10458:     outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
                   10459:     outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
                   10460:     return;
                   10461: }
                   10462: 
                   10463: ASC_INITFUNC(
                   10464: STATIC uchar
                   10465: AscGetChipIRQ(
                   10466:                  PortAddr iop_base,
                   10467:                  ushort bus_type
                   10468: )
                   10469: )
                   10470: {
                   10471:     ushort              cfg_lsw;
                   10472:     uchar               chip_irq;
                   10473: 
                   10474:     if ((bus_type & ASC_IS_EISA) != 0) {
                   10475:         cfg_lsw = AscGetEisaChipCfg(iop_base);
                   10476:         chip_irq = (uchar) (((cfg_lsw >> 8) & 0x07) + 10);
                   10477:         if ((chip_irq == 13) || (chip_irq > 15)) {
                   10478:             return (0);
                   10479:         }
                   10480:         return (chip_irq);
                   10481:     }
                   10482:     if ((bus_type & ASC_IS_VL) != 0) {
                   10483:         cfg_lsw = AscGetChipCfgLsw(iop_base);
                   10484:         chip_irq = (uchar) (((cfg_lsw >> 2) & 0x07));
                   10485:         if ((chip_irq == 0) ||
                   10486:             (chip_irq == 4) ||
                   10487:             (chip_irq == 7)) {
                   10488:             return (0);
                   10489:         }
                   10490:         return ((uchar) (chip_irq + (ASC_MIN_IRQ_NO - 1)));
                   10491:     }
                   10492:     cfg_lsw = AscGetChipCfgLsw(iop_base);
                   10493:     chip_irq = (uchar) (((cfg_lsw >> 2) & 0x03));
                   10494:     if (chip_irq == 3)
                   10495:         chip_irq += (uchar) 2;
                   10496:     return ((uchar) (chip_irq + ASC_MIN_IRQ_NO));
                   10497: }
                   10498: 
                   10499: ASC_INITFUNC(
                   10500: STATIC uchar
                   10501: AscSetChipIRQ(
                   10502:                  PortAddr iop_base,
                   10503:                  uchar irq_no,
                   10504:                  ushort bus_type
                   10505: )
                   10506: )
                   10507: {
                   10508:     ushort              cfg_lsw;
                   10509: 
                   10510:     if ((bus_type & ASC_IS_VL) != 0) {
                   10511:         if (irq_no != 0) {
                   10512:             if ((irq_no < ASC_MIN_IRQ_NO) || (irq_no > ASC_MAX_IRQ_NO)) {
                   10513:                 irq_no = 0;
                   10514:             } else {
                   10515:                 irq_no -= (uchar) ((ASC_MIN_IRQ_NO - 1));
                   10516:             }
                   10517:         }
                   10518:         cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE3);
                   10519:         cfg_lsw |= (ushort) 0x0010;
                   10520:         AscSetChipCfgLsw(iop_base, cfg_lsw);
                   10521:         AscToggleIRQAct(iop_base);
                   10522:         cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE0);
                   10523:         cfg_lsw |= (ushort) ((irq_no & 0x07) << 2);
                   10524:         AscSetChipCfgLsw(iop_base, cfg_lsw);
                   10525:         AscToggleIRQAct(iop_base);
                   10526:         return (AscGetChipIRQ(iop_base, bus_type));
                   10527:     }
                   10528:     if ((bus_type & (ASC_IS_ISA)) != 0) {
                   10529:         if (irq_no == 15)
                   10530:             irq_no -= (uchar) 2;
                   10531:         irq_no -= (uchar) ASC_MIN_IRQ_NO;
                   10532:         cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFF3);
                   10533:         cfg_lsw |= (ushort) ((irq_no & 0x03) << 2);
                   10534:         AscSetChipCfgLsw(iop_base, cfg_lsw);
                   10535:         return (AscGetChipIRQ(iop_base, bus_type));
                   10536:     }
                   10537:     return (0);
                   10538: }
                   10539: 
                   10540: ASC_INITFUNC(
                   10541: STATIC void
                   10542: AscEnableIsaDma(
                   10543:                    uchar dma_channel
                   10544: )
                   10545: )
                   10546: {
                   10547:     if (dma_channel < 4) {
                   10548:         outp(0x000B, (ushort) (0xC0 | dma_channel));
                   10549:         outp(0x000A, dma_channel);
                   10550:     } else if (dma_channel < 8) {
                   10551:         outp(0x00D6, (ushort) (0xC0 | (dma_channel - 4)));
                   10552:         outp(0x00D4, (ushort) (dma_channel - 4));
                   10553:     }
                   10554:     return;
                   10555: }
                   10556: 
                   10557: STATIC int 
                   10558: AscIsrChipHalted(
                   10559:                     REG ASC_DVC_VAR asc_ptr_type * asc_dvc
                   10560: )
                   10561: {
                   10562:     EXT_MSG             ext_msg;
                   10563:     EXT_MSG             out_msg;
                   10564:     ushort              halt_q_addr;
                   10565:     int                 sdtr_accept;
                   10566:     ushort              int_halt_code;
                   10567:     ASC_SCSI_BIT_ID_TYPE scsi_busy;
                   10568:     ASC_SCSI_BIT_ID_TYPE target_id;
                   10569:     PortAddr            iop_base;
                   10570:     uchar               tag_code;
                   10571:     uchar               q_status;
                   10572:     uchar               halt_qp;
                   10573:     uchar               sdtr_data;
                   10574:     uchar               target_ix;
                   10575:     uchar               q_cntl, tid_no;
                   10576:     uchar               cur_dvc_qng;
                   10577:     uchar               asyn_sdtr;
                   10578:     uchar               scsi_status;
                   10579:     asc_board_t            *boardp;
                   10580: 
                   10581:     ASC_ASSERT(asc_dvc->drv_ptr != 0);
                   10582:     boardp = (asc_board_t *) asc_dvc->drv_ptr;
                   10583: 
                   10584:     iop_base = asc_dvc->iop_base;
                   10585:     int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
                   10586: 
                   10587:     halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
                   10588:     halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
                   10589:     target_ix = AscReadLramByte(iop_base,
                   10590:                    (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TARGET_IX));
                   10591:     q_cntl = AscReadLramByte(iop_base,
                   10592:                         (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL));
                   10593:     tid_no = ASC_TIX_TO_TID(target_ix);
                   10594:     target_id = (uchar) ASC_TID_TO_TARGET_ID(tid_no);
                   10595:     if (asc_dvc->pci_fix_asyn_xfer & target_id) {
                   10596: 
                   10597:         asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
                   10598:     } else {
                   10599:         asyn_sdtr = 0;
                   10600:     }
                   10601:     if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
                   10602:         if (asc_dvc->pci_fix_asyn_xfer & target_id) {
                   10603:             AscSetChipSDTR(iop_base, 0, tid_no);
                   10604:             boardp->sdtr_data[tid_no] = 0;
                   10605:         }
                   10606:         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
                   10607:         return (0);
                   10608:     } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
                   10609:         if (asc_dvc->pci_fix_asyn_xfer & target_id) {
                   10610:             AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
                   10611:             boardp->sdtr_data[tid_no] = asyn_sdtr;
                   10612:         }
                   10613:         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
                   10614:         return (0);
                   10615:     } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
                   10616: 
                   10617:         AscMemWordCopyFromLram(iop_base,
                   10618:                                ASCV_MSGIN_BEG,
                   10619:                                (ushort *) & ext_msg,
                   10620:                                (ushort) (sizeof (EXT_MSG) >> 1));
                   10621: 
                   10622:         if (ext_msg.msg_type == MS_EXTEND &&
                   10623:             ext_msg.msg_req == MS_SDTR_CODE &&
                   10624:             ext_msg.msg_len == MS_SDTR_LEN) {
                   10625:             sdtr_accept = TRUE;
                   10626:             if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
                   10627: 
                   10628:                 sdtr_accept = FALSE;
                   10629:                 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
                   10630:             }
                   10631:             if ((ext_msg.xfer_period <
                   10632:                  asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index]) ||
                   10633:                 (ext_msg.xfer_period >
                   10634:                  asc_dvc->sdtr_period_tbl[asc_dvc->max_sdtr_index])) {
                   10635:                 sdtr_accept = FALSE;
                   10636:                 ext_msg.xfer_period =
                   10637:                     asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index];
                   10638:             }
                   10639:             if (sdtr_accept) {
                   10640:                 sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
                   10641:                                            ext_msg.req_ack_offset);
                   10642:                 if ((sdtr_data == 0xFF)) {
                   10643: 
                   10644:                     q_cntl |= QC_MSG_OUT;
                   10645:                     asc_dvc->init_sdtr &= ~target_id;
                   10646:                     asc_dvc->sdtr_done &= ~target_id;
                   10647:                     AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
                   10648:                     boardp->sdtr_data[tid_no] = asyn_sdtr;
                   10649:                 }
                   10650:             }
                   10651:             if (ext_msg.req_ack_offset == 0) {
                   10652: 
                   10653:                 q_cntl &= ~QC_MSG_OUT;
                   10654:                 asc_dvc->init_sdtr &= ~target_id;
                   10655:                 asc_dvc->sdtr_done &= ~target_id;
                   10656:                 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
                   10657:             } else {
                   10658:                 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
                   10659: 
                   10660:                     q_cntl &= ~QC_MSG_OUT;
                   10661:                     asc_dvc->sdtr_done |= target_id;
                   10662:                     asc_dvc->init_sdtr |= target_id;
                   10663:                     asc_dvc->pci_fix_asyn_xfer &= ~target_id;
                   10664:                     sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
                   10665:                                                ext_msg.req_ack_offset);
                   10666:                     AscSetChipSDTR(iop_base, sdtr_data, tid_no);
                   10667:                     boardp->sdtr_data[tid_no] = sdtr_data;
                   10668:                 } else {
                   10669: 
                   10670:                     q_cntl |= QC_MSG_OUT;
                   10671:                     AscMsgOutSDTR(asc_dvc,
                   10672:                                   ext_msg.xfer_period,
                   10673:                                   ext_msg.req_ack_offset);
                   10674:                     asc_dvc->pci_fix_asyn_xfer &= ~target_id;
                   10675:                     sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
                   10676:                                                ext_msg.req_ack_offset);
                   10677:                     AscSetChipSDTR(iop_base, sdtr_data, tid_no);
                   10678:                     boardp->sdtr_data[tid_no] = sdtr_data;
                   10679:                     asc_dvc->sdtr_done |= target_id;
                   10680:                     asc_dvc->init_sdtr |= target_id;
                   10681:                 }
                   10682:             }
                   10683: 
                   10684:             AscWriteLramByte(iop_base,
                   10685:                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
                   10686:                              q_cntl);
                   10687:             AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
                   10688:             return (0);
                   10689:         } else if (ext_msg.msg_type == MS_EXTEND &&
                   10690:                    ext_msg.msg_req == MS_WDTR_CODE &&
                   10691:                    ext_msg.msg_len == MS_WDTR_LEN) {
                   10692: 
                   10693:             ext_msg.wdtr_width = 0;
                   10694:             AscMemWordCopyToLram(iop_base,
                   10695:                                  ASCV_MSGOUT_BEG,
                   10696:                                  (ushort *) & ext_msg,
                   10697:                                  (ushort) (sizeof (EXT_MSG) >> 1));
                   10698:             q_cntl |= QC_MSG_OUT;
                   10699:             AscWriteLramByte(iop_base,
                   10700:                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
                   10701:                              q_cntl);
                   10702:             AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
                   10703:             return (0);
                   10704:         } else {
                   10705: 
                   10706:             ext_msg.msg_type = M1_MSG_REJECT;
                   10707:             AscMemWordCopyToLram(iop_base,
                   10708:                                  ASCV_MSGOUT_BEG,
                   10709:                                  (ushort *) & ext_msg,
                   10710:                                  (ushort) (sizeof (EXT_MSG) >> 1));
                   10711:             q_cntl |= QC_MSG_OUT;
                   10712:             AscWriteLramByte(iop_base,
                   10713:                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
                   10714:                              q_cntl);
                   10715:             AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
                   10716:             return (0);
                   10717:         }
                   10718:     } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
                   10719: 
                   10720:         q_cntl |= QC_REQ_SENSE;
                   10721: 
                   10722:         if ((asc_dvc->init_sdtr & target_id) != 0) {
                   10723: 
                   10724:             asc_dvc->sdtr_done &= ~target_id;
                   10725: 
                   10726:             sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
                   10727:             q_cntl |= QC_MSG_OUT;
                   10728:             AscMsgOutSDTR(asc_dvc,
                   10729:                           asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
                   10730:                            (uchar) (asc_dvc->max_sdtr_index - 1)],
                   10731:                           (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
                   10732:         }
                   10733: 
                   10734:         AscWriteLramByte(iop_base,
                   10735:                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
                   10736:                          q_cntl);
                   10737: 
                   10738:         tag_code = AscReadLramByte(iop_base,
                   10739:                     (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE));
                   10740:         tag_code &= 0xDC;
                   10741:         if (
                   10742:                (asc_dvc->pci_fix_asyn_xfer & target_id)
                   10743:                && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
                   10744: ) {
                   10745: 
                   10746:             tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
                   10747:                          | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
                   10748: 
                   10749:         }
                   10750:         AscWriteLramByte(iop_base,
                   10751:                      (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE),
                   10752:                          tag_code);
                   10753: 
                   10754:         q_status = AscReadLramByte(iop_base,
                   10755:                       (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS));
                   10756:         q_status |= (QS_READY | QS_BUSY);
                   10757:         AscWriteLramByte(iop_base,
                   10758:                        (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
                   10759:                          q_status);
                   10760: 
                   10761:         scsi_busy = AscReadLramByte(iop_base,
                   10762:                                     (ushort) ASCV_SCSIBUSY_B);
                   10763:         scsi_busy &= ~target_id;
                   10764:         AscWriteLramByte(iop_base, (ushort) ASCV_SCSIBUSY_B, scsi_busy);
                   10765: 
                   10766:         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
                   10767:         return (0);
                   10768:     } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
                   10769: 
                   10770:         AscMemWordCopyFromLram(iop_base,
                   10771:                                ASCV_MSGOUT_BEG,
                   10772:                                (ushort *) & out_msg,
                   10773:                                (ushort) (sizeof (EXT_MSG) >> 1));
                   10774: 
                   10775:         if ((out_msg.msg_type == MS_EXTEND) &&
                   10776:             (out_msg.msg_len == MS_SDTR_LEN) &&
                   10777:             (out_msg.msg_req == MS_SDTR_CODE)) {
                   10778: 
                   10779:             asc_dvc->init_sdtr &= ~target_id;
                   10780:             asc_dvc->sdtr_done &= ~target_id;
                   10781:             AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
                   10782:             boardp->sdtr_data[tid_no] = asyn_sdtr;
                   10783:         }
                   10784:         q_cntl &= ~QC_MSG_OUT;
                   10785:         AscWriteLramByte(iop_base,
                   10786:                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
                   10787:                          q_cntl);
                   10788:         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
                   10789:         return (0);
                   10790:     } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
                   10791: 
                   10792:         scsi_status = AscReadLramByte(iop_base,
                   10793:           (ushort) ((ushort) halt_q_addr + (ushort) ASC_SCSIQ_SCSI_STATUS));
                   10794:         cur_dvc_qng = AscReadLramByte(iop_base,
                   10795:                      (ushort) ((ushort) ASC_QADR_BEG + (ushort) target_ix));
                   10796:         if ((cur_dvc_qng > 0) &&
                   10797:             (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
                   10798: 
                   10799:             scsi_busy = AscReadLramByte(iop_base,
                   10800:                                         (ushort) ASCV_SCSIBUSY_B);
                   10801:             scsi_busy |= target_id;
                   10802:             AscWriteLramByte(iop_base,
                   10803:                              (ushort) ASCV_SCSIBUSY_B, scsi_busy);
                   10804:             asc_dvc->queue_full_or_busy |= target_id;
                   10805: 
                   10806:             if (scsi_status == SS_QUEUE_FULL) {
                   10807:                 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
                   10808:                     cur_dvc_qng -= 1;
                   10809:                     asc_dvc->max_dvc_qng[tid_no] = cur_dvc_qng;
                   10810: 
                   10811:                     AscWriteLramByte(iop_base,
                   10812:                           (ushort) ((ushort) ASCV_MAX_DVC_QNG_BEG +
                   10813:                            (ushort) tid_no),
                   10814:                           cur_dvc_qng);
                   10815: 
                   10816:                     /*
                   10817:                      * Set the device queue depth to the number of
                   10818:                      * active requests when the QUEUE FULL condition
                   10819:                      * was encountered.
                   10820:                      */
                   10821:                     boardp->queue_full |= target_id;
                   10822:                     boardp->queue_full_cnt[tid_no] = cur_dvc_qng;
                   10823: #if ASC_QUEUE_FLOW_CONTROL
                   10824:                     if (boardp->device[tid_no] != NULL &&
                   10825:                         boardp->device[tid_no]->queue_curr_depth >
                   10826:                         cur_dvc_qng) {
                   10827:                         boardp->device[tid_no]->queue_curr_depth =
                   10828:                             cur_dvc_qng;
                   10829:                     }
                   10830: #endif /* ASC_QUEUE_FLOW_CONTROL */
                   10831:                 }
                   10832:             }
                   10833:         }
                   10834:         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
                   10835:         return (0);
                   10836:     }
                   10837:     return (0);
                   10838: }
                   10839: 
                   10840: STATIC uchar
                   10841: _AscCopyLramScsiDoneQ(
                   10842:                          PortAddr iop_base,
                   10843:                          ushort q_addr,
                   10844:                          REG ASC_QDONE_INFO * scsiq,
                   10845:                          ulong max_dma_count
                   10846: )
                   10847: {
                   10848:     ushort              _val;
                   10849:     uchar               sg_queue_cnt;
                   10850: 
                   10851:     DvcGetQinfo(iop_base,
                   10852:                 (ushort) (q_addr + (ushort) ASC_SCSIQ_DONE_INFO_BEG),
                   10853:                 (ushort *) scsiq,
                   10854:               (ushort) ((sizeof (ASC_SCSIQ_2) + sizeof (ASC_SCSIQ_3)) / 2));
                   10855:     _val = AscReadLramWord(iop_base,
                   10856:                            (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS));
                   10857:     scsiq->q_status = (uchar) _val;
                   10858:     scsiq->q_no = (uchar) (_val >> 8);
                   10859:     _val = AscReadLramWord(iop_base,
                   10860:                            (ushort) (q_addr + (ushort) ASC_SCSIQ_B_CNTL));
                   10861:     scsiq->cntl = (uchar) _val;
                   10862:     sg_queue_cnt = (uchar) (_val >> 8);
                   10863:     _val = AscReadLramWord(iop_base,
                   10864:                         (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SENSE_LEN));
                   10865:     scsiq->sense_len = (uchar) _val;
                   10866:     scsiq->extra_bytes = (uchar) (_val >> 8);
                   10867:     scsiq->remain_bytes = AscReadLramWord(iop_base,
                   10868:                  (ushort) (q_addr + (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT));
                   10869:     scsiq->remain_bytes &= max_dma_count;
                   10870:     return (sg_queue_cnt);
                   10871: }
                   10872: 
                   10873: STATIC int
                   10874: AscIsrQDone(
                   10875:                REG ASC_DVC_VAR asc_ptr_type * asc_dvc
                   10876: )
                   10877: {
                   10878:     uchar               next_qp;
                   10879:     uchar               n_q_used;
                   10880:     uchar               sg_list_qp;
                   10881:     uchar               sg_queue_cnt;
                   10882:     uchar               q_cnt;
                   10883:     uchar               done_q_tail;
                   10884:     uchar               tid_no;
                   10885:     ASC_SCSI_BIT_ID_TYPE scsi_busy;
                   10886:     ASC_SCSI_BIT_ID_TYPE target_id;
                   10887:     PortAddr            iop_base;
                   10888:     ushort              q_addr;
                   10889:     ushort              sg_q_addr;
                   10890:     uchar               cur_target_qng;
                   10891:     ASC_QDONE_INFO      scsiq_buf;
                   10892:     REG ASC_QDONE_INFO *scsiq;
                   10893:     int                 false_overrun;
                   10894:     ASC_ISR_CALLBACK    asc_isr_callback;
                   10895: 
                   10896:     iop_base = asc_dvc->iop_base;
                   10897:     asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
                   10898:     n_q_used = 1;
                   10899:     scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
                   10900:     done_q_tail = (uchar) AscGetVarDoneQTail(iop_base);
                   10901:     q_addr = ASC_QNO_TO_QADDR(done_q_tail);
                   10902:     next_qp = AscReadLramByte(iop_base,
                   10903:                               (ushort) (q_addr + (ushort) ASC_SCSIQ_B_FWD));
                   10904:     if (next_qp != ASC_QLINK_END) {
                   10905:         AscPutVarDoneQTail(iop_base, next_qp);
                   10906:         q_addr = ASC_QNO_TO_QADDR(next_qp);
                   10907:         sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
                   10908:             asc_dvc->max_dma_count);
                   10909:         AscWriteLramByte(iop_base,
                   10910:                          (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
                   10911:              (uchar) (scsiq->q_status & (uchar) ~ (QS_READY | QS_ABORTED)));
                   10912:         tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
                   10913:         target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
                   10914:         if ((scsiq->cntl & QC_SG_HEAD) != 0) {
                   10915:             sg_q_addr = q_addr;
                   10916:             sg_list_qp = next_qp;
                   10917:             for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
                   10918:                 sg_list_qp = AscReadLramByte(iop_base,
                   10919:                            (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_FWD));
                   10920:                 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
                   10921:                 if (sg_list_qp == ASC_QLINK_END) {
                   10922:                     AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SG_Q_LINKS);
                   10923:                     scsiq->d3.done_stat = QD_WITH_ERROR;
                   10924:                     scsiq->d3.host_stat = QHSTA_D_QDONE_SG_LIST_CORRUPTED;
                   10925:                     goto FATAL_ERR_QDONE;
                   10926:                 }
                   10927:                 AscWriteLramByte(iop_base,
                   10928:                          (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
                   10929:                                  QS_FREE);
                   10930:             }
                   10931:             n_q_used = sg_queue_cnt + 1;
                   10932:             AscPutVarDoneQTail(iop_base, sg_list_qp);
                   10933:         }
                   10934:         if (asc_dvc->queue_full_or_busy & target_id) {
                   10935:             cur_target_qng = AscReadLramByte(iop_base,
                   10936:             (ushort) ((ushort) ASC_QADR_BEG + (ushort) scsiq->d2.target_ix));
                   10937:             if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
                   10938:                 scsi_busy = AscReadLramByte(iop_base,
                   10939:                                             (ushort) ASCV_SCSIBUSY_B);
                   10940:                 scsi_busy &= ~target_id;
                   10941:                 AscWriteLramByte(iop_base,
                   10942:                                  (ushort) ASCV_SCSIBUSY_B, scsi_busy);
                   10943:                 asc_dvc->queue_full_or_busy &= ~target_id;
                   10944:             }
                   10945:         }
                   10946:         if (asc_dvc->cur_total_qng >= n_q_used) {
                   10947:             asc_dvc->cur_total_qng -= n_q_used;
                   10948:             if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
                   10949:                 asc_dvc->cur_dvc_qng[tid_no]--;
                   10950:             }
                   10951:         } else {
                   10952:             AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
                   10953:             scsiq->d3.done_stat = QD_WITH_ERROR;
                   10954:             goto FATAL_ERR_QDONE;
                   10955:         }
                   10956:         if ((scsiq->d2.srb_ptr == 0UL) ||
                   10957:             ((scsiq->q_status & QS_ABORTED) != 0)) {
                   10958:             return (0x11);
                   10959:         } else if (scsiq->q_status == QS_DONE) {
                   10960:             false_overrun = FALSE;
                   10961:             if (scsiq->extra_bytes != 0) {
                   10962:                 scsiq->remain_bytes += (ulong) scsiq->extra_bytes;
                   10963:             }
                   10964:             if (scsiq->d3.done_stat == QD_WITH_ERROR) {
                   10965:                 if (scsiq->d3.host_stat == QHSTA_M_DATA_OVER_RUN) {
                   10966:                     if ((scsiq->cntl & (QC_DATA_IN | QC_DATA_OUT)) == 0) {
                   10967:                         scsiq->d3.done_stat = QD_NO_ERROR;
                   10968:                         scsiq->d3.host_stat = QHSTA_NO_ERROR;
                   10969:                     } else if (false_overrun) {
                   10970:                         scsiq->d3.done_stat = QD_NO_ERROR;
                   10971:                         scsiq->d3.host_stat = QHSTA_NO_ERROR;
                   10972:                     }
                   10973:                 } else if (scsiq->d3.host_stat ==
                   10974:                            QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
                   10975:                     AscStopChip(iop_base);
                   10976:                     AscSetChipControl(iop_base,
                   10977:                         (uchar) (CC_SCSI_RESET | CC_HALT));
                   10978:                     DvcDelayNanoSecond(asc_dvc, 60000);
                   10979:                     AscSetChipControl(iop_base, CC_HALT);
                   10980:                     AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
                   10981:                     AscSetChipStatus(iop_base, 0);
                   10982:                     AscSetChipControl(iop_base, 0);
                   10983:                 }
                   10984:             }
                   10985:             if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
                   10986:                 (*asc_isr_callback) (asc_dvc, scsiq);
                   10987:             } else {
                   10988:                 if ((AscReadLramByte(iop_base,
                   10989:                           (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG)) ==
                   10990:                      SCSICMD_StartStopUnit)) {
                   10991:                     asc_dvc->unit_not_ready &= ~target_id;
                   10992:                     if (scsiq->d3.done_stat != QD_NO_ERROR) {
                   10993:                         asc_dvc->start_motor &= ~target_id;
                   10994:                     }
                   10995:                 }
                   10996:             }
                   10997:             return (1);
                   10998:         } else {
                   10999:             AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
                   11000:           FATAL_ERR_QDONE:
                   11001:             if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
                   11002:                 (*asc_isr_callback) (asc_dvc, scsiq);
                   11003:             }
                   11004:             return (0x80);
                   11005:         }
                   11006:     }
                   11007:     return (0);
                   11008: }
                   11009: 
                   11010: STATIC int
                   11011: AscISR(
                   11012:           REG ASC_DVC_VAR asc_ptr_type * asc_dvc
                   11013: )
                   11014: {
                   11015:     ASC_CS_TYPE         chipstat;
                   11016:     PortAddr            iop_base;
                   11017:     ushort              saved_ram_addr;
                   11018:     uchar               ctrl_reg;
                   11019:     uchar               saved_ctrl_reg;
                   11020:     int                 int_pending;
                   11021:     int                 status;
                   11022:     uchar               host_flag;
                   11023: 
                   11024:     iop_base = asc_dvc->iop_base;
                   11025:     int_pending = FALSE;
                   11026:     if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
                   11027:         || (asc_dvc->isr_callback == 0)
                   11028: ) {
                   11029:         return (ERR);
                   11030:     }
                   11031:     if (asc_dvc->in_critical_cnt != 0) {
                   11032:         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
                   11033:         return (ERR);
                   11034:     }
                   11035:     if (asc_dvc->is_in_int) {
                   11036:         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
                   11037:         return (ERR);
                   11038:     }
                   11039:     asc_dvc->is_in_int = TRUE;
                   11040:     ctrl_reg = AscGetChipControl(iop_base);
                   11041:     saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
                   11042:                                    CC_SINGLE_STEP | CC_DIAG | CC_TEST));
                   11043:     chipstat = AscGetChipStatus(iop_base);
                   11044:     if (chipstat & CSW_SCSI_RESET_LATCH) {
                   11045:         if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
                   11046:             int_pending = TRUE;
                   11047:             asc_dvc->sdtr_done = 0;
                   11048:             saved_ctrl_reg &= (uchar) (~CC_HALT);
                   11049:             while (AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) ;
                   11050:             AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
                   11051:             AscSetChipControl(iop_base, CC_HALT);
                   11052:             AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
                   11053:             AscSetChipStatus(iop_base, 0);
                   11054:             chipstat = AscGetChipStatus(iop_base);
                   11055:         }
                   11056:     }
                   11057:     saved_ram_addr = AscGetChipLramAddr(iop_base);
                   11058:     host_flag = AscReadLramByte(iop_base,
                   11059:         ASCV_HOST_FLAG_B) & (uchar) (~ASC_HOST_FLAG_IN_ISR);
                   11060:     AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
                   11061:                      (uchar) (host_flag | (uchar) ASC_HOST_FLAG_IN_ISR));
                   11062:     if ((chipstat & CSW_INT_PENDING)
                   11063:         || (int_pending)
                   11064: ) {
                   11065:         AscAckInterrupt(iop_base);
                   11066:         int_pending = TRUE;
                   11067:         if ((chipstat & CSW_HALTED) &&
                   11068:             (ctrl_reg & CC_SINGLE_STEP)) {
                   11069:             if (AscIsrChipHalted(asc_dvc) == ERR) {
                   11070:                 goto ISR_REPORT_QDONE_FATAL_ERROR;
                   11071:             } else {
                   11072:                 saved_ctrl_reg &= (uchar) (~CC_HALT);
                   11073:             }
                   11074:         } else {
                   11075:           ISR_REPORT_QDONE_FATAL_ERROR:
                   11076:             if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
                   11077:                 while (((status = AscIsrQDone(asc_dvc)) & 0x01) != 0) {
                   11078:                 }
                   11079:             } else {
                   11080:                 do {
                   11081:                     if ((status = AscIsrQDone(asc_dvc)) == 1) {
                   11082:                         break;
                   11083:                     }
                   11084:                 } while (status == 0x11);
                   11085:             }
                   11086:             if ((status & 0x80) != 0)
                   11087:                 int_pending = ERR;
                   11088:         }
                   11089:     }
                   11090:     AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
                   11091:     AscSetChipLramAddr(iop_base, saved_ram_addr);
                   11092:     AscSetChipControl(iop_base, saved_ctrl_reg);
                   11093:     asc_dvc->is_in_int = FALSE;
                   11094:     return (int_pending);
                   11095: }
                   11096: 
                   11097: STATIC uchar _asc_mcode_buf[] ASC_INITDATA =
                   11098: {
                   11099:   0x01,  0x03,  0x01,  0x19,  0x0F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   11100:   0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   11101:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   11102:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   11103:   0x00,  0x00,  0x00,  0x00,  0x91,  0x10,  0x0A,  0x05,  0x01,  0x00,  0x00,  0x00,  0x00,  0xFF,  0x00,  0x00,
                   11104:   0x00,  0x00,  0x00,  0x00,  0xFF,  0x80,  0xFF,  0xFF,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   11105:   0x00,  0x00,  0x00,  0x23,  0x00,  0x24,  0x00,  0x00,  0x00,  0x07,  0x00,  0xFF,  0x00,  0x00,  0x00,  0x00,
                   11106:   0xFF,  0xFF,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xE2,  0x88,  0x00,  0x00,  0x00,  0x00,
                   11107:   0x80,  0x73,  0x48,  0x04,  0x36,  0x00,  0x00,  0xA2,  0xC2,  0x00,  0x80,  0x73,  0x03,  0x23,  0x36,  0x40,
                   11108:   0xB6,  0x00,  0x36,  0x00,  0x05,  0xD6,  0x0C,  0xD2,  0x12,  0xDA,  0x00,  0xA2,  0xC2,  0x00,  0x92,  0x80,
                   11109:   0x1E,  0x98,  0x50,  0x00,  0xF5,  0x00,  0x48,  0x98,  0xDF,  0x23,  0x36,  0x60,  0xB6,  0x00,  0x92,  0x80,
                   11110:   0x4F,  0x00,  0xF5,  0x00,  0x48,  0x98,  0xEF,  0x23,  0x36,  0x60,  0xB6,  0x00,  0x92,  0x80,  0x80,  0x62,
                   11111:   0x92,  0x80,  0x00,  0x46,  0x17,  0xEE,  0x13,  0xEA,  0x02,  0x01,  0x09,  0xD8,  0xCD,  0x04,  0x4D,  0x00,
                   11112:   0x00,  0xA3,  0xD6,  0x00,  0xA6,  0x97,  0x7F,  0x23,  0x04,  0x61,  0x84,  0x01,  0xE6,  0x84,  0xD2,  0xC1,
                   11113:   0x80,  0x73,  0xCD,  0x04,  0x4D,  0x00,  0x00,  0xA3,  0xE2,  0x01,  0xA6,  0x97,  0xCE,  0x81,  0x00,  0x33,
                   11114:   0x02,  0x00,  0xC0,  0x88,  0x80,  0x73,  0x80,  0x77,  0x00,  0x01,  0x01,  0xA1,  0x02,  0x01,  0x4F,  0x00,
                   11115:   0x84,  0x97,  0x07,  0xA6,  0x0C,  0x01,  0x00,  0x33,  0x03,  0x00,  0xC0,  0x88,  0x03,  0x03,  0x03,  0xDE,
                   11116:   0x00,  0x33,  0x05,  0x00,  0xC0,  0x88,  0xCE,  0x00,  0x69,  0x60,  0xCE,  0x00,  0x02,  0x03,  0x4A,  0x60,
                   11117:   0x00,  0xA2,  0x80,  0x01,  0x80,  0x63,  0x07,  0xA6,  0x2C,  0x01,  0x80,  0x81,  0x03,  0x03,  0x80,  0x63,
                   11118:   0xE2,  0x00,  0x07,  0xA6,  0x3C,  0x01,  0x00,  0x33,  0x04,  0x00,  0xC0,  0x88,  0x03,  0x07,  0x02,  0x01,
                   11119:   0x04,  0xCA,  0x0D,  0x23,  0x68,  0x98,  0x4D,  0x04,  0x04,  0x85,  0x05,  0xD8,  0x0D,  0x23,  0x68,  0x98,
                   11120:   0xCD,  0x04,  0x15,  0x23,  0xF6,  0x88,  0xFB,  0x23,  0x02,  0x61,  0x82,  0x01,  0x80,  0x63,  0x02,  0x03,
                   11121:   0x06,  0xA3,  0x6A,  0x01,  0x00,  0x33,  0x0A,  0x00,  0xC0,  0x88,  0x4E,  0x00,  0x07,  0xA3,  0x76,  0x01,
                   11122:   0x00,  0x33,  0x0B,  0x00,  0xC0,  0x88,  0xCD,  0x04,  0x36,  0x2D,  0x00,  0x33,  0x1A,  0x00,  0xC0,  0x88,
                   11123:   0x50,  0x04,  0x90,  0x81,  0x06,  0xAB,  0x8A,  0x01,  0x90,  0x81,  0x4E,  0x00,  0x07,  0xA3,  0x9A,  0x01,
                   11124:   0x50,  0x00,  0x00,  0xA3,  0x44,  0x01,  0x00,  0x05,  0x84,  0x81,  0x46,  0x97,  0x02,  0x01,  0x05,  0xC6,
                   11125:   0x04,  0x23,  0xA0,  0x01,  0x15,  0x23,  0xA1,  0x01,  0xC6,  0x81,  0xFD,  0x23,  0x02,  0x61,  0x82,  0x01,
                   11126:   0x0A,  0xDA,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA0,  0xBC,  0x01,  0x80,  0x63,  0xCD,  0x04,  0x36,  0x2D,
                   11127:   0x00,  0x33,  0x1B,  0x00,  0xC0,  0x88,  0x06,  0x23,  0x68,  0x98,  0xCD,  0x04,  0xE6,  0x84,  0x06,  0x01,
                   11128:   0x00,  0xA2,  0xDC,  0x01,  0x57,  0x60,  0x00,  0xA0,  0xE2,  0x01,  0xE6,  0x84,  0x80,  0x23,  0xA0,  0x01,
                   11129:   0xE6,  0x84,  0x80,  0x73,  0x4B,  0x00,  0x06,  0x61,  0x00,  0xA2,  0x08,  0x02,  0x04,  0x01,  0x0C,  0xDE,
                   11130:   0x02,  0x01,  0x03,  0xCC,  0x4F,  0x00,  0x84,  0x97,  0x04,  0x82,  0x08,  0x23,  0x02,  0x41,  0x82,  0x01,
                   11131:   0x4F,  0x00,  0x62,  0x97,  0x48,  0x04,  0x84,  0x80,  0xF0,  0x97,  0x00,  0x46,  0x56,  0x00,  0x03,  0xC0,
                   11132:   0x01,  0x23,  0xE8,  0x00,  0x81,  0x73,  0x06,  0x29,  0x03,  0x42,  0x06,  0xE2,  0x03,  0xEE,  0x67,  0xEB,
                   11133:   0x11,  0x23,  0xF6,  0x88,  0x04,  0x98,  0xF4,  0x80,  0x80,  0x73,  0x80,  0x77,  0x07,  0xA4,  0x32,  0x02,
                   11134:   0x7C,  0x95,  0x06,  0xA6,  0x3C,  0x02,  0x03,  0xA6,  0x4C,  0x04,  0xC0,  0x88,  0x04,  0x01,  0x03,  0xD8,
                   11135:   0xB2,  0x98,  0x6A,  0x96,  0x4E,  0x82,  0xFE,  0x95,  0x80,  0x67,  0x83,  0x03,  0x80,  0x63,  0xB6,  0x2D,
                   11136:   0x02,  0xA6,  0x78,  0x02,  0x07,  0xA6,  0x66,  0x02,  0x06,  0xA6,  0x6A,  0x02,  0x03,  0xA6,  0x6E,  0x02,
                   11137:   0x00,  0x33,  0x10,  0x00,  0xC0,  0x88,  0x7C,  0x95,  0x50,  0x82,  0x60,  0x96,  0x50,  0x82,  0x04,  0x23,
                   11138:   0xA0,  0x01,  0x14,  0x23,  0xA1,  0x01,  0x3C,  0x84,  0x04,  0x01,  0x0C,  0xDC,  0xE0,  0x23,  0x25,  0x61,
                   11139:   0xEF,  0x00,  0x14,  0x01,  0x4F,  0x04,  0xA8,  0x01,  0x6F,  0x00,  0xA5,  0x01,  0x03,  0x23,  0xA4,  0x01,
                   11140:   0x06,  0x23,  0x9C,  0x01,  0x24,  0x2B,  0x1C,  0x01,  0x02,  0xA6,  0xB6,  0x02,  0x07,  0xA6,  0x66,  0x02,
                   11141:   0x06,  0xA6,  0x6A,  0x02,  0x03,  0xA6,  0x20,  0x04,  0x01,  0xA6,  0xC0,  0x02,  0x00,  0xA6,  0xC0,  0x02,
                   11142:   0x00,  0x33,  0x12,  0x00,  0xC0,  0x88,  0x00,  0x0E,  0x80,  0x63,  0x00,  0x43,  0x00,  0xA0,  0x98,  0x02,
                   11143:   0x4D,  0x04,  0x04,  0x01,  0x0B,  0xDC,  0xE7,  0x23,  0x04,  0x61,  0x84,  0x01,  0x10,  0x31,  0x12,  0x35,
                   11144:   0x14,  0x01,  0xEC,  0x00,  0x6C,  0x38,  0x00,  0x3F,  0x00,  0x00,  0xF6,  0x82,  0x18,  0x23,  0x04,  0x61,
                   11145:   0x18,  0xA0,  0xEE,  0x02,  0x04,  0x01,  0x9C,  0xC8,  0x00,  0x33,  0x1F,  0x00,  0xC0,  0x88,  0x08,  0x31,
                   11146:   0x0A,  0x35,  0x0C,  0x39,  0x0E,  0x3D,  0x7E,  0x98,  0xB6,  0x2D,  0x01,  0xA6,  0x20,  0x03,  0x00,  0xA6,
                   11147:   0x20,  0x03,  0x07,  0xA6,  0x18,  0x03,  0x06,  0xA6,  0x1C,  0x03,  0x03,  0xA6,  0x20,  0x04,  0x02,  0xA6,
                   11148:   0x78,  0x02,  0x00,  0x33,  0x33,  0x00,  0xC0,  0x88,  0x7C,  0x95,  0xFA,  0x82,  0x60,  0x96,  0xFA,  0x82,
                   11149:   0x82,  0x98,  0x80,  0x42,  0x7E,  0x98,  0x60,  0xE4,  0x04,  0x01,  0x29,  0xC8,  0x31,  0x05,  0x07,  0x01,
                   11150:   0x00,  0xA2,  0x60,  0x03,  0x00,  0x43,  0x87,  0x01,  0x05,  0x05,  0x86,  0x98,  0x7E,  0x98,  0x00,  0xA6,
                   11151:   0x22,  0x03,  0x07,  0xA6,  0x58,  0x03,  0x03,  0xA6,  0x3C,  0x04,  0x06,  0xA6,  0x5C,  0x03,  0x01,  0xA6,
                   11152:   0x22,  0x03,  0x00,  0x33,  0x25,  0x00,  0xC0,  0x88,  0x7C,  0x95,  0x3E,  0x83,  0x60,  0x96,  0x3E,  0x83,
                   11153:   0x04,  0x01,  0x0C,  0xCE,  0x03,  0xC8,  0x00,  0x33,  0x42,  0x00,  0xC0,  0x88,  0x00,  0x01,  0x05,  0x05,
                   11154:   0xFF,  0xA2,  0x7E,  0x03,  0xB1,  0x01,  0x08,  0x23,  0xB2,  0x01,  0x3A,  0x83,  0x05,  0x05,  0x15,  0x01,
                   11155:   0x00,  0xA2,  0x9E,  0x03,  0xEC,  0x00,  0x6E,  0x00,  0x95,  0x01,  0x6C,  0x38,  0x00,  0x3F,  0x00,  0x00,
                   11156:   0x01,  0xA6,  0x9A,  0x03,  0x00,  0xA6,  0x9A,  0x03,  0x12,  0x84,  0x80,  0x42,  0x7E,  0x98,  0x01,  0xA6,
                   11157:   0xA8,  0x03,  0x00,  0xA6,  0xC0,  0x03,  0x12,  0x84,  0xA6,  0x98,  0x80,  0x42,  0x01,  0xA6,  0xA8,  0x03,
                   11158:   0x07,  0xA6,  0xB6,  0x03,  0xD8,  0x83,  0x7C,  0x95,  0xAC,  0x83,  0x00,  0x33,  0x2F,  0x00,  0xC0,  0x88,
                   11159:   0xA6,  0x98,  0x80,  0x42,  0x00,  0xA6,  0xC0,  0x03,  0x07,  0xA6,  0xCE,  0x03,  0xD8,  0x83,  0x7C,  0x95,
                   11160:   0xC4,  0x83,  0x00,  0x33,  0x26,  0x00,  0xC0,  0x88,  0x38,  0x2B,  0x80,  0x32,  0x80,  0x36,  0x04,  0x23,
                   11161:   0xA0,  0x01,  0x12,  0x23,  0xA1,  0x01,  0x12,  0x84,  0x06,  0xF0,  0x06,  0xA4,  0xF6,  0x03,  0x80,  0x6B,
                   11162:   0x05,  0x23,  0x83,  0x03,  0x80,  0x63,  0x03,  0xA6,  0x10,  0x04,  0x07,  0xA6,  0x08,  0x04,  0x06,  0xA6,
                   11163:   0x0C,  0x04,  0x00,  0x33,  0x17,  0x00,  0xC0,  0x88,  0x7C,  0x95,  0xF6,  0x83,  0x60,  0x96,  0xF6,  0x83,
                   11164:   0x20,  0x84,  0x06,  0xF0,  0x06,  0xA4,  0x20,  0x04,  0x80,  0x6B,  0x05,  0x23,  0x83,  0x03,  0x80,  0x63,
                   11165:   0xB6,  0x2D,  0x03,  0xA6,  0x3C,  0x04,  0x07,  0xA6,  0x34,  0x04,  0x06,  0xA6,  0x38,  0x04,  0x00,  0x33,
                   11166:   0x30,  0x00,  0xC0,  0x88,  0x7C,  0x95,  0x20,  0x84,  0x60,  0x96,  0x20,  0x84,  0x1D,  0x01,  0x06,  0xCC,
                   11167:   0x00,  0x33,  0x00,  0x84,  0xC0,  0x20,  0x00,  0x23,  0xEA,  0x00,  0x81,  0x62,  0xA2,  0x0D,  0x80,  0x63,
                   11168:   0x07,  0xA6,  0x5A,  0x04,  0x00,  0x33,  0x18,  0x00,  0xC0,  0x88,  0x03,  0x03,  0x80,  0x63,  0xA3,  0x01,
                   11169:   0x07,  0xA4,  0x64,  0x04,  0x23,  0x01,  0x00,  0xA2,  0x86,  0x04,  0x0A,  0xA0,  0x76,  0x04,  0xE0,  0x00,
                   11170:   0x00,  0x33,  0x1D,  0x00,  0xC0,  0x88,  0x0B,  0xA0,  0x82,  0x04,  0xE0,  0x00,  0x00,  0x33,  0x1E,  0x00,
                   11171:   0xC0,  0x88,  0x42,  0x23,  0xF6,  0x88,  0x00,  0x23,  0x22,  0xA3,  0xE6,  0x04,  0x08,  0x23,  0x22,  0xA3,
                   11172:   0xA2,  0x04,  0x28,  0x23,  0x22,  0xA3,  0xAE,  0x04,  0x02,  0x23,  0x22,  0xA3,  0xC4,  0x04,  0x42,  0x23,
                   11173:   0xF6,  0x88,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA0,  0xAE,  0x04,  0x45,  0x23,  0xF6,  0x88,  0x04,  0x98,
                   11174:   0x00,  0xA2,  0xC0,  0x04,  0xB2,  0x98,  0x00,  0x33,  0x00,  0x82,  0xC0,  0x20,  0x81,  0x62,  0xF0,  0x81,
                   11175:   0x47,  0x23,  0xF6,  0x88,  0x04,  0x01,  0x0B,  0xDE,  0x04,  0x98,  0xB2,  0x98,  0x00,  0x33,  0x00,  0x81,
                   11176:   0xC0,  0x20,  0x81,  0x62,  0x14,  0x01,  0x00,  0xA0,  0x08,  0x02,  0x43,  0x23,  0xF6,  0x88,  0x04,  0x23,
                   11177:   0xA0,  0x01,  0x44,  0x23,  0xA1,  0x01,  0x80,  0x73,  0x4D,  0x00,  0x03,  0xA3,  0xF4,  0x04,  0x00,  0x33,
                   11178:   0x27,  0x00,  0xC0,  0x88,  0x04,  0x01,  0x04,  0xDC,  0x02,  0x23,  0xA2,  0x01,  0x04,  0x23,  0xA0,  0x01,
                   11179:   0x04,  0x98,  0x26,  0x95,  0x4B,  0x00,  0xF6,  0x00,  0x4F,  0x04,  0x4F,  0x00,  0x00,  0xA3,  0x22,  0x05,
                   11180:   0x00,  0x05,  0x76,  0x00,  0x06,  0x61,  0x00,  0xA2,  0x1C,  0x05,  0x0A,  0x85,  0x46,  0x97,  0xCD,  0x04,
                   11181:   0x24,  0x85,  0x48,  0x04,  0x84,  0x80,  0x02,  0x01,  0x03,  0xDA,  0x80,  0x23,  0x82,  0x01,  0x34,  0x85,
                   11182:   0x02,  0x23,  0xA0,  0x01,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA2,  0x40,  0x05,  0x1D,  0x01,  0x04,  0xD6,
                   11183:   0xFF,  0x23,  0x86,  0x41,  0x4B,  0x60,  0xCB,  0x00,  0xFF,  0x23,  0x80,  0x01,  0x49,  0x00,  0x81,  0x01,
                   11184:   0x04,  0x01,  0x02,  0xC8,  0x30,  0x01,  0x80,  0x01,  0xF7,  0x04,  0x03,  0x01,  0x49,  0x04,  0x80,  0x01,
                   11185:   0xC9,  0x00,  0x00,  0x05,  0x00,  0x01,  0xFF,  0xA0,  0x60,  0x05,  0x77,  0x04,  0x01,  0x23,  0xEA,  0x00,
                   11186:   0x5D,  0x00,  0xFE,  0xC7,  0x00,  0x62,  0x00,  0x23,  0xEA,  0x00,  0x00,  0x63,  0x07,  0xA4,  0xF8,  0x05,
                   11187:   0x03,  0x03,  0x02,  0xA0,  0x8E,  0x05,  0xF4,  0x85,  0x00,  0x33,  0x2D,  0x00,  0xC0,  0x88,  0x04,  0xA0,
                   11188:   0xB8,  0x05,  0x80,  0x63,  0x00,  0x23,  0xDF,  0x00,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA2,  0xA4,  0x05,
                   11189:   0x1D,  0x01,  0x06,  0xD6,  0x02,  0x23,  0x02,  0x41,  0x82,  0x01,  0x50,  0x00,  0x62,  0x97,  0x04,  0x85,
                   11190:   0x04,  0x23,  0x02,  0x41,  0x82,  0x01,  0x04,  0x85,  0x08,  0xA0,  0xBE,  0x05,  0xF4,  0x85,  0x03,  0xA0,
                   11191:   0xC4,  0x05,  0xF4,  0x85,  0x01,  0xA0,  0xCE,  0x05,  0x88,  0x00,  0x80,  0x63,  0xCC,  0x86,  0x07,  0xA0,
                   11192:   0xEE,  0x05,  0x5F,  0x00,  0x00,  0x2B,  0xDF,  0x08,  0x00,  0xA2,  0xE6,  0x05,  0x80,  0x67,  0x80,  0x63,
                   11193:   0x01,  0xA2,  0x7A,  0x06,  0x7C,  0x85,  0x06,  0x23,  0x68,  0x98,  0x48,  0x23,  0xF6,  0x88,  0x07,  0x23,
                   11194:   0x80,  0x00,  0x06,  0x87,  0x80,  0x63,  0x7C,  0x85,  0x00,  0x23,  0xDF,  0x00,  0x00,  0x63,  0x4A,  0x00,
                   11195:   0x06,  0x61,  0x00,  0xA2,  0x36,  0x06,  0x1D,  0x01,  0x16,  0xD4,  0xC0,  0x23,  0x07,  0x41,  0x83,  0x03,
                   11196:   0x80,  0x63,  0x06,  0xA6,  0x1C,  0x06,  0x00,  0x33,  0x37,  0x00,  0xC0,  0x88,  0x1D,  0x01,  0x01,  0xD6,
                   11197:   0x20,  0x23,  0x63,  0x60,  0x83,  0x03,  0x80,  0x63,  0x02,  0x23,  0xDF,  0x00,  0x07,  0xA6,  0x7C,  0x05,
                   11198:   0xEF,  0x04,  0x6F,  0x00,  0x00,  0x63,  0x4B,  0x00,  0x06,  0x41,  0xCB,  0x00,  0x52,  0x00,  0x06,  0x61,
                   11199:   0x00,  0xA2,  0x4E,  0x06,  0x1D,  0x01,  0x03,  0xCA,  0xC0,  0x23,  0x07,  0x41,  0x00,  0x63,  0x1D,  0x01,
                   11200:   0x04,  0xCC,  0x00,  0x33,  0x00,  0x83,  0xC0,  0x20,  0x81,  0x62,  0x80,  0x23,  0x07,  0x41,  0x00,  0x63,
                   11201:   0x80,  0x67,  0x08,  0x23,  0x83,  0x03,  0x80,  0x63,  0x00,  0x63,  0x01,  0x23,  0xDF,  0x00,  0x06,  0xA6,
                   11202:   0x84,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x80,  0x67,  0x80,  0x63,  0x00,  0x33,  0x00,  0x40,  0xC0,  0x20,
                   11203:   0x81,  0x62,  0x00,  0x63,  0x00,  0x00,  0xFE,  0x95,  0x83,  0x03,  0x80,  0x63,  0x06,  0xA6,  0x94,  0x06,
                   11204:   0x07,  0xA6,  0x7C,  0x05,  0x00,  0x00,  0x01,  0xA0,  0x14,  0x07,  0x00,  0x2B,  0x40,  0x0E,  0x80,  0x63,
                   11205:   0x01,  0x00,  0x06,  0xA6,  0xAA,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x40,  0x0E,  0x80,  0x63,  0x00,  0x43,
                   11206:   0x00,  0xA0,  0xA2,  0x06,  0x06,  0xA6,  0xBC,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x80,  0x67,  0x40,  0x0E,
                   11207:   0x80,  0x63,  0x07,  0xA6,  0x7C,  0x05,  0x00,  0x23,  0xDF,  0x00,  0x00,  0x63,  0x07,  0xA6,  0xD6,  0x06,
                   11208:   0x00,  0x33,  0x2A,  0x00,  0xC0,  0x88,  0x03,  0x03,  0x80,  0x63,  0x89,  0x00,  0x0A,  0x2B,  0x07,  0xA6,
                   11209:   0xE8,  0x06,  0x00,  0x33,  0x29,  0x00,  0xC0,  0x88,  0x00,  0x43,  0x00,  0xA2,  0xF4,  0x06,  0xC0,  0x0E,
                   11210:   0x80,  0x63,  0xDE,  0x86,  0xC0,  0x0E,  0x00,  0x33,  0x00,  0x80,  0xC0,  0x20,  0x81,  0x62,  0x04,  0x01,
                   11211:   0x02,  0xDA,  0x80,  0x63,  0x7C,  0x85,  0x80,  0x7B,  0x80,  0x63,  0x06,  0xA6,  0x8C,  0x06,  0x00,  0x33,
                   11212:   0x2C,  0x00,  0xC0,  0x88,  0x0C,  0xA2,  0x2E,  0x07,  0xFE,  0x95,  0x83,  0x03,  0x80,  0x63,  0x06,  0xA6,
                   11213:   0x2C,  0x07,  0x07,  0xA6,  0x7C,  0x05,  0x00,  0x33,  0x3D,  0x00,  0xC0,  0x88,  0x00,  0x00,  0x80,  0x67,
                   11214:   0x83,  0x03,  0x80,  0x63,  0x0C,  0xA0,  0x44,  0x07,  0x07,  0xA6,  0x7C,  0x05,  0xBF,  0x23,  0x04,  0x61,
                   11215:   0x84,  0x01,  0xE6,  0x84,  0x00,  0x63,  0xF0,  0x04,  0x01,  0x01,  0xF1,  0x00,  0x00,  0x01,  0xF2,  0x00,
                   11216:   0x01,  0x05,  0x80,  0x01,  0x72,  0x04,  0x71,  0x00,  0x81,  0x01,  0x70,  0x04,  0x80,  0x05,  0x81,  0x05,
                   11217:   0x00,  0x63,  0xF0,  0x04,  0xF2,  0x00,  0x72,  0x04,  0x01,  0x01,  0xF1,  0x00,  0x70,  0x00,  0x81,  0x01,
                   11218:   0x70,  0x04,  0x71,  0x00,  0x81,  0x01,  0x72,  0x00,  0x80,  0x01,  0x71,  0x04,  0x70,  0x00,  0x80,  0x01,
                   11219:   0x70,  0x04,  0x00,  0x63,  0xF0,  0x04,  0xF2,  0x00,  0x72,  0x04,  0x00,  0x01,  0xF1,  0x00,  0x70,  0x00,
                   11220:   0x80,  0x01,  0x70,  0x04,  0x71,  0x00,  0x80,  0x01,  0x72,  0x00,  0x81,  0x01,  0x71,  0x04,  0x70,  0x00,
                   11221:   0x81,  0x01,  0x70,  0x04,  0x00,  0x63,  0x00,  0x23,  0xB3,  0x01,  0x83,  0x05,  0xA3,  0x01,  0xA2,  0x01,
                   11222:   0xA1,  0x01,  0x01,  0x23,  0xA0,  0x01,  0x00,  0x01,  0xC8,  0x00,  0x03,  0xA1,  0xC4,  0x07,  0x00,  0x33,
                   11223:   0x07,  0x00,  0xC0,  0x88,  0x80,  0x05,  0x81,  0x05,  0x04,  0x01,  0x11,  0xC8,  0x48,  0x00,  0xB0,  0x01,
                   11224:   0xB1,  0x01,  0x08,  0x23,  0xB2,  0x01,  0x05,  0x01,  0x48,  0x04,  0x00,  0x43,  0x00,  0xA2,  0xE4,  0x07,
                   11225:   0x00,  0x05,  0xDA,  0x87,  0x00,  0x01,  0xC8,  0x00,  0xFF,  0x23,  0x80,  0x01,  0x05,  0x05,  0x00,  0x63,
                   11226:   0xF7,  0x04,  0x1A,  0x09,  0xF6,  0x08,  0x6E,  0x04,  0x00,  0x02,  0x80,  0x43,  0x76,  0x08,  0x80,  0x02,
                   11227:   0x77,  0x04,  0x00,  0x63,  0xF7,  0x04,  0x1A,  0x09,  0xF6,  0x08,  0x6E,  0x04,  0x00,  0x02,  0x00,  0xA0,
                   11228:   0x14,  0x08,  0x16,  0x88,  0x00,  0x43,  0x76,  0x08,  0x80,  0x02,  0x77,  0x04,  0x00,  0x63,  0xF3,  0x04,
                   11229:   0x00,  0x23,  0xF4,  0x00,  0x74,  0x00,  0x80,  0x43,  0xF4,  0x00,  0xCF,  0x40,  0x00,  0xA2,  0x44,  0x08,
                   11230:   0x74,  0x04,  0x02,  0x01,  0xF7,  0xC9,  0xF6,  0xD9,  0x00,  0x01,  0x01,  0xA1,  0x24,  0x08,  0x04,  0x98,
                   11231:   0x26,  0x95,  0x24,  0x88,  0x73,  0x04,  0x00,  0x63,  0xF3,  0x04,  0x75,  0x04,  0x5A,  0x88,  0x02,  0x01,
                   11232:   0x04,  0xD8,  0x46,  0x97,  0x04,  0x98,  0x26,  0x95,  0x4A,  0x88,  0x75,  0x00,  0x00,  0xA3,  0x64,  0x08,
                   11233:   0x00,  0x05,  0x4E,  0x88,  0x73,  0x04,  0x00,  0x63,  0x80,  0x7B,  0x80,  0x63,  0x06,  0xA6,  0x76,  0x08,
                   11234:   0x00,  0x33,  0x3E,  0x00,  0xC0,  0x88,  0x80,  0x67,  0x83,  0x03,  0x80,  0x63,  0x00,  0x63,  0x38,  0x2B,
                   11235:   0x9C,  0x88,  0x38,  0x2B,  0x92,  0x88,  0x32,  0x09,  0x31,  0x05,  0x92,  0x98,  0x05,  0x05,  0xB2,  0x09,
                   11236:   0x00,  0x63,  0x00,  0x32,  0x00,  0x36,  0x00,  0x3A,  0x00,  0x3E,  0x00,  0x63,  0x80,  0x32,  0x80,  0x36,
                   11237:   0x80,  0x3A,  0x80,  0x3E,  0x00,  0x63,  0x38,  0x2B,  0x40,  0x32,  0x40,  0x36,  0x40,  0x3A,  0x40,  0x3E,
                   11238:   0x00,  0x63,  0x5A,  0x20,  0xC9,  0x40,  0x00,  0xA0,  0xB2,  0x08,  0x5D,  0x00,  0xFE,  0xC3,  0x00,  0x63,
                   11239:   0x80,  0x73,  0xE6,  0x20,  0x02,  0x23,  0xE8,  0x00,  0x82,  0x73,  0xFF,  0xFD,  0x80,  0x73,  0x13,  0x23,
                   11240:   0xF6,  0x88,  0x66,  0x20,  0xC0,  0x20,  0x04,  0x23,  0xA0,  0x01,  0xA1,  0x23,  0xA1,  0x01,  0x81,  0x62,
                   11241:   0xE0,  0x88,  0x80,  0x73,  0x80,  0x77,  0x68,  0x00,  0x00,  0xA2,  0x80,  0x00,  0x03,  0xC2,  0xF1,  0xC7,
                   11242:   0x41,  0x23,  0xF6,  0x88,  0x11,  0x23,  0xA1,  0x01,  0x04,  0x23,  0xA0,  0x01,  0xE6,  0x84,
                   11243: };
                   11244: 
                   11245: STATIC ushort _asc_mcode_size ASC_INITDATA = sizeof(_asc_mcode_buf);
                   11246: STATIC ulong _asc_mcode_chksum ASC_INITDATA = 0x012B5442UL;
                   11247: 
                   11248: #define ASC_SYN_OFFSET_ONE_DISABLE_LIST  16
                   11249: STATIC uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] =
                   11250: {
                   11251:     SCSICMD_Inquiry,
                   11252:     SCSICMD_RequestSense,
                   11253:     SCSICMD_ReadCapacity,
                   11254:     SCSICMD_ReadTOC,
                   11255:     SCSICMD_ModeSelect6,
                   11256:     SCSICMD_ModeSense6,
                   11257:     SCSICMD_ModeSelect10,
                   11258:     SCSICMD_ModeSense10,
                   11259:     0xFF,
                   11260:     0xFF,
                   11261:     0xFF,
                   11262:     0xFF,
                   11263:     0xFF,
                   11264:     0xFF,
                   11265:     0xFF,
                   11266:     0xFF
                   11267: };
                   11268: 
                   11269: STATIC int
                   11270: AscExeScsiQueue(
                   11271:                    REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   11272:                    REG ASC_SCSI_Q * scsiq
                   11273: )
                   11274: {
                   11275:     PortAddr            iop_base;
                   11276:     int                 last_int_level;
                   11277:     int                 sta;
                   11278:     int                 n_q_required;
                   11279:     int                 disable_syn_offset_one_fix;
                   11280:     int                 i;
                   11281:     ulong               addr;
                   11282:     ASC_EXE_CALLBACK    asc_exe_callback;
                   11283:     ushort              sg_entry_cnt = 0;
                   11284:     ushort              sg_entry_cnt_minus_one = 0;
                   11285:     uchar               target_ix;
                   11286:     uchar               tid_no;
                   11287:     uchar               sdtr_data;
                   11288:     uchar               extra_bytes;
                   11289:     uchar               scsi_cmd;
                   11290:     uchar               disable_cmd;
                   11291:     ASC_SG_HEAD *sg_head;
                   11292:     ulong               data_cnt;
                   11293: 
                   11294:     iop_base = asc_dvc->iop_base;
                   11295:     sg_head = scsiq->sg_head;
                   11296:     asc_exe_callback = (ASC_EXE_CALLBACK) asc_dvc->exe_callback;
                   11297:     if (asc_dvc->err_code != 0)
                   11298:         return (ERR);
                   11299:     if (scsiq == (ASC_SCSI_Q *) 0L) {
                   11300:         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
                   11301:         return (ERR);
                   11302:     }
                   11303:     scsiq->q1.q_no = 0;
                   11304:     if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
                   11305:         scsiq->q1.extra_bytes = 0;
                   11306:     }
                   11307:     sta = 0;
                   11308:     target_ix = scsiq->q2.target_ix;
                   11309:     tid_no = ASC_TIX_TO_TID(target_ix);
                   11310:     n_q_required = 1;
                   11311:     if (scsiq->cdbptr[0] == SCSICMD_RequestSense) {
                   11312:         if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
                   11313:             asc_dvc->sdtr_done &= ~scsiq->q1.target_id ;
                   11314:             sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
                   11315:             AscMsgOutSDTR(asc_dvc,
                   11316:                           asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
                   11317:                           (uchar) (asc_dvc->max_sdtr_index - 1)],
                   11318:                           (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
                   11319:             scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
                   11320:         }
                   11321:     }
                   11322:     last_int_level = DvcEnterCritical();
                   11323:     if (asc_dvc->in_critical_cnt != 0) {
                   11324:         DvcLeaveCritical(last_int_level);
                   11325:         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
                   11326:         return (ERR);
                   11327:     }
                   11328:     asc_dvc->in_critical_cnt++;
                   11329:     if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
                   11330:         if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
                   11331:             asc_dvc->in_critical_cnt--;
                   11332:             DvcLeaveCritical(last_int_level);
                   11333:             return (ERR);
                   11334:         }
                   11335:         if (sg_entry_cnt > ASC_MAX_SG_LIST) {
                   11336:             return (ERR);
                   11337:         }
                   11338:         if (sg_entry_cnt == 1) {
                   11339:             scsiq->q1.data_addr = sg_head->sg_list[0].addr;
                   11340:             scsiq->q1.data_cnt = sg_head->sg_list[0].bytes;
                   11341:             scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
                   11342:         }
                   11343:         sg_entry_cnt_minus_one = sg_entry_cnt - 1;
                   11344:     }
                   11345:     scsi_cmd = scsiq->cdbptr[0];
                   11346:     disable_syn_offset_one_fix = FALSE;
                   11347:     if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
                   11348:         !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
                   11349:         if (scsiq->q1.cntl & QC_SG_HEAD) {
                   11350:             data_cnt = 0;
                   11351:             for (i = 0; i < sg_entry_cnt; i++) {
                   11352:                 data_cnt += sg_head->sg_list[i].bytes;
                   11353:             }
                   11354:         } else {
                   11355:             data_cnt = scsiq->q1.data_cnt;
                   11356:         }
                   11357:         if (data_cnt != 0UL) {
                   11358:             if (data_cnt < 512UL) {
                   11359:                 disable_syn_offset_one_fix = TRUE;
                   11360:             } else {
                   11361:                 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST; i++) {
                   11362:                     disable_cmd = _syn_offset_one_disable_cmd[i];
                   11363:                     if (disable_cmd == 0xFF) {
                   11364:                         break;
                   11365:                     }
                   11366:                     if (scsi_cmd == disable_cmd) {
                   11367:                         disable_syn_offset_one_fix = TRUE;
                   11368:                         break;
                   11369:                     }
                   11370:                 }
                   11371:             }
                   11372:         }
                   11373:     }
                   11374:     if (disable_syn_offset_one_fix) {
                   11375:         scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
                   11376:         scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
                   11377:                                ASC_TAG_FLAG_DISABLE_DISCONNECT);
                   11378:     } else {
                   11379:         scsiq->q2.tag_code &= 0x23;
                   11380:     }
                   11381:     if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
                   11382:         if (asc_dvc->bug_fix_cntl) {
                   11383:             if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
                   11384:                 if ((scsi_cmd == SCSICMD_Read6) ||
                   11385:                     (scsi_cmd == SCSICMD_Read10)) {
                   11386:                     addr = sg_head->sg_list[sg_entry_cnt_minus_one].addr +
                   11387:                       sg_head->sg_list[sg_entry_cnt_minus_one].bytes;
                   11388:                     extra_bytes = (uchar) ((ushort) addr & 0x0003);
                   11389:                     if ((extra_bytes != 0) &&
                   11390:                         ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
                   11391:                          == 0)) {
                   11392:                         scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
                   11393:                         scsiq->q1.extra_bytes = extra_bytes;
                   11394:                         sg_head->sg_list[sg_entry_cnt_minus_one].bytes -=
                   11395:                             (ulong) extra_bytes;
                   11396:                     }
                   11397:                 }
                   11398:             }
                   11399:         }
                   11400:         sg_head->entry_to_copy = sg_head->entry_cnt;
                   11401:         n_q_required = AscSgListToQueue(sg_entry_cnt);
                   11402:         if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
                   11403:             (uint) n_q_required) || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
                   11404:             if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
                   11405:                                         n_q_required)) == 1) {
                   11406:                 asc_dvc->in_critical_cnt--;
                   11407:                 if (asc_exe_callback != 0) {
                   11408:                     (*asc_exe_callback) (asc_dvc, scsiq);
                   11409:                 }
                   11410:                 DvcLeaveCritical(last_int_level);
                   11411:                 return (sta);
                   11412:             }
                   11413:         }
                   11414:     } else {
                   11415:         if (asc_dvc->bug_fix_cntl) {
                   11416:             if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
                   11417:                 if ((scsi_cmd == SCSICMD_Read6) ||
                   11418:                     (scsi_cmd == SCSICMD_Read10)) {
                   11419:                     addr = scsiq->q1.data_addr + scsiq->q1.data_cnt;
                   11420:                     extra_bytes = (uchar) ((ushort) addr & 0x0003);
                   11421:                     if ((extra_bytes != 0) &&
                   11422:                         ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
                   11423:                           == 0)) {
                   11424:                         if (((ushort) scsiq->q1.data_cnt & 0x01FF) == 0) {
                   11425:                             scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
                   11426:                             scsiq->q1.data_cnt -= (ulong) extra_bytes;
                   11427:                             scsiq->q1.extra_bytes = extra_bytes;
                   11428:                         }
                   11429:                     }
                   11430:                 }
                   11431:             }
                   11432:         }
                   11433:         n_q_required = 1;
                   11434:         if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
                   11435:             ((scsiq->q1.cntl & QC_URGENT) != 0)) {
                   11436:             if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
                   11437:                                         n_q_required)) == 1) {
                   11438:                 asc_dvc->in_critical_cnt--;
                   11439:                 if (asc_exe_callback != 0) {
                   11440:                     (*asc_exe_callback) (asc_dvc, scsiq);
                   11441:                 }
                   11442:                 DvcLeaveCritical(last_int_level);
                   11443:                 return (sta);
                   11444:             }
                   11445:         }
                   11446:     }
                   11447:     asc_dvc->in_critical_cnt--;
                   11448:     DvcLeaveCritical(last_int_level);
                   11449:     return (sta);
                   11450: }
                   11451: 
                   11452: STATIC int
                   11453: AscSendScsiQueue(
                   11454:                     REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   11455:                     REG ASC_SCSI_Q * scsiq,
                   11456:                     uchar n_q_required
                   11457: )
                   11458: {
                   11459:     PortAddr            iop_base;
                   11460:     uchar               free_q_head;
                   11461:     uchar               next_qp;
                   11462:     uchar               tid_no;
                   11463:     uchar               target_ix;
                   11464:     int                 sta;
                   11465: 
                   11466:     iop_base = asc_dvc->iop_base;
                   11467:     target_ix = scsiq->q2.target_ix;
                   11468:     tid_no = ASC_TIX_TO_TID(target_ix);
                   11469:     sta = 0;
                   11470:     free_q_head = (uchar) AscGetVarFreeQHead(iop_base);
                   11471:     if (n_q_required > 1) {
                   11472:         if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
                   11473:                                        free_q_head, (uchar) (n_q_required)))
                   11474:             != (uchar) ASC_QLINK_END) {
                   11475:             asc_dvc->last_q_shortage = 0;
                   11476:             scsiq->sg_head->queue_cnt = n_q_required - 1;
                   11477:             scsiq->q1.q_no = free_q_head;
                   11478:             if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
                   11479:                                               free_q_head)) == 1) {
                   11480:                 AscPutVarFreeQHead(iop_base, next_qp);
                   11481:                 asc_dvc->cur_total_qng += (uchar) (n_q_required);
                   11482:                 asc_dvc->cur_dvc_qng[tid_no]++;
                   11483:             }
                   11484:             return (sta);
                   11485:         }
                   11486:     } else if (n_q_required == 1) {
                   11487:         if ((next_qp = AscAllocFreeQueue(iop_base,
                   11488:                                          free_q_head)) != ASC_QLINK_END) {
                   11489:             scsiq->q1.q_no = free_q_head;
                   11490:             if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
                   11491:                                         free_q_head)) == 1) {
                   11492:                 AscPutVarFreeQHead(iop_base, next_qp);
                   11493:                 asc_dvc->cur_total_qng++;
                   11494:                 asc_dvc->cur_dvc_qng[tid_no]++;
                   11495:             }
                   11496:             return (sta);
                   11497:         }
                   11498:     }
                   11499:     return (sta);
                   11500: }
                   11501: 
                   11502: STATIC int
                   11503: AscSgListToQueue(
                   11504:                     int sg_list
                   11505: )
                   11506: {
                   11507:     int                 n_sg_list_qs;
                   11508: 
                   11509:     n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
                   11510:     if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
                   11511:         n_sg_list_qs++;
                   11512:     return (n_sg_list_qs + 1);
                   11513: }
                   11514: 
                   11515: 
                   11516: STATIC uint
                   11517: AscGetNumOfFreeQueue(
                   11518:                         REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   11519:                         uchar target_ix,
                   11520:                         uchar n_qs
                   11521: )
                   11522: {
                   11523:     uint                cur_used_qs;
                   11524:     uint                cur_free_qs;
                   11525:     ASC_SCSI_BIT_ID_TYPE target_id;
                   11526:     uchar               tid_no;
                   11527: 
                   11528:     target_id = ASC_TIX_TO_TARGET_ID(target_ix);
                   11529:     tid_no = ASC_TIX_TO_TID(target_ix);
                   11530:     if ((asc_dvc->unit_not_ready & target_id) ||
                   11531:         (asc_dvc->queue_full_or_busy & target_id)) {
                   11532:         return (0);
                   11533:     }
                   11534:     if (n_qs == 1) {
                   11535:         cur_used_qs = (uint) asc_dvc->cur_total_qng +
                   11536:           (uint) asc_dvc->last_q_shortage +
                   11537:           (uint) ASC_MIN_FREE_Q;
                   11538:     } else {
                   11539:         cur_used_qs = (uint) asc_dvc->cur_total_qng +
                   11540:           (uint) ASC_MIN_FREE_Q;
                   11541:     }
                   11542:     if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
                   11543:         cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
                   11544:         if (asc_dvc->cur_dvc_qng[tid_no] >=
                   11545:             asc_dvc->max_dvc_qng[tid_no]) {
                   11546:             return (0);
                   11547:         }
                   11548:         return (cur_free_qs);
                   11549:     }
                   11550:     if (n_qs > 1) {
                   11551:         if ((n_qs > asc_dvc->last_q_shortage) && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
                   11552:             asc_dvc->last_q_shortage = n_qs;
                   11553:         }
                   11554:     }
                   11555:     return (0);
                   11556: }
                   11557: 
                   11558: STATIC int
                   11559: AscPutReadyQueue(
                   11560:                     REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   11561:                     REG ASC_SCSI_Q * scsiq,
                   11562:                     uchar q_no
                   11563: )
                   11564: {
                   11565:     ushort              q_addr;
                   11566:     uchar               tid_no;
                   11567:     uchar               sdtr_data;
                   11568:     uchar               syn_period_ix;
                   11569:     uchar               syn_offset;
                   11570:     PortAddr            iop_base;
                   11571: 
                   11572:     iop_base = asc_dvc->iop_base;
                   11573:     if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
                   11574:         ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
                   11575:         tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
                   11576:         sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
                   11577:         syn_period_ix = (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
                   11578:         syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
                   11579:         AscMsgOutSDTR(asc_dvc,
                   11580:                       asc_dvc->sdtr_period_tbl[syn_period_ix],
                   11581:                       syn_offset);
                   11582:         scsiq->q1.cntl |= QC_MSG_OUT;
                   11583:     }
                   11584:     q_addr = ASC_QNO_TO_QADDR(q_no);
                   11585:     if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
                   11586:         scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
                   11587:     }
                   11588:     scsiq->q1.status = QS_FREE;
                   11589:     AscMemWordCopyToLram(iop_base,
                   11590:                          (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG),
                   11591:                          (ushort *) scsiq->cdbptr,
                   11592:                          (ushort) ((ushort) scsiq->q2.cdb_len >> 1));
                   11593:     DvcPutScsiQ(iop_base,
                   11594:                 (ushort) (q_addr + (ushort) ASC_SCSIQ_CPY_BEG),
                   11595:                 (ushort *) & scsiq->q1.cntl,
                   11596:       (ushort) ((((sizeof (ASC_SCSIQ_1) + sizeof (ASC_SCSIQ_2)) / 2) - 1)));
                   11597:     AscWriteLramWord(iop_base,
                   11598:                      (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
                   11599:              (ushort) (((ushort) scsiq->q1.q_no << 8) | (ushort) QS_READY));
                   11600:     return (1);
                   11601: }
                   11602: 
                   11603: STATIC int
                   11604: AscPutReadySgListQueue(
                   11605:                           REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   11606:                           REG ASC_SCSI_Q * scsiq,
                   11607:                           uchar q_no
                   11608: )
                   11609: {
                   11610:     int                 sta;
                   11611:     int                 i;
                   11612:     ASC_SG_HEAD *sg_head;
                   11613:     ASC_SG_LIST_Q       scsi_sg_q;
                   11614:     ulong               saved_data_addr;
                   11615:     ulong               saved_data_cnt;
                   11616:     PortAddr            iop_base;
                   11617:     ushort              sg_list_dwords;
                   11618:     ushort              sg_index;
                   11619:     ushort              sg_entry_cnt;
                   11620:     ushort              q_addr;
                   11621:     uchar               next_qp;
                   11622: 
                   11623:     iop_base = asc_dvc->iop_base;
                   11624:     sg_head = scsiq->sg_head;
                   11625:     saved_data_addr = scsiq->q1.data_addr;
                   11626:     saved_data_cnt = scsiq->q1.data_cnt;
                   11627:     scsiq->q1.data_addr = sg_head->sg_list[0].addr;
                   11628:     scsiq->q1.data_cnt = sg_head->sg_list[0].bytes;
                   11629:     sg_entry_cnt = sg_head->entry_cnt - 1;
                   11630:     if (sg_entry_cnt != 0) {
                   11631:         scsiq->q1.cntl |= QC_SG_HEAD;
                   11632:         q_addr = ASC_QNO_TO_QADDR(q_no);
                   11633:         sg_index = 1;
                   11634:         scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
                   11635:         scsi_sg_q.sg_head_qp = q_no;
                   11636:         scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
                   11637:         for (i = 0; i < sg_head->queue_cnt; i++) {
                   11638:             scsi_sg_q.seq_no = i + 1;
                   11639:             if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
                   11640:                 sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
                   11641:                 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
                   11642:                 if (i == 0) {
                   11643:                     scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q;
                   11644:                     scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q;
                   11645:                 } else {
                   11646:                     scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
                   11647:                     scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
                   11648:                 }
                   11649:             } else {
                   11650:                 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
                   11651:                 sg_list_dwords = sg_entry_cnt << 1;
                   11652:                 if (i == 0) {
                   11653:                     scsi_sg_q.sg_list_cnt = sg_entry_cnt;
                   11654:                     scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt;
                   11655:                 } else {
                   11656:                     scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
                   11657:                     scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
                   11658:                 }
                   11659:                 sg_entry_cnt = 0;
                   11660:             }
                   11661:             next_qp = AscReadLramByte(iop_base,
                   11662:                                       (ushort) (q_addr + ASC_SCSIQ_B_FWD));
                   11663:             scsi_sg_q.q_no = next_qp;
                   11664:             q_addr = ASC_QNO_TO_QADDR(next_qp);
                   11665:             AscMemWordCopyToLram(iop_base,
                   11666:                                  (ushort) (q_addr + ASC_SCSIQ_SGHD_CPY_BEG),
                   11667:                                  (ushort *) & scsi_sg_q,
                   11668:                                  (ushort) (sizeof (ASC_SG_LIST_Q) >> 1));
                   11669:             AscMemDWordCopyToLram(iop_base,
                   11670:                                   (ushort) (q_addr + ASC_SGQ_LIST_BEG),
                   11671:                               (ulong *) & sg_head->sg_list[sg_index],
                   11672:                                   (ushort) sg_list_dwords);
                   11673:             sg_index += ASC_SG_LIST_PER_Q;
                   11674:         }
                   11675:     } else {
                   11676:         scsiq->q1.cntl &= ~QC_SG_HEAD;
                   11677:     }
                   11678:     sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
                   11679:     scsiq->q1.data_addr = saved_data_addr;
                   11680:     scsiq->q1.data_cnt = saved_data_cnt;
                   11681:     return (sta);
                   11682: }
                   11683: 
                   11684: STATIC int
                   11685: AscAbortSRB(
                   11686:                REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   11687:                ulong srb_ptr
                   11688: )
                   11689: {
                   11690:     int                 sta;
                   11691:     ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready;
                   11692:     PortAddr            iop_base;
                   11693: 
                   11694:     iop_base = asc_dvc->iop_base;
                   11695:     sta = ERR;
                   11696:     saved_unit_not_ready = asc_dvc->unit_not_ready;
                   11697:     asc_dvc->unit_not_ready = 0xFF;
                   11698:     AscWaitISRDone(asc_dvc);
                   11699:     if (AscStopQueueExe(iop_base) == 1) {
                   11700:         if (AscRiscHaltedAbortSRB(asc_dvc, srb_ptr) == 1) {
                   11701:             sta = 1;
                   11702:             AscCleanUpBusyQueue(iop_base);
                   11703:             AscStartQueueExe(iop_base);
                   11704:         } else {
                   11705:             sta = 0;
                   11706:             AscStartQueueExe(iop_base);
                   11707:         }
                   11708:     }
                   11709:     asc_dvc->unit_not_ready = saved_unit_not_ready;
                   11710:     return (sta);
                   11711: }
                   11712: 
                   11713: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
                   11714: STATIC int
                   11715: AscResetDevice(
                   11716:                   REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   11717:                   uchar target_ix
                   11718: )
                   11719: {
                   11720:     PortAddr            iop_base;
                   11721:     int                 sta;
                   11722:     uchar               tid_no;
                   11723: 
                   11724:     ASC_SCSI_BIT_ID_TYPE target_id;
                   11725:     int                 i;
                   11726:     ASC_SCSI_REQ_Q      scsiq_buf;
                   11727:     ASC_SCSI_REQ_Q *scsiq;
                   11728:     uchar       *buf;
                   11729:     ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready;
                   11730:     iop_base = asc_dvc->iop_base;
                   11731:     tid_no = ASC_TIX_TO_TID(target_ix);
                   11732:     target_id = ASC_TID_TO_TARGET_ID(tid_no);
                   11733:     saved_unit_not_ready = asc_dvc->unit_not_ready;
                   11734:     asc_dvc->unit_not_ready = target_id;
                   11735:     sta = ERR;
                   11736:     AscWaitTixISRDone(asc_dvc, target_ix);
                   11737:     if (AscStopQueueExe(iop_base) == 1) {
                   11738:         if (AscRiscHaltedAbortTIX(asc_dvc, target_ix) == 1) {
                   11739:             AscCleanUpBusyQueue(iop_base);
                   11740:             AscStartQueueExe(iop_base);
                   11741:             AscWaitTixISRDone(asc_dvc, target_ix);
                   11742:             sta = TRUE;
                   11743:             scsiq = (ASC_SCSI_REQ_Q *) & scsiq_buf;
                   11744:             buf = (uchar *) & scsiq_buf;
                   11745:             for (i = 0; i < sizeof (ASC_SCSI_REQ_Q); i++) {
                   11746:                 *buf++ = 0x00;
                   11747:             }
                   11748:             scsiq->r1.status = (uchar) QS_READY;
                   11749:             scsiq->r2.cdb_len = 6;
                   11750:             scsiq->r2.tag_code = M2_QTAG_MSG_SIMPLE;
                   11751:             scsiq->r1.target_id = target_id;
                   11752:             scsiq->r2.target_ix = ASC_TIDLUN_TO_IX(tid_no, 0);
                   11753:             scsiq->cdbptr = (uchar *) scsiq->cdb;
                   11754:             scsiq->r1.cntl = QC_NO_CALLBACK | QC_MSG_OUT | QC_URGENT;
                   11755:             AscWriteLramByte(asc_dvc->iop_base, ASCV_MSGOUT_BEG,
                   11756:                              M1_BUS_DVC_RESET);
                   11757:             asc_dvc->unit_not_ready &= ~target_id;
                   11758:             asc_dvc->sdtr_done |= target_id;
                   11759:             if (AscExeScsiQueue(asc_dvc, (ASC_SCSI_Q *) scsiq)
                   11760:                 == 1) {
                   11761:                 asc_dvc->unit_not_ready = target_id;
                   11762:                 DvcSleepMilliSecond(1000);
                   11763:                 _AscWaitQDone(iop_base, (ASC_SCSI_Q *) scsiq);
                   11764:                 if (AscStopQueueExe(iop_base) == 1) {
                   11765:                     AscCleanUpDiscQueue(iop_base);
                   11766:                     AscStartQueueExe(iop_base);
                   11767:                     if (asc_dvc->pci_fix_asyn_xfer & target_id) {
                   11768:                         AscSetRunChipSynRegAtID(iop_base, tid_no,
                   11769:                                              ASYN_SDTR_DATA_FIX_PCI_REV_AB);
                   11770:                     }
                   11771:                     AscWaitTixISRDone(asc_dvc, target_ix);
                   11772:                 }
                   11773:             } else {
                   11774:                 sta = 0;
                   11775:             }
                   11776:             asc_dvc->sdtr_done &= ~target_id;
                   11777:         } else {
                   11778:             sta = ERR;
                   11779:             AscStartQueueExe(iop_base);
                   11780:         }
                   11781:     }
                   11782:     asc_dvc->unit_not_ready = saved_unit_not_ready;
                   11783:     return (sta);
                   11784: }
                   11785: #endif /* version >= v1.3.89 */
                   11786: 
                   11787: STATIC int
                   11788: AscResetSB(
                   11789:               REG ASC_DVC_VAR asc_ptr_type * asc_dvc
                   11790: )
                   11791: {
                   11792:     int                 sta;
                   11793:     int                 i;
                   11794:     PortAddr            iop_base;
                   11795: 
                   11796:     iop_base = asc_dvc->iop_base;
                   11797:     asc_dvc->unit_not_ready = 0xFF;
                   11798:     sta = TRUE;
                   11799:     AscWaitISRDone(asc_dvc);
                   11800:     AscStopQueueExe(iop_base);
                   11801:     asc_dvc->sdtr_done = 0;
                   11802:     AscResetChipAndScsiBus(asc_dvc);
                   11803:     DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
                   11804:     AscReInitLram(asc_dvc);
                   11805:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   11806:         asc_dvc->cur_dvc_qng[i] = 0;
                   11807:         if (asc_dvc->pci_fix_asyn_xfer & (ASC_SCSI_BIT_ID_TYPE) (0x01 << i)) {
                   11808:             AscSetChipSynRegAtID(iop_base, i, ASYN_SDTR_DATA_FIX_PCI_REV_AB);
                   11809:         }
                   11810:     }
                   11811:     asc_dvc->err_code = 0;
                   11812:     AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
                   11813:     if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
                   11814:         sta = ERR;
                   11815:     }
                   11816:     if (AscStartChip(iop_base) == 0) {
                   11817:         sta = ERR;
                   11818:     }
                   11819:     AscStartQueueExe(iop_base);
                   11820:     asc_dvc->unit_not_ready = 0;
                   11821:     asc_dvc->queue_full_or_busy = 0;
                   11822:     return (sta);
                   11823: }
                   11824: 
                   11825: STATIC int
                   11826: AscSetRunChipSynRegAtID(
                   11827:                            PortAddr iop_base,
                   11828:                            uchar tid_no,
                   11829:                            uchar sdtr_data
                   11830: )
                   11831: {
                   11832:     int                 sta = FALSE;
                   11833: 
                   11834:     if (AscHostReqRiscHalt(iop_base)) {
                   11835:         sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
                   11836:         AscStartChip(iop_base);
                   11837:         return (sta);
                   11838:     }
                   11839:     return (sta);
                   11840: }
                   11841: 
                   11842: STATIC int
                   11843: AscSetChipSynRegAtID(
                   11844:                         PortAddr iop_base,
                   11845:                         uchar id,
                   11846:                         uchar sdtr_data
                   11847: )
                   11848: {
                   11849:     ASC_SCSI_BIT_ID_TYPE org_id;
                   11850:     int                 i;
                   11851:     int                 sta = TRUE;
                   11852: 
                   11853:     AscSetBank(iop_base, 1);
                   11854:     org_id = AscReadChipDvcID(iop_base);
                   11855:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   11856:         if (org_id == (0x01 << i))
                   11857:             break;
                   11858:     }
                   11859:     org_id = i;
                   11860:     AscWriteChipDvcID(iop_base, id);
                   11861:     if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
                   11862:         AscSetBank(iop_base, 0);
                   11863:         AscSetChipSyn(iop_base, sdtr_data);
                   11864:         if (AscGetChipSyn(iop_base) != sdtr_data) {
                   11865:             sta = FALSE;
                   11866:         }
                   11867:     } else {
                   11868:         sta = FALSE;
                   11869:     }
                   11870:     AscSetBank(iop_base, 1);
                   11871:     AscWriteChipDvcID(iop_base, org_id);
                   11872:     AscSetBank(iop_base, 0);
                   11873:     return (sta);
                   11874: }
                   11875: 
                   11876: STATIC int
                   11877: AscReInitLram(
                   11878:                  REG ASC_DVC_VAR asc_ptr_type * asc_dvc
                   11879: )
                   11880: {
                   11881:     AscInitLram(asc_dvc);
                   11882:     AscInitQLinkVar(asc_dvc);
                   11883:     return (0);
                   11884: }
                   11885: 
                   11886: STATIC ushort
                   11887: AscInitLram(
                   11888:                REG ASC_DVC_VAR asc_ptr_type * asc_dvc
                   11889: )
                   11890: {
                   11891:     uchar               i;
                   11892:     ushort              s_addr;
                   11893:     PortAddr            iop_base;
                   11894:     ushort              warn_code;
                   11895: 
                   11896:     iop_base = asc_dvc->iop_base;
                   11897:     warn_code = 0;
                   11898:     AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
                   11899:                (ushort) (((int) (asc_dvc->max_total_qng + 2 + 1) * 64) >> 1)
                   11900: );
                   11901:     i = ASC_MIN_ACTIVE_QNO;
                   11902:     s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
                   11903:     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
                   11904:                      (uchar) (i + 1));
                   11905:     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
                   11906:                      (uchar) (asc_dvc->max_total_qng));
                   11907:     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
                   11908:                      (uchar) i);
                   11909:     i++;
                   11910:     s_addr += ASC_QBLK_SIZE;
                   11911:     for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
                   11912:         AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
                   11913:                          (uchar) (i + 1));
                   11914:         AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
                   11915:                          (uchar) (i - 1));
                   11916:         AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
                   11917:                          (uchar) i);
                   11918:     }
                   11919:     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
                   11920:                      (uchar) ASC_QLINK_END);
                   11921:     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
                   11922:                      (uchar) (asc_dvc->max_total_qng - 1));
                   11923:     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
                   11924:                      (uchar) asc_dvc->max_total_qng);
                   11925:     i++;
                   11926:     s_addr += ASC_QBLK_SIZE;
                   11927:     for (; i <= (uchar) (asc_dvc->max_total_qng + 3);
                   11928:          i++, s_addr += ASC_QBLK_SIZE) {
                   11929:         AscWriteLramByte(iop_base,
                   11930:                          (ushort) (s_addr + (ushort) ASC_SCSIQ_B_FWD), i);
                   11931:         AscWriteLramByte(iop_base,
                   11932:                          (ushort) (s_addr + (ushort) ASC_SCSIQ_B_BWD), i);
                   11933:         AscWriteLramByte(iop_base,
                   11934:                          (ushort) (s_addr + (ushort) ASC_SCSIQ_B_QNO), i);
                   11935:     }
                   11936:     return (warn_code);
                   11937: }
                   11938: 
                   11939: STATIC ushort
                   11940: AscInitQLinkVar(
                   11941:                    REG ASC_DVC_VAR asc_ptr_type * asc_dvc
                   11942: )
                   11943: {
                   11944:     PortAddr            iop_base;
                   11945:     int                 i;
                   11946:     ushort              lram_addr;
                   11947: 
                   11948:     iop_base = asc_dvc->iop_base;
                   11949:     AscPutRiscVarFreeQHead(iop_base, 1);
                   11950:     AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
                   11951:     AscPutVarFreeQHead(iop_base, 1);
                   11952:     AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
                   11953:     AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
                   11954:                      (uchar) ((int) asc_dvc->max_total_qng + 1));
                   11955:     AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
                   11956:                      (uchar) ((int) asc_dvc->max_total_qng + 2));
                   11957:     AscWriteLramByte(iop_base, (ushort) ASCV_TOTAL_READY_Q_B,
                   11958:                      asc_dvc->max_total_qng);
                   11959:     AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
                   11960:     AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
                   11961:     AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
                   11962:     AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
                   11963:     AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
                   11964:     AscPutQDoneInProgress(iop_base, 0);
                   11965:     lram_addr = ASC_QADR_BEG;
                   11966:     for (i = 0; i < 32; i++, lram_addr += 2) {
                   11967:         AscWriteLramWord(iop_base, lram_addr, 0);
                   11968:     }
                   11969:     return (0);
                   11970: }
                   11971: 
                   11972: STATIC int
                   11973: AscSetLibErrorCode(
                   11974:                       REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   11975:                       ushort err_code
                   11976: )
                   11977: {
                   11978:     if (asc_dvc->err_code == 0) {
                   11979:         asc_dvc->err_code = err_code;
                   11980:         AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
                   11981:                          err_code);
                   11982:     }
                   11983:     return (err_code);
                   11984: }
                   11985: 
                   11986: 
                   11987: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
                   11988: STATIC int
                   11989: _AscWaitQDone(
                   11990:                  PortAddr iop_base,
                   11991:                  REG ASC_SCSI_Q * scsiq
                   11992: )
                   11993: {
                   11994:     ushort              q_addr;
                   11995:     uchar               q_status;
                   11996:     int                 count = 0;
                   11997: 
                   11998:     while (scsiq->q1.q_no == 0) ;
                   11999:     q_addr = ASC_QNO_TO_QADDR(scsiq->q1.q_no);
                   12000:     do {
                   12001:         q_status = AscReadLramByte(iop_base, q_addr + ASC_SCSIQ_B_STATUS);
                   12002:         DvcSleepMilliSecond(100L);
                   12003:         if (count++ > 30) {
                   12004:             return (0);
                   12005:         }
                   12006:     } while ((q_status & QS_READY) != 0);
                   12007:     return (1);
                   12008: }
                   12009: #endif /* version >= v1.3.89 */
                   12010: 
                   12011: STATIC uchar 
                   12012: AscMsgOutSDTR(
                   12013:                  REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   12014:                  uchar sdtr_period,
                   12015:                  uchar sdtr_offset
                   12016: )
                   12017: {
                   12018:     EXT_MSG             sdtr_buf;
                   12019:     uchar               sdtr_period_index;
                   12020:     PortAddr            iop_base;
                   12021: 
                   12022:     iop_base = asc_dvc->iop_base;
                   12023:     sdtr_buf.msg_type = MS_EXTEND;
                   12024:     sdtr_buf.msg_len = MS_SDTR_LEN;
                   12025:     sdtr_buf.msg_req = MS_SDTR_CODE;
                   12026:     sdtr_buf.xfer_period = sdtr_period;
                   12027:     sdtr_offset &= ASC_SYN_MAX_OFFSET;
                   12028:     sdtr_buf.req_ack_offset = sdtr_offset;
                   12029:     if ((sdtr_period_index =
                   12030:          AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
                   12031:         asc_dvc->max_sdtr_index) {
                   12032:         AscMemWordCopyToLram(iop_base,
                   12033:                              ASCV_MSGOUT_BEG,
                   12034:                              (ushort *) & sdtr_buf,
                   12035:                              (ushort) (sizeof (EXT_MSG) >> 1));
                   12036:         return ((sdtr_period_index << 4) | sdtr_offset);
                   12037:     } else {
                   12038: 
                   12039:         sdtr_buf.req_ack_offset = 0;
                   12040:         AscMemWordCopyToLram(iop_base,
                   12041:                              ASCV_MSGOUT_BEG,
                   12042:                              (ushort *) & sdtr_buf,
                   12043:                              (ushort) (sizeof (EXT_MSG) >> 1));
                   12044:         return (0);
                   12045:     }
                   12046: }
                   12047: 
                   12048: STATIC uchar
                   12049: AscCalSDTRData(
                   12050:                   REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   12051:                   uchar sdtr_period,
                   12052:                   uchar syn_offset
                   12053: )
                   12054: {
                   12055:     uchar               byte;
                   12056:     uchar               sdtr_period_ix;
                   12057: 
                   12058:     sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
                   12059:     if (
                   12060:            (sdtr_period_ix > asc_dvc->max_sdtr_index)
                   12061: ) {
                   12062:         return (0xFF);
                   12063:     }
                   12064:     byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
                   12065:     return (byte);
                   12066: }
                   12067: 
                   12068: STATIC void
                   12069: AscSetChipSDTR(
                   12070:                   PortAddr iop_base,
                   12071:                   uchar sdtr_data,
                   12072:                   uchar tid_no
                   12073: )
                   12074: {
                   12075:     AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
                   12076:     AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
                   12077:     return;
                   12078: }
                   12079: 
                   12080: STATIC uchar
                   12081: AscGetSynPeriodIndex(
                   12082:                         ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   12083:                         ruchar syn_time
                   12084: )
                   12085: {
                   12086:     ruchar             *period_table;
                   12087:     int                 max_index;
                   12088:     int                 min_index;
                   12089:     int                 i;
                   12090: 
                   12091:     period_table = asc_dvc->sdtr_period_tbl;
                   12092:     max_index = (int) asc_dvc->max_sdtr_index;
                   12093:     min_index = (int)asc_dvc->host_init_sdtr_index ;
                   12094:     if ((syn_time <= period_table[max_index])) {
                   12095:         for (i = min_index; i < (max_index - 1); i++) {
                   12096:             if (syn_time <= period_table[i]) {
                   12097:                 return ((uchar) i);
                   12098:             }
                   12099:         }
                   12100:         return ((uchar) max_index);
                   12101:     } else {
                   12102:         return ((uchar) (max_index + 1));
                   12103:     }
                   12104: }
                   12105: 
                   12106: STATIC uchar
                   12107: AscAllocFreeQueue(
                   12108:                      PortAddr iop_base,
                   12109:                      uchar free_q_head
                   12110: )
                   12111: {
                   12112:     ushort              q_addr;
                   12113:     uchar               next_qp;
                   12114:     uchar               q_status;
                   12115: 
                   12116:     q_addr = ASC_QNO_TO_QADDR(free_q_head);
                   12117:     q_status = (uchar) AscReadLramByte(iop_base,
                   12118:                                     (ushort) (q_addr + ASC_SCSIQ_B_STATUS));
                   12119:     next_qp = AscReadLramByte(iop_base,
                   12120:                               (ushort) (q_addr + ASC_SCSIQ_B_FWD));
                   12121:     if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
                   12122:         return (next_qp);
                   12123:     }
                   12124:     return (ASC_QLINK_END);
                   12125: }
                   12126: 
                   12127: STATIC uchar
                   12128: AscAllocMultipleFreeQueue(
                   12129:                              PortAddr iop_base,
                   12130:                              uchar free_q_head,
                   12131:                              uchar n_free_q
                   12132: )
                   12133: {
                   12134:     uchar               i;
                   12135: 
                   12136:     for (i = 0; i < n_free_q; i++) {
                   12137:         if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
                   12138:             == ASC_QLINK_END) {
                   12139:             return (ASC_QLINK_END);
                   12140:         }
                   12141:     }
                   12142:     return (free_q_head);
                   12143: }
                   12144: 
                   12145: STATIC int
                   12146: AscRiscHaltedAbortSRB(
                   12147:                          REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   12148:                          ulong srb_ptr
                   12149: )
                   12150: {
                   12151:     PortAddr            iop_base;
                   12152:     ushort              q_addr;
                   12153:     uchar               q_no;
                   12154:     ASC_QDONE_INFO      scsiq_buf;
                   12155:     ASC_QDONE_INFO *scsiq;
                   12156:     ASC_ISR_CALLBACK    asc_isr_callback;
                   12157:     int                 last_int_level;
                   12158: 
                   12159:     iop_base = asc_dvc->iop_base;
                   12160:     asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
                   12161:     last_int_level = DvcEnterCritical();
                   12162:     scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
                   12163:     for (q_no = ASC_MIN_ACTIVE_QNO; q_no <= asc_dvc->max_total_qng;
                   12164:          q_no++) {
                   12165:         q_addr = ASC_QNO_TO_QADDR(q_no);
                   12166:         scsiq->d2.srb_ptr = AscReadLramDWord(iop_base,
                   12167:                            (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR));
                   12168:         if (scsiq->d2.srb_ptr == srb_ptr) {
                   12169:             _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count);
                   12170:             if (((scsiq->q_status & QS_READY) != 0)
                   12171:                  && ((scsiq->q_status & QS_ABORTED) == 0)
                   12172:                  && ((scsiq->cntl & QCSG_SG_XFER_LIST) == 0)) {
                   12173:                 scsiq->q_status |= QS_ABORTED;
                   12174:                 scsiq->d3.done_stat = QD_ABORTED_BY_HOST;
                   12175:                 AscWriteLramDWord(iop_base,
                   12176:                             (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR),
                   12177:                                   0L);
                   12178:                 AscWriteLramByte(iop_base,
                   12179:                             (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
                   12180:                                  scsiq->q_status);
                   12181:                 (*asc_isr_callback) (asc_dvc, scsiq);
                   12182:                 return (1);
                   12183:             }
                   12184:         }
                   12185:     }
                   12186:     DvcLeaveCritical(last_int_level);
                   12187:     return (0);
                   12188: }
                   12189: 
                   12190: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
                   12191: STATIC int
                   12192: AscRiscHaltedAbortTIX(
                   12193:                          REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   12194:                          uchar target_ix
                   12195: )
                   12196: {
                   12197:     PortAddr            iop_base;
                   12198:     ushort              q_addr;
                   12199:     uchar               q_no;
                   12200:     ASC_QDONE_INFO      scsiq_buf;
                   12201:     ASC_QDONE_INFO *scsiq;
                   12202:     ASC_ISR_CALLBACK    asc_isr_callback;
                   12203:     int                 last_int_level;
                   12204: 
                   12205:     iop_base = asc_dvc->iop_base;
                   12206:     asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
                   12207:     last_int_level = DvcEnterCritical();
                   12208:     scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
                   12209:     for (q_no = ASC_MIN_ACTIVE_QNO; q_no <= asc_dvc->max_total_qng;
                   12210:          q_no++) {
                   12211:         q_addr = ASC_QNO_TO_QADDR(q_no);
                   12212:         _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count);
                   12213:         if (((scsiq->q_status & QS_READY) != 0) &&
                   12214:             ((scsiq->q_status & QS_ABORTED) == 0) &&
                   12215:             ((scsiq->cntl & QCSG_SG_XFER_LIST) == 0)) {
                   12216:             if (scsiq->d2.target_ix == target_ix) {
                   12217:                 scsiq->q_status |= QS_ABORTED;
                   12218:                 scsiq->d3.done_stat = QD_ABORTED_BY_HOST;
                   12219:                 AscWriteLramDWord(iop_base,
                   12220:                             (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR),
                   12221:                                   0L);
                   12222:                 AscWriteLramByte(iop_base,
                   12223:                             (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
                   12224:                                  scsiq->q_status);
                   12225:                 (*asc_isr_callback) (asc_dvc, scsiq);
                   12226:             }
                   12227:         }
                   12228:     }
                   12229:     DvcLeaveCritical(last_int_level);
                   12230:     return (1);
                   12231: }
                   12232: #endif /* version >= v1.3.89 */
                   12233: 
                   12234: STATIC int
                   12235: AscHostReqRiscHalt(
                   12236:                       PortAddr iop_base
                   12237: )
                   12238: {
                   12239:     int                 count = 0;
                   12240:     int                 sta = 0;
                   12241:     uchar               saved_stop_code;
                   12242: 
                   12243:     if (AscIsChipHalted(iop_base))
                   12244:         return (1);
                   12245:     saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
                   12246:     AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
                   12247:                      ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP
                   12248: );
                   12249:     do {
                   12250:         if (AscIsChipHalted(iop_base)) {
                   12251:             sta = 1;
                   12252:             break;
                   12253:         }
                   12254:         DvcSleepMilliSecond(100);
                   12255:     } while (count++ < 20);
                   12256:     AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
                   12257:     return (sta);
                   12258: }
                   12259: 
                   12260: STATIC int
                   12261: AscStopQueueExe(
                   12262:                    PortAddr iop_base
                   12263: )
                   12264: {
                   12265:     int                 count = 0;
                   12266: 
                   12267:     if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
                   12268:         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
                   12269:                          ASC_STOP_REQ_RISC_STOP);
                   12270:         do {
                   12271:             if (
                   12272:                    AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
                   12273:                    ASC_STOP_ACK_RISC_STOP) {
                   12274:                 return (1);
                   12275:             }
                   12276:             DvcSleepMilliSecond(100);
                   12277:         } while (count++ < 20);
                   12278:     }
                   12279:     return (0);
                   12280: }
                   12281: 
                   12282: STATIC int
                   12283: AscStartQueueExe(
                   12284:                     PortAddr iop_base
                   12285: )
                   12286: {
                   12287:     if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
                   12288:         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
                   12289:     }
                   12290:     return (1);
                   12291: }
                   12292: 
                   12293: STATIC int
                   12294: AscCleanUpBusyQueue(
                   12295:                        PortAddr iop_base
                   12296: )
                   12297: {
                   12298:     int                 count;
                   12299:     uchar               stop_code;
                   12300: 
                   12301:     count = 0;
                   12302:     if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
                   12303:         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
                   12304:                          ASC_STOP_CLEAN_UP_BUSY_Q);
                   12305:         do {
                   12306:             stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
                   12307:             if ((stop_code & ASC_STOP_CLEAN_UP_BUSY_Q) == 0)
                   12308:                 break;
                   12309:             DvcSleepMilliSecond(100);
                   12310:         } while (count++ < 20);
                   12311:     }
                   12312:     return (1);
                   12313: }
                   12314: 
                   12315: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
                   12316: STATIC int
                   12317: AscCleanUpDiscQueue(
                   12318:                        PortAddr iop_base
                   12319: )
                   12320: {
                   12321:     int                 count;
                   12322:     uchar               stop_code;
                   12323: 
                   12324:     count = 0;
                   12325:     if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
                   12326:         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
                   12327:                          ASC_STOP_CLEAN_UP_DISC_Q);
                   12328:         do {
                   12329:             stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
                   12330:             if ((stop_code & ASC_STOP_CLEAN_UP_DISC_Q) == 0)
                   12331:                 break;
                   12332:             DvcSleepMilliSecond(100);
                   12333:         } while (count++ < 20);
                   12334:     }
                   12335:     return (1);
                   12336: }
                   12337: #endif /* version >= v1.3.89 */
                   12338: 
                   12339: STATIC int
                   12340: AscWaitTixISRDone(
                   12341:                      ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   12342:                      uchar target_ix
                   12343: )
                   12344: {
                   12345:     uchar               cur_req;
                   12346:     uchar               tid_no;
                   12347:     int                 i = 0;
                   12348: 
                   12349:     tid_no = ASC_TIX_TO_TID(target_ix);
                   12350:     while (i++ < 10) {
                   12351:         if ((cur_req = asc_dvc->cur_dvc_qng[tid_no]) == 0) {
                   12352:             break;
                   12353:         }
                   12354:         DvcSleepMilliSecond(1000L);
                   12355:         if (asc_dvc->cur_dvc_qng[tid_no] == cur_req) {
                   12356:             break;
                   12357:         }
                   12358:     }
                   12359:     return (1);
                   12360: }
                   12361: 
                   12362: STATIC int
                   12363: AscWaitISRDone(
                   12364:                   REG ASC_DVC_VAR asc_ptr_type * asc_dvc
                   12365: )
                   12366: {
                   12367:     int                 tid;
                   12368: 
                   12369:     for (tid = 0; tid <= ASC_MAX_TID; tid++) {
                   12370:         AscWaitTixISRDone(asc_dvc, ASC_TID_TO_TIX(tid));
                   12371:     }
                   12372:     return (1);
                   12373: }
                   12374: 
                   12375: STATIC ulong
                   12376: AscGetOnePhyAddr(
                   12377:                     REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   12378:                     uchar * buf_addr,
                   12379:                     ulong buf_size
                   12380: )
                   12381: {
                   12382:     ASC_MIN_SG_HEAD     sg_head;
                   12383: 
                   12384:     sg_head.entry_cnt = ASC_MIN_SG_LIST;
                   12385:     if (DvcGetSGList(asc_dvc, (uchar *) buf_addr,
                   12386:                   buf_size, (ASC_SG_HEAD *) & sg_head) != buf_size) {
                   12387:         return (0L);
                   12388:     }
                   12389:     if (sg_head.entry_cnt > 1) {
                   12390:         return (0L);
                   12391:     }
                   12392:     return (sg_head.sg_list[0].addr);
                   12393: }
                   12394: 
                   12395: STATIC void
                   12396: DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
                   12397: {
                   12398:     udelay(micro_sec);
                   12399: }
                   12400: 
                   12401: STATIC void
                   12402: DvcDelayNanoSecond(ASC_DVC_VAR asc_ptr_type * asc_dvc, ulong nano_sec)
                   12403: {
                   12404:     udelay((nano_sec + 999)/1000);
                   12405: }
                   12406: 
                   12407: ASC_INITFUNC(
                   12408: STATIC ulong
                   12409: AscGetEisaProductID(
                   12410:                        PortAddr iop_base
                   12411: )
                   12412: )
                   12413: {
                   12414:     PortAddr            eisa_iop;
                   12415:     ushort              product_id_high, product_id_low;
                   12416:     ulong               product_id;
                   12417: 
                   12418:     eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK;
                   12419:     product_id_low = inpw(eisa_iop);
                   12420:     product_id_high = inpw(eisa_iop + 2);
                   12421:     product_id = ((ulong) product_id_high << 16) | (ulong) product_id_low;
                   12422:     return (product_id);
                   12423: }
                   12424: 
                   12425: ASC_INITFUNC(
                   12426: STATIC PortAddr
                   12427: AscSearchIOPortAddrEISA(
                   12428:                            PortAddr iop_base
                   12429: )
                   12430: )
                   12431: {
                   12432:     ulong               eisa_product_id;
                   12433: 
                   12434:     if (iop_base == 0) {
                   12435:         iop_base = ASC_EISA_MIN_IOP_ADDR;
                   12436:     } else {
                   12437:         if (iop_base == ASC_EISA_MAX_IOP_ADDR)
                   12438:             return (0);
                   12439:         if ((iop_base & 0x0050) == 0x0050) {
                   12440:             iop_base += ASC_EISA_BIG_IOP_GAP;
                   12441:         } else {
                   12442:             iop_base += ASC_EISA_SMALL_IOP_GAP;
                   12443:         }
                   12444:     }
                   12445:     while (iop_base <= ASC_EISA_MAX_IOP_ADDR) {
                   12446:         eisa_product_id = AscGetEisaProductID(iop_base);
                   12447:         if ((eisa_product_id == ASC_EISA_ID_740) ||
                   12448:             (eisa_product_id == ASC_EISA_ID_750)) {
                   12449:             if (AscFindSignature(iop_base)) {
                   12450:                 inpw(iop_base + 4);
                   12451:                 return (iop_base);
                   12452:             }
                   12453:         }
                   12454:         if (iop_base == ASC_EISA_MAX_IOP_ADDR)
                   12455:             return (0);
                   12456:         if ((iop_base & 0x0050) == 0x0050) {
                   12457:             iop_base += ASC_EISA_BIG_IOP_GAP;
                   12458:         } else {
                   12459:             iop_base += ASC_EISA_SMALL_IOP_GAP;
                   12460:         }
                   12461:     }
                   12462:     return (0);
                   12463: }
                   12464: 
                   12465: STATIC int
                   12466: AscStartChip(
                   12467:                 PortAddr iop_base
                   12468: )
                   12469: {
                   12470:     AscSetChipControl(iop_base, 0);
                   12471:     if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
                   12472:         return (0);
                   12473:     }
                   12474:     return (1);
                   12475: }
                   12476: 
                   12477: STATIC int
                   12478: AscStopChip(
                   12479:                PortAddr iop_base
                   12480: )
                   12481: {
                   12482:     uchar               cc_val;
                   12483: 
                   12484:     cc_val = AscGetChipControl(iop_base) & (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
                   12485:     AscSetChipControl(iop_base, (uchar) (cc_val | CC_HALT));
                   12486:     AscSetChipIH(iop_base, INS_HALT);
                   12487:     AscSetChipIH(iop_base, INS_RFLAG_WTM);
                   12488:     if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
                   12489:         return (0);
                   12490:     }
                   12491:     return (1);
                   12492: }
                   12493: 
                   12494: STATIC int
                   12495: AscIsChipHalted(
                   12496:                    PortAddr iop_base
                   12497: )
                   12498: {
                   12499:     if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
                   12500:         if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
                   12501:             return (1);
                   12502:         }
                   12503:     }
                   12504:     return (0);
                   12505: }
                   12506: 
                   12507: STATIC void
                   12508: AscSetChipIH(
                   12509:                 PortAddr iop_base,
                   12510:                 ushort ins_code
                   12511: )
                   12512: {
                   12513:     AscSetBank(iop_base, 1);
                   12514:     AscWriteChipIH(iop_base, ins_code);
                   12515:     AscSetBank(iop_base, 0);
                   12516:     return;
                   12517: }
                   12518: 
                   12519: STATIC void
                   12520: AscAckInterrupt(
                   12521:                    PortAddr iop_base
                   12522: )
                   12523: {
                   12524:     uchar               host_flag;
                   12525:     uchar               risc_flag;
                   12526:     ushort              loop;
                   12527: 
                   12528:     loop = 0;
                   12529:     do {
                   12530:         risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
                   12531:         if (loop++ > 0x7FFF) {
                   12532:             break;
                   12533:         }
                   12534:     } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
                   12535:     host_flag = AscReadLramByte(iop_base, ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
                   12536:     AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
                   12537:                      (uchar) (host_flag | ASC_HOST_FLAG_ACK_INT));
                   12538:     AscSetChipStatus(iop_base, CIW_INT_ACK);
                   12539:     loop = 0;
                   12540:     while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
                   12541:         AscSetChipStatus(iop_base, CIW_INT_ACK);
                   12542:         if (loop++ > 3) {
                   12543:             break;
                   12544:         }
                   12545:     }
                   12546:     AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
                   12547:     return;
                   12548: }
                   12549: 
                   12550: STATIC void
                   12551: AscDisableInterrupt(
                   12552:                        PortAddr iop_base
                   12553: )
                   12554: {
                   12555:     ushort              cfg;
                   12556: 
                   12557:     cfg = AscGetChipCfgLsw(iop_base);
                   12558:     AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
                   12559:     return;
                   12560: }
                   12561: 
                   12562: STATIC void
                   12563: AscEnableInterrupt(
                   12564:                       PortAddr iop_base
                   12565: )
                   12566: {
                   12567:     ushort              cfg;
                   12568: 
                   12569:     cfg = AscGetChipCfgLsw(iop_base);
                   12570:     AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
                   12571:     return;
                   12572: }
                   12573: 
                   12574: 
                   12575: 
                   12576: STATIC void
                   12577: AscSetBank(
                   12578:               PortAddr iop_base,
                   12579:               uchar bank
                   12580: )
                   12581: {
                   12582:     uchar               val;
                   12583: 
                   12584:     val = AscGetChipControl(iop_base) &
                   12585:       (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET | CC_CHIP_RESET));
                   12586:     if (bank == 1) {
                   12587:         val |= CC_BANK_ONE;
                   12588:     } else if (bank == 2) {
                   12589:         val |= CC_DIAG | CC_BANK_ONE;
                   12590:     } else {
                   12591:         val &= ~CC_BANK_ONE;
                   12592:     }
                   12593:     AscSetChipControl(iop_base, val);
                   12594:     return;
                   12595: }
                   12596: 
                   12597: STATIC int
                   12598: AscResetChipAndScsiBus(
                   12599:                           ASC_DVC_VAR *asc_dvc
                   12600: )
                   12601: {
                   12602:     PortAddr    iop_base;
                   12603: 
                   12604:     iop_base = asc_dvc->iop_base;
                   12605:     while (AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) ;
                   12606:     AscStopChip(iop_base);
                   12607:     AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
                   12608:     DvcDelayNanoSecond(asc_dvc, 60000);
                   12609:     AscSetChipIH(iop_base, INS_RFLAG_WTM);
                   12610:     AscSetChipIH(iop_base, INS_HALT);
                   12611:     AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
                   12612:     AscSetChipControl(iop_base, CC_HALT);
                   12613:     DvcSleepMilliSecond(200);
                   12614:     AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
                   12615:     AscSetChipStatus(iop_base, 0);
                   12616:     return (AscIsChipHalted(iop_base));
                   12617: }
                   12618: 
                   12619: ASC_INITFUNC(
                   12620: STATIC ulong
                   12621: AscGetMaxDmaCount(
                   12622:                      ushort bus_type
                   12623: )
                   12624: )
                   12625: {
                   12626:     if (bus_type & ASC_IS_ISA)
                   12627:         return (ASC_MAX_ISA_DMA_COUNT);
                   12628:     else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
                   12629:         return (ASC_MAX_VL_DMA_COUNT);
                   12630:     return (ASC_MAX_PCI_DMA_COUNT);
                   12631: }
                   12632: 
                   12633: ASC_INITFUNC(
                   12634: STATIC ushort
                   12635: AscGetIsaDmaChannel(
                   12636:                        PortAddr iop_base
                   12637: )
                   12638: )
                   12639: {
                   12640:     ushort              channel;
                   12641: 
                   12642:     channel = AscGetChipCfgLsw(iop_base) & 0x0003;
                   12643:     if (channel == 0x03)
                   12644:         return (0);
                   12645:     else if (channel == 0x00)
                   12646:         return (7);
                   12647:     return (channel + 4);
                   12648: }
                   12649: 
                   12650: ASC_INITFUNC(
                   12651: STATIC ushort
                   12652: AscSetIsaDmaChannel(
                   12653:                        PortAddr iop_base,
                   12654:                        ushort dma_channel
                   12655: )
                   12656: )
                   12657: {
                   12658:     ushort              cfg_lsw;
                   12659:     uchar               value;
                   12660: 
                   12661:     if ((dma_channel >= 5) && (dma_channel <= 7)) {
                   12662:         if (dma_channel == 7)
                   12663:             value = 0x00;
                   12664:         else
                   12665:             value = dma_channel - 4;
                   12666:         cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
                   12667:         cfg_lsw |= value;
                   12668:         AscSetChipCfgLsw(iop_base, cfg_lsw);
                   12669:         return (AscGetIsaDmaChannel(iop_base));
                   12670:     }
                   12671:     return (0);
                   12672: }
                   12673: 
                   12674: ASC_INITFUNC(
                   12675: STATIC uchar
                   12676: AscSetIsaDmaSpeed(
                   12677:                      PortAddr iop_base,
                   12678:                      uchar speed_value
                   12679: )
                   12680: )
                   12681: {
                   12682:     speed_value &= 0x07;
                   12683:     AscSetBank(iop_base, 1);
                   12684:     AscWriteChipDmaSpeed(iop_base, speed_value);
                   12685:     AscSetBank(iop_base, 0);
                   12686:     return (AscGetIsaDmaSpeed(iop_base));
                   12687: }
                   12688: 
                   12689: ASC_INITFUNC(
                   12690: STATIC uchar
                   12691: AscGetIsaDmaSpeed(
                   12692:                      PortAddr iop_base
                   12693: )
                   12694: )
                   12695: {
                   12696:     uchar               speed_value;
                   12697: 
                   12698:     AscSetBank(iop_base, 1);
                   12699:     speed_value = AscReadChipDmaSpeed(iop_base);
                   12700:     speed_value &= 0x07;
                   12701:     AscSetBank(iop_base, 0);
                   12702:     return (speed_value);
                   12703: }
                   12704: 
                   12705: ASC_INITFUNC(
                   12706: STATIC ushort
                   12707: AscReadPCIConfigWord(
                   12708:     ASC_DVC_VAR asc_ptr_type *asc_dvc,
                   12709:     ushort pci_config_offset)
                   12710: )
                   12711: {
                   12712:     uchar       lsb, msb;
                   12713: 
                   12714:     lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset);
                   12715:     msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1);
                   12716:     return ((ushort) ((msb << 8) | lsb));
                   12717: }
                   12718: 
                   12719: ASC_INITFUNC(
                   12720: STATIC ushort 
                   12721: AscInitGetConfig(
                   12722:         ASC_DVC_VAR asc_ptr_type * asc_dvc
                   12723: )
                   12724: )
                   12725: {
                   12726:     ushort              warn_code;
                   12727:     PortAddr            iop_base;
                   12728:     ushort              PCIDeviceID;
                   12729:     ushort              PCIVendorID;
                   12730:     uchar               PCIRevisionID;
                   12731:     uchar               prevCmdRegBits;
                   12732: 
                   12733:     warn_code = 0;
                   12734:     iop_base = asc_dvc->iop_base;
                   12735:     asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
                   12736:     if (asc_dvc->err_code != 0) {
                   12737:         return (UW_ERR);
                   12738:     }
                   12739:     if (asc_dvc->bus_type == ASC_IS_PCI) {
                   12740:         PCIVendorID = AscReadPCIConfigWord(asc_dvc,
                   12741:                                     AscPCIConfigVendorIDRegister);
                   12742: 
                   12743:         PCIDeviceID = AscReadPCIConfigWord(asc_dvc,
                   12744:                                     AscPCIConfigDeviceIDRegister);
                   12745: 
                   12746:         PCIRevisionID = DvcReadPCIConfigByte(asc_dvc,
                   12747:                                     AscPCIConfigRevisionIDRegister);
                   12748: 
                   12749:         if (PCIVendorID != ASC_PCI_VENDORID) {
                   12750:             warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
                   12751:         }
                   12752:         prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc,
                   12753:                                     AscPCIConfigCommandRegister);
                   12754: 
                   12755:         if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster) !=
                   12756:             AscPCICmdRegBits_IOMemBusMaster) {
                   12757:             DvcWritePCIConfigByte(asc_dvc,
                   12758:                             AscPCIConfigCommandRegister,
                   12759:                             (prevCmdRegBits |
                   12760:                              AscPCICmdRegBits_IOMemBusMaster));
                   12761: 
                   12762:             if ((DvcReadPCIConfigByte(asc_dvc,
                   12763:                                 AscPCIConfigCommandRegister)
                   12764:                  & AscPCICmdRegBits_IOMemBusMaster)
                   12765:                 != AscPCICmdRegBits_IOMemBusMaster) {
                   12766:                 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
                   12767:             }
                   12768:         }
                   12769:         if ((PCIDeviceID == ASC_PCI_DEVICEID_1200A) ||
                   12770:             (PCIDeviceID == ASC_PCI_DEVICEID_1200B)) {
                   12771:             DvcWritePCIConfigByte(asc_dvc,
                   12772:                             AscPCIConfigLatencyTimer, 0x00);
                   12773:             if (DvcReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer)
                   12774:                 != 0x00) {
                   12775:                 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
                   12776:             }
                   12777:         } else if (PCIDeviceID == ASC_PCI_DEVICEID_ULTRA) {
                   12778:             if (DvcReadPCIConfigByte(asc_dvc,
                   12779:                                 AscPCIConfigLatencyTimer) < 0x20) {
                   12780:                 DvcWritePCIConfigByte(asc_dvc,
                   12781:                                     AscPCIConfigLatencyTimer, 0x20);
                   12782: 
                   12783:                 if (DvcReadPCIConfigByte(asc_dvc,
                   12784:                                     AscPCIConfigLatencyTimer) < 0x20) {
                   12785:                     warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
                   12786:                 }
                   12787:             }
                   12788:         }
                   12789:     }
                   12790: 
                   12791:     if (AscFindSignature(iop_base)) {
                   12792:         warn_code |= AscInitAscDvcVar(asc_dvc);
                   12793:         warn_code |= AscInitFromEEP(asc_dvc);
                   12794:         asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
                   12795:         if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) {
                   12796:             asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
                   12797:         }
                   12798:     } else {
                   12799:         asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
                   12800:     }
                   12801:     return(warn_code);
                   12802: }
                   12803: 
                   12804: ASC_INITFUNC(
                   12805: STATIC ushort
                   12806: AscInitSetConfig(
                   12807:                     ASC_DVC_VAR asc_ptr_type * asc_dvc
                   12808: )
                   12809: )
                   12810: {
                   12811:     ushort              warn_code = 0;
                   12812: 
                   12813:     asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
                   12814:     if (asc_dvc->err_code != 0)
                   12815:         return (UW_ERR);
                   12816:     if (AscFindSignature(asc_dvc->iop_base)) {
                   12817:         warn_code |= AscInitFromAscDvcVar(asc_dvc);
                   12818:         asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
                   12819:     } else {
                   12820:         asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
                   12821:     }
                   12822:     return (warn_code);
                   12823: }
                   12824: 
                   12825: ASC_INITFUNC(
                   12826: STATIC ushort
                   12827: AscInitFromAscDvcVar(
                   12828:                         ASC_DVC_VAR asc_ptr_type * asc_dvc
                   12829: )
                   12830: )
                   12831: {
                   12832:     PortAddr            iop_base;
                   12833:     ushort              cfg_msw;
                   12834:     ushort              warn_code;
                   12835:     ushort              pci_device_id;
                   12836: 
                   12837:     iop_base = asc_dvc->iop_base;
                   12838:     pci_device_id = asc_dvc->cfg->pci_device_id;
                   12839:     warn_code = 0;
                   12840:     cfg_msw = AscGetChipCfgMsw(iop_base);
                   12841:     if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
                   12842:         cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
                   12843:         warn_code |= ASC_WARN_CFG_MSW_RECOVER;
                   12844:         AscSetChipCfgMsw(iop_base, cfg_msw);
                   12845:     }
                   12846:     if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
                   12847:         asc_dvc->cfg->cmd_qng_enabled) {
                   12848:         asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
                   12849:         warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
                   12850:     }
                   12851:     if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
                   12852:         warn_code |= ASC_WARN_AUTO_CONFIG;
                   12853:     }
                   12854:     if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
                   12855:         if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
                   12856:             != asc_dvc->irq_no) {
                   12857:             asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
                   12858:         }
                   12859:     }
                   12860:     if (asc_dvc->bus_type & ASC_IS_PCI) {
                   12861:         cfg_msw &= 0xFFC0;
                   12862:         AscSetChipCfgMsw(iop_base, cfg_msw);
                   12863:         if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
                   12864:         } else {
                   12865:             if ((pci_device_id == ASC_PCI_DEVICE_ID_REV_A) ||
                   12866:                 (pci_device_id == ASC_PCI_DEVICE_ID_REV_B)) {
                   12867:                 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
                   12868:                 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
                   12869:             }
                   12870:         }
                   12871:     } else if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
                   12872:         if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
                   12873:             == ASC_CHIP_VER_ASYN_BUG) {
                   12874:             asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
                   12875:         }
                   12876:     }
                   12877:     if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
                   12878:         asc_dvc->cfg->chip_scsi_id) {
                   12879:         asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
                   12880:     }
                   12881:     if (asc_dvc->bus_type & ASC_IS_ISA) {
                   12882:         AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
                   12883:         AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
                   12884:     }
                   12885:     return (warn_code);
                   12886: }
                   12887: 
                   12888: ASC_INITFUNC(
                   12889: STATIC ushort
                   12890: AscInitAsc1000Driver(
                   12891:                         ASC_DVC_VAR asc_ptr_type * asc_dvc
                   12892: )
                   12893: )
                   12894: {
                   12895:     ushort              warn_code;
                   12896:     PortAddr            iop_base;
                   12897:     extern ushort       _asc_mcode_size;
                   12898:     extern ulong        _asc_mcode_chksum;
                   12899:     extern uchar        _asc_mcode_buf[];
                   12900: 
                   12901:     iop_base = asc_dvc->iop_base;
                   12902:     warn_code = 0;
                   12903:     if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
                   12904:         !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
                   12905:         AscResetChipAndScsiBus(asc_dvc);
                   12906:         DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
                   12907:     }
                   12908:     asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
                   12909:     if (asc_dvc->err_code != 0)
                   12910:         return (UW_ERR);
                   12911:     if (!AscFindSignature(asc_dvc->iop_base)) {
                   12912:         asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
                   12913:         return (warn_code);
                   12914:     }
                   12915:     AscDisableInterrupt(iop_base);
                   12916:     warn_code |= AscInitLram(asc_dvc);
                   12917:     if (asc_dvc->err_code != 0)
                   12918:         return (UW_ERR);
                   12919:     if (AscLoadMicroCode(iop_base, 0, (ushort *) _asc_mcode_buf,
                   12920:                          _asc_mcode_size) != _asc_mcode_chksum) {
                   12921:         asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
                   12922:         return (warn_code);
                   12923:     }
                   12924:     warn_code |= AscInitMicroCodeVar(asc_dvc);
                   12925:     asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
                   12926:     AscEnableInterrupt(iop_base);
                   12927:     return (warn_code);
                   12928: }
                   12929: 
                   12930: ASC_INITFUNC(
                   12931: STATIC ushort
                   12932: AscInitAscDvcVar(
                   12933:                     ASC_DVC_VAR asc_ptr_type * asc_dvc
                   12934: )
                   12935: )
                   12936: {
                   12937:     int                 i;
                   12938:     PortAddr            iop_base;
                   12939:     ushort              warn_code;
                   12940:     uchar               chip_version;
                   12941: 
                   12942:     iop_base = asc_dvc->iop_base;
                   12943:     warn_code = 0;
                   12944:     asc_dvc->err_code = 0;
                   12945:     if ((asc_dvc->bus_type &
                   12946:          (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
                   12947:         asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
                   12948:     }
                   12949:     AscSetChipControl(iop_base, CC_HALT);
                   12950:     AscSetChipStatus(iop_base, 0);
                   12951:     asc_dvc->bug_fix_cntl = 0;
                   12952:     asc_dvc->pci_fix_asyn_xfer = 0;
                   12953:     asc_dvc->pci_fix_asyn_xfer_always = 0;
                   12954:     asc_dvc->init_state = 0;
                   12955:     asc_dvc->sdtr_done = 0;
                   12956:     asc_dvc->cur_total_qng = 0;
                   12957:     asc_dvc->is_in_int = 0;
                   12958:     asc_dvc->in_critical_cnt = 0;
                   12959:     asc_dvc->last_q_shortage = 0;
                   12960:     asc_dvc->use_tagged_qng = 0;
                   12961:     asc_dvc->no_scam = 0;
                   12962:     asc_dvc->unit_not_ready = 0;
                   12963:     asc_dvc->queue_full_or_busy = 0;
                   12964:     asc_dvc->redo_scam = 0 ;
                   12965:     asc_dvc->res2 = 0 ;
                   12966:     asc_dvc->host_init_sdtr_index = 0 ;
                   12967:     asc_dvc->res7 = 0 ;
                   12968:     asc_dvc->res8 = 0 ;
                   12969:     asc_dvc->cfg->can_tagged_qng = 0 ;
                   12970:     asc_dvc->cfg->cmd_qng_enabled = 0;
                   12971:     asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
                   12972:     asc_dvc->init_sdtr = 0;
                   12973:     asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
                   12974:     asc_dvc->scsi_reset_wait = 3;
                   12975:     asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
                   12976:     asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
                   12977:     asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
                   12978:     asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
                   12979:     asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
                   12980:     asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
                   12981:     asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
                   12982:       ASC_LIB_VERSION_MINOR;
                   12983:     chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
                   12984:     asc_dvc->cfg->chip_version = chip_version;
                   12985:     asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
                   12986:     asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
                   12987:     asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
                   12988:     asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
                   12989:     asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
                   12990:     asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
                   12991:     asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
                   12992:     asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
                   12993:     asc_dvc->max_sdtr_index = 7;
                   12994:     if ((asc_dvc->bus_type & ASC_IS_PCI) &&
                   12995:         (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
                   12996:         asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
                   12997:         asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
                   12998:         asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
                   12999:         asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
                   13000:         asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
                   13001:         asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
                   13002:         asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
                   13003:         asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
                   13004:         asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
                   13005:         asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
                   13006:         asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
                   13007:         asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
                   13008:         asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
                   13009:         asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
                   13010:         asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
                   13011:         asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
                   13012:         asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
                   13013:         asc_dvc->max_sdtr_index = 15;
                   13014:         if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150)
                   13015:         {
                   13016:             AscSetExtraControl(iop_base,
                   13017:                 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
                   13018:         } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
                   13019:             AscSetExtraControl(iop_base,
                   13020:                 (SEC_ACTIVE_NEGATE | SEC_ENABLE_FILTER));
                   13021:         }
                   13022:     }
                   13023:     if (asc_dvc->bus_type == ASC_IS_PCI) {
                   13024:            AscSetExtraControl(iop_base, (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
                   13025:     }
                   13026: 
                   13027:     asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
                   13028:     if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
                   13029:         AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
                   13030:         asc_dvc->bus_type = ASC_IS_ISAPNP;
                   13031:     }
                   13032:     if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
                   13033:         asc_dvc->cfg->isa_dma_channel = (uchar) AscGetIsaDmaChannel(iop_base);
                   13034:     }
                   13035:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   13036:         asc_dvc->cur_dvc_qng[i] = 0;
                   13037:         asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
                   13038:         asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *) 0L;
                   13039:         asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *) 0L;
                   13040:         asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
                   13041:     }
                   13042:     return (warn_code);
                   13043: }
                   13044: 
                   13045: ASC_INITFUNC(
                   13046: STATIC ushort
                   13047: AscInitFromEEP(
                   13048:                   ASC_DVC_VAR asc_ptr_type * asc_dvc
                   13049: )
                   13050: )
                   13051: {
                   13052:     ASCEEP_CONFIG       eep_config_buf;
                   13053:     ASCEEP_CONFIG       *eep_config;
                   13054:     PortAddr            iop_base;
                   13055:     ushort              chksum;
                   13056:     ushort              warn_code;
                   13057:     ushort              cfg_msw, cfg_lsw;
                   13058:     int                 i;
                   13059:     int                 write_eep = 0;
                   13060: 
                   13061:     iop_base = asc_dvc->iop_base;
                   13062:     warn_code = 0;
                   13063:     AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
                   13064:     AscStopQueueExe(iop_base);
                   13065:     if ((AscStopChip(iop_base) == FALSE) ||
                   13066:         (AscGetChipScsiCtrl(iop_base) != 0)) {
                   13067:         asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
                   13068:         AscResetChipAndScsiBus(asc_dvc);
                   13069:         DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
                   13070:     }
                   13071:     if (AscIsChipHalted(iop_base) == FALSE) {
                   13072:         asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
                   13073:         return (warn_code);
                   13074:     }
                   13075:     AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
                   13076:     if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
                   13077:         asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
                   13078:         return (warn_code);
                   13079:     }
                   13080:     eep_config = (ASCEEP_CONFIG *) & eep_config_buf;
                   13081:     cfg_msw = AscGetChipCfgMsw(iop_base);
                   13082:     cfg_lsw = AscGetChipCfgLsw(iop_base);
                   13083:     if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
                   13084:         cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
                   13085:         warn_code |= ASC_WARN_CFG_MSW_RECOVER;
                   13086:         AscSetChipCfgMsw(iop_base, cfg_msw);
                   13087:     }
                   13088:     chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
                   13089:     if (chksum == 0) {
                   13090:         chksum = 0xaa55;
                   13091:     }
                   13092:     if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
                   13093:         warn_code |= ASC_WARN_AUTO_CONFIG;
                   13094:         if (asc_dvc->cfg->chip_version == 3) {
                   13095:             if (eep_config->cfg_lsw != cfg_lsw) {
                   13096:                 warn_code |= ASC_WARN_EEPROM_RECOVER;
                   13097:                 eep_config->cfg_lsw = AscGetChipCfgLsw(iop_base);
                   13098:             }
                   13099:             if (eep_config->cfg_msw != cfg_msw) {
                   13100:                 warn_code |= ASC_WARN_EEPROM_RECOVER;
                   13101:                 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
                   13102:             }
                   13103:         }
                   13104:     }
                   13105:     eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
                   13106:     eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
                   13107:     if (chksum != eep_config->chksum) {
                   13108:             if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
                   13109:                     ASC_CHIP_VER_PCI_ULTRA_3050 )
                   13110:             {
                   13111:                 eep_config->init_sdtr = 0xFF;
                   13112:                 eep_config->disc_enable = 0xFF;
                   13113:                 eep_config->start_motor = 0xFF;
                   13114:                 eep_config->use_cmd_qng = 0;
                   13115:                 eep_config->max_total_qng = 0xF0;
                   13116:                 eep_config->max_tag_qng = 0x20;
                   13117:                 eep_config->cntl = 0xBFFF;
                   13118:                 eep_config->chip_scsi_id = 7;
                   13119:                 eep_config->no_scam = 0;
                   13120:                 eep_config->adapter_info[0] = 0;
                   13121:                 eep_config->adapter_info[1] = 0;
                   13122:                 eep_config->adapter_info[2] = 0;
                   13123:                 eep_config->adapter_info[3] = 0;
                   13124:                 eep_config->adapter_info[4] = 0;
                   13125:                 /* Indicate EEPROM-less board. */
                   13126:                 eep_config->adapter_info[5] = 0xBB;
                   13127:             } else {
                   13128:                 write_eep = 1 ;
                   13129:                 warn_code |= ASC_WARN_EEPROM_CHKSUM ;
                   13130:             }
                   13131:     }
                   13132:     asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr ;
                   13133:     asc_dvc->cfg->disc_enable = eep_config->disc_enable;
                   13134:     asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
                   13135:     asc_dvc->cfg->isa_dma_speed = eep_config->isa_dma_speed;
                   13136:     asc_dvc->start_motor = eep_config->start_motor;
                   13137:     asc_dvc->dvc_cntl = eep_config->cntl;
                   13138:     asc_dvc->no_scam = eep_config->no_scam;
                   13139:     asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
                   13140:     asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
                   13141:     asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
                   13142:     asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
                   13143:     asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
                   13144:     asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
                   13145:     if (!AscTestExternalLram(asc_dvc)) {
                   13146:         if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA)) {
                   13147:             eep_config->max_total_qng = ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
                   13148:             eep_config->max_tag_qng = ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
                   13149:         } else {
                   13150:             eep_config->cfg_msw |= 0x0800;
                   13151:             cfg_msw |= 0x0800;
                   13152:             AscSetChipCfgMsw(iop_base, cfg_msw);
                   13153:             eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
                   13154:             eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
                   13155:         }
                   13156:     } else {
                   13157:     }
                   13158:     if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
                   13159:         eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
                   13160:     }
                   13161:     if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
                   13162:         eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
                   13163:     }
                   13164:     if (eep_config->max_tag_qng > eep_config->max_total_qng) {
                   13165:         eep_config->max_tag_qng = eep_config->max_total_qng;
                   13166:     }
                   13167:     if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
                   13168:         eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
                   13169:     }
                   13170:     asc_dvc->max_total_qng = eep_config->max_total_qng;
                   13171:     if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
                   13172:         eep_config->use_cmd_qng) {
                   13173:         eep_config->disc_enable = eep_config->use_cmd_qng;
                   13174:         warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
                   13175:     }
                   13176:     if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
                   13177:         asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
                   13178:     }
                   13179:     eep_config->chip_scsi_id &= ASC_MAX_TID;
                   13180:     asc_dvc->cfg->chip_scsi_id = eep_config->chip_scsi_id;
                   13181:     if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
                   13182:         !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
                   13183:         asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
                   13184:     }
                   13185: 
                   13186:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   13187:         asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
                   13188:         asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
                   13189:         asc_dvc->cfg->sdtr_period_offset[i] =
                   13190:             (uchar) (ASC_DEF_SDTR_OFFSET |
                   13191:                      (asc_dvc->host_init_sdtr_index << 4));
                   13192:     }
                   13193:     eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
                   13194:     if (write_eep) {
                   13195:         (void) AscSetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
                   13196:     }
                   13197:     return (warn_code);
                   13198: }
                   13199: 
                   13200: ASC_INITFUNC(
                   13201: STATIC ushort
                   13202: AscInitMicroCodeVar(
                   13203:                        ASC_DVC_VAR asc_ptr_type * asc_dvc
                   13204: )
                   13205: )
                   13206: {
                   13207:     int                 i;
                   13208:     ushort              warn_code;
                   13209:     PortAddr            iop_base;
                   13210:     ulong               phy_addr;
                   13211: 
                   13212:     iop_base = asc_dvc->iop_base;
                   13213:     warn_code = 0;
                   13214:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   13215:         AscPutMCodeInitSDTRAtID(iop_base, i,
                   13216:                                 asc_dvc->cfg->sdtr_period_offset[i]
                   13217: );
                   13218:     }
                   13219:     AscInitQLinkVar(asc_dvc);
                   13220:     AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
                   13221:                      asc_dvc->cfg->disc_enable);
                   13222:     AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
                   13223:                      ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
                   13224:     if ((phy_addr = AscGetOnePhyAddr(asc_dvc,
                   13225:                                  (uchar *) asc_dvc->cfg->overrun_buf,
                   13226:                                      ASC_OVERRUN_BSIZE)) == 0L) {
                   13227:         asc_dvc->err_code |= ASC_IERR_GET_PHY_ADDR;
                   13228:     } else {
                   13229:         phy_addr = (phy_addr & 0xFFFFFFF8UL) + 8;
                   13230:         AscWriteLramDWord(iop_base, ASCV_OVERRUN_PADDR_D, phy_addr);
                   13231:         AscWriteLramDWord(iop_base, ASCV_OVERRUN_BSIZE_D,
                   13232:                           ASC_OVERRUN_BSIZE - 8);
                   13233:     }
                   13234:     asc_dvc->cfg->mcode_date = AscReadLramWord(iop_base,
                   13235:                                                (ushort) ASCV_MC_DATE_W);
                   13236:     asc_dvc->cfg->mcode_version = AscReadLramWord(iop_base,
                   13237:                                                   (ushort) ASCV_MC_VER_W);
                   13238:     AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
                   13239:     if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
                   13240:         asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
                   13241:         return (warn_code);
                   13242:     }
                   13243:     if (AscStartChip(iop_base) != 1) {
                   13244:         asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
                   13245:         return (warn_code);
                   13246:     }
                   13247:     return (warn_code);
                   13248: }
                   13249: 
                   13250: ASC_INITFUNC(
                   13251: STATIC int
                   13252: AscTestExternalLram(
                   13253:                        ASC_DVC_VAR asc_ptr_type * asc_dvc
                   13254: )
                   13255: )
                   13256: {
                   13257:     PortAddr            iop_base;
                   13258:     ushort              q_addr;
                   13259:     ushort              saved_word;
                   13260:     int                 sta;
                   13261: 
                   13262:     iop_base = asc_dvc->iop_base;
                   13263:     sta = 0;
                   13264:     q_addr = ASC_QNO_TO_QADDR(241);
                   13265:     saved_word = AscReadLramWord(iop_base, q_addr);
                   13266:     AscSetChipLramAddr(iop_base, q_addr);
                   13267:     AscSetChipLramData(iop_base, 0x55AA);
                   13268:     DvcSleepMilliSecond(10);
                   13269:     AscSetChipLramAddr(iop_base, q_addr);
                   13270:     if (AscGetChipLramData(iop_base) == 0x55AA) {
                   13271:         sta = 1;
                   13272:         AscWriteLramWord(iop_base, q_addr, saved_word);
                   13273:     }
                   13274:     return (sta);
                   13275: }
                   13276: 
                   13277: ASC_INITFUNC(
                   13278: STATIC int
                   13279: AscWriteEEPCmdReg(
                   13280:                      PortAddr iop_base,
                   13281:                      uchar cmd_reg
                   13282: )
                   13283: )
                   13284: {
                   13285:     uchar               read_back;
                   13286:     int                 retry;
                   13287: 
                   13288:     retry = 0;
                   13289:     while (TRUE) {
                   13290:         AscSetChipEEPCmd(iop_base, cmd_reg);
                   13291:         DvcSleepMilliSecond(1);
                   13292:         read_back = AscGetChipEEPCmd(iop_base);
                   13293:         if (read_back == cmd_reg) {
                   13294:             return (1);
                   13295:         }
                   13296:         if (retry++ > ASC_EEP_MAX_RETRY) {
                   13297:             return (0);
                   13298:         }
                   13299:     }
                   13300: }
                   13301: 
                   13302: ASC_INITFUNC(
                   13303: STATIC int
                   13304: AscWriteEEPDataReg(
                   13305:                       PortAddr iop_base,
                   13306:                       ushort data_reg
                   13307: )
                   13308: )
                   13309: {
                   13310:     ushort              read_back;
                   13311:     int                 retry;
                   13312: 
                   13313:     retry = 0;
                   13314:     while (TRUE) {
                   13315:         AscSetChipEEPData(iop_base, data_reg);
                   13316:         DvcSleepMilliSecond(1);
                   13317:         read_back = AscGetChipEEPData(iop_base);
                   13318:         if (read_back == data_reg) {
                   13319:             return (1);
                   13320:         }
                   13321:         if (retry++ > ASC_EEP_MAX_RETRY) {
                   13322:             return (0);
                   13323:         }
                   13324:     }
                   13325: }
                   13326: 
                   13327: ASC_INITFUNC(
                   13328: STATIC void
                   13329: AscWaitEEPRead(
                   13330:                   void
                   13331: )
                   13332: )
                   13333: {
                   13334:     DvcSleepMilliSecond(1);
                   13335:     return;
                   13336: }
                   13337: 
                   13338: ASC_INITFUNC(
                   13339: STATIC void
                   13340: AscWaitEEPWrite(
                   13341:                    void
                   13342: )
                   13343: )
                   13344: {
                   13345:     DvcSleepMilliSecond(20);
                   13346:     return;
                   13347: }
                   13348: 
                   13349: ASC_INITFUNC(
                   13350: STATIC ushort
                   13351: AscReadEEPWord(
                   13352:                   PortAddr iop_base,
                   13353:                   uchar addr
                   13354: )
                   13355: )
                   13356: {
                   13357:     ushort              read_wval;
                   13358:     uchar               cmd_reg;
                   13359: 
                   13360:     AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
                   13361:     AscWaitEEPRead();
                   13362:     cmd_reg = addr | ASC_EEP_CMD_READ;
                   13363:     AscWriteEEPCmdReg(iop_base, cmd_reg);
                   13364:     AscWaitEEPRead();
                   13365:     read_wval = AscGetChipEEPData(iop_base);
                   13366:     AscWaitEEPRead();
                   13367:     return (read_wval);
                   13368: }
                   13369: 
                   13370: ASC_INITFUNC(
                   13371: STATIC ushort
                   13372: AscWriteEEPWord(
                   13373:                    PortAddr iop_base,
                   13374:                    uchar addr,
                   13375:                    ushort word_val
                   13376: )
                   13377: )
                   13378: {
                   13379:     ushort              read_wval;
                   13380: 
                   13381:     read_wval = AscReadEEPWord(iop_base, addr);
                   13382:     if (read_wval != word_val) {
                   13383:         AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
                   13384:         AscWaitEEPRead();
                   13385:         AscWriteEEPDataReg(iop_base, word_val);
                   13386:         AscWaitEEPRead();
                   13387:         AscWriteEEPCmdReg(iop_base,
                   13388:                           (uchar) ((uchar) ASC_EEP_CMD_WRITE | addr));
                   13389:         AscWaitEEPWrite();
                   13390:         AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
                   13391:         AscWaitEEPRead();
                   13392:         return (AscReadEEPWord(iop_base, addr));
                   13393:     }
                   13394:     return (read_wval);
                   13395: }
                   13396: 
                   13397: ASC_INITFUNC(
                   13398: STATIC ushort
                   13399: AscGetEEPConfig(
                   13400:                    PortAddr iop_base,
                   13401:                    ASCEEP_CONFIG * cfg_buf, ushort bus_type
                   13402: )
                   13403: )
                   13404: {
                   13405:     ushort              wval;
                   13406:     ushort              sum;
                   13407:     ushort      *wbuf;
                   13408:     int                 cfg_beg;
                   13409:     int                 cfg_end;
                   13410:     int                 s_addr;
                   13411:     int                 isa_pnp_wsize;
                   13412: 
                   13413:     wbuf = (ushort *) cfg_buf;
                   13414:     sum = 0;
                   13415:     isa_pnp_wsize = 0;
                   13416:     for (s_addr = 0; s_addr < (2 + isa_pnp_wsize); s_addr++, wbuf++) {
                   13417:         wval = AscReadEEPWord(iop_base, (uchar) s_addr);
                   13418:         sum += wval;
                   13419:         *wbuf = wval;
                   13420:     }
                   13421:     if (bus_type & ASC_IS_VL) {
                   13422:         cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
                   13423:         cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
                   13424:     } else {
                   13425:         cfg_beg = ASC_EEP_DVC_CFG_BEG;
                   13426:         cfg_end = ASC_EEP_MAX_DVC_ADDR;
                   13427:     }
                   13428:     for (s_addr = cfg_beg; s_addr <= (cfg_end - 1);
                   13429:          s_addr++, wbuf++) {
                   13430:         wval = AscReadEEPWord(iop_base, (uchar) s_addr);
                   13431:         sum += wval;
                   13432:         *wbuf = wval;
                   13433:     }
                   13434:     *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
                   13435:     return (sum);
                   13436: }
                   13437: 
                   13438: ASC_INITFUNC(
                   13439: STATIC int
                   13440: AscSetEEPConfigOnce(
                   13441:                        PortAddr iop_base,
                   13442:                        ASCEEP_CONFIG * cfg_buf, ushort bus_type
                   13443: )
                   13444: )
                   13445: {
                   13446:     int                 n_error;
                   13447:     ushort      *wbuf;
                   13448:     ushort              sum;
                   13449:     int                 s_addr;
                   13450:     int                 cfg_beg;
                   13451:     int                 cfg_end;
                   13452: 
                   13453:     wbuf = (ushort *) cfg_buf;
                   13454:     n_error = 0;
                   13455:     sum = 0;
                   13456:     for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
                   13457:         sum += *wbuf;
                   13458:         if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
                   13459:             n_error++;
                   13460:         }
                   13461:     }
                   13462:     if (bus_type & ASC_IS_VL) {
                   13463:         cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
                   13464:         cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
                   13465:     } else {
                   13466:         cfg_beg = ASC_EEP_DVC_CFG_BEG;
                   13467:         cfg_end = ASC_EEP_MAX_DVC_ADDR;
                   13468:     }
                   13469:     for (s_addr = cfg_beg; s_addr <= (cfg_end - 1);
                   13470:          s_addr++, wbuf++) {
                   13471:         sum += *wbuf;
                   13472:         if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
                   13473:             n_error++;
                   13474:         }
                   13475:     }
                   13476:     *wbuf = sum;
                   13477:     if (sum != AscWriteEEPWord(iop_base, (uchar) s_addr, sum)) {
                   13478:         n_error++;
                   13479:     }
                   13480:     wbuf = (ushort *) cfg_buf;
                   13481:     for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
                   13482:         if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
                   13483:             n_error++;
                   13484:         }
                   13485:     }
                   13486:     for (s_addr = cfg_beg; s_addr <= cfg_end;
                   13487:          s_addr++, wbuf++) {
                   13488:         if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
                   13489:             n_error++;
                   13490:         }
                   13491:     }
                   13492:     return (n_error);
                   13493: }
                   13494: 
                   13495: ASC_INITFUNC(
                   13496: STATIC int
                   13497: AscSetEEPConfig(
                   13498:                    PortAddr iop_base,
                   13499:                    ASCEEP_CONFIG * cfg_buf, ushort bus_type
                   13500: )
                   13501: )
                   13502: {
                   13503:     int            retry;
                   13504:     int            n_error;
                   13505: 
                   13506:     retry = 0;
                   13507:     while (TRUE) {
                   13508:         if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
                   13509:                                            bus_type)) == 0) {
                   13510:             break;
                   13511:         }
                   13512:         if (++retry > ASC_EEP_MAX_RETRY) {
                   13513:             break;
                   13514:         }
                   13515:     }
                   13516:     return (n_error);
                   13517: }
                   13518: 
                   13519: STATIC void
                   13520: AscAsyncFix(
                   13521:                ASC_DVC_VAR asc_ptr_type *asc_dvc,
                   13522:                uchar tid_no,
                   13523:                ASC_SCSI_INQUIRY *inq)
                   13524: {
                   13525:     uchar                dvc_type;
                   13526:     ASC_SCSI_BIT_ID_TYPE tid_bits;
                   13527: 
                   13528:     dvc_type = inq->byte0.peri_dvc_type;
                   13529:     tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
                   13530: 
                   13531:     if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) {
                   13532:         if (!(asc_dvc->init_sdtr & tid_bits)) {
                   13533:             if ((dvc_type == SCSI_TYPE_CDROM) &&
                   13534:                 (AscCompareString((uchar *) inq->vendor_id,
                   13535:                     (uchar *) "HP ", 3) == 0)) {
                   13536:                 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
                   13537:             }
                   13538:             asc_dvc->pci_fix_asyn_xfer |= tid_bits;
                   13539:             if ((dvc_type == SCSI_TYPE_PROC) ||
                   13540:                 (dvc_type == SCSI_TYPE_SCANNER)) {
                   13541:                 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
                   13542:             }
                   13543:             if ((dvc_type == SCSI_TYPE_SASD) &&
                   13544:                 (AscCompareString((uchar *) inq->vendor_id,
                   13545:                  (uchar *) "TANDBERG", 8) == 0) &&
                   13546:                 (AscCompareString((uchar *) inq->product_id,
                   13547:                  (uchar *) " TDC 36", 7) == 0)) {
                   13548:                 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
                   13549:             }
                   13550:             if ((dvc_type == SCSI_TYPE_SASD) &&
                   13551:                 (AscCompareString((uchar *) inq->vendor_id,
                   13552:                  (uchar *) "WANGTEK ", 8) == 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 *) "NEC     ", 8) == 0) &&
                   13559:                 (AscCompareString((uchar *) inq->product_id,
                   13560:                  (uchar *) "CD-ROM DRIVE    ", 16) == 0)) {
                   13561:                 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
                   13562:             }
                   13563: 
                   13564:             if ((dvc_type == SCSI_TYPE_CDROM) &&
                   13565:                 (AscCompareString((uchar *) inq->vendor_id,
                   13566:                  (uchar *) "YAMAHA", 6) == 0) &&
                   13567:                 (AscCompareString((uchar *) inq->product_id,
                   13568:                  (uchar *) "CDR400", 6) == 0)) {
                   13569:                 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
                   13570:             }
                   13571:             if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
                   13572:                 AscSetRunChipSynRegAtID(asc_dvc->iop_base, tid_no,
                   13573:                                         ASYN_SDTR_DATA_FIX_PCI_REV_AB);
                   13574:             }
                   13575:         }
                   13576:     }
                   13577:     return;
                   13578: }
                   13579: 
                   13580: STATIC int
                   13581: AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq)
                   13582: {
                   13583:     if ((inq->add_len >= 32) &&
                   13584:         (AscCompareString((uchar *) inq->vendor_id,
                   13585:             (uchar *) "QUANTUM XP34301", 15) == 0) &&
                   13586:         (AscCompareString((uchar *) inq->product_rev_level,
                   13587:             (uchar *) "1071", 4) == 0))
                   13588:     {
                   13589:         return 0;
                   13590:     }
                   13591:     return 1;
                   13592: }
                   13593: 
                   13594: STATIC void
                   13595: AscInquiryHandling(ASC_DVC_VAR asc_ptr_type *asc_dvc,
                   13596:                    uchar tid_no, ASC_SCSI_INQUIRY *inq)
                   13597: {
                   13598:     ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no);
                   13599:     ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng;
                   13600: 
                   13601:     orig_init_sdtr = asc_dvc->init_sdtr;
                   13602:     orig_use_tagged_qng = asc_dvc->use_tagged_qng;
                   13603: 
                   13604:     asc_dvc->init_sdtr &= ~tid_bit;
                   13605:     asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
                   13606:     asc_dvc->use_tagged_qng &= ~tid_bit;
                   13607: 
                   13608:     if (inq->byte3.rsp_data_fmt >= 2 || inq->byte2.ansi_apr_ver >= 2) {
                   13609:         if ((asc_dvc->cfg->sdtr_enable & tid_bit) && inq->byte7.Sync) {
                   13610:             asc_dvc->init_sdtr |= tid_bit;
                   13611:         }
                   13612:         if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) && inq->byte7.CmdQue) {
                   13613:             if (AscTagQueuingSafe(inq)) {
                   13614:                 asc_dvc->use_tagged_qng |= tid_bit;
                   13615:                 asc_dvc->cfg->can_tagged_qng |= tid_bit;
                   13616:             }
                   13617:         }
                   13618:     }
                   13619:     if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) {
                   13620:         AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
                   13621:                          asc_dvc->cfg->disc_enable);
                   13622:         AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
                   13623:                          asc_dvc->use_tagged_qng);
                   13624:         AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
                   13625:                          asc_dvc->cfg->can_tagged_qng);
                   13626: 
                   13627:         asc_dvc->max_dvc_qng[tid_no] =
                   13628:           asc_dvc->cfg->max_tag_qng[tid_no];
                   13629:         AscWriteLramByte(asc_dvc->iop_base,
                   13630:                          (ushort) (ASCV_MAX_DVC_QNG_BEG + tid_no),
                   13631:                          asc_dvc->max_dvc_qng[tid_no]);
                   13632:     }
                   13633:     if (orig_init_sdtr != asc_dvc->init_sdtr) {
                   13634:         AscAsyncFix(asc_dvc, tid_no, inq);
                   13635:     }
                   13636:     return;
                   13637: }
                   13638: 
                   13639: STATIC int
                   13640: AscCompareString(
                   13641:                     ruchar * str1,
                   13642:                     ruchar * str2,
                   13643:                     int len
                   13644: )
                   13645: {
                   13646:     int                 i;
                   13647:     int                 diff;
                   13648: 
                   13649:     for (i = 0; i < len; i++) {
                   13650:         diff = (int) (str1[i] - str2[i]);
                   13651:         if (diff != 0)
                   13652:             return (diff);
                   13653:     }
                   13654:     return (0);
                   13655: }
                   13656: 
                   13657: STATIC uchar
                   13658: AscReadLramByte(
                   13659:                    PortAddr iop_base,
                   13660:                    ushort addr
                   13661: )
                   13662: {
                   13663:     uchar               byte_data;
                   13664:     ushort              word_data;
                   13665: 
                   13666:     if (isodd_word(addr)) {
                   13667:         AscSetChipLramAddr(iop_base, addr - 1);
                   13668:         word_data = AscGetChipLramData(iop_base);
                   13669:         byte_data = (uchar) ((word_data >> 8) & 0xFF);
                   13670:     } else {
                   13671:         AscSetChipLramAddr(iop_base, addr);
                   13672:         word_data = AscGetChipLramData(iop_base);
                   13673:         byte_data = (uchar) (word_data & 0xFF);
                   13674:     }
                   13675:     return (byte_data);
                   13676: }
                   13677: 
                   13678: STATIC ushort
                   13679: AscReadLramWord(
                   13680:                    PortAddr iop_base,
                   13681:                    ushort addr
                   13682: )
                   13683: {
                   13684:     ushort              word_data;
                   13685: 
                   13686:     AscSetChipLramAddr(iop_base, addr);
                   13687:     word_data = AscGetChipLramData(iop_base);
                   13688:     return (word_data);
                   13689: }
                   13690: 
                   13691: STATIC ulong
                   13692: AscReadLramDWord(
                   13693:                     PortAddr iop_base,
                   13694:                     ushort addr
                   13695: )
                   13696: {
                   13697:     ushort              val_low, val_high;
                   13698:     ulong               dword_data;
                   13699: 
                   13700:     AscSetChipLramAddr(iop_base, addr);
                   13701:     val_low = AscGetChipLramData(iop_base);
                   13702:     val_high = AscGetChipLramData(iop_base);
                   13703:     dword_data = ((ulong) val_high << 16) | (ulong) val_low;
                   13704:     return (dword_data);
                   13705: }
                   13706: 
                   13707: STATIC void
                   13708: AscWriteLramWord(
                   13709:                     PortAddr iop_base,
                   13710:                     ushort addr,
                   13711:                     ushort word_val
                   13712: )
                   13713: {
                   13714:     AscSetChipLramAddr(iop_base, addr);
                   13715:     AscSetChipLramData(iop_base, word_val);
                   13716:     return;
                   13717: }
                   13718: 
                   13719: STATIC void
                   13720: AscWriteLramDWord(
                   13721:                      PortAddr iop_base,
                   13722:                      ushort addr,
                   13723:                      ulong dword_val
                   13724: )
                   13725: {
                   13726:     ushort              word_val;
                   13727: 
                   13728:     AscSetChipLramAddr(iop_base, addr);
                   13729:     word_val = (ushort) dword_val;
                   13730:     AscSetChipLramData(iop_base, word_val);
                   13731:     word_val = (ushort) (dword_val >> 16);
                   13732:     AscSetChipLramData(iop_base, word_val);
                   13733:     return;
                   13734: }
                   13735: 
                   13736: STATIC void
                   13737: AscWriteLramByte(
                   13738:                     PortAddr iop_base,
                   13739:                     ushort addr,
                   13740:                     uchar byte_val
                   13741: )
                   13742: {
                   13743:     ushort              word_data;
                   13744: 
                   13745:     if (isodd_word(addr)) {
                   13746:         addr--;
                   13747:         word_data = AscReadLramWord(iop_base, addr);
                   13748:         word_data &= 0x00FF;
                   13749:         word_data |= (((ushort) byte_val << 8) & 0xFF00);
                   13750:     } else {
                   13751:         word_data = AscReadLramWord(iop_base, addr);
                   13752:         word_data &= 0xFF00;
                   13753:         word_data |= ((ushort) byte_val & 0x00FF);
                   13754:     }
                   13755:     AscWriteLramWord(iop_base, addr, word_data);
                   13756:     return;
                   13757: }
                   13758: 
                   13759: STATIC void
                   13760: AscMemWordCopyToLram(
                   13761:                         PortAddr iop_base,
                   13762:                         ushort s_addr,
                   13763:                         ushort * s_buffer,
                   13764:                         int words
                   13765: )
                   13766: {
                   13767:     AscSetChipLramAddr(iop_base, s_addr);
                   13768:     DvcOutPortWords(iop_base + IOP_RAM_DATA, s_buffer, words);
                   13769:     return;
                   13770: }
                   13771: 
                   13772: STATIC void
                   13773: AscMemDWordCopyToLram(
                   13774:                          PortAddr iop_base,
                   13775:                          ushort s_addr,
                   13776:                          ulong * s_buffer,
                   13777:                          int dwords
                   13778: )
                   13779: {
                   13780:     AscSetChipLramAddr(iop_base, s_addr);
                   13781:     DvcOutPortDWords(iop_base + IOP_RAM_DATA, s_buffer, dwords);
                   13782:     return;
                   13783: }
                   13784: 
                   13785: STATIC void
                   13786: AscMemWordCopyFromLram(
                   13787:                           PortAddr iop_base,
                   13788:                           ushort s_addr,
                   13789:                           ushort * d_buffer,
                   13790:                           int words
                   13791: )
                   13792: {
                   13793:     AscSetChipLramAddr(iop_base, s_addr);
                   13794:     DvcInPortWords(iop_base + IOP_RAM_DATA, d_buffer, words);
                   13795:     return;
                   13796: }
                   13797: 
                   13798: STATIC ulong
                   13799: AscMemSumLramWord(
                   13800:                      PortAddr iop_base,
                   13801:                      ushort s_addr,
                   13802:                      rint words
                   13803: )
                   13804: {
                   13805:     ulong               sum;
                   13806:     int                 i;
                   13807: 
                   13808:     sum = 0L;
                   13809:     for (i = 0; i < words; i++, s_addr += 2) {
                   13810:         sum += AscReadLramWord(iop_base, s_addr);
                   13811:     }
                   13812:     return (sum);
                   13813: }
                   13814: 
                   13815: STATIC void
                   13816: AscMemWordSetLram(
                   13817:                      PortAddr iop_base,
                   13818:                      ushort s_addr,
                   13819:                      ushort set_wval,
                   13820:                      rint words
                   13821: )
                   13822: {
                   13823:     rint             i;
                   13824: 
                   13825:     AscSetChipLramAddr(iop_base, s_addr);
                   13826:     for (i = 0; i < words; i++) {
                   13827:         AscSetChipLramData(iop_base, set_wval);
                   13828:     }
                   13829:     return;
                   13830: }
                   13831: 
                   13832: 
                   13833: /*
                   13834:  * --- Adv Library Functions
                   13835:  */
                   13836: 
                   13837: /* a_qswap.h */
                   13838: STATIC unsigned char _adv_mcode_buf[] ASC_INITDATA = {
                   13839:   0x9C,  0xF0,  0x80,  0x01,  0x00,  0xF0,  0x44,  0x0A,  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,  0x72,  0x01,  0xD6,  0x11,  0x00,  0x00,  0x70,  0x01,
                   13842:   0x30,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x90,  0x10,  0x2D,  0x03,  0x00,  0x00,  0x00,  0x00,
                   13843:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   13844:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   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,  0x00,  0x00,  0x00,  0x00,
                   13850:   0x48,  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:   0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,
                   13853:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   13854:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   13855:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   13856:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   13857:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x78,  0x56,  0x34,  0x12,
                   13858:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   13859:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   13860:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   13861:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   13862:   0x00,  0x00,  0x04,  0xF7,  0x70,  0x01,  0x0C,  0x1C,  0x06,  0xF7,  0x02,  0x00,  0x00,  0xF2,  0xD6,  0x0A,
                   13863:   0x04,  0xF7,  0x70,  0x01,  0x06,  0xF7,  0x02,  0x00,  0x3E,  0x57,  0x3C,  0x56,  0x0C,  0x1C,  0x00,  0xFC,
                   13864:   0xA6,  0x00,  0x01,  0x58,  0xAA,  0x13,  0x20,  0xF0,  0xA6,  0x03,  0x06,  0xEC,  0xB9,  0x00,  0x0E,  0x47,
                   13865:   0x03,  0xE6,  0x10,  0x00,  0xCE,  0x45,  0x02,  0x13,  0x3E,  0x57,  0x06,  0xEA,  0xB9,  0x00,  0x47,  0x4B,
                   13866:   0x03,  0xF6,  0xE0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x01,  0x48,  0x4E,  0x12,  0x03,  0xF6,  0xC0,  0x00,
                   13867:   0x00,  0xF2,  0x68,  0x0A,  0x41,  0x58,  0x03,  0xF6,  0xD0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x49,  0x44,
                   13868:   0x59,  0xF0,  0x0A,  0x02,  0x03,  0xF6,  0xE0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x44,  0x58,  0x00,  0xF2,
                   13869:   0xE2,  0x0D,  0x02,  0xCC,  0x4A,  0xE4,  0x01,  0x00,  0x55,  0xF0,  0x08,  0x03,  0x45,  0xF4,  0x02,  0x00,
                   13870:   0x83,  0x5A,  0x04,  0xCC,  0x01,  0x4A,  0x12,  0x12,  0x00,  0xF2,  0xE2,  0x0D,  0x00,  0xCD,  0x48,  0xE4,
                   13871:   0x01,  0x00,  0xE9,  0x13,  0x00,  0xF2,  0xC6,  0x0F,  0xFA,  0x10,  0x0E,  0x47,  0x03,  0xE6,  0x10,  0x00,
                   13872:   0xCE,  0x45,  0x02,  0x13,  0x3E,  0x57,  0xCE,  0x47,  0x97,  0x13,  0x04,  0xEC,  0xB4,  0x00,  0x00,  0xF2,
                   13873:   0xE2,  0x0D,  0x00,  0xCD,  0x48,  0xE4,  0x00,  0x00,  0x12,  0x12,  0x3E,  0x57,  0x06,  0xCC,  0x45,  0xF4,
                   13874:   0x02,  0x00,  0x83,  0x5A,  0x00,  0xCC,  0x00,  0xEA,  0xB4,  0x00,  0x92,  0x10,  0x00,  0xF0,  0x8C,  0x01,
                   13875:   0x43,  0xF0,  0x5C,  0x02,  0x44,  0xF0,  0x60,  0x02,  0x45,  0xF0,  0x64,  0x02,  0x46,  0xF0,  0x68,  0x02,
                   13876:   0x47,  0xF0,  0x6E,  0x02,  0x48,  0xF0,  0x9E,  0x02,  0xB9,  0x54,  0x62,  0x10,  0x00,  0x1C,  0x5A,  0x10,
                   13877:   0x02,  0x1C,  0x56,  0x10,  0x1E,  0x1C,  0x52,  0x10,  0x00,  0xF2,  0x1E,  0x11,  0x50,  0x10,  0x06,  0xFC,
                   13878:   0xA8,  0x00,  0x03,  0xF6,  0xBE,  0x00,  0x00,  0xF2,  0x4E,  0x0A,  0x8C,  0x10,  0x01,  0xF6,  0x01,  0x00,
                   13879:   0x01,  0xFA,  0xA8,  0x00,  0x00,  0xF2,  0x2C,  0x0B,  0x06,  0x10,  0xB9,  0x54,  0x01,  0xFA,  0xA8,  0x00,
                   13880:   0x03,  0xF6,  0xBE,  0x00,  0x00,  0xF2,  0x58,  0x0A,  0x01,  0xFC,  0xA8,  0x00,  0x20,  0x10,  0x58,  0x1C,
                   13881:   0x00,  0xF2,  0x1C,  0x0B,  0x5A,  0x1C,  0x01,  0xF6,  0x01,  0x00,  0x38,  0x54,  0x00,  0xFA,  0xA6,  0x00,
                   13882:   0x01,  0xFA,  0xA8,  0x00,  0x20,  0x1C,  0x00,  0xF0,  0x72,  0x01,  0x01,  0xF6,  0x01,  0x00,  0x38,  0x54,
                   13883:   0x00,  0xFA,  0xA6,  0x00,  0x01,  0xFA,  0xA8,  0x00,  0x20,  0x1C,  0x00,  0xF0,  0x80,  0x01,  0x03,  0xF6,
                   13884:   0xE0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x01,  0x48,  0x0A,  0x13,  0x00,  0xF2,  0x38,  0x10,  0x00,  0xF2,
                   13885:   0x54,  0x0F,  0x24,  0x10,  0x03,  0xF6,  0xC0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x02,  0xF6,  0xD0,  0x00,
                   13886:   0x02,  0x57,  0x03,  0x59,  0x01,  0xCC,  0x49,  0x44,  0x5B,  0xF0,  0x04,  0x03,  0x00,  0xF2,  0x9C,  0x0F,
                   13887:   0x00,  0xF0,  0x80,  0x01,  0x00,  0xF2,  0x14,  0x10,  0x0C,  0x1C,  0x02,  0x4B,  0xBF,  0x57,  0x9E,  0x43,
                   13888:   0x77,  0x57,  0x07,  0x4B,  0x20,  0xF0,  0xA6,  0x03,  0x40,  0x1C,  0x1E,  0xF0,  0x30,  0x03,  0x26,  0xF0,
                   13889:   0x2C,  0x03,  0xA0,  0xF0,  0x1A,  0x03,  0x11,  0xF0,  0xA6,  0x03,  0x12,  0x10,  0x9F,  0xF0,  0x3E,  0x03,
                   13890:   0x46,  0x1C,  0x82,  0xE7,  0x05,  0x00,  0x9E,  0xE7,  0x11,  0x00,  0x00,  0xF0,  0x06,  0x0A,  0x0C,  0x1C,
                   13891:   0x48,  0x1C,  0x46,  0x1C,  0x38,  0x54,  0x00,  0xEC,  0xBA,  0x00,  0x08,  0x44,  0x00,  0xEA,  0xBA,  0x00,
                   13892:   0x03,  0xF6,  0xC0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x08,  0x44,  0x00,  0x4C,  0x82,  0xE7,  0x02,  0x00,
                   13893:   0x00,  0xF2,  0x12,  0x11,  0x00,  0xF2,  0x12,  0x11,  0x85,  0xF0,  0x70,  0x03,  0x00,  0xF2,  0x60,  0x0B,
                   13894:   0x06,  0xF0,  0x80,  0x03,  0x09,  0xF0,  0x24,  0x09,  0x1E,  0xF0,  0xFC,  0x09,  0x00,  0xF0,  0x02,  0x0A,
                   13895:   0x00,  0xFC,  0xBE,  0x00,  0x98,  0x57,  0x55,  0xF0,  0xAC,  0x04,  0x01,  0xE6,  0x0C,  0x00,  0x00,  0xF2,
                   13896:   0x4E,  0x0D,  0x00,  0xF2,  0x12,  0x11,  0x00,  0xF2,  0xBC,  0x11,  0x00,  0xF2,  0xC8,  0x11,  0x01,  0xF0,
                   13897:   0x7C,  0x02,  0x00,  0xF0,  0x8A,  0x02,  0x46,  0x1C,  0x0C,  0x1C,  0x67,  0x1B,  0xBF,  0x57,  0x77,  0x57,
                   13898:   0x02,  0x4B,  0x48,  0x1C,  0x32,  0x1C,  0x00,  0xF2,  0x92,  0x0D,  0x30,  0x1C,  0x96,  0xF0,  0xBC,  0x03,
                   13899:   0xB1,  0xF0,  0xC0,  0x03,  0x1E,  0xF0,  0xFC,  0x09,  0x85,  0xF0,  0x02,  0x0A,  0x00,  0xFC,  0xBE,  0x00,
                   13900:   0x98,  0x57,  0x14,  0x12,  0x01,  0xE6,  0x0C,  0x00,  0x00,  0xF2,  0x4E,  0x0D,  0x00,  0xF2,  0x12,  0x11,
                   13901:   0x01,  0xF0,  0x7C,  0x02,  0x00,  0xF0,  0x8A,  0x02,  0x03,  0xF6,  0xE0,  0x00,  0x00,  0xF2,  0x68,  0x0A,
                   13902:   0x01,  0x48,  0x55,  0xF0,  0x98,  0x04,  0x03,  0x82,  0x03,  0xFC,  0xA0,  0x00,  0x9B,  0x57,  0x40,  0x12,
                   13903:   0x69,  0x18,  0x00,  0xF2,  0x12,  0x11,  0x85,  0xF0,  0x42,  0x04,  0x69,  0x08,  0x00,  0xF2,  0x12,  0x11,
                   13904:   0x85,  0xF0,  0x02,  0x0A,  0x68,  0x08,  0x4C,  0x44,  0x28,  0x12,  0x44,  0x48,  0x03,  0xF6,  0xE0,  0x00,
                   13905:   0x00,  0xF2,  0x68,  0x0A,  0x45,  0x58,  0x00,  0xF2,  0xF6,  0x0D,  0x00,  0xCC,  0x01,  0x48,  0x55,  0xF0,
                   13906:   0x98,  0x04,  0x4C,  0x44,  0xEF,  0x13,  0x00,  0xF2,  0xC6,  0x0F,  0x00,  0xF2,  0x14,  0x10,  0x08,  0x10,
                   13907:   0x68,  0x18,  0x45,  0x5A,  0x00,  0xF2,  0xF6,  0x0D,  0x04,  0x80,  0x18,  0xE4,  0x10,  0x00,  0x28,  0x12,
                   13908:   0x01,  0xE6,  0x06,  0x00,  0x04,  0x80,  0x18,  0xE4,  0x01,  0x00,  0x04,  0x12,  0x01,  0xE6,  0x0D,  0x00,
                   13909:   0x00,  0xF2,  0x4E,  0x0D,  0x00,  0xF2,  0x12,  0x11,  0x04,  0xE6,  0x02,  0x00,  0x9E,  0xE7,  0x15,  0x00,
                   13910:   0x01,  0xF0,  0x1C,  0x0A,  0x00,  0xF0,  0x02,  0x0A,  0x69,  0x08,  0x05,  0x80,  0x48,  0xE4,  0x00,  0x00,
                   13911:   0x0C,  0x12,  0x00,  0xE6,  0x11,  0x00,  0x00,  0xEA,  0xB8,  0x00,  0x00,  0xF2,  0xB6,  0x10,  0x82,  0xE7,
                   13912:   0x02,  0x00,  0x1C,  0x90,  0x40,  0x5C,  0x00,  0x16,  0x01,  0xE6,  0x06,  0x00,  0x00,  0xF2,  0x4E,  0x0D,
                   13913:   0x01,  0xF0,  0x80,  0x01,  0x1E,  0xF0,  0x80,  0x01,  0x00,  0xF0,  0xA0,  0x04,  0x42,  0x5B,  0x06,  0xF7,
                   13914:   0x03,  0x00,  0x46,  0x59,  0xBF,  0x57,  0x77,  0x57,  0x01,  0xE6,  0x80,  0x00,  0x07,  0x80,  0x31,  0x44,
                   13915:   0x04,  0x80,  0x18,  0xE4,  0x20,  0x00,  0x56,  0x13,  0x20,  0x80,  0x48,  0xE4,  0x03,  0x00,  0x4E,  0x12,
                   13916:   0x00,  0xFC,  0xA2,  0x00,  0x98,  0x57,  0x55,  0xF0,  0x1C,  0x05,  0x31,  0xE4,  0x40,  0x00,  0x00,  0xFC,
                   13917:   0xA0,  0x00,  0x98,  0x57,  0x36,  0x12,  0x4C,  0x1C,  0x00,  0xF2,  0x12,  0x11,  0x89,  0x48,  0x00,  0xF2,
                   13918:   0x12,  0x11,  0x86,  0xF0,  0x2E,  0x05,  0x82,  0xE7,  0x06,  0x00,  0x1B,  0x80,  0x48,  0xE4,  0x22,  0x00,
                   13919:   0x5B,  0xF0,  0x0C,  0x05,  0x48,  0xE4,  0x20,  0x00,  0x59,  0xF0,  0x10,  0x05,  0x00,  0xE6,  0x20,  0x00,
                   13920:   0x09,  0x48,  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0x2E,  0x05,  0x83,  0x80,  0x04,  0x10,  0x00,  0xF2,
                   13921:   0xA2,  0x0D,  0x00,  0xE6,  0x01,  0x00,  0x00,  0xEA,  0x26,  0x01,  0x01,  0xEA,  0x27,  0x01,  0x04,  0x80,
                   13922:   0x18,  0xE4,  0x10,  0x00,  0x36,  0x12,  0xB9,  0x54,  0x00,  0xF2,  0xF6,  0x0E,  0x01,  0xE6,  0x06,  0x00,
                   13923:   0x04,  0x80,  0x18,  0xE4,  0x01,  0x00,  0x04,  0x12,  0x01,  0xE6,  0x0D,  0x00,  0x00,  0xF2,  0x4E,  0x0D,
                   13924:   0x00,  0xF2,  0x12,  0x11,  0x00,  0xF2,  0xBC,  0x11,  0x00,  0xF2,  0xC8,  0x11,  0x04,  0xE6,  0x02,  0x00,
                   13925:   0x9E,  0xE7,  0x15,  0x00,  0x01,  0xF0,  0x1C,  0x0A,  0x00,  0xF0,  0x02,  0x0A,  0x00,  0xFC,  0x20,  0x01,
                   13926:   0x98,  0x57,  0x34,  0x12,  0x00,  0xFC,  0x24,  0x01,  0x98,  0x57,  0x2C,  0x13,  0xB9,  0x54,  0x00,  0xF2,
                   13927:   0xF6,  0x0E,  0x86,  0xF0,  0xA8,  0x05,  0x03,  0xF6,  0x01,  0x00,  0x00,  0xF2,  0x8C,  0x0E,  0x85,  0xF0,
                   13928:   0x9E,  0x05,  0x82,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x60,  0x0B,  0x82,  0xE7,  0x02,  0x00,  0x00,  0xFC,
                   13929:   0x24,  0x01,  0xB0,  0x57,  0x00,  0xFA,  0x24,  0x01,  0x00,  0xFC,  0x9E,  0x00,  0x98,  0x57,  0x5A,  0x12,
                   13930:   0x00,  0xFC,  0xB6,  0x00,  0x98,  0x57,  0x52,  0x13,  0x03,  0xE6,  0x0C,  0x00,  0x00,  0xFC,  0x9C,  0x00,
                   13931:   0x98,  0x57,  0x04,  0x13,  0x03,  0xE6,  0x19,  0x00,  0x05,  0xE6,  0x08,  0x00,  0x00,  0xF6,  0x00,  0x01,
                   13932:   0x00,  0x57,  0x00,  0x57,  0x03,  0x58,  0x00,  0xDC,  0x18,  0xF4,  0x00,  0x80,  0x04,  0x13,  0x05,  0xE6,
                   13933:   0x0F,  0x00,  0xB9,  0x54,  0x00,  0xF2,  0xF6,  0x0E,  0x86,  0xF0,  0x0A,  0x06,  0x00,  0xF2,  0xBA,  0x0E,
                   13934:   0x85,  0xF0,  0x00,  0x06,  0x82,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x60,  0x0B,  0x82,  0xE7,  0x02,  0x00,
                   13935:   0x00,  0xFC,  0xB6,  0x00,  0xB0,  0x57,  0x00,  0xFA,  0xB6,  0x00,  0x01,  0xF6,  0x01,  0x00,  0x00,  0xF2,
                   13936:   0xF6,  0x0E,  0x9C,  0x32,  0x4E,  0x1C,  0x32,  0x1C,  0x00,  0xF2,  0x92,  0x0D,  0x30,  0x1C,  0x82,  0xE7,
                   13937:   0x04,  0x00,  0xB1,  0xF0,  0x22,  0x06,  0x0A,  0xF0,  0x3E,  0x06,  0x05,  0xF0,  0xD6,  0x06,  0x06,  0xF0,
                   13938:   0xDC,  0x06,  0x09,  0xF0,  0x24,  0x09,  0x1E,  0xF0,  0xFC,  0x09,  0x00,  0xF0,  0x02,  0x0A,  0x04,  0x80,
                   13939:   0x18,  0xE4,  0x20,  0x00,  0x30,  0x12,  0x09,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x21,  0x80,
                   13940:   0x18,  0xE4,  0xE0,  0x00,  0x09,  0x48,  0x00,  0xF2,  0x12,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF2,
                   13941:   0x12,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x99,  0xA4,  0x00,  0xF2,  0x12,  0x11,
                   13942:   0x09,  0xE7,  0x00,  0x00,  0x9A,  0x10,  0x04,  0x80,  0x18,  0xE4,  0x02,  0x00,  0x34,  0x12,  0x09,  0xE7,
                   13943:   0x1B,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x21,  0x80,  0x18,  0xE4,  0xE0,  0x00,  0x09,  0x48,  0x00,  0xF2,
                   13944:   0x12,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF2,
                   13945:   0x12,  0x11,  0x09,  0xE7,  0x01,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF0,
                   13946:   0x0C,  0x09,  0xBB,  0x55,  0x9A,  0x81,  0x03,  0xF7,  0x20,  0x00,  0x09,  0x6F,  0x93,  0x45,  0x55,  0xF0,
                   13947:   0xE2,  0x06,  0xB1,  0xF0,  0xC2,  0x06,  0x0A,  0xF0,  0xBA,  0x06,  0x09,  0xF0,  0x24,  0x09,  0x1E,  0xF0,
                   13948:   0xFC,  0x09,  0x00,  0xF0,  0x02,  0x0A,  0x00,  0xF2,  0x60,  0x0B,  0x47,  0x10,  0x09,  0xE7,  0x08,  0x00,
                   13949:   0x41,  0x10,  0x05,  0x80,  0x48,  0xE4,  0x00,  0x00,  0x1E,  0x12,  0x00,  0xE6,  0x11,  0x00,  0x00,  0xEA,
                   13950:   0xB8,  0x00,  0x00,  0xF2,  0xB6,  0x10,  0x2C,  0x90,  0xAE,  0x90,  0x08,  0x50,  0x8A,  0x50,  0x38,  0x54,
                   13951:   0x1F,  0x40,  0x00,  0xF2,  0xB4,  0x0D,  0x08,  0x10,  0x08,  0x90,  0x8A,  0x90,  0x30,  0x50,  0xB2,  0x50,
                   13952:   0x9C,  0x32,  0x0C,  0x92,  0x8E,  0x92,  0x38,  0x54,  0x04,  0x80,  0x30,  0xE4,  0x08,  0x00,  0x04,  0x40,
                   13953:   0x0C,  0x1C,  0x00,  0xF6,  0x03,  0x00,  0xB1,  0xF0,  0x26,  0x07,  0x9E,  0xF0,  0x3A,  0x07,  0x01,  0x48,
                   13954:   0x55,  0xF0,  0xFC,  0x09,  0x0C,  0x1C,  0x10,  0x44,  0xED,  0x10,  0x0B,  0xF0,  0x5E,  0x07,  0x0C,  0xF0,
                   13955:   0x62,  0x07,  0x05,  0xF0,  0x52,  0x07,  0x06,  0xF0,  0x58,  0x07,  0x09,  0xF0,  0x24,  0x09,  0x00,  0xF0,
                   13956:   0x02,  0x0A,  0x00,  0xF2,  0x60,  0x0B,  0xCF,  0x10,  0x09,  0xE7,  0x08,  0x00,  0xC9,  0x10,  0x2E,  0x1C,
                   13957:   0x02,  0x10,  0x2C,  0x1C,  0xAA,  0xF0,  0x64,  0x07,  0xAC,  0xF0,  0x72,  0x07,  0x40,  0x10,  0x34,  0x1C,
                   13958:   0xF3,  0x10,  0xAD,  0xF0,  0x7C,  0x07,  0xC8,  0x10,  0x36,  0x1C,  0xE9,  0x10,  0x2B,  0xF0,  0x82,  0x08,
                   13959:   0x6B,  0x18,  0x18,  0xF4,  0x00,  0xFE,  0x20,  0x12,  0x01,  0x58,  0xD2,  0xF0,  0x82,  0x08,  0x76,  0x18,
                   13960:   0x18,  0xF4,  0x03,  0x00,  0xEC,  0x12,  0x00,  0xFC,  0x22,  0x01,  0x18,  0xF4,  0x01,  0x00,  0xE2,  0x12,
                   13961:   0x0B,  0xF0,  0x64,  0x07,  0x0C,  0xF0,  0x64,  0x07,  0x36,  0x1C,  0x34,  0x1C,  0xB7,  0x10,  0x38,  0x54,
                   13962:   0xB9,  0x54,  0x84,  0x80,  0x19,  0xE4,  0x20,  0x00,  0xB2,  0x13,  0x85,  0x80,  0x81,  0x48,  0x66,  0x12,
                   13963:   0x04,  0x80,  0x18,  0xE4,  0x08,  0x00,  0x58,  0x13,  0x1F,  0x80,  0x08,  0x44,  0xC8,  0x44,  0x9F,  0x12,
                   13964:   0x1F,  0x40,  0x34,  0x91,  0xB6,  0x91,  0x44,  0x55,  0xE5,  0x55,  0x02,  0xEC,  0xB8,  0x00,  0x02,  0x49,
                   13965:   0xBB,  0x55,  0x82,  0x81,  0xC0,  0x55,  0x48,  0xF4,  0x0F,  0x00,  0x5A,  0xF0,  0x1A,  0x08,  0x4A,  0xE4,
                   13966:   0x17,  0x00,  0xD5,  0xF0,  0xFA,  0x07,  0x02,  0xF6,  0x0F,  0x00,  0x02,  0xF4,  0x02,  0x00,  0x02,  0xEA,
                   13967:   0xB8,  0x00,  0x04,  0x91,  0x86,  0x91,  0x02,  0x4B,  0x2C,  0x90,  0x08,  0x50,  0x2E,  0x90,  0x0A,  0x50,
                   13968:   0x2C,  0x51,  0xAE,  0x51,  0x00,  0xF2,  0xB6,  0x10,  0x38,  0x54,  0x00,  0xF2,  0xB4,  0x0D,  0x56,  0x10,
                   13969:   0x34,  0x91,  0xB6,  0x91,  0x0C,  0x10,  0x04,  0x80,  0x18,  0xE4,  0x08,  0x00,  0x41,  0x12,  0x0C,  0x91,
                   13970:   0x8E,  0x91,  0x04,  0x80,  0x18,  0xE4,  0xF7,  0x00,  0x04,  0x40,  0x30,  0x90,  0xB2,  0x90,  0x36,  0x10,
                   13971:   0x02,  0x80,  0x48,  0xE4,  0x10,  0x00,  0x31,  0x12,  0x82,  0xE7,  0x10,  0x00,  0x84,  0x80,  0x19,  0xE4,
                   13972:   0x20,  0x00,  0x10,  0x13,  0x0C,  0x90,  0x8E,  0x90,  0x5D,  0xF0,  0x78,  0x07,  0x0C,  0x58,  0x8D,  0x58,
                   13973:   0x00,  0xF0,  0x64,  0x07,  0x38,  0x54,  0xB9,  0x54,  0x19,  0x80,  0xF1,  0x10,  0x3A,  0x55,  0x19,  0x81,
                   13974:   0xBB,  0x55,  0x10,  0x90,  0x92,  0x90,  0x10,  0x58,  0x91,  0x58,  0x14,  0x59,  0x95,  0x59,  0x00,  0xF0,
                   13975:   0x64,  0x07,  0x04,  0x80,  0x18,  0xE4,  0x20,  0x00,  0x06,  0x12,  0x6C,  0x19,  0x19,  0x41,  0x7C,  0x10,
                   13976:   0x6C,  0x19,  0x0C,  0x51,  0xED,  0x19,  0x8E,  0x51,  0x6B,  0x18,  0x18,  0xF4,  0x00,  0xFF,  0x02,  0x13,
                   13977:   0x6A,  0x10,  0x01,  0x58,  0xD2,  0xF0,  0xC0,  0x08,  0x76,  0x18,  0x18,  0xF4,  0x03,  0x00,  0x0A,  0x12,
                   13978:   0x00,  0xFC,  0x22,  0x01,  0x18,  0xF4,  0x01,  0x00,  0x06,  0x13,  0x9E,  0xE7,  0x16,  0x00,  0x4C,  0x10,
                   13979:   0xD1,  0xF0,  0xCA,  0x08,  0x9E,  0xE7,  0x17,  0x00,  0x42,  0x10,  0xD0,  0xF0,  0xD4,  0x08,  0x9E,  0xE7,
                   13980:   0x19,  0x00,  0x38,  0x10,  0xCF,  0xF0,  0xDE,  0x08,  0x9E,  0xE7,  0x20,  0x00,  0x2E,  0x10,  0xCE,  0xF0,
                   13981:   0xE8,  0x08,  0x9E,  0xE7,  0x21,  0x00,  0x24,  0x10,  0xCD,  0xF0,  0xF2,  0x08,  0x9E,  0xE7,  0x22,  0x00,
                   13982:   0x1A,  0x10,  0xCC,  0xF0,  0x04,  0x09,  0x84,  0x80,  0x19,  0xE4,  0x04,  0x00,  0x06,  0x12,  0x9E,  0xE7,
                   13983:   0x12,  0x00,  0x08,  0x10,  0xCB,  0xF0,  0x0C,  0x09,  0x9E,  0xE7,  0x24,  0x00,  0xB1,  0xF0,  0x0C,  0x09,
                   13984:   0x05,  0xF0,  0x1E,  0x09,  0x09,  0xF0,  0x24,  0x09,  0x1E,  0xF0,  0xFC,  0x09,  0xE4,  0x10,  0x00,  0xF2,
                   13985:   0x60,  0x0B,  0xE9,  0x10,  0x9C,  0x32,  0x82,  0xE7,  0x20,  0x00,  0x32,  0x1C,  0xE9,  0x09,  0x00,  0xF2,
                   13986:   0x12,  0x11,  0x85,  0xF0,  0x02,  0x0A,  0x69,  0x08,  0x01,  0xF0,  0x44,  0x09,  0x1E,  0xF0,  0xFC,  0x09,
                   13987:   0x00,  0xF0,  0x38,  0x09,  0x30,  0x44,  0x06,  0x12,  0x9E,  0xE7,  0x42,  0x00,  0xB8,  0x10,  0x04,  0xF6,
                   13988:   0x01,  0x00,  0xB3,  0x45,  0x74,  0x12,  0x04,  0x80,  0x18,  0xE4,  0x20,  0x00,  0x22,  0x13,  0x4B,  0xE4,
                   13989:   0x02,  0x00,  0x36,  0x12,  0x4B,  0xE4,  0x28,  0x00,  0xAC,  0x13,  0x00,  0xF2,  0xBC,  0x11,  0x00,  0xF2,
                   13990:   0xC8,  0x11,  0x03,  0xF6,  0xD0,  0x00,  0xFA,  0x14,  0x82,  0xE7,  0x01,  0x00,  0x00,  0xF0,  0x80,  0x01,
                   13991:   0x9E,  0xE7,  0x44,  0x00,  0x4B,  0xE4,  0x02,  0x00,  0x06,  0x12,  0x03,  0xE6,  0x02,  0x00,  0x76,  0x10,
                   13992:   0x00,  0xF2,  0xA2,  0x0D,  0x03,  0xE6,  0x02,  0x00,  0x6C,  0x10,  0x00,  0xF2,  0xA2,  0x0D,  0x19,  0x82,
                   13993:   0x34,  0x46,  0x0A,  0x13,  0x03,  0xE6,  0x02,  0x00,  0x9E,  0xE7,  0x43,  0x00,  0x68,  0x10,  0x04,  0x80,
                   13994:   0x30,  0xE4,  0x20,  0x00,  0x04,  0x40,  0x00,  0xF2,  0xBC,  0x11,  0x00,  0xF2,  0xC8,  0x11,  0x82,  0xE7,
                   13995:   0x01,  0x00,  0x06,  0xF7,  0x02,  0x00,  0x00,  0xF0,  0x08,  0x03,  0x04,  0x80,  0x18,  0xE4,  0x20,  0x00,
                   13996:   0x06,  0x12,  0x03,  0xE6,  0x02,  0x00,  0x3E,  0x10,  0x04,  0x80,  0x18,  0xE4,  0x02,  0x00,  0x3A,  0x12,
                   13997:   0x04,  0x80,  0x18,  0xE4,  0xFD,  0x00,  0x04,  0x40,  0x1C,  0x1C,  0x9D,  0xF0,  0xEA,  0x09,  0x1C,  0x1C,
                   13998:   0x9D,  0xF0,  0xF0,  0x09,  0xC1,  0x10,  0x9E,  0xE7,  0x13,  0x00,  0x0A,  0x10,  0x9E,  0xE7,  0x41,  0x00,
                   13999:   0x04,  0x10,  0x9E,  0xE7,  0x24,  0x00,  0x00,  0xFC,  0xBE,  0x00,  0x98,  0x57,  0xD5,  0xF0,  0x8A,  0x02,
                   14000:   0x04,  0xE6,  0x04,  0x00,  0x06,  0x10,  0x04,  0xE6,  0x04,  0x00,  0x9D,  0x41,  0x1C,  0x42,  0x9F,  0xE7,
                   14001:   0x00,  0x00,  0x06,  0xF7,  0x02,  0x00,  0x03,  0xF6,  0xE0,  0x00,  0x3C,  0x14,  0x44,  0x58,  0x45,  0x58,
                   14002:   0x00,  0xF2,  0xF6,  0x0D,  0x00,  0xF2,  0x7E,  0x10,  0x00,  0xF2,  0xC6,  0x0F,  0x3C,  0x14,  0x1E,  0x1C,
                   14003:   0x00,  0xF0,  0x80,  0x01,  0x12,  0x1C,  0x22,  0x1C,  0xD2,  0x14,  0x00,  0xF0,  0x72,  0x01,  0x83,  0x59,
                   14004:   0x03,  0xDC,  0x73,  0x57,  0x80,  0x5D,  0x00,  0x16,  0x83,  0x59,  0x03,  0xDC,  0x38,  0x54,  0x70,  0x57,
                   14005:   0x33,  0x54,  0x3B,  0x54,  0x80,  0x5D,  0x00,  0x16,  0x03,  0x57,  0x83,  0x59,  0x38,  0x54,  0x00,  0xCC,
                   14006:   0x00,  0x16,  0x03,  0x57,  0x83,  0x59,  0x00,  0x4C,  0x00,  0x16,  0x02,  0x80,  0x48,  0xE4,  0x01,  0x00,
                   14007:   0x0E,  0x12,  0x48,  0xE4,  0x05,  0x00,  0x08,  0x12,  0x00,  0xF2,  0xBC,  0x11,  0x00,  0xF2,  0xC8,  0x11,
                   14008:   0xC1,  0x5A,  0x3A,  0x55,  0x02,  0xEC,  0xB5,  0x00,  0x45,  0x59,  0x00,  0xF2,  0xF6,  0x0D,  0x83,  0x58,
                   14009:   0x30,  0xE7,  0x00,  0x00,  0x10,  0x4D,  0x30,  0xE7,  0x40,  0x00,  0x10,  0x4F,  0x38,  0x90,  0xBA,  0x90,
                   14010:   0x10,  0x5C,  0x80,  0x5C,  0x83,  0x5A,  0x10,  0x4E,  0x04,  0xEA,  0xB5,  0x00,  0x43,  0x5B,  0x03,  0xF4,
                   14011:   0xE0,  0x00,  0x83,  0x59,  0x04,  0xCC,  0x01,  0x4A,  0x0A,  0x12,  0x45,  0x5A,  0x00,  0xF2,  0xF6,  0x0D,
                   14012:   0x00,  0xF2,  0x38,  0x10,  0x00,  0x16,  0x08,  0x1C,  0x00,  0xFC,  0xAC,  0x00,  0x06,  0x58,  0x67,  0x18,
                   14013:   0x18,  0xF4,  0x8F,  0xE1,  0x01,  0xFC,  0xAE,  0x00,  0x19,  0xF4,  0x70,  0x1E,  0xB0,  0x54,  0x07,  0x58,
                   14014:   0x00,  0xFC,  0xB0,  0x00,  0x08,  0x58,  0x00,  0xFC,  0xB2,  0x00,  0x09,  0x58,  0x0A,  0x1C,  0x00,  0xE6,
                   14015:   0x0F,  0x00,  0x00,  0xEA,  0xB9,  0x00,  0x38,  0x54,  0x00,  0xFA,  0x24,  0x01,  0x00,  0xFA,  0xB6,  0x00,
                   14016:   0x18,  0x1C,  0x14,  0x1C,  0x10,  0x1C,  0x32,  0x1C,  0x12,  0x1C,  0x00,  0x16,  0x3E,  0x57,  0x0C,  0x14,
                   14017:   0x0E,  0x47,  0x07,  0xE6,  0x10,  0x00,  0xCE,  0x47,  0xF5,  0x13,  0x00,  0x16,  0x00,  0xF2,  0xA2,  0x0D,
                   14018:   0x02,  0x4B,  0x03,  0xF6,  0xE0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x01,  0x48,  0x20,  0x12,  0x44,  0x58,
                   14019:   0x45,  0x58,  0x9E,  0xE7,  0x15,  0x00,  0x9C,  0xE7,  0x04,  0x00,  0x00,  0xF2,  0xF6,  0x0D,  0x00,  0xF2,
                   14020:   0x7E,  0x10,  0x00,  0xF2,  0xC6,  0x0F,  0x00,  0xF2,  0x7A,  0x0A,  0x1E,  0x1C,  0xD5,  0x10,  0x00,  0x16,
                   14021:   0x69,  0x08,  0x48,  0xE4,  0x04,  0x00,  0x64,  0x12,  0x48,  0xE4,  0x02,  0x00,  0x20,  0x12,  0x48,  0xE4,
                   14022:   0x03,  0x00,  0x1A,  0x12,  0x48,  0xE4,  0x08,  0x00,  0x14,  0x12,  0x48,  0xE4,  0x01,  0x00,  0xF0,  0x12,
                   14023:   0x48,  0xE4,  0x07,  0x00,  0x12,  0x12,  0x01,  0xE6,  0x07,  0x00,  0x00,  0xF2,  0x4E,  0x0D,  0x00,  0xF2,
                   14024:   0x12,  0x11,  0x05,  0xF0,  0x60,  0x0B,  0x00,  0x16,  0x00,  0xE6,  0x01,  0x00,  0x00,  0xEA,  0x99,  0x00,
                   14025:   0x02,  0x80,  0x48,  0xE4,  0x03,  0x00,  0xE7,  0x12,  0x48,  0xE4,  0x06,  0x00,  0xE1,  0x12,  0x01,  0xE6,
                   14026:   0x06,  0x00,  0x00,  0xF2,  0x4E,  0x0D,  0x00,  0xF2,  0x12,  0x11,  0x04,  0xE6,  0x02,  0x00,  0x9E,  0xE7,
                   14027:   0x15,  0x00,  0x01,  0xF0,  0x1C,  0x0A,  0x00,  0xF0,  0x02,  0x0A,  0x00,  0x16,  0x02,  0x80,  0x48,  0xE4,
                   14028:   0x10,  0x00,  0x1C,  0x12,  0x82,  0xE7,  0x08,  0x00,  0x3C,  0x56,  0x03,  0x82,  0x00,  0xF2,  0xE2,  0x0D,
                   14029:   0x30,  0xE7,  0x08,  0x00,  0x04,  0xF7,  0x70,  0x01,  0x06,  0xF7,  0x02,  0x00,  0x00,  0xF0,  0x80,  0x01,
                   14030:   0x6C,  0x19,  0xED,  0x19,  0x5D,  0xF0,  0xD4,  0x0B,  0x44,  0x55,  0xE5,  0x55,  0x59,  0xF0,  0x52,  0x0C,
                   14031:   0x04,  0x55,  0xA5,  0x55,  0x1F,  0x80,  0x01,  0xEC,  0xB8,  0x00,  0x82,  0x48,  0x82,  0x80,  0x49,  0x44,
                   14032:   0x2E,  0x13,  0x01,  0xEC,  0xB8,  0x00,  0x41,  0xE4,  0x02,  0x00,  0x01,  0xEA,  0xB8,  0x00,  0x49,  0xE4,
                   14033:   0x11,  0x00,  0x59,  0xF0,  0x2E,  0x0C,  0x01,  0xE6,  0x17,  0x00,  0x01,  0xEA,  0xB8,  0x00,  0x02,  0x4B,
                   14034:   0x88,  0x90,  0xAC,  0x50,  0x8A,  0x90,  0xAE,  0x50,  0x01,  0xEC,  0xB8,  0x00,  0x82,  0x48,  0x82,  0x80,
                   14035:   0x10,  0x44,  0x02,  0x4B,  0x1F,  0x40,  0xC0,  0x44,  0x00,  0xF2,  0xB4,  0x0D,  0x04,  0x55,  0xA5,  0x55,
                   14036:   0x9F,  0x10,  0x0C,  0x51,  0x8E,  0x51,  0x30,  0x90,  0xB2,  0x90,  0x00,  0x56,  0xA1,  0x56,  0x30,  0x50,
                   14037:   0xB2,  0x50,  0x34,  0x90,  0xB6,  0x90,  0x40,  0x56,  0xE1,  0x56,  0x34,  0x50,  0xB6,  0x50,  0x65,  0x10,
                   14038:   0xB1,  0xF0,  0x70,  0x0C,  0x85,  0xF0,  0xCA,  0x0B,  0xE9,  0x09,  0x4B,  0xE4,  0x03,  0x00,  0x78,  0x12,
                   14039:   0x4B,  0xE4,  0x02,  0x00,  0x01,  0x13,  0xB1,  0xF0,  0x86,  0x0C,  0x85,  0xF0,  0xCA,  0x0B,  0x69,  0x08,
                   14040:   0x48,  0xE4,  0x03,  0x00,  0xD5,  0xF0,  0x86,  0x0B,  0x00,  0xF2,  0x12,  0x11,  0x85,  0xF0,  0xCA,  0x0B,
                   14041:   0xE8,  0x09,  0x3C,  0x56,  0x00,  0xFC,  0x20,  0x01,  0x98,  0x57,  0x02,  0x13,  0xBB,  0x45,  0x4B,  0xE4,
                   14042:   0x00,  0x00,  0x08,  0x12,  0x03,  0xE6,  0x01,  0x00,  0x04,  0xF6,  0x00,  0x80,  0xA8,  0x14,  0xD2,  0x14,
                   14043:   0x30,  0x1C,  0x02,  0x80,  0x48,  0xE4,  0x03,  0x00,  0x10,  0x13,  0x00,  0xFC,  0xB6,  0x00,  0x98,  0x57,
                   14044:   0x02,  0x13,  0x4C,  0x1C,  0x3E,  0x1C,  0x00,  0xF0,  0x8E,  0x0B,  0x00,  0xFC,  0x24,  0x01,  0xB0,  0x57,
                   14045:   0x00,  0xFA,  0x24,  0x01,  0x4C,  0x1C,  0x3E,  0x1C,  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0x8E,  0x0B,
                   14046:   0x00,  0xF2,  0x8C,  0x0E,  0x00,  0xF0,  0x8E,  0x0B,  0xB1,  0xF0,  0xF8,  0x0C,  0x85,  0xF0,  0x86,  0x0B,
                   14047:   0x69,  0x08,  0x48,  0xE4,  0x01,  0x00,  0xD5,  0xF0,  0x86,  0x0B,  0xFC,  0x14,  0x42,  0x58,  0x6C,  0x14,
                   14048:   0x80,  0x14,  0x30,  0x1C,  0x4A,  0xF4,  0x02,  0x00,  0x55,  0xF0,  0x86,  0x0B,  0x4A,  0xF4,  0x01,  0x00,
                   14049:   0x0E,  0x12,  0x02,  0x80,  0x48,  0xE4,  0x03,  0x00,  0x06,  0x13,  0x3E,  0x1C,  0x00,  0xF0,  0x8E,  0x0B,
                   14050:   0x00,  0xFC,  0xB6,  0x00,  0xB0,  0x57,  0x00,  0xFA,  0xB6,  0x00,  0x4C,  0x1C,  0x3E,  0x1C,  0x00,  0xF2,
                   14051:   0x12,  0x11,  0x86,  0xF0,  0x8E,  0x0B,  0x00,  0xF2,  0xBA,  0x0E,  0x00,  0xF0,  0x8E,  0x0B,  0x4C,  0x1C,
                   14052:   0xB1,  0xF0,  0x50,  0x0D,  0x85,  0xF0,  0x5C,  0x0D,  0x69,  0x08,  0xF3,  0x10,  0x86,  0xF0,  0x64,  0x0D,
                   14053:   0x4E,  0x1C,  0x89,  0x48,  0x00,  0x16,  0x00,  0xF6,  0x00,  0x01,  0x00,  0x57,  0x00,  0x57,  0x03,  0x58,
                   14054:   0x00,  0xDC,  0x18,  0xF4,  0xFF,  0x7F,  0x30,  0x56,  0x00,  0x5C,  0x00,  0x16,  0x00,  0xF6,  0x00,  0x01,
                   14055:   0x00,  0x57,  0x00,  0x57,  0x03,  0x58,  0x00,  0xDC,  0x18,  0xF4,  0x00,  0x80,  0x30,  0x56,  0x00,  0x5C,
                   14056:   0x00,  0x16,  0x00,  0xF6,  0x00,  0x01,  0x00,  0x57,  0x00,  0x57,  0x03,  0x58,  0x00,  0xDC,  0x0B,  0x58,
                   14057:   0x00,  0x16,  0x03,  0xF6,  0x24,  0x01,  0x00,  0xF2,  0x58,  0x0A,  0x03,  0xF6,  0xB6,  0x00,  0x00,  0xF2,
                   14058:   0x58,  0x0A,  0x00,  0x16,  0x02,  0xEC,  0xB8,  0x00,  0x02,  0x49,  0x18,  0xF4,  0xFF,  0x00,  0x00,  0x54,
                   14059:   0x00,  0x54,  0x00,  0x54,  0x00,  0xF4,  0x08,  0x00,  0xE1,  0x18,  0x80,  0x54,  0x03,  0x58,  0x00,  0xDD,
                   14060:   0x01,  0xDD,  0x02,  0xDD,  0x03,  0xDC,  0x02,  0x4B,  0x30,  0x50,  0xB2,  0x50,  0x34,  0x51,  0xB6,  0x51,
                   14061:   0x00,  0x16,  0x45,  0x5A,  0x1D,  0xF4,  0xFF,  0x00,  0x85,  0x56,  0x85,  0x56,  0x85,  0x56,  0x05,  0xF4,
                   14062:   0x02,  0x12,  0x83,  0x5A,  0x00,  0x16,  0x1D,  0xF4,  0xFF,  0x00,  0x85,  0x56,  0x85,  0x56,  0x85,  0x56,
                   14063:   0x05,  0xF4,  0x00,  0x12,  0x83,  0x5A,  0x00,  0x16,  0x38,  0x54,  0xBB,  0x55,  0x3C,  0x56,  0xBD,  0x56,
                   14064:   0x00,  0xF2,  0x12,  0x11,  0x85,  0xF0,  0x82,  0x0E,  0xE9,  0x09,  0xC1,  0x59,  0x00,  0xF2,  0x12,  0x11,
                   14065:   0x85,  0xF0,  0x82,  0x0E,  0xE8,  0x0A,  0x83,  0x55,  0x83,  0x55,  0x4B,  0xF4,  0x90,  0x01,  0x5C,  0xF0,
                   14066:   0x36,  0x0E,  0xBD,  0x56,  0x40,  0x10,  0x4B,  0xF4,  0x30,  0x00,  0x59,  0xF0,  0x48,  0x0E,  0x01,  0xF6,
                   14067:   0x0C,  0x00,  0x00,  0xF6,  0x01,  0x00,  0x2E,  0x10,  0x02,  0xFC,  0x9C,  0x00,  0x9A,  0x57,  0x14,  0x13,
                   14068:   0x4B,  0xF4,  0x64,  0x00,  0x59,  0xF0,  0x64,  0x0E,  0x03,  0xF6,  0x64,  0x00,  0x01,  0xF6,  0x19,  0x00,
                   14069:   0x00,  0xF6,  0x01,  0x00,  0x43,  0xF4,  0x33,  0x00,  0x56,  0xF0,  0x76,  0x0E,  0x04,  0xF4,  0x00,  0x01,
                   14070:   0x43,  0xF4,  0x19,  0x00,  0xF3,  0x10,  0xB4,  0x56,  0xC3,  0x58,  0x02,  0xFC,  0x9E,  0x00,  0x9A,  0x57,
                   14071:   0x08,  0x13,  0x3C,  0x56,  0x00,  0xF6,  0x02,  0x00,  0x00,  0x16,  0x00,  0x16,  0x09,  0xE7,  0x01,  0x00,
                   14072:   0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0xB8,  0x0E,  0x09,  0xE7,  0x02,  0x00,  0x00,  0xF2,  0x12,  0x11,
                   14073:   0x86,  0xF0,  0xB8,  0x0E,  0x09,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0xB8,  0x0E,
                   14074:   0x4E,  0x1C,  0x89,  0x49,  0x00,  0xF2,  0x12,  0x11,  0x00,  0x16,  0x09,  0xE7,  0x01,  0x00,  0x00,  0xF2,
                   14075:   0x12,  0x11,  0x86,  0xF0,  0xF2,  0x0E,  0x09,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,
                   14076:   0xF2,  0x0E,  0x09,  0xE7,  0x01,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0xF2,  0x0E,  0x89,  0x49,
                   14077:   0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0xF2,  0x0E,  0x4E,  0x1C,  0x89,  0x4A,  0x00,  0xF2,  0x12,  0x11,
                   14078:   0x00,  0x16,  0x3C,  0x56,  0x00,  0x16,  0x00,  0xEC,  0x26,  0x01,  0x48,  0xE4,  0x01,  0x00,  0x1E,  0x13,
                   14079:   0x38,  0x44,  0x00,  0xEA,  0x26,  0x01,  0x49,  0xF4,  0x00,  0x00,  0x04,  0x12,  0x4E,  0x1C,  0x02,  0x10,
                   14080:   0x4C,  0x1C,  0x01,  0xEC,  0x27,  0x01,  0x89,  0x48,  0x00,  0xF2,  0x12,  0x11,  0x02,  0x14,  0x00,  0x16,
                   14081:   0x85,  0xF0,  0x52,  0x0F,  0x38,  0x54,  0x00,  0xEA,  0x99,  0x00,  0x00,  0xF2,  0x60,  0x0B,  0x02,  0x80,
                   14082:   0x48,  0xE4,  0x06,  0x00,  0x1C,  0x13,  0x00,  0xEC,  0x99,  0x00,  0x48,  0xE4,  0x01,  0x00,  0x0A,  0x12,
                   14083:   0x04,  0x80,  0x30,  0xE4,  0x01,  0x00,  0x04,  0x40,  0x08,  0x10,  0x04,  0x80,  0x18,  0xE4,  0xFE,  0x00,
                   14084:   0x04,  0x40,  0x00,  0x16,  0x02,  0xF6,  0xE0,  0x00,  0x02,  0x57,  0x03,  0x59,  0x01,  0xCC,  0x81,  0x48,
                   14085:   0x22,  0x12,  0x00,  0x4E,  0x83,  0x5A,  0x90,  0x4C,  0x20,  0xE7,  0x00,  0x00,  0xC3,  0x58,  0x1B,  0xF4,
                   14086:   0xFF,  0x00,  0x83,  0x55,  0x83,  0x55,  0x83,  0x55,  0x03,  0xF4,  0x00,  0x12,  0x8B,  0x55,  0x83,  0x59,
                   14087:   0x00,  0x4E,  0x00,  0x16,  0x00,  0x4E,  0x02,  0xF6,  0xF0,  0x00,  0x02,  0x57,  0x03,  0x59,  0x00,  0x4E,
                   14088:   0x83,  0x5A,  0x30,  0xE7,  0x00,  0x00,  0x20,  0xE7,  0x00,  0x00,  0x00,  0x16,  0x02,  0xF6,  0xF0,  0x00,
                   14089:   0x02,  0x57,  0x03,  0x59,  0x01,  0xCC,  0x00,  0x4E,  0x83,  0x5A,  0x30,  0xE7,  0x00,  0x00,  0x80,  0x4C,
                   14090:   0xC3,  0x58,  0x1B,  0xF4,  0xFF,  0x00,  0x83,  0x55,  0x83,  0x55,  0x83,  0x55,  0x03,  0xF4,  0x00,  0x12,
                   14091:   0x83,  0x59,  0x00,  0x4E,  0x00,  0x16,  0x03,  0xF6,  0xE0,  0x00,  0x03,  0x57,  0x83,  0x59,  0x3A,  0x55,
                   14092:   0x02,  0xCC,  0x45,  0x5A,  0x00,  0xF2,  0xF6,  0x0D,  0xC0,  0x5A,  0x40,  0x5C,  0x38,  0x54,  0x00,  0xCD,
                   14093:   0x01,  0xCC,  0x4A,  0x46,  0x0A,  0x13,  0x83,  0x59,  0x00,  0x4C,  0x01,  0x48,  0x16,  0x13,  0x0C,  0x10,
                   14094:   0xC5,  0x58,  0x00,  0xF2,  0xF6,  0x0D,  0x00,  0x4C,  0x01,  0x48,  0x08,  0x13,  0x05,  0xF6,  0xF0,  0x00,
                   14095:   0x05,  0x57,  0x08,  0x10,  0x45,  0x58,  0x00,  0xF2,  0xF6,  0x0D,  0x8D,  0x56,  0x83,  0x5A,  0x80,  0x4C,
                   14096:   0x05,  0x17,  0x00,  0x16,  0x02,  0x4B,  0x06,  0xF7,  0x04,  0x00,  0x62,  0x0B,  0x03,  0x82,  0x00,  0xF2,
                   14097:   0xE2,  0x0D,  0x02,  0x80,  0x00,  0x4C,  0x45,  0xF4,  0x02,  0x00,  0x52,  0x14,  0x06,  0xF7,  0x02,  0x00,
                   14098:   0x06,  0x14,  0x00,  0xF2,  0x54,  0x0F,  0x00,  0x16,  0x02,  0x4B,  0x01,  0xF6,  0xFF,  0x00,  0x38,  0x1C,
                   14099:   0x05,  0xF4,  0x04,  0x00,  0x83,  0x5A,  0x18,  0xDF,  0x19,  0xDF,  0x1D,  0xF7,  0x3C,  0x00,  0xB8,  0xF0,
                   14100:   0x4E,  0x10,  0x9C,  0x14,  0x01,  0x48,  0x1C,  0x13,  0x0E,  0xF7,  0x3C,  0x00,  0x03,  0xF7,  0x04,  0x00,
                   14101:   0xAF,  0x19,  0x03,  0x42,  0x45,  0xF4,  0x02,  0x00,  0x83,  0x5A,  0x02,  0xCC,  0x02,  0x41,  0x45,  0xF4,
                   14102:   0x02,  0x00,  0x00,  0x16,  0x91,  0x44,  0xD5,  0xF0,  0x3E,  0x10,  0x00,  0xF0,  0x9E,  0x02,  0x01,  0xF6,
                   14103:   0xFF,  0x00,  0x38,  0x1C,  0x05,  0xF4,  0x04,  0x00,  0x83,  0x5A,  0x18,  0xDF,  0x19,  0xDF,  0x0E,  0xF7,
                   14104:   0x3C,  0x00,  0x03,  0xF7,  0x04,  0x00,  0x0F,  0x79,  0x1C,  0xF7,  0x3C,  0x00,  0xB8,  0xF0,  0x9C,  0x10,
                   14105:   0x4E,  0x14,  0x01,  0x48,  0x06,  0x13,  0x45,  0xF4,  0x04,  0x00,  0x00,  0x16,  0x91,  0x44,  0xD5,  0xF0,
                   14106:   0x82,  0x10,  0x00,  0xF0,  0x9E,  0x02,  0x02,  0xF6,  0xFF,  0x00,  0x38,  0x1C,  0x2C,  0xBC,  0xAE,  0xBC,
                   14107:   0xE2,  0x08,  0x00,  0xEC,  0xB8,  0x00,  0x02,  0x48,  0x1D,  0xF7,  0x80,  0x00,  0xB8,  0xF0,  0xCC,  0x10,
                   14108:   0x1E,  0x14,  0x01,  0x48,  0x0E,  0x13,  0x0E,  0xF7,  0x80,  0x00,  0x38,  0x54,  0x03,  0x58,  0xAF,  0x19,
                   14109:   0x82,  0x48,  0x00,  0x16,  0x82,  0x48,  0x12,  0x45,  0xD5,  0xF0,  0xBA,  0x10,  0x00,  0xF0,  0x9E,  0x02,
                   14110:   0x39,  0xF0,  0xF8,  0x10,  0x38,  0x44,  0x00,  0x16,  0x7E,  0x18,  0x18,  0xF4,  0x03,  0x00,  0x04,  0x13,
                   14111:   0x61,  0x18,  0x00,  0x16,  0x38,  0x1C,  0x00,  0xFC,  0x22,  0x01,  0x18,  0xF4,  0x01,  0x00,  0xF1,  0x12,
                   14112:   0xE3,  0x10,  0x30,  0x44,  0x30,  0x44,  0x30,  0x44,  0xB1,  0xF0,  0x18,  0x11,  0x00,  0x16,  0x3E,  0x57,
                   14113:   0x03,  0xF6,  0xE0,  0x00,  0x03,  0x57,  0x83,  0x59,  0x04,  0xCC,  0x01,  0x4A,  0x6A,  0x12,  0x45,  0x5A,
                   14114:   0x00,  0xF2,  0xF6,  0x0D,  0x02,  0x4B,  0x70,  0x14,  0x34,  0x13,  0x02,  0x80,  0x48,  0xE4,  0x08,  0x00,
                   14115:   0x18,  0x12,  0x9C,  0xE7,  0x02,  0x00,  0x9E,  0xE7,  0x15,  0x00,  0x00,  0xF2,  0xC6,  0x0F,  0x00,  0xF2,
                   14116:   0x7A,  0x0A,  0x1E,  0x1C,  0x01,  0xF6,  0x01,  0x00,  0x00,  0x16,  0x30,  0xE4,  0x10,  0x00,  0x04,  0x40,
                   14117:   0x00,  0xF2,  0xE2,  0x0D,  0x20,  0xE7,  0x01,  0x00,  0x01,  0xF6,  0x01,  0x00,  0x00,  0x16,  0x04,  0xDC,
                   14118:   0x01,  0x4A,  0x24,  0x12,  0x45,  0x5A,  0x00,  0xF2,  0xF6,  0x0D,  0x43,  0x5B,  0x06,  0xEC,  0x98,  0x00,
                   14119:   0x00,  0xF2,  0x38,  0x10,  0xC6,  0x59,  0x20,  0x14,  0x0A,  0x13,  0x00,  0xF2,  0xC6,  0x0F,  0x00,  0xF2,
                   14120:   0x14,  0x10,  0xA7,  0x10,  0x83,  0x5A,  0xD7,  0x10,  0x0E,  0x47,  0x07,  0xE6,  0x10,  0x00,  0xCE,  0x47,
                   14121:   0x5A,  0xF0,  0x20,  0x11,  0xB9,  0x54,  0x00,  0x16,  0x14,  0x90,  0x96,  0x90,  0x02,  0xFC,  0xA8,  0x00,
                   14122:   0x03,  0xFC,  0xAA,  0x00,  0x48,  0x55,  0x02,  0x13,  0xC9,  0x55,  0x00,  0x16,  0x00,  0xEC,  0xBA,  0x00,
                   14123:   0x10,  0x44,  0x00,  0xEA,  0xBA,  0x00,  0x00,  0x16,  0x03,  0xF6,  0xC0,  0x00,  0x00,  0xF2,  0x68,  0x0A,
                   14124:   0x10,  0x44,  0x00,  0x4C,  0x00,  0x16
                   14125: };
                   14126: 
                   14127: unsigned short _adv_mcode_size ASC_INITDATA =
                   14128:     sizeof(_adv_mcode_buf); /* 0x11D6 */
                   14129: unsigned long  _adv_mcode_chksum ASC_INITDATA = 0x03494981UL;
                   14130: 
                   14131: /* a_init.c */
                   14132: /*
                   14133:  * EEPROM Configuration.
                   14134:  *
                   14135:  * All drivers should use this structure to set the default EEPROM
                   14136:  * configuration. The BIOS now uses this structure when it is built.
                   14137:  * Additional structure information can be found in a_condor.h where
                   14138:  * the structure is defined.
                   14139:  */
                   14140: STATIC ADVEEP_CONFIG
                   14141: Default_EEPROM_Config ASC_INITDATA = {
                   14142:     ADV_EEPROM_BIOS_ENABLE,     /* cfg_msw */
                   14143:     0x0000,                     /* cfg_lsw */
                   14144:     0xFFFF,                     /* disc_enable */
                   14145:     0xFFFF,                     /* wdtr_able */
                   14146:     0xFFFF,                     /* sdtr_able */
                   14147:     0xFFFF,                     /* start_motor */
                   14148:     0xFFFF,                     /* tagqng_able */
                   14149:     0xFFFF,                     /* bios_scan */
                   14150:     0,                          /* scam_tolerant */
                   14151:     7,                          /* adapter_scsi_id */
                   14152:     0,                          /* bios_boot_delay */
                   14153:     3,                          /* scsi_reset_delay */
                   14154:     0,                          /* bios_id_lun */
                   14155:     0,                          /* termination */
                   14156:     0,                          /* reserved1 */
                   14157:     0xFFEF,                     /* bios_ctrl */
                   14158:     0xFFFF,                     /* ultra_able */
                   14159:     0,                          /* reserved2 */
                   14160:     ASC_DEF_MAX_HOST_QNG,       /* max_host_qng */
                   14161:     ASC_DEF_MAX_DVC_QNG,        /* max_dvc_qng */
                   14162:     0,                          /* dvc_cntl */
                   14163:     0,                          /* bug_fix */
                   14164:     0,                          /* serial_number_word1 */
                   14165:     0,                          /* serial_number_word2 */
                   14166:     0,                          /* serial_number_word3 */
                   14167:     0,                          /* check_sum */
                   14168:     { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* oem_name[16] */
                   14169:     0,                          /* dvc_err_code */
                   14170:     0,                          /* adv_err_code */
                   14171:     0,                          /* adv_err_addr */
                   14172:     0,                          /* saved_dvc_err_code */
                   14173:     0,                          /* saved_adv_err_code */
                   14174:     0,                          /* saved_adv_err_addr */
                   14175:     0                           /* num_of_err */
                   14176: };
                   14177: 
                   14178: /*
                   14179:  * Initialize the ADV_DVC_VAR structure.
                   14180:  *
                   14181:  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
                   14182:  *
                   14183:  * For a non-fatal error return a warning code. If there are no warnings
                   14184:  * then 0 is returned.
                   14185:  */
                   14186: ASC_INITFUNC(
                   14187: int
                   14188: AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
                   14189: )
                   14190: {
                   14191:     ushort      warn_code;
                   14192:     AdvPortAddr iop_base;
                   14193:     uchar       pci_cmd_reg;
                   14194:     int         status;
                   14195: 
                   14196:     warn_code = 0;
                   14197:     asc_dvc->err_code = 0;
                   14198:     iop_base = asc_dvc->iop_base;
                   14199: 
                   14200:     /*
                   14201:      * PCI Command Register
                   14202:      */
                   14203: 
                   14204:     if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc,
                   14205:                             AscPCIConfigCommandRegister))
                   14206:          & AscPCICmdRegBits_BusMastering)
                   14207:         != AscPCICmdRegBits_BusMastering)
                   14208:     {
                   14209:         pci_cmd_reg |= AscPCICmdRegBits_BusMastering;
                   14210: 
                   14211:         DvcAdvWritePCIConfigByte(asc_dvc,
                   14212:                 AscPCIConfigCommandRegister, pci_cmd_reg);
                   14213: 
                   14214:         if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister))
                   14215:              & AscPCICmdRegBits_BusMastering)
                   14216:             != AscPCICmdRegBits_BusMastering)
                   14217:         {
                   14218:             warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
                   14219:         }
                   14220:     }
                   14221: 
                   14222:     /*
                   14223:      * PCI Latency Timer
                   14224:      *
                   14225:      * If the "latency timer" register is 0x20 or above, then we don't need
                   14226:      * to change it.  Otherwise, set it to 0x20 (i.e. set it to 0x20 if it
                   14227:      * comes up less than 0x20).
                   14228:      */
                   14229:     if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) {
                   14230:         DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer, 0x20);
                   14231:         if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20)
                   14232:         {
                   14233:             warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
                   14234:         }
                   14235:     }
                   14236: 
                   14237:     /*
                   14238:      * Save the state of the PCI Configuration Command Register
                   14239:      * "Parity Error Response Control" Bit. If the bit is clear (0),
                   14240:      * in AdvInitAsc3550Driver() tell the microcode to ignore DMA
                   14241:      * parity errors.
                   14242:      */
                   14243:     asc_dvc->cfg->control_flag = 0;
                   14244:     if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister)
                   14245:          & AscPCICmdRegBits_ParErrRespCtrl)) == 0)
                   14246:     {
                   14247:         asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
                   14248:     }
                   14249: 
                   14250:     asc_dvc->cur_host_qng = 0;
                   14251: 
                   14252:     asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
                   14253:       ADV_LIB_VERSION_MINOR;
                   14254:     asc_dvc->cfg->chip_version =
                   14255:       AdvGetChipVersion(iop_base, asc_dvc->bus_type);
                   14256: 
                   14257:     /*
                   14258:      * Reset the chip to start and allow register writes.
                   14259:      */
                   14260:     if (AdvFindSignature(iop_base) == 0)
                   14261:     {
                   14262:         asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
                   14263:         return ADV_ERROR;
                   14264:     }
                   14265:     else {
                   14266: 
                   14267:         AdvResetChip(asc_dvc);
                   14268: 
                   14269:         if ((status = AdvInitFromEEP(asc_dvc)) == ADV_ERROR)
                   14270:         {
                   14271:             return ADV_ERROR;
                   14272:         }
                   14273:         warn_code |= status;
                   14274: 
                   14275:         /*
                   14276:          * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
                   14277:          * Resets should be performed.
                   14278:          */
                   14279:         if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
                   14280:         {
                   14281:             AdvResetSCSIBus(asc_dvc);
                   14282:         }
                   14283:     }
                   14284: 
                   14285:     return warn_code;
                   14286: }
                   14287: 
                   14288: /*
                   14289:  * Initialize the ASC3550.
                   14290:  *
                   14291:  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
                   14292:  *
                   14293:  * For a non-fatal error return a warning code. If there are no warnings
                   14294:  * then 0 is returned.
                   14295:  */
                   14296: ASC_INITFUNC(
                   14297: int
                   14298: AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
                   14299: )
                   14300: {
                   14301:     AdvPortAddr iop_base;
                   14302:     ushort      warn_code;
                   14303:     ulong       sum;
                   14304:     int         begin_addr;
                   14305:     int         end_addr;
                   14306:     int         code_sum;
                   14307:     int         word;
                   14308:     int         rql_addr;                   /* RISC Queue List address */
                   14309:     int         i;
                   14310:     ushort      scsi_cfg1;
                   14311:     uchar       biosmem[ASC_MC_BIOSLEN];    /* BIOS RISC Memory 0x40-0x8F. */
                   14312: 
                   14313:     /* If there is already an error, don't continue. */
                   14314:     if (asc_dvc->err_code != 0)
                   14315:     {
                   14316:         return ADV_ERROR;
                   14317:     }
                   14318: 
                   14319:     warn_code = 0;
                   14320:     iop_base = asc_dvc->iop_base;
                   14321: 
                   14322:     /*
                   14323:      * Save the RISC memory BIOS region before writing the microcode.
                   14324:      * The BIOS may already be loaded and using its RISC LRAM region
                   14325:      * so its region must be saved and restored.
                   14326:      *
                   14327:      * Note: This code makes the assumption, which is currently true,
                   14328:      * that a chip reset does not clear RISC LRAM.
                   14329:      */
                   14330:     for (i = 0; i < ASC_MC_BIOSLEN; i++)
                   14331:     {
                   14332:         AdvReadByteLram(iop_base, ASC_MC_BIOSMEM + i, biosmem[i]);
                   14333:     }
                   14334: 
                   14335:     /*
                   14336:      * Load the Microcode
                   14337:      *
                   14338:      * Write the microcode image to RISC memory starting at address 0.
                   14339:      */
                   14340:     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
                   14341:     for (word = 0; word < _adv_mcode_size; word += 2)
                   14342:     {
                   14343:         AdvWriteWordAutoIncLram(iop_base,
                   14344:             *((ushort *) (&_adv_mcode_buf[word])));
                   14345:     }
                   14346: 
                   14347:     /*
                   14348:      * Clear the rest of Condor's Internal RAM (8KB).
                   14349:      */
                   14350:     for (; word < ADV_CONDOR_MEMSIZE; word += 2)
                   14351:     {
                   14352:         AdvWriteWordAutoIncLram(iop_base, 0);
                   14353:     }
                   14354: 
                   14355:     /*
                   14356:      * Verify the microcode checksum.
                   14357:      */
                   14358:     sum = 0;
                   14359:     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
                   14360:     for (word = 0; word < _adv_mcode_size; word += 2)
                   14361:     {
                   14362:         sum += AdvReadWordAutoIncLram(iop_base);
                   14363:     }
                   14364: 
                   14365:     if (sum != _adv_mcode_chksum)
                   14366:     {
                   14367:         asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
                   14368:         return ADV_ERROR;
                   14369:     }
                   14370: 
                   14371:     /*
                   14372:      * Restore the RISC memory BIOS region.
                   14373:      */
                   14374:     for (i = 0; i < ASC_MC_BIOSLEN; i++)
                   14375:     {
                   14376:         AdvWriteByteLram(iop_base, ASC_MC_BIOSMEM + i, biosmem[i]);
                   14377:     }
                   14378: 
                   14379:     /*
                   14380:      * Calculate and write the microcode code checksum to the microcode
                   14381:      * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).  
                   14382:      */
                   14383:     AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
                   14384:     AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
                   14385:     code_sum = 0;
                   14386:     for (word = begin_addr; word < end_addr; word += 2)
                   14387:     {
                   14388:         code_sum += *((ushort *) (&_adv_mcode_buf[word]));
                   14389:     }
                   14390:     AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
                   14391: 
                   14392:     /*
                   14393:      * Read microcode version and date.
                   14394:      */
                   14395:     AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
                   14396:     AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
                   14397: 
                   14398:     /*
                   14399:      * Initialize microcode operating variables
                   14400:      */
                   14401:     AdvWriteWordLram(iop_base, ASC_MC_ADAPTER_SCSI_ID,
                   14402:                        asc_dvc->chip_scsi_id);
                   14403: 
                   14404:     /*
                   14405:      * If the PCI Configuration Command Register "Parity Error Response
                   14406:      * Control" Bit was clear (0), then set the microcode variable
                   14407:      * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
                   14408:      * to ignore DMA parity errors.
                   14409:      */
                   14410:     if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
                   14411:     {
                   14412:         /* 
                   14413:          * Note: Don't remove the use of a temporary variable in
                   14414:          * the following code, otherwise the Microsoft C compiler
                   14415:          * will turn the following lines into a no-op.
                   14416:          */
                   14417:         AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
                   14418:         word |= CONTROL_FLAG_IGNORE_PERR;
                   14419:         AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
                   14420:     }
                   14421: 
                   14422:     /*
                   14423:      * Set default microcode operating variables for WDTR, SDTR, and
                   14424:      * command tag queuing based on the EEPROM configuration values.
                   14425:      *
                   14426:      * These ADV_DVC_VAR fields and the microcode variables will be
                   14427:      * changed in AdvInquiryHandling() if it is found a device is
                   14428:      * incapable of a particular feature.
                   14429:      */
                   14430: 
                   14431:     /*
                   14432:      * Set the microcode ULTRA target mask from EEPROM value. The
                   14433:      * SDTR target mask overrides the ULTRA target mask in the
                   14434:      * microcode so it is safe to set this value without determining
                   14435:      * whether the device supports SDTR.
                   14436:      * 
                   14437:      * Note: There is no way to know whether a device supports ULTRA
                   14438:      * speed without attempting a SDTR ULTRA speed negotiation with
                   14439:      * the device. The device will reject the speed if it does not
                   14440:      * support it by responding with an SDTR message containing a
                   14441:      * slower speed.
                   14442:      */
                   14443:     AdvWriteWordLram(iop_base, ASC_MC_ULTRA_ABLE, asc_dvc->ultra_able);
                   14444:     AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
                   14445: 
                   14446: 
                   14447:     /*
                   14448:      * Set SCSI_CFG0 Microcode Default Value.
                   14449:      *
                   14450:      * The microcode will set the SCSI_CFG0 register using this value
                   14451:      * after it is started below.
                   14452:      */
                   14453:     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
                   14454:         PARITY_EN | SEL_TMO_LONG | OUR_ID_EN | asc_dvc->chip_scsi_id);
                   14455:   
                   14456:     /*
                   14457:      * Determine SCSI_CFG1 Microcode Default Value.
                   14458:      *
                   14459:      * The microcode will set the SCSI_CFG1 register using this value
                   14460:      * after it is started below.
                   14461:      */
                   14462: 
                   14463:     /* Read current SCSI_CFG1 Register value. */
                   14464:     scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
                   14465: 
                   14466:     /*
                   14467:      * If all three connectors are in use, return an error.
                   14468:      */
                   14469:     if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
                   14470:         (scsi_cfg1 & CABLE_ILLEGAL_B) == 0)
                   14471:     {
                   14472:         asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
                   14473:         return ADV_ERROR;
                   14474:     }
                   14475: 
                   14476:     /*
                   14477:      * If the internal narrow cable is reversed all of the SCSI_CTRL
                   14478:      * register signals will be set. Check for and return an error if
                   14479:      * this condition is found.
                   14480:      */
                   14481:     if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
                   14482:     {
                   14483:         asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
                   14484:         return ADV_ERROR;
                   14485:     }
                   14486: 
                   14487:     /*
                   14488:      * If this is a differential board and a single-ended device
                   14489:      * is attached to one of the connectors, return an error.
                   14490:      */
                   14491:     if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0)
                   14492:     {
                   14493:         asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
                   14494:         return ADV_ERROR;
                   14495:     }
                   14496: 
                   14497:     /*
                   14498:      * If automatic termination control is enabled, then set the
                   14499:      * termination value based on a table listed in a_condor.h.
                   14500:      *
                   14501:      * If manual termination was specified with an EEPROM setting
                   14502:      * then 'termination' was set-up in AdvInitFromEEP() and
                   14503:      * is ready to be 'ored' into SCSI_CFG1.
                   14504:      */
                   14505:     if (asc_dvc->cfg->termination == 0)
                   14506:     {
                   14507:         /*
                   14508:          * The software always controls termination by setting TERM_CTL_SEL.
                   14509:          * If TERM_CTL_SEL were set to 0, the hardware would set termination.
                   14510:          */
                   14511:         asc_dvc->cfg->termination |= TERM_CTL_SEL;
                   14512: 
                   14513:         switch(scsi_cfg1 & CABLE_DETECT)
                   14514:         {
                   14515:             /* TERM_CTL_H: on, TERM_CTL_L: on */
                   14516:             case 0x3: case 0x7: case 0xB: case 0xD: case 0xE: case 0xF:
                   14517:                 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
                   14518:                 break;
                   14519: 
                   14520:             /* TERM_CTL_H: on, TERM_CTL_L: off */
                   14521:             case 0x1: case 0x5: case 0x9: case 0xA: case 0xC:
                   14522:                 asc_dvc->cfg->termination |= TERM_CTL_H;
                   14523:                 break;
                   14524: 
                   14525:             /* TERM_CTL_H: off, TERM_CTL_L: off */
                   14526:             case 0x2: case 0x6:
                   14527:                 break;
                   14528:         }
                   14529:     }
                   14530: 
                   14531:     /*
                   14532:      * Clear any set TERM_CTL_H and TERM_CTL_L bits.
                   14533:      */
                   14534:     scsi_cfg1 &= ~TERM_CTL;
                   14535: 
                   14536:     /*
                   14537:      * Invert the TERM_CTL_H and TERM_CTL_L bits and then
                   14538:      * set 'scsi_cfg1'. The TERM_POL bit does not need to be
                   14539:      * referenced, because the hardware internally inverts
                   14540:      * the Termination High and Low bits if TERM_POL is set.
                   14541:      */
                   14542:     scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
                   14543: 
                   14544:     /*
                   14545:      * Set SCSI_CFG1 Microcode Default Value
                   14546:      *
                   14547:      * Set filter value and possibly modified termination control
                   14548:      * bits in the Microcode SCSI_CFG1 Register Value.
                   14549:      *
                   14550:      * The microcode will set the SCSI_CFG1 register using this value
                   14551:      * after it is started below.
                   14552:      */
                   14553:     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
                   14554:                        FLTR_11_TO_20NS | scsi_cfg1);
                   14555: 
                   14556:     /*
                   14557:      * Set SEL_MASK Microcode Default Value
                   14558:      *
                   14559:      * The microcode will set the SEL_MASK register using this value
                   14560:      * after it is started below.
                   14561:      */
                   14562:     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
                   14563:                         ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
                   14564: 
                   14565:     /*
                   14566:      * Link all the RISC Queue Lists together in a doubly-linked
                   14567:      * NULL terminated list.
                   14568:      *
                   14569:      * Skip the NULL (0) queue which is not used.
                   14570:      */
                   14571:     for (i = 1, rql_addr = ASC_MC_RISC_Q_LIST_BASE + ASC_MC_RISC_Q_LIST_SIZE;
                   14572:          i < ASC_MC_RISC_Q_TOTAL_CNT;
                   14573:          i++, rql_addr += ASC_MC_RISC_Q_LIST_SIZE)
                   14574:     {
                   14575:         /*
                   14576:          * Set the current RISC Queue List's RQL_FWD and RQL_BWD pointers
                   14577:          * in a one word write and set the state (RQL_STATE) to free.
                   14578:          */
                   14579:         AdvWriteWordLram(iop_base, rql_addr, ((i + 1) + ((i - 1) << 8)));
                   14580:         AdvWriteByteLram(iop_base, rql_addr + RQL_STATE, ASC_MC_QS_FREE);
                   14581:     }
                   14582: 
                   14583:     /*
                   14584:      * Set the Host and RISC Queue List pointers.
                   14585:      *
                   14586:      * Both sets of pointers are initialized with the same values:
                   14587:      * ASC_MC_RISC_Q_FIRST(0x01) and ASC_MC_RISC_Q_LAST (0xFF).
                   14588:      */
                   14589:     AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_READY, ASC_MC_RISC_Q_FIRST);
                   14590:     AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_DONE, ASC_MC_RISC_Q_LAST);
                   14591: 
                   14592:     AdvWriteByteLram(iop_base, ASC_MC_RISC_NEXT_READY, ASC_MC_RISC_Q_FIRST);
                   14593:     AdvWriteByteLram(iop_base, ASC_MC_RISC_NEXT_DONE, ASC_MC_RISC_Q_LAST);
                   14594: 
                   14595:     /*
                   14596:      * Finally, set up the last RISC Queue List (255) with
                   14597:      * a NULL forward pointer.
                   14598:      */
                   14599:     AdvWriteWordLram(iop_base, rql_addr, (ASC_MC_NULL_Q + ((i - 1) << 8)));
                   14600:     AdvWriteByteLram(iop_base, rql_addr + RQL_STATE, ASC_MC_QS_FREE);
                   14601: 
                   14602:     AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
                   14603:          (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
                   14604: 
                   14605:     /* 
                   14606:      * Note: Don't remove the use of a temporary variable in
                   14607:      * the following code, otherwise the Microsoft C compiler
                   14608:      * will turn the following lines into a no-op.
                   14609:      */
                   14610:     AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
                   14611:     AdvWriteWordRegister(iop_base, IOPW_PC, word);
                   14612: 
                   14613:     /* finally, finally, gentlemen, start your engine */
                   14614:     AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
                   14615:  
                   14616:     return warn_code;
                   14617: }
                   14618: 
                   14619: /*
                   14620:  * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
                   14621:  * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
                   14622:  * all of this is done.
                   14623:  *
                   14624:  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
                   14625:  *
                   14626:  * For a non-fatal error return a warning code. If there are no warnings
                   14627:  * then 0 is returned.
                   14628:  *
                   14629:  * Note: Chip is stopped on entry.
                   14630:  */
                   14631: ASC_INITFUNC(
                   14632: STATIC int
                   14633: AdvInitFromEEP(ADV_DVC_VAR *asc_dvc)
                   14634: )
                   14635: {
                   14636:     AdvPortAddr         iop_base;
                   14637:     ushort              warn_code;
                   14638:     ADVEEP_CONFIG       eep_config;
                   14639:     int                 i;
                   14640: 
                   14641:     iop_base = asc_dvc->iop_base;
                   14642: 
                   14643:     warn_code = 0;
                   14644: 
                   14645:     /*
                   14646:      * Read the board's EEPROM configuration.
                   14647:      *
                   14648:      * Set default values if a bad checksum is found.
                   14649:      */
                   14650:     if (AdvGetEEPConfig(iop_base, &eep_config) != eep_config.check_sum)
                   14651:     {
                   14652:         warn_code |= ASC_WARN_EEPROM_CHKSUM;
                   14653: 
                   14654:         /*
                   14655:          * Set EEPROM default values.
                   14656:          */
                   14657:         for (i = 0; i < sizeof(ADVEEP_CONFIG); i++)
                   14658:         {
                   14659:             *((uchar *) &eep_config + i) =
                   14660:                 *((uchar *) &Default_EEPROM_Config + i);
                   14661:         }
                   14662: 
                   14663:         /*
                   14664:          * Assume the 6 byte board serial number that was read
                   14665:          * from EEPROM is correct even if the EEPROM checksum
                   14666:          * failed.
                   14667:          */
                   14668:         eep_config.serial_number_word3 =
                   14669:             AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 1);
                   14670:         eep_config.serial_number_word2 =
                   14671:             AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 2);
                   14672:         eep_config.serial_number_word1 =
                   14673:             AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 3);
                   14674:         AdvSetEEPConfig(iop_base, &eep_config);
                   14675:     }
                   14676: 
                   14677:     /*
                   14678:      * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
                   14679:      * EEPROM configuration that was read.
                   14680:      *
                   14681:      * This is the mapping of EEPROM fields to Adv Library fields.
                   14682:      */
                   14683:     asc_dvc->wdtr_able = eep_config.wdtr_able;
                   14684:     asc_dvc->sdtr_able = eep_config.sdtr_able;
                   14685:     asc_dvc->ultra_able = eep_config.ultra_able;
                   14686:     asc_dvc->tagqng_able = eep_config.tagqng_able;
                   14687:     asc_dvc->cfg->disc_enable = eep_config.disc_enable;
                   14688:     asc_dvc->max_host_qng = eep_config.max_host_qng;
                   14689:     asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
                   14690:     asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
                   14691:     asc_dvc->start_motor = eep_config.start_motor;
                   14692:     asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
                   14693:     asc_dvc->cfg->bios_boot_wait = eep_config.bios_boot_delay;
                   14694:     asc_dvc->bios_ctrl = eep_config.bios_ctrl;
                   14695:     asc_dvc->no_scam = eep_config.scam_tolerant;
                   14696:     asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
                   14697:     asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
                   14698:     asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
                   14699: 
                   14700:     /*
                   14701:      * Set the host maximum queuing (max. 253, min. 16) and the per device
                   14702:      * maximum queuing (max. 63, min. 4).
                   14703:      */
                   14704:     if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
                   14705:     {
                   14706:         eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
                   14707:     } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
                   14708:     {
                   14709:         /* If the value is zero, assume it is uninitialized. */
                   14710:         if (eep_config.max_host_qng == 0)
                   14711:         {
                   14712:             eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
                   14713:         } else
                   14714:         {
                   14715:             eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
                   14716:         }
                   14717:     }
                   14718: 
                   14719:     if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
                   14720:     {
                   14721:         eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
                   14722:     } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
                   14723:     {
                   14724:         /* If the value is zero, assume it is uninitialized. */
                   14725:         if (eep_config.max_dvc_qng == 0)
                   14726:         {
                   14727:             eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
                   14728:         } else
                   14729:         {
                   14730:             eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
                   14731:         }
                   14732:     }
                   14733: 
                   14734:     /*
                   14735:      * If 'max_dvc_qng' is greater than 'max_host_qng', then
                   14736:      * set 'max_dvc_qng' to 'max_host_qng'.
                   14737:      */
                   14738:     if (eep_config.max_dvc_qng > eep_config.max_host_qng)
                   14739:     {
                   14740:         eep_config.max_dvc_qng = eep_config.max_host_qng;
                   14741:     }
                   14742: 
                   14743:     /*
                   14744:      * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_CFG 'max_dvc_qng'
                   14745:      * values based on possibly adjusted EEPROM values.
                   14746:      */
                   14747:     asc_dvc->max_host_qng = eep_config.max_host_qng;
                   14748:     asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
                   14749: 
                   14750: 
                   14751:     /*
                   14752:      * If the EEPROM 'termination' field is set to automatic (0), then set
                   14753:      * the ADV_DVC_CFG 'termination' field to automatic also.
                   14754:      *
                   14755:      * If the termination is specified with a non-zero 'termination'
                   14756:      * value check that a legal value is set and set the ADV_DVC_CFG
                   14757:      * 'termination' field appropriately.
                   14758:      */
                   14759:     if (eep_config.termination == 0)
                   14760:     {
                   14761:         asc_dvc->cfg->termination = 0;    /* auto termination */
                   14762:     } else
                   14763:     {
                   14764:         /* Enable manual control with low off / high off. */
                   14765:         if (eep_config.termination == 1)
                   14766:         {
                   14767:             asc_dvc->cfg->termination = TERM_CTL_SEL;
                   14768: 
                   14769:         /* Enable manual control with low off / high on. */
                   14770:         } else if (eep_config.termination == 2)
                   14771:         {
                   14772:             asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
                   14773: 
                   14774:         /* Enable manual control with low on / high on. */
                   14775:         } else if (eep_config.termination == 3)
                   14776:         {
                   14777:             asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
                   14778:         } else
                   14779:         {
                   14780:             /*
                   14781:              * The EEPROM 'termination' field contains a bad value. Use
                   14782:              * automatic termination instead.
                   14783:              */
                   14784:             asc_dvc->cfg->termination = 0;
                   14785:             warn_code |= ASC_WARN_EEPROM_TERMINATION;
                   14786:         }
                   14787:     }
                   14788: 
                   14789:     return warn_code;
                   14790: }
                   14791: 
                   14792: /*
                   14793:  * Read EEPROM configuration into the specified buffer.
                   14794:  *
                   14795:  * Return a checksum based on the EEPROM configuration read.
                   14796:  */
                   14797: ASC_INITFUNC(
                   14798: STATIC ushort
                   14799: AdvGetEEPConfig(AdvPortAddr iop_base, ADVEEP_CONFIG *cfg_buf)
                   14800: )
                   14801: {
                   14802:     ushort              wval, chksum;
                   14803:     ushort              *wbuf;
                   14804:     int                 eep_addr;
                   14805: 
                   14806:     wbuf = (ushort *) cfg_buf;
                   14807:     chksum = 0;
                   14808: 
                   14809:     for (eep_addr = ASC_EEP_DVC_CFG_BEGIN;
                   14810:          eep_addr < ASC_EEP_DVC_CFG_END;
                   14811:          eep_addr++, wbuf++)
                   14812:     {
                   14813:         wval = AdvReadEEPWord(iop_base, eep_addr);
                   14814:         chksum += wval;
                   14815:         *wbuf = wval;
                   14816:     }
                   14817:     *wbuf = AdvReadEEPWord(iop_base, eep_addr);
                   14818:     wbuf++;
                   14819:     for (eep_addr = ASC_EEP_DVC_CTL_BEGIN;
                   14820:          eep_addr < ASC_EEP_MAX_WORD_ADDR;
                   14821:          eep_addr++, wbuf++)
                   14822:     {
                   14823:         *wbuf = AdvReadEEPWord(iop_base, eep_addr);
                   14824:     }
                   14825:     return chksum;
                   14826: }
                   14827: 
                   14828: /*
                   14829:  * Read the EEPROM from specified location
                   14830:  */
                   14831: ASC_INITFUNC(
                   14832: STATIC ushort
                   14833: AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
                   14834: )
                   14835: {
                   14836:     AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
                   14837:         ASC_EEP_CMD_READ | eep_word_addr);
                   14838:     AdvWaitEEPCmd(iop_base);
                   14839:     return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
                   14840: }
                   14841: 
                   14842: /*
                   14843:  * Wait for EEPROM command to complete
                   14844:  */
                   14845: ASC_INITFUNC(
                   14846: STATIC void
                   14847: AdvWaitEEPCmd(AdvPortAddr iop_base)
                   14848: )
                   14849: {
                   14850:     int eep_delay_ms;
                   14851: 
                   14852:     for (eep_delay_ms = 0; eep_delay_ms < ASC_EEP_DELAY_MS; eep_delay_ms++)
                   14853:     {
                   14854:         if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE)
                   14855:         {
                   14856:             break;
                   14857:         }
                   14858:         DvcSleepMilliSecond(1);
                   14859:     }
                   14860:     if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) == 0)
                   14861:     {
                   14862:         ADV_ASSERT(0);
                   14863:     }
                   14864:     return;
                   14865: }
                   14866: 
                   14867: /*
                   14868:  * Write the EEPROM from 'cfg_buf'.
                   14869:  */
                   14870: ASC_INITFUNC(
                   14871: STATIC void
                   14872: AdvSetEEPConfig(AdvPortAddr iop_base, ADVEEP_CONFIG *cfg_buf)
                   14873: )
                   14874: {
                   14875:     ushort       *wbuf;
                   14876:     ushort       addr, chksum;
                   14877: 
                   14878:     wbuf = (ushort *) cfg_buf;
                   14879:     chksum = 0;
                   14880: 
                   14881:     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
                   14882:     AdvWaitEEPCmd(iop_base);
                   14883: 
                   14884:     /*
                   14885:      * Write EEPROM from word 0 to word 15
                   14886:      */
                   14887:     for (addr = ASC_EEP_DVC_CFG_BEGIN;
                   14888:          addr < ASC_EEP_DVC_CFG_END; addr++, wbuf++)
                   14889:     {
                   14890:         chksum += *wbuf;
                   14891:         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf);
                   14892:         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
                   14893:         AdvWaitEEPCmd(iop_base);
                   14894:         DvcSleepMilliSecond(ASC_EEP_DELAY_MS);
                   14895:     }
                   14896: 
                   14897:     /*
                   14898:      * Write EEPROM checksum at word 18
                   14899:      */
                   14900:     AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
                   14901:     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
                   14902:     AdvWaitEEPCmd(iop_base);
                   14903:     wbuf++;        /* skip over check_sum */
                   14904: 
                   14905:     /*
                   14906:      * Write EEPROM OEM name at words 19 to 26 
                   14907:      */
                   14908:     for (addr = ASC_EEP_DVC_CTL_BEGIN;
                   14909:          addr < ASC_EEP_MAX_WORD_ADDR; addr++, wbuf++)
                   14910:     {
                   14911:         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf);
                   14912:         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
                   14913:         AdvWaitEEPCmd(iop_base);
                   14914:     }
                   14915:     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
                   14916:     AdvWaitEEPCmd(iop_base);
                   14917:     return;
                   14918: }
                   14919: 
                   14920: /*
                   14921:  * This function resets the chip and SCSI bus
                   14922:  *
                   14923:  * It is up to the caller to add a delay to let the bus settle after
                   14924:  * calling this function.
                   14925:  *
                   14926:  * The SCSI_CFG0, SCSI_CFG1, and MEM_CFG registers are set-up in
                   14927:  * AdvInitAsc3550Driver(). Here when doing a write to one of these
                   14928:  * registers read first and then write.
                   14929:  *
                   14930:  * Note: A SCSI Bus Reset can not be done until after the EEPROM
                   14931:  * configuration is read to determine whether SCSI Bus Resets
                   14932:  * should be performed.
                   14933:  */
                   14934: ASC_INITFUNC(
                   14935: STATIC void
                   14936: AdvResetChip(ADV_DVC_VAR *asc_dvc)
                   14937: )
                   14938: {
                   14939:     AdvPortAddr    iop_base;
                   14940:     ushort         word;
                   14941:     uchar          byte;
                   14942: 
                   14943:     iop_base = asc_dvc->iop_base;
                   14944: 
                   14945:     /*
                   14946:      * Reset Chip.
                   14947:      */
                   14948:     AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
                   14949:     DvcSleepMilliSecond(100);
                   14950:     AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_WR_IO_REG);
                   14951: 
                   14952:     /*
                   14953:      * Initialize Chip registers.
                   14954:      * 
                   14955:      * Note: Don't remove the use of a temporary variable in the following
                   14956:      * code, otherwise the Microsoft C compiler will turn the following lines
                   14957:      * into a no-op.
                   14958:      */
                   14959:     byte = AdvReadByteRegister(iop_base, IOPB_MEM_CFG);
                   14960:     byte |= RAM_SZ_8KB;
                   14961:     AdvWriteByteRegister(iop_base, IOPB_MEM_CFG, byte);
                   14962: 
                   14963:     word = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
                   14964:     word &= ~BIG_ENDIAN;
                   14965:     AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, word);
                   14966: 
                   14967:     /*
                   14968:      * Setting the START_CTL_EMFU 3:2 bits sets a FIFO threshold
                   14969:      * of 128 bytes. This register is only accessible to the host.
                   14970:      */
                   14971:     AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
                   14972:         START_CTL_EMFU | READ_CMD_MRM);
                   14973: }
                   14974: 
                   14975: /* a_advlib.c */
                   14976: /*
                   14977:  * Description:
                   14978:  *      Send a SCSI request to the ASC3550 chip
                   14979:  *
                   14980:  * If there is no SG list for the request, set 'sg_entry_cnt' to 0.
                   14981:  *
                   14982:  * If 'sg_real_addr' is non-zero on entry, AscGetSGList() will not be
                   14983:  * called. It is assumed the caller has already initialized 'sg_real_addr'.
                   14984:  *
                   14985:  * Return:
                   14986:  *      ADV_SUCCESS(1) - the request is in the mailbox
                   14987:  *      ADV_BUSY(0) - total request count > 253, try later
                   14988:  *      ADV_ERROR(-1) - invalid scsi request Q
                   14989:  */
                   14990: STATIC int
                   14991: AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc,
                   14992:                 ADV_SCSI_REQ_Q *scsiq)
                   14993: {
                   14994:     if (scsiq == (ADV_SCSI_REQ_Q *) 0L)
                   14995:     {
                   14996:         /* 'scsiq' should never be NULL. */
                   14997:         ADV_ASSERT(0);
                   14998:         return ADV_ERROR;
                   14999:     }
                   15000: 
                   15001:     return AdvSendScsiCmd(asc_dvc, scsiq);
                   15002: }
                   15003: 
                   15004: /*
                   15005:  * Reset SCSI Bus and purge all outstanding requests.
                   15006:  *
                   15007:  * Return Value:
                   15008:  *      ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
                   15009:  *
                   15010:  * Note: Should always return ADV_TRUE.
                   15011:  */
                   15012: STATIC int
                   15013: AdvResetSB(ADV_DVC_VAR *asc_dvc)
                   15014: {
                   15015:     int         status;
                   15016: 
                   15017:     status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET, 0L, 0);
                   15018: 
                   15019:     AdvResetSCSIBus(asc_dvc);
                   15020: 
                   15021:     return status;
                   15022: }
                   15023: 
                   15024: /*
                   15025:  * Reset SCSI Bus and delay.
                   15026:  */
                   15027: STATIC void
                   15028: AdvResetSCSIBus(ADV_DVC_VAR *asc_dvc)
                   15029: {
                   15030:     AdvPortAddr    iop_base;
                   15031:     ushort         scsi_ctrl;
                   15032: 
                   15033:     iop_base = asc_dvc->iop_base;
                   15034: 
                   15035:     /*
                   15036:      * The microcode currently sets the SCSI Bus Reset signal while
                   15037:      * handling the AscSendIdleCmd() IDLE_CMD_SCSI_RESET command above.
                   15038:      * But the SCSI Bus Reset Hold Time in the microcode is not deterministic
                   15039:      * (it may in fact be for less than the SCSI Spec. minimum of 25 us).
                   15040:      * Therefore on return the Adv Library sets the SCSI Bus Reset signal
                   15041:      * for ASC_SCSI_RESET_HOLD_TIME_US, which is defined to be greater
                   15042:      * than 25 us.
                   15043:      */
                   15044:     scsi_ctrl = AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL);
                   15045:     AdvWriteWordRegister(iop_base, IOPW_SCSI_CTRL,
                   15046:         scsi_ctrl | ADV_SCSI_CTRL_RSTOUT);
                   15047:     DvcDelayMicroSecond(asc_dvc, (ushort) ASC_SCSI_RESET_HOLD_TIME_US);
                   15048:     AdvWriteWordRegister(iop_base, IOPW_SCSI_CTRL,
                   15049:         scsi_ctrl & ~ADV_SCSI_CTRL_RSTOUT);
                   15050: 
                   15051:     DvcSleepMilliSecond((ulong) asc_dvc->scsi_reset_wait * 1000);
                   15052: }
                   15053: 
                   15054: 
                   15055: /*
                   15056:  * Adv Library Interrupt Service Routine
                   15057:  *
                   15058:  *  This function is called by a driver's interrupt service routine.
                   15059:  *  The function disables and re-enables interrupts.
                   15060:  *
                   15061:  *  When a microcode idle command is completed, the ADV_DVC_VAR
                   15062:  *  'idle_cmd_done' field is set to ADV_TRUE.
                   15063:  *
                   15064:  *  Note: AdvISR() can be called when interrupts are disabled or even
                   15065:  *  when there is no hardware interrupt condition present. It will
                   15066:  *  always check for completed idle commands and microcode requests.
                   15067:  *  This is an important feature that shouldn't be changed because it
                   15068:  *  allows commands to be completed from polling mode loops.
                   15069:  *
                   15070:  * Return:
                   15071:  *   ADV_TRUE(1) - interrupt was pending
                   15072:  *   ADV_FALSE(0) - no interrupt was pending
                   15073:  */
                   15074: STATIC int
                   15075: AdvISR(ADV_DVC_VAR *asc_dvc)
                   15076: {
                   15077:     AdvPortAddr                 iop_base;
                   15078:     uchar                       int_stat;
                   15079:     ushort                      next_done_loc, target_bit;
                   15080:     int                         completed_q;
1.1.1.2 ! root     15081:     long                        flags;
1.1       root     15082:     ADV_SCSI_REQ_Q              *scsiq;
                   15083:     ASC_REQ_SENSE               *sense_data;
                   15084:     int                         ret;
                   15085: 
                   15086:     flags = DvcEnterCritical();
                   15087:     iop_base = asc_dvc->iop_base;
                   15088: 
                   15089:     if (AdvIsIntPending(iop_base))
                   15090:     {
                   15091:         ret = ADV_TRUE;
                   15092:     } else
                   15093:     {
                   15094:         ret = ADV_FALSE;
                   15095:     }
                   15096: 
                   15097:     /* Reading the register clears the interrupt. */
                   15098:     int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
                   15099: 
                   15100:     if (int_stat & ADV_INTR_STATUS_INTRB)
                   15101:     {
                   15102:         asc_dvc->idle_cmd_done = ADV_TRUE;
                   15103:     }
                   15104: 
                   15105:     /*
                   15106:      * Notify the driver of a hardware detected SCSI Bus Reset.
                   15107:      */
                   15108:     if (int_stat & ADV_INTR_STATUS_INTRC)
                   15109:     {
                   15110:         if (asc_dvc->sbreset_callback != 0)
                   15111:         {
                   15112:             (*(ADV_SBRESET_CALLBACK) asc_dvc->sbreset_callback)(asc_dvc);
                   15113:         }
                   15114:     }
                   15115: 
                   15116:     /*
                   15117:      * ASC_MC_HOST_NEXT_DONE (0x129) is actually the last completed RISC
                   15118:      * Queue List request. Its forward pointer (RQL_FWD) points to the
                   15119:      * current completed RISC Queue List request.
                   15120:      */
                   15121:     AdvReadByteLram(iop_base, ASC_MC_HOST_NEXT_DONE, next_done_loc);
                   15122:     next_done_loc = ASC_MC_RISC_Q_LIST_BASE +
                   15123:         (next_done_loc * ASC_MC_RISC_Q_LIST_SIZE) + RQL_FWD;
                   15124: 
                   15125:     AdvReadByteLram(iop_base, next_done_loc, completed_q);
                   15126: 
                   15127:     /* Loop until all completed Q's are processed. */
                   15128:     while (completed_q != ASC_MC_NULL_Q)
                   15129:     {
                   15130:         AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_DONE, completed_q);
                   15131: 
                   15132:         next_done_loc = ASC_MC_RISC_Q_LIST_BASE +
                   15133:           (completed_q * ASC_MC_RISC_Q_LIST_SIZE);
                   15134: 
                   15135:         /*
                   15136:          * Read the ADV_SCSI_REQ_Q virtual address pointer from
                   15137:          * the RISC list entry. The microcode has changed the
                   15138:          * ADV_SCSI_REQ_Q physical address to its virtual address.
                   15139:          *
                   15140:          * Refer to comments at the end of AdvSendScsiCmd() for
                   15141:          * more information on the RISC list structure.
                   15142:          */
                   15143:         {
                   15144:             ushort lsw, msw;
                   15145:             AdvReadWordLram(iop_base, next_done_loc + RQL_PHYADDR, lsw);
                   15146:             AdvReadWordLram(iop_base, next_done_loc + RQL_PHYADDR + 2, msw);
                   15147: 
                   15148:             scsiq = (ADV_SCSI_REQ_Q *) (((ulong) msw << 16) | lsw);
                   15149:         }
                   15150:         ADV_ASSERT(scsiq != NULL);
                   15151: 
                   15152:         target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
                   15153: 
                   15154:         /*
                   15155:          * Clear request microcode control flag.
                   15156:          */
                   15157:         scsiq->cntl = 0;
                   15158: 
                   15159:         /*
                   15160:          * Check Condition handling
                   15161:          */
                   15162:         if ((scsiq->done_status == QD_WITH_ERROR) &&
                   15163:             (scsiq->scsi_status == SS_CHK_CONDITION) &&
                   15164:             (sense_data = (ASC_REQ_SENSE *) scsiq->vsense_addr) != 0 &&
                   15165:             (scsiq->orig_sense_len - scsiq->sense_len) >= ASC_MIN_SENSE_LEN)
                   15166:         {
                   15167:             /*
                   15168:              * Command returned with a check condition and valid
                   15169:              * sense data.
                   15170:              */
                   15171:         }
                   15172:         /*
                   15173:          * If the command that completed was a SCSI INQUIRY and
                   15174:          * LUN 0 was sent the command, then process the INQUIRY
                   15175:          * command information for the device.
                   15176:          */
                   15177:         else if (scsiq->done_status == QD_NO_ERROR &&
                   15178:                    scsiq->cdb[0] == SCSICMD_Inquiry &&
                   15179:                    scsiq->target_lun == 0)
                   15180:         {
                   15181:             AdvInquiryHandling(asc_dvc, scsiq);
                   15182:         }
                   15183: 
                   15184:         
                   15185:         /* Change the RISC Queue List state to free. */
                   15186:         AdvWriteByteLram(iop_base, next_done_loc + RQL_STATE, ASC_MC_QS_FREE);
                   15187: 
                   15188:         /* Get the RISC Queue List forward pointer. */
                   15189:         AdvReadByteLram(iop_base, next_done_loc + RQL_FWD, completed_q);
                   15190: 
                   15191:         /*
                   15192:          * Notify the driver of the completed request by passing
                   15193:          * the ADV_SCSI_REQ_Q pointer to its callback function.
                   15194:          */
                   15195:         ADV_ASSERT(asc_dvc->cur_host_qng > 0);
                   15196:         asc_dvc->cur_host_qng--;
                   15197:         scsiq->a_flag |= ADV_SCSIQ_DONE;
                   15198:         (*(ADV_ISR_CALLBACK) asc_dvc->isr_callback)(asc_dvc, scsiq);
                   15199:         /*
                   15200:          * Note: After the driver callback function is called, 'scsiq'
                   15201:          * can no longer be referenced.
                   15202:          *
                   15203:          * Fall through and continue processing other completed
                   15204:          * requests...
                   15205:          */
                   15206: 
                   15207:         /*
                   15208:          * Disable interrupts again in case the driver inadvertently
                   15209:          * enabled interrupts in its callback function.
                   15210:          *
                   15211:          * The DvcEnterCritical() return value is ignored, because
                   15212:          * the 'flags' saved when AdvISR() was first entered will be
                   15213:          * used to restore the interrupt flag on exit.
                   15214:          */
                   15215:         (void) DvcEnterCritical();
                   15216:     }
                   15217:     DvcLeaveCritical(flags);
                   15218:     return ret;
                   15219: }
                   15220: 
                   15221: /*
                   15222:  * Send an idle command to the chip and wait for completion.
                   15223:  *
                   15224:  * Interrupts do not have to be enabled on entry.
                   15225:  *
                   15226:  * Return Values:
                   15227:  *   ADV_TRUE - command completed successfully
                   15228:  *   ADV_FALSE - command failed
                   15229:  */
                   15230: STATIC int
                   15231: AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
                   15232:                ushort idle_cmd,
                   15233:                ulong idle_cmd_parameter,
                   15234:                int flags)
                   15235: {
                   15236:     int         last_int_level;
                   15237:     ulong       i;
                   15238:     AdvPortAddr iop_base;
                   15239:     int         ret;
                   15240: 
                   15241:     asc_dvc->idle_cmd_done = 0;
                   15242: 
                   15243:     last_int_level = DvcEnterCritical();
                   15244:     iop_base = asc_dvc->iop_base;
                   15245: 
                   15246:     /*
                   15247:      * Write the idle command value after the idle command parameter
                   15248:      * has been written to avoid a race condition. If the order is not
                   15249:      * followed, the microcode may process the idle command before the
                   15250:      * parameters have been written to LRAM.
                   15251:      */
                   15252:     AdvWriteDWordLram(iop_base, ASC_MC_IDLE_PARA_STAT, idle_cmd_parameter);
                   15253:     AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
                   15254:     DvcLeaveCritical(last_int_level);
                   15255: 
                   15256:     /*
                   15257:      * If the 'flags' argument contains the ADV_NOWAIT flag, then
                   15258:      * return with success.
                   15259:      */
                   15260:     if (flags & ADV_NOWAIT)
                   15261:     {
                   15262:         return ADV_TRUE;
                   15263:     }
                   15264: 
                   15265:     for (i = 0; i < SCSI_WAIT_10_SEC * SCSI_MS_PER_SEC; i++)
                   15266:     {
                   15267:         /*
                   15268:          * 'idle_cmd_done' is set by AdvISR().
                   15269:          */
                   15270:         if (asc_dvc->idle_cmd_done)
                   15271:         {
                   15272:             break;
                   15273:         }
                   15274:         DvcSleepMilliSecond(1);
                   15275: 
                   15276:         /*
                   15277:          * If interrupts were disabled on entry to AdvSendIdleCmd(),
                   15278:          * then they will still be disabled here. Call AdvISR() to
                   15279:          * check for the idle command completion.
                   15280:          */
                   15281:         (void) AdvISR(asc_dvc);
                   15282:     }
                   15283: 
                   15284:     last_int_level = DvcEnterCritical();
                   15285: 
                   15286:     if (asc_dvc->idle_cmd_done == ADV_FALSE)
                   15287:     {
                   15288:         ADV_ASSERT(0); /* The idle command should never timeout. */
                   15289:         return ADV_FALSE;
                   15290:     } else
                   15291:     {
                   15292:         AdvReadWordLram(iop_base, ASC_MC_IDLE_PARA_STAT, ret);
                   15293:         return ret;
                   15294:     }
                   15295: }
                   15296: 
                   15297: /*
                   15298:  * Send the SCSI request block to the adapter
                   15299:  *
                   15300:  * Each of the 255 Adv Library/Microcode RISC Lists or mailboxes has the
                   15301:  * following structure:
                   15302:  *
                   15303:  * 0: RQL_FWD - RISC list forward pointer (1 byte)
                   15304:  * 1: RQL_BWD - RISC list backward pointer (1 byte)
                   15305:  * 2: RQL_STATE - RISC list state byte - free, ready, done, aborted (1 byte)
                   15306:  * 3: RQL_TID - request target id (1 byte)
                   15307:  * 4: RQL_PHYADDR - ADV_SCSI_REQ_Q physical pointer (4 bytes)
                   15308:  *
                   15309:  * Return:
                   15310:  *      ADV_SUCCESS(1) - the request is in the mailbox
                   15311:  *      ADV_BUSY(0) - total request count > 253, try later
                   15312:  */
                   15313: STATIC int
                   15314: AdvSendScsiCmd(
                   15315:     ADV_DVC_VAR *asc_dvc,
                   15316:     ADV_SCSI_REQ_Q  *scsiq)
                   15317: {
                   15318:     ushort                 next_ready_loc;
                   15319:     uchar                  next_ready_loc_fwd;
                   15320:     int                    last_int_level;
                   15321:     AdvPortAddr            iop_base;
                   15322:     long                   req_size;
                   15323:     ulong                  q_phy_addr;
                   15324: 
                   15325:     /*
                   15326:      * The ADV_SCSI_REQ_Q 'target_id' field should never be equal
                   15327:      * to the host adapter ID or exceed ADV_MAX_TID.
                   15328:      */
                   15329:     if (scsiq->target_id == asc_dvc->chip_scsi_id ||
                   15330:         scsiq->target_id > ADV_MAX_TID)
                   15331:     {
                   15332:         scsiq->host_status = QHSTA_M_INVALID_DEVICE;
                   15333:         scsiq->done_status = QD_WITH_ERROR;
                   15334:         return ADV_ERROR;
                   15335:     }
                   15336: 
                   15337:     iop_base = asc_dvc->iop_base;
                   15338: 
                   15339:     last_int_level = DvcEnterCritical();
                   15340: 
                   15341:     if (asc_dvc->cur_host_qng >= asc_dvc->max_host_qng)
                   15342:     {
                   15343:         DvcLeaveCritical(last_int_level);
                   15344:         return ADV_BUSY;
                   15345:     } else
                   15346:     {
                   15347:         ADV_ASSERT(asc_dvc->cur_host_qng < ASC_MC_RISC_Q_TOTAL_CNT);
                   15348:         asc_dvc->cur_host_qng++;
                   15349:     }
                   15350: 
                   15351:     /*
                   15352:      * Clear the ADV_SCSI_REQ_Q done flag.
                   15353:      */
                   15354:     scsiq->a_flag &= ~ADV_SCSIQ_DONE;
                   15355: 
                   15356:     /*
                   15357:      * Save the original sense buffer length.
                   15358:      *
                   15359:      * After the request completes 'sense_len' will be set to the residual
                   15360:      * byte count of the Auto-Request Sense if a command returns CHECK
                   15361:      * CONDITION and the Sense Data is valid indicated by 'host_status' not
                   15362:      * being set to QHSTA_M_AUTO_REQ_SENSE_FAIL. To determine the valid
                   15363:      * Sense Data Length subtract 'sense_len' from 'orig_sense_len'.
                   15364:      */
                   15365:     scsiq->orig_sense_len = scsiq->sense_len;
                   15366: 
                   15367:     AdvReadByteLram(iop_base, ASC_MC_HOST_NEXT_READY, next_ready_loc);
                   15368:     next_ready_loc = ASC_MC_RISC_Q_LIST_BASE +
                   15369:         (next_ready_loc * ASC_MC_RISC_Q_LIST_SIZE);
                   15370: 
                   15371:     /*
                   15372:      * Write the physical address of the Q to the mailbox.
                   15373:      * We need to skip the first four bytes, because the microcode
                   15374:      * uses them internally for linking Q's together.
                   15375:      */
                   15376:     req_size = sizeof(ADV_SCSI_REQ_Q);
                   15377:     q_phy_addr = DvcGetPhyAddr(asc_dvc, scsiq,
                   15378:                     (uchar *) scsiq, &req_size,
                   15379:                     ADV_IS_SCSIQ_FLAG);
                   15380:     ADV_ASSERT(ADV_DWALIGN(q_phy_addr) == q_phy_addr);
                   15381:     ADV_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
                   15382: 
                   15383:     scsiq->scsiq_ptr = (ADV_SCSI_REQ_Q *) scsiq;
                   15384: 
                   15385:     /*
                   15386:      * The RISC list structure, which 'next_ready_loc' is a pointer
                   15387:      * to in microcode LRAM, has the format detailed in the comment
                   15388:      * header for this function.
                   15389:      *
                   15390:      * Write the ADV_SCSI_REQ_Q physical pointer to 'next_ready_loc' request.
                   15391:      */
                   15392:     AdvWriteDWordLram(iop_base, next_ready_loc + RQL_PHYADDR, q_phy_addr);
                   15393: 
                   15394:     /* Write target_id to 'next_ready_loc' request. */
                   15395:     AdvWriteByteLram(iop_base, next_ready_loc + RQL_TID, scsiq->target_id);
                   15396: 
                   15397:     /*
                   15398:      * Set the ASC_MC_HOST_NEXT_READY (0x128) microcode variable to
                   15399:      * the 'next_ready_loc' request forward pointer.
                   15400:      *
                   15401:      * Do this *before* changing the 'next_ready_loc' queue to QS_READY.
                   15402:      * After the state is changed to QS_READY 'RQL_FWD' will be changed
                   15403:      * by the microcode.
                   15404:      *
                   15405:      * NOTE: The temporary variable 'next_ready_loc_fwd' is required to
                   15406:      * prevent some compilers from optimizing out 'AdvReadByteLram()' if
                   15407:      * it were used as the 3rd argument to 'AdvWriteByteLram()'.
                   15408:      */
                   15409:     AdvReadByteLram(iop_base, next_ready_loc + RQL_FWD, next_ready_loc_fwd);
                   15410:     AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_READY, next_ready_loc_fwd);
                   15411: 
                   15412:     /*
                   15413:      * Change the state of 'next_ready_loc' request from QS_FREE to
                   15414:      * QS_READY which will cause the microcode to pick it up and
                   15415:      * execute it.
                   15416:      *
                   15417:      * Can't reference 'next_ready_loc' after changing the request
                   15418:      * state to QS_READY. The microcode now owns the request.
                   15419:      */
                   15420:     AdvWriteByteLram(iop_base, next_ready_loc + RQL_STATE, ASC_MC_QS_READY);
                   15421: 
                   15422:     DvcLeaveCritical(last_int_level);
                   15423:     return ADV_SUCCESS;
                   15424: }
                   15425: 
                   15426: /*
                   15427:  * Inquiry Information Byte 7 Handling
                   15428:  *
                   15429:  * Handle SCSI Inquiry Command information for a device by setting
                   15430:  * microcode operating variables that affect WDTR, SDTR, and Tag 
                   15431:  * Queuing.
                   15432:  */
                   15433: STATIC void
                   15434: AdvInquiryHandling(
                   15435:     ADV_DVC_VAR          *asc_dvc,
                   15436:     ADV_SCSI_REQ_Q       *scsiq)
                   15437: {
                   15438:     AdvPortAddr          iop_base;
                   15439:     uchar                tid;
                   15440:     ASC_SCSI_INQUIRY     *inq;
                   15441:     ushort               tidmask;
                   15442:     ushort               cfg_word;
                   15443: 
                   15444:     /*
                   15445:      * AdvInquiryHandling() requires up to INQUIRY information Byte 7
                   15446:      * to be available.
                   15447:      *
                   15448:      * If less than 8 bytes of INQUIRY information were requested or less
                   15449:      * than 8 bytes were transferred, then return. cdb[4] is the request
                   15450:      * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the
                   15451:      * microcode to the transfer residual count.
                   15452:      */
                   15453:     if (scsiq->cdb[4] < 8 || (scsiq->cdb[4] - scsiq->data_cnt) < 8)
                   15454:     {
                   15455:         return;
                   15456:     }
                   15457: 
                   15458:     iop_base = asc_dvc->iop_base;
                   15459:     tid = scsiq->target_id;
                   15460:     inq = (ASC_SCSI_INQUIRY *) scsiq->vdata_addr;
                   15461: 
                   15462:     /*
                   15463:      * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
                   15464:      */
                   15465:     if (inq->byte3.rsp_data_fmt < 2 && inq->byte2.ansi_apr_ver < 2)
                   15466:     {
                   15467:         return;
                   15468:     } else
                   15469:     {
                   15470:         /*
                   15471:          * INQUIRY Byte 7 Handling
                   15472:          *
                   15473:          * Use a device's INQUIRY byte 7 to determine whether it
                   15474:          * supports WDTR, SDTR, and Tag Queuing. If the feature
                   15475:          * is enabled in the EEPROM and the device supports the
                   15476:          * feature, then enable it in the microcode.
                   15477:          */
                   15478: 
                   15479:         tidmask = ADV_TID_TO_TIDMASK(tid);
                   15480: 
                   15481:         /*
                   15482:          * Wide Transfers
                   15483:          *
                   15484:          * If the EEPROM enabled WDTR for the device and the device
                   15485:          * supports wide bus (16 bit) transfers, then turn on the
                   15486:          * device's 'wdtr_able' bit and write the new value to the
                   15487:          * microcode.
                   15488:          */
                   15489:         if ((asc_dvc->wdtr_able & tidmask) && inq->byte7.WBus16)
                   15490:         {
                   15491:             AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
                   15492:             if ((cfg_word & tidmask) == 0)
                   15493:             {
                   15494:                 cfg_word |= tidmask;
                   15495:                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
                   15496: 
                   15497:                 /*
                   15498:                  * Clear the microcode "WDTR negotiation" done indicator
                   15499:                  * for the target to cause it to negotiate with the new
                   15500:                  * setting set above.
                   15501:                  */
                   15502:                 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
                   15503:                 cfg_word &= ~tidmask;
                   15504:                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
                   15505:             }
                   15506:         }
                   15507: 
                   15508:         /*
                   15509:          * Synchronous Transfers
                   15510:          *
                   15511:          * If the EEPROM enabled SDTR for the device and the device
                   15512:          * supports synchronous transfers, then turn on the device's
                   15513:          * 'sdtr_able' bit. Write the new value to the microcode.
                   15514:          */
                   15515:         if ((asc_dvc->sdtr_able & tidmask) && inq->byte7.Sync)
                   15516:         {
                   15517:             AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
                   15518:             if ((cfg_word & tidmask) == 0)
                   15519:             {
                   15520:                 cfg_word |= tidmask;
                   15521:                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
                   15522: 
                   15523:                 /*
                   15524:                  * Clear the microcode "SDTR negotiation" done indicator
                   15525:                  * for the target to cause it to negotiate with the new
                   15526:                  * setting set above.
                   15527:                  */
                   15528:                 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
                   15529:                 cfg_word &= ~tidmask;
                   15530:                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
                   15531:             }
                   15532:         }
                   15533: 
                   15534:         /*
                   15535:          * If the EEPROM enabled Tag Queuing for device and the
                   15536:          * device supports Tag Queuing, then turn on the device's
                   15537:          * 'tagqng_enable' bit in the microcode and set the microcode
                   15538:          * maximum command count to the ADV_DVC_VAR 'max_dvc_qng'
                   15539:          * value.
                   15540:          *
                   15541:          * Tag Queuing is disabled for the BIOS which runs in polled
                   15542:          * mode and would see no benefit from Tag Queuing. Also by
                   15543:          * disabling Tag Queuing in the BIOS devices with Tag Queuing
                   15544:          * bugs will at least work with the BIOS.
                   15545:          */
                   15546:         if ((asc_dvc->tagqng_able & tidmask) && inq->byte7.CmdQue)
                   15547:         {
                   15548:             AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
                   15549:             cfg_word |= tidmask;
                   15550:             AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
                   15551:             AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
                   15552:                 asc_dvc->max_dvc_qng);
                   15553:         }
                   15554:     }
                   15555: }

unix.superglobalmegacorp.com

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