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

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: 
                   4719:                /*
                   4720:                 * Modify board configuration.
                   4721:                 */
                   4722:                 ASC_DBG(2, "advansys_detect: AscInitSetConfig()\n");
                   4723:                 switch (ret = AscInitSetConfig(asc_dvc_varp)) {
                   4724:                 case 0:    /* No error. */
                   4725:                     break;
                   4726:                 case ASC_WARN_IO_PORT_ROTATE:
                   4727:                     ASC_PRINT1(
                   4728: "AscInitSetConfig: board %d: I/O port address modified\n",
                   4729:                         boardp->id);
                   4730:                     break;
                   4731:                 case ASC_WARN_AUTO_CONFIG:
                   4732:                     ASC_PRINT1(
                   4733: "AscInitSetConfig: board %d: I/O port increment switch enabled\n",
                   4734:                         boardp->id);
                   4735:                     break;
                   4736:                 case ASC_WARN_EEPROM_CHKSUM:
                   4737:                     ASC_PRINT1(
                   4738: "AscInitSetConfig: board %d: EEPROM checksum error\n",
                   4739:                         boardp->id);
                   4740:                     break;
                   4741:                 case ASC_WARN_IRQ_MODIFIED:
                   4742:                     ASC_PRINT1(
                   4743: "AscInitSetConfig: board %d: IRQ modified\n",
                   4744:                         boardp->id);
                   4745:                     break;
                   4746:                 case ASC_WARN_CMD_QNG_CONFLICT:
                   4747:                     ASC_PRINT1(
                   4748: "AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
                   4749:                         boardp->id);
                   4750:                     break;
                   4751:                 default:
                   4752:                     ASC_PRINT2(
                   4753: "AscInitSetConfig: board %d: unknown warning: %x\n",
                   4754:                         boardp->id, ret);
                   4755:                     break;
                   4756:                 }
                   4757:                 if (asc_dvc_varp->err_code != 0) {
                   4758:                     ASC_PRINT3(
                   4759: "AscInitSetConfig: board %d error: init_state %x, err_code %x\n",
                   4760:                         boardp->id, asc_dvc_varp->init_state,
                   4761:                         asc_dvc_varp->err_code);
                   4762: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
                   4763:                     kfree(boardp->prtbuf);
                   4764: #endif /* version >= v1.3.0 */
                   4765:                     scsi_unregister(shp);
                   4766:                     asc_board_count--;
                   4767:                     continue;
                   4768:                 }
                   4769: 
                   4770:                 /*
                   4771:                  * Finish initializing the 'Scsi_Host' structure.
                   4772:                  */
                   4773:                 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
                   4774:                 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
                   4775:                     shp->irq = asc_dvc_varp->irq_no;
                   4776:                 }
                   4777:             } else {
                   4778: 
                   4779:                 ADVEEP_CONFIG *ep;
                   4780: 
                   4781:                 /*
                   4782:                  * Save Wide EEP Configuration Information.
                   4783:                  */
                   4784:                 ep = &boardp->eep_config.adv_eep;
                   4785: 
                   4786:                 ep->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
                   4787:                 ep->max_host_qng = adv_dvc_varp->max_host_qng;
                   4788:                 ep->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
                   4789:                 ep->termination = adv_dvc_varp->cfg->termination;
                   4790:                 ep->disc_enable = adv_dvc_varp->cfg->disc_enable;
                   4791:                 ep->bios_ctrl = adv_dvc_varp->bios_ctrl;
                   4792:                 ep->wdtr_able = adv_dvc_varp->wdtr_able;
                   4793:                 ep->sdtr_able = adv_dvc_varp->sdtr_able;
                   4794:                 ep->ultra_able = adv_dvc_varp->ultra_able;
                   4795:                 ep->tagqng_able = adv_dvc_varp->tagqng_able;
                   4796:                 ep->start_motor = adv_dvc_varp->start_motor;
                   4797:                 ep->scsi_reset_delay = adv_dvc_varp->scsi_reset_wait;
                   4798:                 ep->bios_boot_delay = adv_dvc_varp->cfg->bios_boot_wait;
                   4799:                 ep->serial_number_word1 = adv_dvc_varp->cfg->serial1;
                   4800:                 ep->serial_number_word2 = adv_dvc_varp->cfg->serial2;
                   4801:                 ep->serial_number_word3 = adv_dvc_varp->cfg->serial3;
                   4802: 
                   4803:                 /*
                   4804:                  * Set the adapter's target id bit in the 'init_tidmask' field.
                   4805:                  */
                   4806:                 boardp->init_tidmask |=
                   4807:                     ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
                   4808: 
                   4809:                 /*
                   4810:                  * Finish initializing the 'Scsi_Host' structure.
                   4811:                  */
                   4812:                 shp->irq = adv_dvc_varp->irq_no;
                   4813:             }
                   4814: 
                   4815: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
                   4816:             /*
                   4817:              * Channels are numbered beginning with 0. For AdvanSys One host
                   4818:              * structure supports one channel. Multi-channel boards have a
                   4819:              * separate host structure for each channel. 
                   4820:              */
                   4821:             shp->max_channel = 0;
                   4822: #endif /* version >= v1.3.89 */
                   4823:             if (ASC_NARROW_BOARD(boardp)) {
                   4824:                 shp->max_id = ASC_MAX_TID + 1;
                   4825:                 shp->max_lun = ASC_MAX_LUN + 1;
                   4826: 
                   4827:                 shp->io_port = asc_dvc_varp->iop_base;
                   4828:                 shp->n_io_port = ASC_IOADR_GAP;
                   4829:                 shp->this_id = asc_dvc_varp->cfg->chip_scsi_id;
                   4830: 
                   4831:                 /* Set maximum number of queues the adapter can handle. */
                   4832:                 shp->can_queue = asc_dvc_varp->max_total_qng;
                   4833:             } else {
                   4834:                 shp->max_id = ADV_MAX_TID + 1;
                   4835:                 shp->max_lun = ADV_MAX_LUN + 1;
                   4836: 
                   4837:                 /*
                   4838:                  * Save the I/O Port address and length even though the
                   4839:                  * in v1.3.0 and greater kernels the region is not used
                   4840:                  * by a Wide board. Instead the board is accessed with
                   4841:                  * Memory Mapped I/O.
                   4842:                  */
                   4843:                 shp->io_port = iop;
                   4844:                 shp->n_io_port = ADV_CONDOR_IOLEN;
                   4845: 
                   4846:                 shp->this_id = adv_dvc_varp->chip_scsi_id;
                   4847: 
                   4848:                 /* Set maximum number of queues the adapter can handle. */
                   4849:                 shp->can_queue = adv_dvc_varp->max_host_qng;
                   4850:             }
                   4851: 
                   4852: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89)
                   4853:             /*
                   4854:              * In old kernels without tag queuing support and with memory
                   4855:              * allocation problems set a conservative 'cmd_per_lun' value.
                   4856:              */
                   4857: #ifdef MODULE
                   4858:             shp->cmd_per_lun = 1;
                   4859: #else /* MODULE */
                   4860:             shp->cmd_per_lun = 4;
                   4861: #endif /* MODULE */
                   4862:             ASC_DBG1(1, "advansys_detect: cmd_per_lun: %d\n", shp->cmd_per_lun);
                   4863: #else /* version >= v1.3.89 */
                   4864:             /*
                   4865:              * Following v1.3.89, 'cmd_per_lun' is no longer needed
                   4866:              * and should be set to zero.
                   4867:              *
                   4868:              * But because of a bug introduced in v1.3.89 if the driver is
                   4869:              * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
                   4870:              * SCSI function 'allocate_device' will panic. To allow the driver
                   4871:              * to work as a module in these kernels set 'cmd_per_lun' to 1.
                   4872:              */
                   4873: #ifdef MODULE
                   4874:             shp->cmd_per_lun = 1;
                   4875: #else /* MODULE */
                   4876:             shp->cmd_per_lun = 0;
                   4877: #endif /* MODULE */
                   4878:             /*
                   4879:              * Use the host 'select_queue_depths' function to determine
                   4880:              * the number of commands to queue per device.
                   4881:              */
                   4882:             shp->select_queue_depths = advansys_select_queue_depths;
                   4883: #endif /* version >= v1.3.89 */
                   4884: 
                   4885:             /*
                   4886:              * Set the maximum number of scatter-gather elements the
                   4887:              * adapter can handle.
                   4888:              */
                   4889:             if (ASC_NARROW_BOARD(boardp)) {
                   4890:                 /*
                   4891:                  * Allow two commands with 'sg_tablesize' scatter-gather
                   4892:                  * elements to be executed simultaneously. This value is
                   4893:                  * the theoretical hardware limit. It may be decreased
                   4894:                  * below.
                   4895:                  */
                   4896:                 shp->sg_tablesize =
                   4897:                     (((asc_dvc_varp->max_total_qng - 2) / 2) *
                   4898:                     ASC_SG_LIST_PER_Q) + 1;
                   4899:             } else {
                   4900:                 shp->sg_tablesize = ADV_MAX_SG_LIST;
                   4901:             }
                   4902: 
                   4903: #ifdef MODULE
                   4904:             /*
                   4905:              * If the driver is compiled as a module, set a limit on the
                   4906:              * 'sg_tablesize' value to prevent memory allocation failures.
                   4907:              * Memory allocation errors are more likely to occur at module
                   4908:              * load time, then at driver initialization time.
                   4909:              */
                   4910:             if (shp->sg_tablesize > 64) {
                   4911:                 shp->sg_tablesize = 64;
                   4912:             }
                   4913: #endif /* MODULE */
                   4914: 
                   4915:             /*
                   4916:              * The value of 'sg_tablesize' can not exceed the SCSI
                   4917:              * mid-level driver definition of SG_ALL. SG_ALL also
                   4918:              * must not be exceeded, because it is used to define the
                   4919:              * size of the scatter-gather table in 'struct asc_sg_head'.
                   4920:              */
                   4921:             if (shp->sg_tablesize > SG_ALL) {
                   4922:                 shp->sg_tablesize = SG_ALL;
                   4923:             }
                   4924: 
                   4925:             ASC_DBG1(1, "advansys_detect: sg_tablesize: %d\n",
                   4926:                 shp->sg_tablesize);
                   4927: 
                   4928:             /* BIOS start address. */
                   4929:             if (ASC_NARROW_BOARD(boardp)) {
                   4930:                 shp->base = (char *) ((ulong) AscGetChipBiosAddress(
                   4931:                                                 asc_dvc_varp->iop_base,
                   4932:                                                 asc_dvc_varp->bus_type));
                   4933:             } else {
                   4934:                 /*
                   4935:                  * Fill-in BIOS board variables. The Wide BIOS saves
                   4936:                  * information in LRAM that is used by the driver.
                   4937:                  */
                   4938:                 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_SIGNATURE,
                   4939:                     boardp->bios_signature);
                   4940:                 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_VERSION,
                   4941:                     boardp->bios_version);
                   4942:                 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODESEG,
                   4943:                     boardp->bios_codeseg);
                   4944:                 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODELEN,
                   4945:                     boardp->bios_codelen);
                   4946: 
                   4947:                 ASC_DBG2(1,
                   4948:                     "advansys_detect: bios_signature %x, bios_version %x\n",
                   4949:                     boardp->bios_signature, boardp->bios_version);
                   4950: 
                   4951:                 ASC_DBG2(1,
                   4952:                     "advansys_detect: bios_codeseg %x, bios_codelen %x\n",
                   4953:                     boardp->bios_codeseg, boardp->bios_codelen);
                   4954: 
                   4955:                 /*
                   4956:                  * If the BIOS saved a valid signature, then fill in
                   4957:                  * the BIOS code segment base address.
                   4958:                  */
                   4959:                 if (boardp->bios_signature == 0x55AA) {
                   4960:                     /*
                   4961:                      * Convert x86 realmode code segment to a linear
                   4962:                      * address by shifting left 4.
                   4963:                      */
                   4964:                     shp->base = (uchar *) (boardp->bios_codeseg << 4);
                   4965:                 } else {
                   4966:                     shp->base = 0;
                   4967:                 }
                   4968:             }
                   4969: 
                   4970:             /*
                   4971:              * Register Board Resources - I/O Port, DMA, IRQ
                   4972:              */
                   4973: 
                   4974:             /* Register I/O port range. */
                   4975:             ASC_DBG(2, "advansys_detect: request_region()\n");
                   4976:             request_region(shp->io_port, shp->n_io_port, "advansys");
                   4977: 
                   4978:             /* Register DMA Channel for Narrow boards. */
                   4979:             shp->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
                   4980:             if (ASC_NARROW_BOARD(boardp)) {
                   4981:                 /* Register DMA channel for ISA bus. */
                   4982:                 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
                   4983:                     shp->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
                   4984:                     if ((ret =
                   4985:                          request_dma(shp->dma_channel, "advansys")) != 0) {
                   4986:                         ASC_PRINT3(
                   4987: "advansys_detect: board %d: request_dma() %d failed %d\n",
                   4988:                             boardp->id, shp->dma_channel, ret);
                   4989:                         release_region(shp->io_port, shp->n_io_port);
                   4990: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
                   4991:                         kfree(boardp->prtbuf);
                   4992: #endif /* version >= v1.3.0 */
                   4993:                         scsi_unregister(shp);
                   4994:                         asc_board_count--;
                   4995:                         continue;
                   4996:                     }
                   4997:                     AscEnableIsaDma(shp->dma_channel);
                   4998:                 }
                   4999:             }
                   5000: 
                   5001:             /* Register IRQ Number. */
                   5002:             ASC_DBG1(2, "advansys_detect: request_irq() %d\n", shp->irq);
                   5003: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
                   5004:             if ((ret = request_irq(shp->irq, advansys_interrupt,
                   5005:                             SA_INTERRUPT, "advansys")) != 0)
                   5006: #else /* version >= v1.3.70 */
                   5007:            /*
                   5008:             * If request_irq() fails with the SA_INTERRUPT flag set,
                   5009:             * then try again without the SA_INTERRUPT flag set. This
                   5010:             * allows IRQ sharing to work even with other drivers that
                   5011:             * do not set the SA_INTERRUPT flag.
                   5012:             *
                   5013:             * If SA_INTERRUPT is not set, then interrupts are enabled
                   5014:             * before the driver interrupt function is called.
                   5015:             */
                   5016:             if (((ret = request_irq(shp->irq, advansys_interrupt,
                   5017:                             SA_INTERRUPT | (share_irq == TRUE ? SA_SHIRQ : 0),
                   5018:                             "advansys", boardp)) != 0) &&
                   5019:                 ((ret = request_irq(shp->irq, advansys_interrupt,
                   5020:                             (share_irq == TRUE ? SA_SHIRQ : 0),
                   5021:                             "advansys", boardp)) != 0))
                   5022: #endif /* version >= v1.3.70 */
                   5023:             {
                   5024:                 if (ret == -EBUSY) {
                   5025:                     ASC_PRINT2(
                   5026: "advansys_detect: board %d: request_irq(): IRQ %d already in use.\n",
                   5027:                         boardp->id, shp->irq);
                   5028:                 } else if (ret == -EINVAL) {
                   5029:                     ASC_PRINT2(
                   5030: "advansys_detect: board %d: request_irq(): IRQ %d not valid.\n",
                   5031:                         boardp->id, shp->irq);
                   5032:                 } else {
                   5033:                     ASC_PRINT3(
                   5034: "advansys_detect: board %d: request_irq(): IRQ %d failed with %d\n",
                   5035:                         boardp->id, shp->irq, ret);
                   5036:                 }
                   5037:                 release_region(shp->io_port, shp->n_io_port);
                   5038: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
                   5039:                 iounmap(boardp->ioremap_addr);
                   5040: #endif /* version >= v1,3,0 */
                   5041:                 if (shp->dma_channel != NO_ISA_DMA) {
                   5042:                     free_dma(shp->dma_channel);
                   5043:                 }
                   5044: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
                   5045:                 kfree(boardp->prtbuf);
                   5046: #endif /* version >= v1.3.0 */
                   5047:                 scsi_unregister(shp);
                   5048:                 asc_board_count--;
                   5049:                 continue;
                   5050:             }
                   5051: 
                   5052:             /*
                   5053:              * Initialize board RISC chip and enable interrupts.
                   5054:              */
                   5055:             if (ASC_NARROW_BOARD(boardp)) {
                   5056:                 ASC_DBG(2, "advansys_detect: AscInitAsc1000Driver()\n");
                   5057:                 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
                   5058:                 err_code = asc_dvc_varp->err_code;
                   5059: 
                   5060:                 if (warn_code || err_code) {
                   5061:                     ASC_PRINT4(
                   5062: "AscInitAsc1000Driver: board %d: error: init_state %x, warn %x error %x\n",
                   5063:                         boardp->id, asc_dvc_varp->init_state,
                   5064:                         warn_code, err_code);
                   5065:                 }
                   5066:             } else {
                   5067:                 int             req_cnt;
                   5068:                 adv_req_t       *reqp = NULL;
                   5069:                 int             sg_cnt;
                   5070:                 adv_sgblk_t     *sgp = NULL;
                   5071: 
                   5072: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
                   5073:                 req_cnt = sizeof(adv_req_buf)/sizeof(adv_req_t);
                   5074:                 sg_cnt = sizeof(adv_sgblk_buf)/sizeof(adv_sgblk_t);
                   5075:                 reqp = (adv_req_t *) &adv_req_buf[0];
                   5076:                 sgp = (adv_sgblk_t *) &adv_sgblk_buf[0];
                   5077: #else /* version >= v1.3.0 */
                   5078:                 /*
                   5079:                  * Allocate up to 'max_host_qng' request structures for
                   5080:                  * the Wide board.
                   5081:                  */
                   5082:                 for (req_cnt = adv_dvc_varp->max_host_qng;
                   5083:                     req_cnt > 0; req_cnt--) {
                   5084: 
                   5085:                     reqp = (adv_req_t *)
                   5086:                         kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC);
                   5087: 
                   5088:                     ASC_DBG3(1,
                   5089:                         "advansys_detect: reqp %x, req_cnt %d, bytes %d\n",
                   5090:                         (unsigned) reqp, req_cnt, sizeof(adv_req_t) * req_cnt);
                   5091: 
                   5092:                     if (reqp != NULL) {
                   5093:                         break;
                   5094:                     }
                   5095:                 }
                   5096: 
                   5097:                 /*
                   5098:                  * Allocate up to ADV_TOT_SG_LIST request structures for
                   5099:                  * the Wide board.
                   5100:                  */
                   5101:                 for (sg_cnt = ADV_TOT_SG_LIST; sg_cnt > 0; sg_cnt--) {
                   5102: 
                   5103:                     sgp = (adv_sgblk_t *)
                   5104:                         kmalloc(sizeof(adv_sgblk_t) * sg_cnt, GFP_ATOMIC);
                   5105: 
                   5106:                     ASC_DBG3(1,
                   5107:                         "advansys_detect: sgp %x, sg_cnt %d, bytes %d\n",
                   5108:                         (unsigned) sgp, sg_cnt, sizeof(adv_sgblk_t) * sg_cnt);
                   5109: 
                   5110:                     if (sgp != NULL) {
                   5111:                         break;
                   5112:                     }
                   5113:                 }
                   5114: #endif /* version >= v1.3.0 */
                   5115: 
                   5116:                 /*
                   5117:                  * If no request structures or scatter-gather structures could
                   5118:                  * be allocated, then return an error. Otherwise continue with
                   5119:                  * initialization.
                   5120:                  */
                   5121:                 if (reqp == NULL) {
                   5122:                     ASC_PRINT1(
                   5123: "advansys_detect: board %d: error: failed to kmalloc() adv_req_t buffer.\n",
                   5124:                         boardp->id);
                   5125:                     err_code = ADV_ERROR;
                   5126:                 } else if (sgp == NULL) {
                   5127:                     kfree(reqp);
                   5128:                     ASC_PRINT1(
                   5129: "advansys_detect: board %d: error: failed to kmalloc() adv_sgblk_t buffer.\n",
                   5130:                         boardp->id);
                   5131:                     err_code = ADV_ERROR;
                   5132:                 } else {
                   5133:                     
                   5134:                     /*
                   5135:                      * Save original pointer for kfree() in case the
                   5136:                      * driver is built as a module and can be unloaded.
                   5137:                      */
                   5138:                     boardp->orig_reqp = reqp;
                   5139: 
                   5140:                     /*
                   5141:                      * Point 'adv_reqp' to the request structures and
                   5142:                      * link them together.
                   5143:                      */
                   5144:                     req_cnt--;
                   5145:                     reqp[req_cnt].next_reqp = NULL;
                   5146:                     for (; req_cnt > 0; req_cnt--) {
                   5147:                         reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
                   5148:                     }
                   5149:                     boardp->adv_reqp = &reqp[0];
                   5150: 
                   5151:                     /*
                   5152:                      * Save original pointer for kfree() in case the
                   5153:                      * driver is built as a module and can be unloaded.
                   5154:                      */
                   5155:                     boardp->orig_sgblkp = sgp;
                   5156: 
                   5157:                     /*
                   5158:                      * Point 'adv_sgblkp' to the request structures and
                   5159:                      * link them together.
                   5160:                      */
                   5161:                     sg_cnt--;
                   5162:                     sgp[sg_cnt].next_sgblkp = NULL;
                   5163:                     for (; sg_cnt > 0; sg_cnt--) {
                   5164:                         sgp[sg_cnt - 1].next_sgblkp = &sgp[sg_cnt];
                   5165:                     }
                   5166:                     boardp->adv_sgblkp = &sgp[0];
                   5167: 
                   5168:                     ASC_DBG(2, "advansys_detect: AdvInitAsc3550Driver()\n");
                   5169:                     warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
                   5170:                     err_code = adv_dvc_varp->err_code;
                   5171: 
                   5172:                     if (warn_code || err_code) {
                   5173:                         ASC_PRINT3(
                   5174: "AdvInitAsc3550Driver: board %d: error: warn %x, error %x\n",
                   5175:                             boardp->id, warn_code, adv_dvc_varp->err_code);
                   5176:                     }
                   5177:                 }
                   5178:             }
                   5179: 
                   5180:             if (err_code != 0) {
                   5181:                 release_region(shp->io_port, shp->n_io_port);
                   5182:                 if (ASC_WIDE_BOARD(boardp)) {
                   5183: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
                   5184:                     iounmap(boardp->ioremap_addr);
                   5185: #endif /* version >= v1,3,0 */
                   5186:                     if (boardp->orig_reqp) {
                   5187:                         kfree(boardp->orig_reqp);
                   5188:                         boardp->orig_reqp = boardp->adv_reqp = NULL;
                   5189:                     }
                   5190:                     if (boardp->orig_sgblkp) {
                   5191:                         kfree(boardp->orig_sgblkp);
                   5192:                         boardp->orig_sgblkp = boardp->adv_sgblkp = NULL;
                   5193:                     }
                   5194:                 }
                   5195:                 if (shp->dma_channel != NO_ISA_DMA) {
                   5196:                     free_dma(shp->dma_channel);
                   5197:                 }
                   5198: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
                   5199:                 kfree(boardp->prtbuf);
                   5200: #endif /* version >= v1.3.0 */
                   5201: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
                   5202:                 free_irq(shp->irq);
                   5203: #else /* version >= v1.3.70 */
                   5204:                 free_irq(shp->irq, boardp);
                   5205: #endif /* version >= v1.3.70 */
                   5206:                 scsi_unregister(shp);
                   5207:                 asc_board_count--;
                   5208:                 continue;
                   5209:             }
                   5210:             ASC_DBG_PRT_SCSI_HOST(2, shp);
                   5211:         }
                   5212:     }
                   5213:     ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n", asc_board_count);
                   5214:     return asc_board_count;
                   5215: }
                   5216: 
                   5217: /*
                   5218:  * advansys_release()
                   5219:  *
                   5220:  * Release resources allocated for a single AdvanSys adapter.
                   5221:  */
                   5222: int
                   5223: advansys_release(struct Scsi_Host *shp)
                   5224: {
                   5225:     asc_board_t    *boardp;
                   5226: 
                   5227:     ASC_DBG(1, "advansys_release: begin\n");
                   5228:     boardp = ASC_BOARDP(shp);
                   5229: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
                   5230:     free_irq(shp->irq);
                   5231: #else /* version >= v1.3.70 */
                   5232:     free_irq(shp->irq, boardp);
                   5233: #endif /* version >= v1.3.70 */
                   5234:     if (shp->dma_channel != NO_ISA_DMA) {
                   5235:         ASC_DBG(1, "advansys_release: free_dma()\n");
                   5236:         free_dma(shp->dma_channel);
                   5237:     }
                   5238:     release_region(shp->io_port, shp->n_io_port);
                   5239:     if (ASC_WIDE_BOARD(boardp)) {
                   5240: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
                   5241:         iounmap(boardp->ioremap_addr);
                   5242: #endif /* version >= v1,3,0 */
                   5243:         if (boardp->orig_reqp) {
                   5244:             kfree(boardp->orig_reqp);
                   5245:             boardp->orig_reqp = boardp->adv_reqp = NULL;
                   5246:         }
                   5247:         if (boardp->orig_sgblkp) {
                   5248:             kfree(boardp->orig_sgblkp);
                   5249:             boardp->orig_sgblkp = boardp->adv_sgblkp = NULL;
                   5250:         }
                   5251:     }
                   5252: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
                   5253:     ASC_ASSERT(boardp->prtbuf != NULL);
                   5254:     kfree(boardp->prtbuf);
                   5255: #endif /* version >= v1.3.0 */
                   5256:     scsi_unregister(shp);
                   5257:     ASC_DBG(1, "advansys_release: end\n");
                   5258:     return 0;
                   5259: }
                   5260: 
                   5261: /*
                   5262:  * advansys_info()
                   5263:  *
                   5264:  * Return suitable for printing on the console with the argument
                   5265:  * adapter's configuration information.
                   5266:  *
                   5267:  * Note: The information line should not exceed ASC_INFO_SIZE bytes,
                   5268:  * otherwise the static 'info' array will be overrun.
                   5269:  */
                   5270: const char *
                   5271: advansys_info(struct Scsi_Host *shp)
                   5272: {
                   5273:     static char     info[ASC_INFO_SIZE];
                   5274:     asc_board_t     *boardp;
                   5275:     ASC_DVC_VAR     *asc_dvc_varp;
                   5276:     ADV_DVC_VAR     *adv_dvc_varp;
                   5277:     char            *busname;
                   5278: 
                   5279:     boardp = ASC_BOARDP(shp);
                   5280:     if (ASC_NARROW_BOARD(boardp)) {
                   5281:         asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
                   5282:         ASC_DBG(1, "advansys_info: begin\n");
                   5283:         if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
                   5284:             if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) == ASC_IS_ISAPNP) {
                   5285:                 busname = "ISA PnP";
                   5286:             } else {
                   5287:                 busname = "ISA";
                   5288:             }
                   5289:             sprintf(info,
                   5290: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,92)
                   5291: "AdvanSys SCSI %s: %s %u CDB: BIOS %X, IO %X/%X, IRQ %u, DMA %u",
                   5292: #else /* version >= v2.1.92 */ 
                   5293: "AdvanSys SCSI %s: %s %u CDB: BIOS %X, IO %lX/%X, IRQ %u, DMA %u",
                   5294: #endif /* version >= v2.1.92 */ 
                   5295:                 ASC_VERSION, busname, asc_dvc_varp->max_total_qng,
                   5296:                 (unsigned) shp->base,
                   5297:                 shp->io_port, shp->n_io_port - 1,
                   5298:                 shp->irq, shp->dma_channel);
                   5299:         } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
                   5300:             if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
                   5301:                 == ASC_IS_PCI_ULTRA) {
                   5302:                 busname = "PCI Ultra";
                   5303:             } else {
                   5304:                 busname = "PCI";
                   5305:             }
                   5306:             sprintf(info,
                   5307: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,92)
                   5308:                 "AdvanSys SCSI %s: %s %u CDB: IO %X/%X, IRQ %u",
                   5309: #else /* version >= v2.1.92 */ 
                   5310:                 "AdvanSys SCSI %s: %s %u CDB: IO %lX/%X, IRQ %u",
                   5311: #endif /* version >= v2.1.92 */ 
                   5312:                 ASC_VERSION, busname, asc_dvc_varp->max_total_qng,
                   5313:                 shp->io_port, shp->n_io_port - 1, shp->irq);
                   5314:         } else {
                   5315:             if (asc_dvc_varp->bus_type & ASC_IS_VL) {
                   5316:                 busname = "VL";
                   5317:             } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
                   5318:                 busname = "EISA";
                   5319:             } else {
                   5320:                 busname = "?";
                   5321:                 ASC_PRINT2(
                   5322:     "advansys_info: board %d: unknown bus type %d\n",
                   5323:                     boardp->id, asc_dvc_varp->bus_type);
                   5324:             }
                   5325:             sprintf(info,
                   5326: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,92)
                   5327:                 "AdvanSys SCSI %s: %s %u CDB: BIOS %X, IO %X/%X, IRQ %u",
                   5328: #else /* version >= v2.1.92 */ 
                   5329:                 "AdvanSys SCSI %s: %s %u CDB: BIOS %X, IO %lX/%X, IRQ %u",
                   5330: #endif /* version >= v2.1.92 */ 
                   5331:                 ASC_VERSION, busname, asc_dvc_varp->max_total_qng,
                   5332:                 (unsigned) shp->base, shp->io_port - 1,
                   5333:                 shp->n_io_port, shp->irq);
                   5334:         }
                   5335:     } else {
                   5336:         /*
                   5337:          * Wide Adapter Information
                   5338:          *
                   5339:          * Memory-mapped I/O is used instead of I/O space to access
                   5340:          * the adapter, but display the I/O Port range. The Memory
                   5341:          * I/O address is displayed through the driver /proc file.
                   5342:          */
                   5343:         adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
                   5344:         if (boardp->bios_signature == 0x55AA) {
                   5345:             sprintf(info,
                   5346: "AdvanSys SCSI %s: PCI Ultra-Wide: BIOS %X/%X, IO %X/%X, IRQ %u",
                   5347:                 ASC_VERSION,
                   5348:                 boardp->bios_codeseg << 4,
                   5349:                 boardp->bios_codelen > 0 ?
                   5350:                 (boardp->bios_codelen << 9) - 1 : 0,
                   5351:                 (unsigned) boardp->ioport, ADV_CONDOR_IOLEN - 1,
                   5352:                 shp->irq);
                   5353:         } else {
                   5354:             sprintf(info,
                   5355: "AdvanSys SCSI %s: PCI Ultra-Wide: IO %X/%X, IRQ %u",
                   5356:                 ASC_VERSION,
                   5357:                 (unsigned) boardp->ioport,
                   5358:                 (ADV_CONDOR_IOLEN - 1),
                   5359:                 shp->irq);
                   5360:         }
                   5361:     }
                   5362:     ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
                   5363:     ASC_DBG(1, "advansys_info: end\n");
                   5364:     return info;
                   5365: }
                   5366: 
                   5367: /*
                   5368:  * advansys_command() - polled I/O entrypoint.
                   5369:  *
                   5370:  * Apparently host drivers shouldn't return until the command
                   5371:  * is finished.
                   5372:  *
                   5373:  * Note: This is an old interface that is no longer used by the SCSI
                   5374:  * mid-level driver. The new interface, advansys_queuecommand(),
                   5375:  * currently handles all requests.
                   5376:  */
                   5377: int
                   5378: advansys_command(Scsi_Cmnd *scp)
                   5379: {
                   5380:     ASC_DBG1(1, "advansys_command: scp %x\n", (unsigned) scp);
                   5381:     ASC_STATS(scp->host, command);
                   5382:     scp->SCp.Status = 0; /* Set to a known state */
                   5383:     advansys_queuecommand(scp, advansys_command_done);
                   5384:     while (scp->SCp.Status == 0) {
                   5385:         continue;
                   5386:     }
                   5387:     ASC_DBG1(1, "advansys_command: result %x\n", scp->result);
                   5388:     return scp->result;
                   5389: }
                   5390: 
                   5391: /*
                   5392:  * advansys_queuecommand() - interrupt-driven I/O entrypoint.
                   5393:  *
                   5394:  * This function always returns 0. Command return status is saved
                   5395:  * in the 'scp' result field.
                   5396:  */
                   5397: int
                   5398: advansys_queuecommand(Scsi_Cmnd *scp, void (*done)(Scsi_Cmnd *))
                   5399: {
                   5400:     struct Scsi_Host    *shp;
                   5401:     asc_board_t         *boardp;
1.1.1.2   root     5402:     long                flags;
1.1       root     5403:     Scsi_Cmnd           *done_scp;
                   5404: 
                   5405:     shp = scp->host;
                   5406:     boardp = ASC_BOARDP(shp);
                   5407:     ASC_STATS(shp, queuecommand);
                   5408: 
                   5409:     /*
                   5410:      * Disable interrupts to preserve request ordering and provide
                   5411:      * mutually exclusive access to global structures used to initiate
                   5412:      * a request.
                   5413:      */
                   5414:     save_flags(flags);
                   5415:     cli();
                   5416: 
                   5417:     /*
                   5418:      * Block new commands while handling a reset or abort request.
                   5419:      */
                   5420:     if (boardp->flags & (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) {
                   5421:         if (boardp->flags & ASC_HOST_IN_RESET) {
                   5422:             ASC_DBG1(1,
                   5423:                 "advansys_queuecommand: scp %x blocked for reset request\n",
                   5424:                 (unsigned) scp);
                   5425:             scp->result = HOST_BYTE(DID_RESET);
                   5426:         } else {
                   5427:             ASC_DBG1(1,
                   5428:                 "advansys_queuecommand: scp %x blocked for abort request\n",
                   5429:                 (unsigned) scp);
                   5430:             scp->result = HOST_BYTE(DID_ABORT);
                   5431:         }
                   5432: 
                   5433:         /*
                   5434:          * Add blocked requests to the board's 'done' queue. The queued
                   5435:          * requests will be completed at the end of the abort or reset
                   5436:          * handling.
                   5437:          */
                   5438:         asc_enqueue(&boardp->done, scp, ASC_BACK);
                   5439:         restore_flags(flags);
                   5440:         return 0;
                   5441:     }
                   5442: 
                   5443:     /*
                   5444:      * Attempt to execute any waiting commands for the board.
                   5445:      */
                   5446:     if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
                   5447:         ASC_DBG(1,
                   5448:             "advansys_queuecommand: before asc_execute_queue() waiting\n");
                   5449:         asc_execute_queue(&boardp->waiting);
                   5450:     }
                   5451: 
                   5452:     /*
                   5453:      * Save the function pointer to Linux mid-level 'done' function
                   5454:      * and attempt to execute the command.
                   5455:      *
                   5456:      * If ASC_ERROR is returned the request has been added to the
                   5457:      * board's 'active' queue and will be completed by the interrupt
                   5458:      * handler.
                   5459:      *
                   5460:      * If ASC_BUSY is returned add the request to the board's per
                   5461:      * target waiting list.
                   5462:      * 
                   5463:      * If an error occurred, the request will have been placed on the
                   5464:      * board's 'done' queue and must be completed before returning.
                   5465:      */
                   5466:     scp->scsi_done = done;
                   5467:     switch (asc_execute_scsi_cmnd(scp)) {
                   5468:     case ASC_NOERROR:
                   5469:         break;
                   5470:     case ASC_BUSY:
                   5471:         asc_enqueue(&boardp->waiting, scp, ASC_BACK);
                   5472:         break;
                   5473:     case ASC_ERROR:
                   5474:     default:
                   5475:         done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
                   5476:         /* Interrupts could be enabled here. */
                   5477:         asc_scsi_done_list(done_scp);
                   5478:         break;
                   5479:     }
                   5480: 
                   5481:     restore_flags(flags);
                   5482:     return 0;
                   5483: }
                   5484: 
                   5485: /*
                   5486:  * advansys_abort()
                   5487:  *
                   5488:  * Abort the command specified by 'scp'.
                   5489:  */
                   5490: int
                   5491: advansys_abort(Scsi_Cmnd *scp)
                   5492: {
                   5493:     struct Scsi_Host    *shp;
                   5494:     asc_board_t         *boardp;
                   5495:     ASC_DVC_VAR         *asc_dvc_varp;
                   5496:     ADV_DVC_VAR         *adv_dvc_varp;
1.1.1.2   root     5497:     long                flags;
1.1       root     5498:     int                 do_scsi_done;
                   5499:     int                 scp_found;
                   5500:     Scsi_Cmnd           *done_scp = NULL;
                   5501:     int                 ret;
                   5502: 
                   5503:     /* Save current flags and disable interrupts. */
                   5504:     save_flags(flags);
                   5505:     cli();
                   5506: 
                   5507:     ASC_DBG1(1, "advansys_abort: scp %x\n", (unsigned) scp);
                   5508: 
                   5509: #ifdef ADVANSYS_STATS
                   5510:     if (scp->host != NULL) {
                   5511:         ASC_STATS(scp->host, abort);
                   5512:     }    
                   5513: #endif /* ADVANSYS_STATS */
                   5514: 
                   5515: #ifdef ADVANSYS_ASSERT
                   5516:     do_scsi_done = ASC_ERROR;
                   5517:     scp_found = ASC_ERROR;
                   5518:     ret = ASC_ERROR;
                   5519: #endif /* ADVANSYS_ASSERT */
                   5520: 
                   5521: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
                   5522:     if (scp->serial_number != scp->serial_number_at_timeout) {
                   5523:         ASC_PRINT1(
                   5524: "advansys_abort: timeout serial number changed for request %x\n",
                   5525:             (unsigned) scp);
                   5526:         do_scsi_done = ASC_FALSE;
                   5527:         scp_found = ASC_FALSE;
                   5528:         ret = SCSI_ABORT_NOT_RUNNING;
                   5529:     } else
                   5530: #endif /* version >= v1.3.89 */
                   5531:     if ((shp = scp->host) == NULL) {
                   5532:         scp->result = HOST_BYTE(DID_ERROR);
                   5533:         do_scsi_done = ASC_TRUE;
                   5534:         scp_found = ASC_FALSE;
                   5535:         ret = SCSI_ABORT_ERROR;
                   5536:     } else if ((boardp = ASC_BOARDP(shp))->flags & 
                   5537:                 (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) {
                   5538:         ASC_PRINT2(
                   5539: "advansys_abort: board %d: Nested host reset or abort, flags 0x%x\n",
                   5540:             boardp->id, boardp->flags);
                   5541:         do_scsi_done = ASC_TRUE;
                   5542:         if ((asc_rmqueue(&boardp->active, scp) == ASC_TRUE) ||
                   5543:             (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE)) {
                   5544:             scp_found = ASC_TRUE;
                   5545:         } else {
                   5546:             scp_found = ASC_FALSE;
                   5547:         }
                   5548:         scp->result = HOST_BYTE(DID_ERROR);
                   5549:         ret = SCSI_ABORT_ERROR;
                   5550:     } else {
                   5551:         /* Set abort flag to avoid nested reset or abort requests. */
                   5552:         boardp->flags |= ASC_HOST_IN_ABORT;
                   5553: 
                   5554:         do_scsi_done = ASC_TRUE;
                   5555:         if (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE) {
                   5556:             /*
                   5557:              * If asc_rmqueue() found the command on the waiting
                   5558:              * queue, it had not been sent to the device. After
                   5559:              * the queue is removed, no other handling is required.
                   5560:              */
                   5561:             ASC_DBG1(1, "advansys_abort: scp %x found on waiting queue\n",
                   5562:                 (unsigned) scp);
                   5563:             scp_found = ASC_TRUE;
                   5564:             scp->result = HOST_BYTE(DID_ABORT);
                   5565:             ret = SCSI_ABORT_SUCCESS;
                   5566:         } else if (asc_isqueued(&boardp->active, scp) == ASC_TRUE) {
                   5567:             /*
                   5568:              * If asc_isqueued() found the command on the active
                   5569:              * queue, it has been sent to the device. The command
                   5570:              * will be returned through the interrupt handler after
                   5571:              * it has been aborted.
                   5572:              */
                   5573: 
                   5574:             if (ASC_NARROW_BOARD(boardp)) {
                   5575:                 /*
                   5576:                  * Narrow Board
                   5577:                  */
                   5578:                 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
                   5579:                 scp->result = HOST_BYTE(DID_ABORT);
                   5580: 
                   5581:                 sti(); /* Enable interrupts for AscAbortSRB(). */
                   5582:                 ASC_DBG1(1, "advansys_abort: before AscAbortSRB(), scp %x\n",
                   5583:                     (unsigned) scp);
                   5584:                 switch (AscAbortSRB(asc_dvc_varp, (ulong) scp)) {
                   5585:                 case ASC_TRUE:
                   5586:                     /* asc_isr_callback() will be called */
                   5587:                     ASC_DBG(1, "advansys_abort: AscAbortSRB() TRUE\n");
                   5588:                     ret = SCSI_ABORT_PENDING;
                   5589:                     break;
                   5590:                 case ASC_FALSE:
                   5591:                     /* Request has apparently already completed. */
                   5592:                     ASC_DBG(1, "advansys_abort: AscAbortSRB() FALSE\n");
                   5593:                     ret = SCSI_ABORT_NOT_RUNNING;
                   5594:                     break;
                   5595:                 case ASC_ERROR:
                   5596:                 default:
                   5597:                     ASC_DBG(1, "advansys_abort: AscAbortSRB() ERROR\n");
                   5598:                     ret = SCSI_ABORT_ERROR;
                   5599:                     break;
                   5600:                 }
                   5601:                 cli();
                   5602:             } else {
                   5603:                 /*
                   5604:                  * Wide Board
                   5605:                  */
                   5606:                 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
                   5607:                 scp->result = HOST_BYTE(DID_ABORT);
                   5608: 
                   5609:                 ASC_DBG1(1, "advansys_abort: before AdvAbortSRB(), scp %x\n",
                   5610:                     (unsigned) scp);
                   5611:                 switch (AdvAbortSRB(adv_dvc_varp, (ulong) scp)) {
                   5612:                 case ASC_TRUE:
                   5613:                     /* asc_isr_callback() will be called */
                   5614:                     ASC_DBG(1, "advansys_abort: AdvAbortSRB() TRUE\n");
                   5615:                     ret = SCSI_ABORT_PENDING;
                   5616:                     break;
                   5617:                 case ASC_FALSE:
                   5618:                     /* Request has apparently already completed. */
                   5619:                     ASC_DBG(1, "advansys_abort: AdvAbortSRB() FALSE\n");
                   5620:                     ret = SCSI_ABORT_NOT_RUNNING;
                   5621:                     break;
                   5622:                 case ASC_ERROR:
                   5623:                 default:
                   5624:                     ASC_DBG(1, "advansys_abort: AdvAbortSRB() ERROR\n");
                   5625:                     ret = SCSI_ABORT_ERROR;
                   5626:                     break;
                   5627:                 }
                   5628:                 /*
                   5629:                  * Ensure all requests completed by the microcode have
                   5630:                  * been processed by calling AdvISR().
                   5631:                  */
                   5632:                 (void) AdvISR(adv_dvc_varp);
                   5633:             }
                   5634: 
                   5635:             /*
                   5636:              * The request will either still be on the active queue
                   5637:              * or have been added to the board's done queue.
                   5638:              */
                   5639:             if (asc_rmqueue(&boardp->active, scp) == ASC_TRUE) {
                   5640:                 scp->result = HOST_BYTE(DID_ABORT);
                   5641:                 scp_found = ASC_TRUE;
                   5642:             } else {
                   5643:                 scp_found = asc_rmqueue(&boardp->done, scp);
                   5644:                 ASC_ASSERT(scp_found == ASC_TRUE);
                   5645:             }
                   5646: 
                   5647:         } else {
                   5648:             /*
                   5649:              * The command was not found on the active or waiting queues.
                   5650:              */
                   5651:             do_scsi_done = ASC_TRUE;
                   5652:             scp_found = ASC_FALSE;
                   5653:             ret = SCSI_ABORT_NOT_RUNNING;
                   5654:         }
                   5655: 
                   5656:         /* Clear abort flag. */
                   5657:         boardp->flags &= ~ASC_HOST_IN_ABORT;
                   5658: 
                   5659:         /*
                   5660:          * Because the ASC_HOST_IN_ABORT flag causes both
                   5661:          * 'advansys_interrupt' and 'asc_isr_callback' to
                   5662:          * queue requests to the board's 'done' queue and
                   5663:          * prevents waiting commands from being executed,
                   5664:          * these queued requests must be handled here.
                   5665:          */
                   5666:         done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
                   5667: 
                   5668:         /*
                   5669:          * Start any waiting commands for the board.
                   5670:          */
                   5671:         if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
                   5672:             ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
                   5673:             asc_execute_queue(&boardp->waiting);
                   5674:         }
                   5675:     }
                   5676: 
                   5677:     /* Interrupts could be enabled here. */
                   5678: 
                   5679:     /*
                   5680:      * Complete the request to be aborted, unless it has been
                   5681:      * restarted as detected above, even if it was not found on
                   5682:      * the device active or waiting queues.
                   5683:      */
                   5684:     ASC_ASSERT(do_scsi_done != ASC_ERROR);
                   5685:     ASC_ASSERT(scp_found != ASC_ERROR);
                   5686:     if (do_scsi_done == ASC_TRUE) {
                   5687:         if (scp->scsi_done == NULL) {
                   5688:             ASC_PRINT1(
                   5689: "advansys_abort: aborted request scsi_done() is NULL, %x\n",
                   5690:                 (unsigned) scp);
                   5691:         } else {
                   5692:             if (scp_found == ASC_FALSE) {
                   5693:                 ASC_PRINT1(
                   5694: "advansys_abort: abort request not active or waiting, completing anyway %x\n",
                   5695:                     (unsigned) scp);
                   5696:             }
                   5697:             ASC_STATS(scp->host, done);
                   5698:             scp->scsi_done(scp);
                   5699:         }
                   5700:     }
                   5701: 
                   5702:     /*
                   5703:      * It is possible for the request done function to re-enable
                   5704:      * interrupts without confusing the driver. But here interrupts
                   5705:      * aren't enabled until all requests have been completed.
                   5706:      */
                   5707:     if (done_scp != NULL) {
                   5708:         asc_scsi_done_list(done_scp);
                   5709:     }
                   5710: 
                   5711:     ASC_DBG1(1, "advansys_abort: ret %d\n", ret);
                   5712: 
                   5713:     /* Re-enable interrupts, if they were enabled on entry. */
                   5714:     restore_flags(flags);
                   5715: 
                   5716:     ASC_ASSERT(ret != ASC_ERROR);
                   5717:     return ret;
                   5718: }
                   5719: 
                   5720: /*
                   5721:  * advansys_reset()
                   5722:  *
                   5723:  * Reset the device associated with the command 'scp'.
                   5724:  */
                   5725: int
                   5726: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89)
                   5727: advansys_reset(Scsi_Cmnd *scp)
                   5728: #else /* version >= v1.3.89 */
                   5729: advansys_reset(Scsi_Cmnd *scp, unsigned int reset_flags)
                   5730: #endif /* version >= v1.3.89 */
                   5731: {
                   5732:     struct Scsi_Host     *shp;
                   5733:     asc_board_t          *boardp;
                   5734:     ASC_DVC_VAR          *asc_dvc_varp;
                   5735:     ADV_DVC_VAR          *adv_dvc_varp;
1.1.1.2   root     5736:     long                 flags;
1.1       root     5737:     Scsi_Cmnd            *done_scp = NULL, *last_scp = NULL;
                   5738:     Scsi_Cmnd            *tscp, *new_last_scp;
                   5739:     int                  do_scsi_done;
                   5740:     int                  scp_found;
                   5741:     int                  status;
                   5742:     int                  target;
                   5743:     int                  ret;
                   5744:     int                  device_reset = ASC_FALSE;
                   5745: 
                   5746:     /* Save current flags and disable interrupts. */
                   5747:     save_flags(flags);
                   5748:     cli();
                   5749: 
                   5750:     ASC_DBG1(1, "advansys_reset: %x\n", (unsigned) scp);
                   5751: 
                   5752: #ifdef ADVANSYS_STATS
                   5753:     if (scp->host != NULL) {
                   5754:         ASC_STATS(scp->host, reset);
                   5755:     }    
                   5756: #endif /* ADVANSYS_STATS */
                   5757: 
                   5758: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
                   5759:     if ((reset_flags & SCSI_RESET_ASYNCHRONOUS) &&
                   5760:         (scp->serial_number != scp->serial_number_at_timeout)) {
                   5761:         ASC_PRINT1(
                   5762: "advansys_reset: timeout serial number changed for request %x\n",
                   5763:             (unsigned) scp);
                   5764:         do_scsi_done = ASC_FALSE;
                   5765:         scp_found = ASC_FALSE;
                   5766:         ret = SCSI_RESET_NOT_RUNNING;
                   5767:     } else
                   5768: #endif /* version >= v1.3.89 */
                   5769:     if ((shp = scp->host) == NULL) {
                   5770:         scp->result = HOST_BYTE(DID_ERROR);
                   5771:         do_scsi_done = ASC_TRUE;
                   5772:         scp_found = ASC_FALSE;
                   5773:         ret = SCSI_RESET_ERROR;
                   5774:     } else if ((boardp = ASC_BOARDP(shp))->flags & 
                   5775:                 (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) {
                   5776:         ASC_PRINT2(
                   5777: "advansys_reset: board %d: Nested host reset or abort, flags 0x%x\n",
                   5778:             boardp->id, boardp->flags);
                   5779:         do_scsi_done = ASC_TRUE;
                   5780:         if ((asc_rmqueue(&boardp->active, scp) == ASC_TRUE) ||
                   5781:             (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE)) {
                   5782:             scp_found = ASC_TRUE;
                   5783:         } else {
                   5784:             scp_found = ASC_FALSE;
                   5785:         }
                   5786:         scp->result = HOST_BYTE(DID_ERROR);
                   5787:         ret = SCSI_RESET_ERROR;
                   5788:     } else if (jiffies >= boardp->last_reset &&
                   5789:                jiffies < (boardp->last_reset + (10 * HZ))) {
                   5790:         /*
                   5791:          * Don't allow a reset to be attempted within 10 seconds
                   5792:          * of the last reset.
                   5793:          *
                   5794:          * If 'jiffies' wrapping occurs, the reset request will go
                   5795:          * through, because a wrapped 'jiffies' would not pass the
                   5796:          * test above.
                   5797:          */
                   5798:         ASC_DBG(1,
                   5799:             "advansys_reset: reset within 10 sec of last reset ignored\n");
                   5800:         do_scsi_done = ASC_TRUE;
                   5801:         if ((asc_rmqueue(&boardp->active, scp) == ASC_TRUE) ||
                   5802:             (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE)) {
                   5803:             scp_found = ASC_TRUE;
                   5804:         } else {
                   5805:             scp_found = ASC_FALSE;
                   5806:         }
                   5807:         scp->result = HOST_BYTE(DID_ERROR);
                   5808:         ret = SCSI_RESET_ERROR;
                   5809:     } else {
                   5810:         do_scsi_done = ASC_TRUE;
                   5811: 
                   5812:         /* Set reset flag to avoid nested reset or abort requests. */
                   5813:         boardp->flags |= ASC_HOST_IN_RESET;
                   5814: 
                   5815:         /*
                   5816:           * If the request is on the target waiting or active queue
                   5817:          * or the board done queue, then remove it and note that it
                   5818:          * was found.
                   5819:          */
                   5820:         if (asc_rmqueue(&boardp->active, scp) == ASC_TRUE) {
                   5821:             ASC_DBG(1, "advansys_reset: active scp_found = TRUE\n");
                   5822:             scp_found = ASC_TRUE;
                   5823:         } else if (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE) {
                   5824:             ASC_DBG(1, "advansys_reset: waiting scp_found = TRUE\n");
                   5825:             scp_found = ASC_TRUE;
                   5826:         } else if (asc_rmqueue(&boardp->done, scp) == ASC_TRUE) {
                   5827:             scp_found = ASC_TRUE;
                   5828:         } else {
                   5829:             scp_found = ASC_FALSE;
                   5830:         }
                   5831: 
                   5832: 
                   5833:         if (ASC_NARROW_BOARD(boardp)) {
                   5834:             /*
                   5835:              * Narrow Board
                   5836:              *
                   5837:              * If the suggest reset bus flags are set, then reset the bus.
                   5838:              * Otherwise only reset the device.
                   5839:              */
                   5840:             asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
                   5841: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
                   5842:             if (reset_flags &
                   5843:                 (SCSI_RESET_SUGGEST_BUS_RESET |
                   5844:                  SCSI_RESET_SUGGEST_HOST_RESET)) {
                   5845: #endif /* version >= v1.3.89 */
                   5846: 
                   5847:                 /*
                   5848:                  * Reset the target's SCSI bus.
                   5849:                  */
                   5850:                 ASC_DBG(1, "advansys_reset: before AscResetSB()\n");
                   5851:                 sti();    /* Enable interrupts for AscResetSB(). */
                   5852:                 status = AscResetSB(asc_dvc_varp);
                   5853:                 cli();
                   5854:                 switch (status) {
                   5855:                 case ASC_TRUE:
                   5856:                     ASC_DBG(1, "advansys_reset: AscResetSB() success\n");
                   5857:                     ret = SCSI_RESET_SUCCESS;
                   5858:                     break;
                   5859:                 case ASC_ERROR:
                   5860:                 default:
                   5861:                     ASC_DBG(1, "advansys_reset: AscResetSB() failed\n");
                   5862:                     ret = SCSI_RESET_ERROR;
                   5863:                     break;
                   5864:                 }
                   5865: 
                   5866: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
                   5867:             } else {
                   5868:                 /*
                   5869:                  * Reset the specified device. If the device reset fails,
                   5870:                  * then reset the SCSI bus.
                   5871:                  */
                   5872: 
                   5873:                 ASC_DBG1(1,
                   5874:                     "advansys_reset: before AscResetDevice(), target %d\n",
                   5875:                     scp->target);
                   5876:                 sti();    /* Enable interrupts for AscResetDevice(). */
                   5877:                 status = AscResetDevice(asc_dvc_varp, scp->target);
                   5878:                 cli();
                   5879: 
                   5880:                 switch (status) {
                   5881:                 case ASC_TRUE:
                   5882:                     ASC_DBG(1, "advansys_reset: AscResetDevice() success\n");
                   5883:                     device_reset = ASC_TRUE;
                   5884:                     ret = SCSI_RESET_SUCCESS;
                   5885:                     break;
                   5886:                 case ASC_ERROR:
                   5887:                 default:
                   5888:                     ASC_DBG(1,
                   5889: "advansys_reset: AscResetDevice() failed; Calling AscResetSB()\n");
                   5890:                     sti();    /* Enable interrupts for AscResetSB(). */
                   5891:                     status = AscResetSB(asc_dvc_varp);
                   5892:                     cli();
                   5893:                     switch (status) {
                   5894:                     case ASC_TRUE:
                   5895:                         ASC_DBG(1, "advansys_reset: AscResetSB() TRUE\n");
                   5896:                         ret = SCSI_RESET_SUCCESS;
                   5897:                         break;
                   5898:                     case ASC_ERROR:
                   5899:                     default:
                   5900:                         ASC_DBG(1, "advansys_reset: AscResetSB() ERROR\n");
                   5901:                         ret = SCSI_RESET_ERROR;
                   5902:                         break;
                   5903:                     }
                   5904:                     break;
                   5905:                 }
                   5906:             }
                   5907: #endif /* version >= v1.3.89 */
                   5908:         } else {
                   5909:             /*
                   5910:              * Wide Board
                   5911:              *
                   5912:              * If the suggest reset bus flags are set, then reset the bus.
                   5913:              * Otherwise only reset the device.
                   5914:              */
                   5915:             adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
                   5916: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
                   5917:             if (reset_flags &
                   5918:                 (SCSI_RESET_SUGGEST_BUS_RESET |
                   5919:                  SCSI_RESET_SUGGEST_HOST_RESET)) {
                   5920: #endif /* version >= v1.3.89 */
                   5921: 
                   5922:                 /*
                   5923:                  * Reset the target's SCSI bus.
                   5924:                  */
                   5925:                 ASC_DBG(1, "advansys_reset: before AdvResetSB()\n");
                   5926:                 switch (AdvResetSB(adv_dvc_varp)) {
                   5927:                 case ASC_TRUE:
                   5928:                     ASC_DBG(1, "advansys_reset: AdvResetSB() success\n");
                   5929:                     ret = SCSI_RESET_SUCCESS;
                   5930:                     break;
                   5931:                 case ASC_FALSE:
                   5932:                 default:
                   5933:                     ASC_DBG(1, "advansys_reset: AdvResetSB() failed\n");
                   5934:                     ret = SCSI_RESET_ERROR;
                   5935:                     break;
                   5936:                 }
                   5937:                 /*
                   5938:                  * Ensure all requests completed by the microcode have
                   5939:                  * been processed by calling AdvISR().
                   5940:                  */
                   5941:                 (void) AdvISR(adv_dvc_varp);
                   5942: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
                   5943:             } else {
                   5944:                 /*
                   5945:                  * Reset the specified device. If the device reset fails,
                   5946:                  * then reset the SCSI bus.
                   5947:                  */
                   5948: 
                   5949:                 ASC_DBG1(1,
                   5950:                     "advansys_reset: before AdvResetDevice(), target %d\n",
                   5951:                     scp->target);
                   5952:                 
                   5953:                 switch (AdvResetDevice(adv_dvc_varp, scp->target)) {
                   5954:                 case ASC_TRUE:
                   5955:                     ASC_DBG(1, "advansys_reset: AdvResetDevice() success\n");
                   5956:                     device_reset = ASC_TRUE;
                   5957:                     ret = SCSI_RESET_SUCCESS;
                   5958:                     break;
                   5959:                 case ASC_FALSE:
                   5960:                 default:
                   5961:                     ASC_DBG(1,
                   5962: "advansys_reset: AdvResetDevice() failed; Calling AdvResetSB()\n");
                   5963:                     
                   5964:                     switch (AdvResetSB(adv_dvc_varp)) {
                   5965:                     case ASC_TRUE:
                   5966:                         ASC_DBG(1, "advansys_reset: AdvResetSB() TRUE\n");
                   5967:                         ret = SCSI_RESET_SUCCESS;
                   5968:                         break;
                   5969:                     case ASC_FALSE:
                   5970:                     default:
                   5971:                         ASC_DBG(1, "advansys_reset: AdvResetSB() ERROR\n");
                   5972:                         ret = SCSI_RESET_ERROR;
                   5973:                         break;
                   5974:                     }
                   5975:                     break;
                   5976:                 }
                   5977:                 /*
                   5978:                  * Ensure all requests completed by the microcode have
                   5979:                  * been processed by calling AdvISR().
                   5980:                  */
                   5981:                 (void) AdvISR(adv_dvc_varp);
                   5982:             }
                   5983: #endif /* version >= v1.3.89 */
                   5984:         }
                   5985: 
                   5986:         /*
                   5987:          * Because the ASC_HOST_IN_RESET flag causes both
                   5988:          * 'advansys_interrupt' and 'asc_isr_callback' to
                   5989:          * queue requests to the board's 'done' queue and
                   5990:          * prevents waiting commands from being executed,
                   5991:          * these queued requests must be handled here.
                   5992:          */
                   5993:         done_scp = asc_dequeue_list(&boardp->done, &last_scp,
                   5994:                                     ASC_TID_ALL);
                   5995: 
                   5996:         /*
                   5997:          * If a device reset was performed dequeue all waiting
                   5998:          * and active requests for the device and set the request
                   5999:          * status to DID_RESET.
                   6000:          *
                   6001:          * If a SCSI bus reset was performed dequeue all waiting
                   6002:          * and active requests for all devices and set the request
                   6003:          * status to DID_RESET.
                   6004:          */
                   6005:         if (device_reset == ASC_TRUE) {
                   6006:             target = scp->target;
                   6007:         } else {
                   6008:             target = ASC_TID_ALL;
                   6009:         }
                   6010: 
                   6011:         /*
                   6012:          * Add active requests to 'done_scp' and set the request status
                   6013:          * to DID_RESET.
                   6014:          */
                   6015:         if (done_scp == NULL) {
                   6016:             done_scp = asc_dequeue_list(&boardp->active, &last_scp, target);
1.1.1.2   root     6017:             for (tscp = done_scp; tscp; tscp = (REQP) REQPNEXT(tscp)) {
1.1       root     6018:                 tscp->result = HOST_BYTE(DID_RESET);
                   6019:             }
                   6020:         } else {
                   6021:             ASC_ASSERT(last_scp != NULL);
1.1.1.2   root     6022:             REQPNEXT(last_scp) =
                   6023:              (unsigned char *) asc_dequeue_list(&boardp->active,
                   6024:                                                 &new_last_scp, target);
                   6025:             if (new_last_scp != (Scsi_Cmnd *) NULL) {
                   6026:                ASC_ASSERT((REQP) REQPNEXT(last_scp) != NULL);
                   6027:                 for (tscp = (Scsi_Cmnd *) REQPNEXT(last_scp);
                   6028:                     tscp;
                   6029:                     tscp = (Scsi_Cmnd *) REQPNEXT(tscp)) {
1.1       root     6030:                     tscp->result = HOST_BYTE(DID_RESET);
                   6031:                 }
                   6032:                 last_scp = new_last_scp;
                   6033:             }
                   6034:         }
                   6035: 
                   6036:         /*
                   6037:          * Add waiting requests to 'done_scp' and set the request status
                   6038:          * to DID_RESET.
                   6039:          */
                   6040:         if (done_scp == NULL) {
                   6041:             done_scp = asc_dequeue_list(&boardp->waiting, &last_scp, target);
1.1.1.2   root     6042:             for (tscp = done_scp; tscp; tscp = (REQP) REQPNEXT(tscp)) {
1.1       root     6043:                 tscp->result = HOST_BYTE(DID_RESET);
                   6044:             }
                   6045:         } else {
                   6046:             ASC_ASSERT(last_scp != NULL);
1.1.1.2   root     6047:             REQPNEXT(last_scp) =
                   6048:              (unsigned char *) asc_dequeue_list(&boardp->waiting,
                   6049:                                                 &new_last_scp, target);
1.1       root     6050:             if (new_last_scp != NULL) {
1.1.1.2   root     6051:                ASC_ASSERT((REQP) REQPNEXT(last_scp) != NULL);
                   6052:                 for (tscp = (REQP) REQPNEXT(last_scp);
                   6053:                     tscp;
                   6054:                     tscp = (REQP) REQPNEXT(tscp)) {
1.1       root     6055:                     tscp->result = HOST_BYTE(DID_RESET);
                   6056:                 }
                   6057:                 last_scp = new_last_scp;
                   6058:             }
                   6059:         }
                   6060: 
                   6061:         /* Save the time of the most recently completed reset. */
                   6062:         boardp->last_reset = jiffies;
                   6063: 
                   6064:         /* Clear reset flag. */
                   6065:         boardp->flags &= ~ASC_HOST_IN_RESET;
                   6066: 
                   6067:         /*
                   6068:          * Start any waiting commands for the board.
                   6069:          */
                   6070:         if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
                   6071:             ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
                   6072:             asc_execute_queue(&boardp->waiting);
                   6073:         }
                   6074:         ret = SCSI_RESET_SUCCESS;
                   6075:     }
                   6076: 
                   6077:     /* Interrupts could be enabled here. */
                   6078: 
                   6079:     ASC_ASSERT(do_scsi_done != ASC_ERROR);
                   6080:     ASC_ASSERT(scp_found != ASC_ERROR);
                   6081:     if (do_scsi_done == ASC_TRUE) {
                   6082:         if (scp->scsi_done == NULL) {
                   6083:             ASC_PRINT1(
                   6084: "advansys_reset: reset request scsi_done() is NULL, %x\n",
                   6085:                 (unsigned) scp);
                   6086:         } else {
                   6087:             if (scp_found == ASC_FALSE) {
                   6088:                 ASC_PRINT1(
                   6089: "advansys_reset: reset request not active or waiting, completing anyway %x\n",
                   6090:                     (unsigned) scp);
                   6091:             }
                   6092:             ASC_STATS(scp->host, done);
                   6093:             scp->scsi_done(scp);
                   6094:         }
                   6095:     }
                   6096: 
                   6097:     /*
                   6098:      * It is possible for the request done function to re-enable
                   6099:      * interrupts without confusing the driver. But here interrupts
                   6100:      * aren't enabled until requests have been completed.
                   6101:      */
                   6102:     if (done_scp != NULL) {
                   6103:         asc_scsi_done_list(done_scp);
                   6104:     }
                   6105: 
                   6106:     ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
                   6107: 
                   6108:     /* Re-enable interrupts, if they were enabled on entry. */
                   6109:     restore_flags(flags);
                   6110: 
                   6111:     ASC_ASSERT(ret != ASC_ERROR);
                   6112:     return ret;
                   6113: }
                   6114: 
                   6115: /*
                   6116:  * advansys_biosparam()
                   6117:  *
                   6118:  * Translate disk drive geometry if the "BIOS greater than 1 GB"
                   6119:  * support is enabled for a drive.
                   6120:  *
                   6121:  * ip (information pointer) is an int array with the following definition:
                   6122:  * ip[0]: heads
                   6123:  * ip[1]: sectors
                   6124:  * ip[2]: cylinders
                   6125:  */
                   6126: int
                   6127: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
                   6128: advansys_biosparam(Disk *dp, int dep, int ip[])
                   6129: #else /* version >= v1.3.0 */
                   6130: advansys_biosparam(Disk *dp, kdev_t dep, int ip[])
                   6131: #endif /* version >= v1.3.0 */
                   6132: {
                   6133:     asc_board_t     *boardp;
                   6134: 
                   6135:     ASC_DBG(1, "advansys_biosparam: begin\n");
                   6136:     ASC_STATS(dp->device->host, biosparam);
                   6137:     boardp = ASC_BOARDP(dp->device->host);
                   6138:     if (ASC_NARROW_BOARD(boardp)) {
                   6139:         if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
                   6140:              ASC_CNTL_BIOS_GT_1GB) && dp->capacity > 0x200000) {
                   6141:                 ip[0] = 255;
                   6142:                 ip[1] = 63;
                   6143:         } else {
                   6144:                 ip[0] = 64;
                   6145:                 ip[1] = 32;
                   6146:         }
                   6147:     } else {
                   6148:         if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
                   6149:              BIOS_CTRL_EXTENDED_XLAT) && dp->capacity > 0x200000) {
                   6150:                 ip[0] = 255;
                   6151:                 ip[1] = 63;
                   6152:         } else {
                   6153:                 ip[0] = 64;
                   6154:                 ip[1] = 32;
                   6155:         }
                   6156:     }
                   6157:     ip[2] = dp->capacity / (ip[0] * ip[1]);
                   6158:     ASC_DBG(1, "advansys_biosparam: end\n");
                   6159:     return 0;
                   6160: }
                   6161: 
                   6162: /*
                   6163:  * advansys_setup()
                   6164:  *
                   6165:  * This function is called from init/main.c at boot time.
                   6166:  * It it passed LILO parameters that can be set from the
                   6167:  * LILO command line or in /etc/lilo.conf.
                   6168:  *
                   6169:  * It is used by the AdvanSys driver to either disable I/O
                   6170:  * port scanning or to limit scanning to 1 - 4 I/O ports.
                   6171:  * Regardless of the option setting EISA and PCI boards
                   6172:  * will still be searched for and detected. This option
                   6173:  * only affects searching for ISA and VL boards.
                   6174:  *
                   6175:  * If ADVANSYS_DEBUG is defined the driver debug level may
                   6176:  * be set using the 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port.
                   6177:  *
                   6178:  * Examples:
                   6179:  * 1. Eliminate I/O port scanning:
                   6180:  *         boot: linux advansys=
                   6181:  *       or
                   6182:  *         boot: linux advansys=0x0
                   6183:  * 2. Limit I/O port scanning to one I/O port:
                   6184:  *        boot: linux advansys=0x110
                   6185:  * 3. Limit I/O port scanning to four I/O ports:
                   6186:  *        boot: linux advansys=0x110,0x210,0x230,0x330
                   6187:  * 4. If ADVANSYS_DEBUG, limit I/O port scanning to four I/O ports and
                   6188:  *    set the driver debug level to 2.
                   6189:  *        boot: linux advansys=0x110,0x210,0x230,0x330,0xdeb2
                   6190:  *
                   6191:  * ints[0] - number of arguments
                   6192:  * ints[1] - first argument
                   6193:  * ints[2] - second argument
                   6194:  * ...
                   6195:  */
                   6196: ASC_INITFUNC(
                   6197: void
                   6198: advansys_setup(char *str, int *ints)
                   6199: )
                   6200: {
                   6201:     int    i;
                   6202: 
                   6203:     if (asc_iopflag == ASC_TRUE) {
                   6204:         printk("AdvanSys SCSI: 'advansys' LILO option may appear only once\n");
                   6205:         return;
                   6206:     }
                   6207: 
                   6208:     asc_iopflag = ASC_TRUE;
                   6209: 
                   6210:     if (ints[0] > ASC_NUM_IOPORT_PROBE) {
                   6211: #ifdef ADVANSYS_DEBUG
                   6212:         if ((ints[0] == ASC_NUM_IOPORT_PROBE + 1) &&
                   6213:             (ints[ASC_NUM_IOPORT_PROBE + 1] >> 4 == 0xdeb)) {
                   6214:             asc_dbglvl = ints[ASC_NUM_IOPORT_PROBE + 1] & 0xf;
                   6215:         } else {
                   6216: #endif /* ADVANSYS_DEBUG */
                   6217:             printk("AdvanSys SCSI: only %d I/O ports accepted\n",
                   6218:                 ASC_NUM_IOPORT_PROBE);
                   6219: #ifdef ADVANSYS_DEBUG
                   6220:         }
                   6221: #endif /* ADVANSYS_DEBUG */
                   6222:     }
                   6223: 
                   6224: #ifdef ADVANSYS_DEBUG
                   6225:     ASC_DBG1(1, "advansys_setup: ints[0] %d\n", ints[0]);
                   6226:     for (i = 1; i < ints[0]; i++) {
                   6227:         ASC_DBG2(1, " ints[%d] %x", i, ints[i]);
                   6228:     }
                   6229:     ASC_DBG(1, "\n");
                   6230: #endif /* ADVANSYS_DEBUG */
                   6231: 
                   6232:     for (i = 1; i <= ints[0] && i <= ASC_NUM_IOPORT_PROBE; i++) {
                   6233:         asc_ioport[i-1] = ints[i];
                   6234:         ASC_DBG2(1, "advansys_setup: asc_ioport[%d] %x\n",
                   6235:             i - 1, asc_ioport[i-1]);
                   6236:     }
                   6237: }
                   6238: 
                   6239: 
                   6240: /*
                   6241:  * --- Loadable Driver Support
                   6242:  */
                   6243: 
                   6244: #ifdef MODULE
                   6245: Scsi_Host_Template driver_template = ADVANSYS;
                   6246: # include "scsi_module.c"
                   6247: #endif /* MODULE */
                   6248: 
                   6249: 
                   6250: /*
                   6251:  * --- Miscellaneous Driver Functions
                   6252:  */
                   6253: 
                   6254: /*
                   6255:  * First-level interrupt handler.
                   6256:  *
                   6257:  * For versions > v1.3.70, 'dev_id' is a pointer to the interrupting
                   6258:  * adapter's asc_board_t. Because all boards are currently checked
                   6259:  * for interrupts on each interrupt, 'dev_id' is not referenced. 'dev_id'
                   6260:  * could be used to identify an interrupt passed to the AdvanSys driver,
                   6261:  * which is for a device sharing an interrupt with an AdvanSys adapter.
                   6262:  */
                   6263: STATIC void
                   6264: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
                   6265: advansys_interrupt(int irq, struct pt_regs *regs)
                   6266: #else /* version >= v1.3.70 */
                   6267: advansys_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                   6268: #endif /* version >= v1.3.70 */
                   6269: {
                   6270: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,95)
1.1.1.2   root     6271:     long            flags;
1.1       root     6272: #else /* version >= v2.1.95 */
                   6273:     unsigned long   flags;
                   6274: #endif /* version >= v2.1.95 */
                   6275:     int             i;
                   6276:     asc_board_t     *boardp;
                   6277:     Scsi_Cmnd       *done_scp = NULL, *last_scp = NULL;
                   6278:     Scsi_Cmnd       *new_last_scp;
                   6279: 
                   6280: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,95)
                   6281:     /* Disable interrupts, if they aren't already disabled. */
                   6282:     save_flags(flags);
                   6283:     cli();
                   6284: #else /* version >= v2.1.95 */
                   6285:     /*
                   6286:      * Disable interrupts, if they aren't already disabled and acquire
                   6287:      * the I/O spinlock.
                   6288:      */
                   6289:     spin_lock_irqsave(&io_request_lock, flags);
                   6290: #endif /* version >= v2.1.95 */
                   6291: 
                   6292:     ASC_DBG(1, "advansys_interrupt: begin\n");
                   6293: 
                   6294:     /*
                   6295:      * Check for interrupts on all boards.
                   6296:      * AscISR() will call asc_isr_callback().
                   6297:      */
                   6298:     for (i = 0; i < asc_board_count; i++) {
                   6299:         boardp = ASC_BOARDP(asc_host[i]);
                   6300:         ASC_DBG2(2, "advansys_interrupt: i %d, boardp %lx\n",
                   6301:             i, (ulong) boardp)            
                   6302:         if (ASC_NARROW_BOARD(boardp)) {
                   6303:             /*
                   6304:              * Narrow Board
                   6305:              */
                   6306:             if (AscIsIntPending(asc_host[i]->io_port)) {
                   6307:                 ASC_STATS(asc_host[i], interrupt);
                   6308:                 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
                   6309:                 AscISR(&boardp->dvc_var.asc_dvc_var);
                   6310:             }
                   6311:         } else {
                   6312:             /*
                   6313:              * Wide Board
                   6314:              */
                   6315:             ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
                   6316:             if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
                   6317:                 ASC_STATS(asc_host[i], interrupt);
                   6318:             }
                   6319:         }
                   6320: 
                   6321:         /*
                   6322:          * Start waiting requests and create a list of completed requests.
                   6323:          * 
                   6324:          * If a reset or abort request is being performed for the board,
                   6325:          * the reset or abort handler will complete pending requests after
                   6326:          * it has completed.
                   6327:          */
                   6328:         if ((boardp->flags & (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) == 0) {
                   6329:             ASC_DBG2(1, "advansys_interrupt: done_scp %lx, last_scp %lx\n",
                   6330:                 (ulong) done_scp, (ulong) last_scp);
                   6331: 
                   6332:             /* Start any waiting commands for the board. */
                   6333:             if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
                   6334:                 ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
                   6335:                 asc_execute_queue(&boardp->waiting);
                   6336:             }
                   6337: 
                   6338:              /*
                   6339:               * Add to the list of requests that must be completed.
                   6340:               *
                   6341:               * 'done_scp' will always be NULL on the first iteration
                   6342:               * of this loop. 'last_scp' is set at the same time as
                   6343:               * 'done_scp'.
                   6344:               */
                   6345:             if (done_scp == NULL) {
                   6346:                 done_scp = asc_dequeue_list(&boardp->done, &last_scp,
                   6347:                     ASC_TID_ALL);
                   6348:             } else {
                   6349:                 ASC_ASSERT(last_scp != NULL);
1.1.1.2   root     6350:                 REQPNEXT(last_scp) =
                   6351:                  (unsigned char *) asc_dequeue_list(&boardp->done,
                   6352:                                                     &new_last_scp,
                   6353:                                                     ASC_TID_ALL);
1.1       root     6354:                 if (new_last_scp != NULL) {
                   6355:                     ASC_ASSERT(REQPNEXT(last_scp) != NULL);
                   6356:                     last_scp = new_last_scp;
                   6357:                 }
                   6358:             }
                   6359:         }
                   6360:     }
                   6361: 
                   6362:     /* Interrupts could be enabled here. */
                   6363: 
                   6364:     /*
                   6365:      * It is possible for the request done function to re-enable
                   6366:      * interrupts without confusing the driver. But here the
                   6367:      * original flags aren't restored until all requests have been
                   6368:      * completed.
                   6369:      */
                   6370:     asc_scsi_done_list(done_scp);
                   6371: 
                   6372: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,95)
                   6373:     /*
                   6374:      * Restore the original flags which will enable interrupts
                   6375:      * if and only if they were enabled on entry.
                   6376:      */
                   6377:     restore_flags(flags);
                   6378: #else /* version >= v2.1.95 */
                   6379:     /*
                   6380:      * Release the I/O spinlock and restore the original flags
                   6381:      * which will enable interrupts if and only if they were
                   6382:      * enabled on entry.
                   6383:      */
                   6384:     spin_unlock_irqrestore(&io_request_lock, flags);
                   6385: #endif /* version >= v2.1.95 */
                   6386: 
                   6387:     ASC_DBG(1, "advansys_interrupt: end\n");
                   6388:     return;
                   6389: }
                   6390: 
                   6391: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
                   6392: /*
                   6393:  * Set the number of commands to queue per device for the
                   6394:  * specified host adapter.
                   6395:  */
                   6396: STATIC void
                   6397: advansys_select_queue_depths(struct Scsi_Host *shp, Scsi_Device *devicelist)
                   6398: {
                   6399:     Scsi_Device        *device;
                   6400:     asc_board_t        *boardp;
                   6401: 
                   6402:     boardp = ASC_BOARDP(shp);
                   6403:     boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
                   6404:     for (device = devicelist; device != NULL; device = device->next) {
                   6405:         if (device->host != shp) {
                   6406:             continue;
                   6407:         }
                   6408:         /*
                   6409:          * Save a pointer to the device and set its initial/maximum
                   6410:          * queue depth.
                   6411:          */
                   6412:         boardp->device[device->id] = device;
                   6413:         if (ASC_NARROW_BOARD(boardp)) {
                   6414:             device->queue_depth =
                   6415:                 boardp->dvc_var.asc_dvc_var.max_dvc_qng[device->id];
                   6416:         } else {
                   6417:             device->queue_depth =
                   6418:                 boardp->dvc_var.adv_dvc_var.max_dvc_qng;
                   6419:         }
                   6420:         ASC_DBG3(1, "advansys_select_queue_depths: shp %x, id %d, depth %d\n",
                   6421:             (unsigned) shp, device->id, device->queue_depth);
                   6422:     }
                   6423: }
                   6424: #endif /* version >= v1.3.89 */
                   6425: 
                   6426: /*
                   6427:  * Function used only with polled I/O requests that are initiated by
                   6428:  * advansys_command().
                   6429:  */
                   6430: STATIC void
                   6431: advansys_command_done(Scsi_Cmnd *scp)
                   6432: {
                   6433:     ASC_DBG1(1, "advansys_command_done: scp %x\n", (unsigned) scp);
                   6434:     scp->SCp.Status = 1;
                   6435: }
                   6436: 
                   6437: /*
                   6438:  * Complete all requests on the singly linked list pointed
                   6439:  * to by 'scp'.
                   6440:  *
                   6441:  * Interrupts can be enabled on entry.
                   6442:  */
                   6443: STATIC void
                   6444: asc_scsi_done_list(Scsi_Cmnd *scp)
                   6445: {
                   6446:     Scsi_Cmnd    *tscp;
                   6447: 
                   6448:     ASC_DBG(2, "asc_scsi_done_list: begin\n");
                   6449:     while (scp != NULL) {
                   6450:         ASC_DBG1(3, "asc_scsi_done_list: scp %x\n", (unsigned) scp);
1.1.1.2   root     6451:         tscp = (REQP) REQPNEXT(scp);
1.1       root     6452:         REQPNEXT(scp) = NULL;
                   6453:         ASC_STATS(scp->host, done);
                   6454:         ASC_ASSERT(scp->scsi_done != NULL);
                   6455:         scp->scsi_done(scp);
                   6456:         scp = tscp;
                   6457:     }
                   6458:     ASC_DBG(2, "asc_scsi_done_list: done\n");
                   6459:     return;
                   6460: }
                   6461: 
                   6462: /*
                   6463:  * Execute a single 'Scsi_Cmnd'.
                   6464:  *
                   6465:  * The function 'done' is called when the request has been completed.
                   6466:  *
                   6467:  * Scsi_Cmnd:
                   6468:  *
                   6469:  *  host - board controlling device
                   6470:  *  device - device to send command
                   6471:  *  target - target of device
                   6472:  *  lun - lun of device
                   6473:  *  cmd_len - length of SCSI CDB
                   6474:  *  cmnd - buffer for SCSI 8, 10, or 12 byte CDB
                   6475:  *  use_sg - if non-zero indicates scatter-gather request with use_sg elements
                   6476:  *
                   6477:  *  if (use_sg == 0) {
                   6478:  *    request_buffer - buffer address for request
                   6479:  *    request_bufflen - length of request buffer
                   6480:  *  } else {
                   6481:  *    request_buffer - pointer to scatterlist structure
                   6482:  *  }
                   6483:  *
                   6484:  *  sense_buffer - sense command buffer
                   6485:  *
                   6486:  *  result (4 bytes of an int):
                   6487:  *    Byte Meaning
                   6488:  *    0 SCSI Status Byte Code
                   6489:  *    1 SCSI One Byte Message Code
                   6490:  *    2 Host Error Code
                   6491:  *    3 Mid-Level Error Code
                   6492:  *
                   6493:  *  host driver fields:
                   6494:  *    SCp - Scsi_Pointer used for command processing status
                   6495:  *    scsi_done - used to save caller's done function
                   6496:  *    host_scribble - used for pointer to another Scsi_Cmnd
                   6497:  *
                   6498:  * If this function returns ASC_NOERROR or ASC_ERROR the request
                   6499:  * has been enqueued on the board's 'done' queue and must be
                   6500:  * completed by the caller.
                   6501:  *
                   6502:  * If ASC_BUSY is returned the request must be enqueued by the
                   6503:  * caller and re-tried later.
                   6504:  */
                   6505: STATIC int
                   6506: asc_execute_scsi_cmnd(Scsi_Cmnd *scp)
                   6507: {
                   6508:     asc_board_t        *boardp;
                   6509:     ASC_DVC_VAR        *asc_dvc_varp;
                   6510:     ADV_DVC_VAR        *adv_dvc_varp;
                   6511:     ADV_SCSI_REQ_Q     *adv_scsiqp;
                   6512:     Scsi_Device        *device;
                   6513:     int                ret;
                   6514: 
                   6515:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
                   6516:     ASC_DBG2(1, "asc_execute_scsi_cmnd: scp %x, done %x\n",
                   6517:         (unsigned) scp, (unsigned) scp->scsi_done);
                   6518: 
                   6519:     boardp = ASC_BOARDP(scp->host);
                   6520:     device = boardp->device[scp->target];
                   6521: 
                   6522:     if (ASC_NARROW_BOARD(boardp)) {
                   6523:         /*
                   6524:          * Build and execute Narrow Board request.
                   6525:          */
                   6526: 
                   6527:         asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
                   6528: 
                   6529:         /*
                   6530:          * Build Asc Library request structure using the
                   6531:          * global structures 'asc_scsi_req' and 'asc_sg_head'.
                   6532:          *
                   6533:          * asc_build_req() can not return ASC_BUSY.
                   6534:          */
                   6535:         if (asc_build_req(boardp, scp) == ASC_ERROR) {
                   6536:             ASC_STATS(scp->host, build_error);
                   6537:             return ASC_ERROR;
                   6538:         }
                   6539: 
                   6540:         /*
                   6541:          * Execute the command. If there is no error, add the command
                   6542:          * to the active queue.
                   6543:          */
                   6544:         switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
                   6545:         case ASC_NOERROR:
                   6546:             ASC_STATS(scp->host, exe_noerror);
                   6547:             /*
                   6548:              * Increment monotonically increasing per device successful
                   6549:              * request counter. Wrapping doesn't matter.
                   6550:              */
                   6551:             boardp->reqcnt[scp->target]++;
                   6552: 
                   6553: #if ASC_QUEUE_FLOW_CONTROL
                   6554:             /*
                   6555:              * Conditionally increment the device queue depth.
                   6556:              *
                   6557:              * If no error occurred and there have been 100 consecutive
                   6558:              * successful requests and the current queue depth is less
                   6559:              * than the maximum queue depth, then increment the current
                   6560:              * queue depth.
                   6561:              */
                   6562:             if (boardp->nerrcnt[scp->target]++ > 100) {
                   6563:                 boardp->nerrcnt[scp->target] = 0;
                   6564:                 if (device != NULL &&
                   6565:                     (device->queue_curr_depth < device->queue_depth) &&
                   6566:                     (!(boardp->queue_full &
                   6567:                        ADV_TID_TO_TIDMASK(scp->target)) ||
                   6568:                      (boardp->queue_full_cnt[scp->target] >
                   6569:                       device->queue_curr_depth))) {
                   6570:                     device->queue_curr_depth++;
                   6571:                 }
                   6572:             }
                   6573: #endif /* ASC_QUEUE_FLOW_CONTROL */
                   6574:             asc_enqueue(&boardp->active, scp, ASC_BACK);
                   6575:             ASC_DBG(1,
                   6576:                 "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
                   6577:             break;
                   6578:         case ASC_BUSY:
                   6579:             /* Caller must enqueue request and retry later. */
                   6580:             ASC_STATS(scp->host, exe_busy);
                   6581: #if ASC_QUEUE_FLOW_CONTROL
                   6582:             /*
                   6583:              * Clear consecutive no error counter and if possible decrement
                   6584:              * queue depth.
                   6585:              */
                   6586:             boardp->nerrcnt[scp->target] = 0;
                   6587:             if (device != NULL && device->queue_curr_depth > 1) {
                   6588:                 device->queue_curr_depth--;
                   6589:             }
                   6590: #endif /* ASC_QUEUE_FLOW_CONTROL */
                   6591:             break;
                   6592:         case ASC_ERROR:
                   6593:             ASC_PRINT2(
                   6594: "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code %x\n",
                   6595:                 boardp->id, asc_dvc_varp->err_code);
                   6596:             ASC_STATS(scp->host, exe_error);
                   6597: #if ASC_QUEUE_FLOW_CONTROL
                   6598:             /* Clear consecutive no error counter. */
                   6599:             boardp->nerrcnt[scp->target] = 0;
                   6600: #endif /* ASC_QUEUE_FLOW_CONTROL */
                   6601:             scp->result = HOST_BYTE(DID_ERROR);
                   6602:             asc_enqueue(&boardp->done, scp, ASC_BACK);
                   6603:             break;
                   6604:         default:
                   6605:             ASC_PRINT2(
                   6606: "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code %x\n",
                   6607:                 boardp->id, asc_dvc_varp->err_code);
                   6608:             ASC_STATS(scp->host, exe_unknown);
                   6609: #if ASC_QUEUE_FLOW_CONTROL
                   6610:             /* Clear consecutive no error counter. */
                   6611:             boardp->nerrcnt[scp->target] = 0;
                   6612: #endif /* ASC_QUEUE_FLOW_CONTROL */
                   6613:             scp->result = HOST_BYTE(DID_ERROR);
                   6614:             asc_enqueue(&boardp->done, scp, ASC_BACK);
                   6615:             break;
                   6616:         }
                   6617:     } else {
                   6618:         /*
                   6619:          * Build and execute Wide Board request.
                   6620:          */
                   6621:         adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
                   6622: 
                   6623:         /*
                   6624:          * Build and get a pointer to an Adv Library request structure.
                   6625:          *
                   6626:          * If the request is successfully built then send  it below,
                   6627:          * otherwise return with an error.
                   6628:          */
                   6629:         switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
                   6630:         case ASC_NOERROR:
                   6631:             ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
                   6632:             break;
                   6633:         case ASC_BUSY:
                   6634:             ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
                   6635:             return ASC_BUSY;
                   6636:         case ASC_ERROR:
                   6637:         default:
                   6638:             ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
                   6639:             ASC_STATS(scp->host, build_error);
                   6640:             return ASC_ERROR;
                   6641:         }
                   6642:     
                   6643:         /*
                   6644:          * Execute the command. If there is no error, add the command
                   6645:          * to the active queue.
                   6646:          */
                   6647:         switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
                   6648:         case ASC_NOERROR:
                   6649:             ASC_STATS(scp->host, exe_noerror);
                   6650:             /*
                   6651:              * Increment monotonically increasing per device successful
                   6652:              * request counter. Wrapping doesn't matter.
                   6653:              */
                   6654:             boardp->reqcnt[scp->target]++;
                   6655:             asc_enqueue(&boardp->active, scp, ASC_BACK);
                   6656:             ASC_DBG(1,
                   6657:                 "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
                   6658:             break;
                   6659:         case ASC_BUSY:
                   6660:             /* Caller must enqueue request and retry later. */
                   6661:             ASC_STATS(scp->host, exe_busy);
                   6662:             break;
                   6663:         case ASC_ERROR:
                   6664:             ASC_PRINT2(
                   6665: "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code %x\n",
                   6666:                 boardp->id, adv_dvc_varp->err_code);
                   6667:             ASC_STATS(scp->host, exe_error);
                   6668:             scp->result = HOST_BYTE(DID_ERROR);
                   6669:             asc_enqueue(&boardp->done, scp, ASC_BACK);
                   6670:             break;
                   6671:         default:
                   6672:             ASC_PRINT2(
                   6673: "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code %x\n",
                   6674:                 boardp->id, adv_dvc_varp->err_code);
                   6675:             ASC_STATS(scp->host, exe_unknown);
                   6676:             scp->result = HOST_BYTE(DID_ERROR);
                   6677:             asc_enqueue(&boardp->done, scp, ASC_BACK);
                   6678:             break;
                   6679:         }
                   6680:     }
                   6681: 
                   6682:     ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
                   6683:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
                   6684:     return ret;
                   6685: }
                   6686: 
                   6687: /*
                   6688:  * Build a request structure for the Asc Library (Narrow Board).
                   6689:  *
                   6690:  * The global structures 'asc_scsi_q' and 'asc_sg_head' are
                   6691:  * used to build the request.
                   6692:  *
                   6693:  * If an error occurs, then return ASC_ERROR.
                   6694:  */
                   6695: STATIC int
                   6696: asc_build_req(asc_board_t *boardp, Scsi_Cmnd *scp)
                   6697: {
                   6698:     /*
                   6699:      * Mutually exclusive access is required to 'asc_scsi_q' and
                   6700:      * 'asc_sg_head' until after the request is started.
                   6701:      */
                   6702:     memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
                   6703: 
                   6704:     /*
                   6705:      * Point the ASC_SCSI_Q to the 'Scsi_Cmnd'.
                   6706:      */
                   6707:     asc_scsi_q.q2.srb_ptr = (ulong) scp;
                   6708: 
                   6709:     /*
                   6710:      * Build the ASC_SCSI_Q request.
                   6711:      */
                   6712:     ASC_ASSERT(scp->cmd_len <= ASC_MAX_CDB_LEN);
                   6713:     if (scp->cmd_len > ASC_MAX_CDB_LEN) {
                   6714:         scp->cmd_len = ASC_MAX_CDB_LEN;
                   6715:     }
                   6716:     asc_scsi_q.cdbptr = &scp->cmnd[0];
                   6717:     asc_scsi_q.q2.cdb_len = scp->cmd_len;
                   6718:     asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->target);
                   6719:     asc_scsi_q.q1.target_lun = scp->lun;
                   6720:     asc_scsi_q.q2.target_ix = ASC_TIDLUN_TO_IX(scp->target, scp->lun);
                   6721: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
                   6722:     asc_scsi_q.q1.sense_addr = (ulong) &scp->sense_buffer[0];
                   6723: #else /* version >= v2.0.0 */
                   6724:     asc_scsi_q.q1.sense_addr = virt_to_bus(&scp->sense_buffer[0]);
                   6725: #endif /* version >= v2.0.0 */
                   6726:     asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
                   6727: 
                   6728:     /*
                   6729:      * If there are any outstanding requests for the current target,
                   6730:      * then every 255th request send an ORDERED request. This heuristic
                   6731:      * tries to retain the benefit of request sorting while preventing
                   6732:      * request starvation. 255 is the max number of tags or pending commands
                   6733:      * a device may have outstanding.
                   6734:      *
                   6735:      * The request count is incremented below for every successfully
                   6736:      * started request.
                   6737:      * 
                   6738:      */
                   6739:     if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->target] > 0) &&
                   6740:         (boardp->reqcnt[scp->target] % 255) == 0) {
                   6741:         asc_scsi_q.q2.tag_code = M2_QTAG_MSG_ORDERED;
                   6742:     } else {
                   6743:         asc_scsi_q.q2.tag_code = M2_QTAG_MSG_SIMPLE;
                   6744:     }
                   6745: 
                   6746:     /*
                   6747:      * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
                   6748:      * buffer command.
                   6749:      */
                   6750:     if (scp->use_sg == 0) {
                   6751:         /*
                   6752:          * CDB request of single contiguous buffer.
                   6753:          */
                   6754:         ASC_STATS(scp->host, cont_cnt);
                   6755: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
                   6756:         asc_scsi_q.q1.data_addr = (ulong) scp->request_buffer;
                   6757: #else /* version >= v2.0.0 */
                   6758:         asc_scsi_q.q1.data_addr = virt_to_bus(scp->request_buffer);
                   6759: #endif /* version >= v2.0.0 */
                   6760:         asc_scsi_q.q1.data_cnt = scp->request_bufflen;
                   6761:         ASC_STATS_ADD(scp->host, cont_xfer,
                   6762:                       ASC_CEILING(scp->request_bufflen, 512));
                   6763:         asc_scsi_q.q1.sg_queue_cnt = 0;
                   6764:         asc_scsi_q.sg_head = NULL;
                   6765:     } else {
                   6766:         /*
                   6767:          * CDB scatter-gather request list.
                   6768:          */
                   6769:         int                     sgcnt;
                   6770:         struct scatterlist      *slp;
                   6771: 
                   6772:         if (scp->use_sg > scp->host->sg_tablesize) {
                   6773:             ASC_PRINT3(
                   6774: "asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
                   6775:                 boardp->id, scp->use_sg, scp->host->sg_tablesize);
                   6776:             scp->result = HOST_BYTE(DID_ERROR);
                   6777:             asc_enqueue(&boardp->done, scp, ASC_BACK);
                   6778:             return ASC_ERROR;
                   6779:         }
                   6780: 
                   6781:         ASC_STATS(scp->host, sg_cnt);
                   6782: 
                   6783:         /*
                   6784:          * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
                   6785:          * structure to point to it.
                   6786:          */
                   6787:         memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
                   6788: 
                   6789:         asc_scsi_q.q1.cntl |= QC_SG_HEAD;
                   6790:         asc_scsi_q.sg_head = &asc_sg_head;
                   6791:         asc_scsi_q.q1.data_cnt = 0;
                   6792:         asc_scsi_q.q1.data_addr = 0;
                   6793:         asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = scp->use_sg;
                   6794:         ASC_STATS_ADD(scp->host, sg_elem, asc_sg_head.entry_cnt);
                   6795: 
                   6796:         /*
                   6797:          * Convert scatter-gather list into ASC_SG_HEAD list.
                   6798:          */
                   6799:         slp = (struct scatterlist *) scp->request_buffer;
                   6800:         for (sgcnt = 0; sgcnt < scp->use_sg; sgcnt++, slp++) {
                   6801: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
                   6802:             asc_sg_head.sg_list[sgcnt].addr = (ulong) slp->address;
                   6803: #else /* version >= v2.0.0 */
                   6804:             asc_sg_head.sg_list[sgcnt].addr = virt_to_bus(slp->address);
                   6805: #endif /* version >= v2.0.0 */
                   6806:             asc_sg_head.sg_list[sgcnt].bytes = slp->length;
                   6807:             ASC_STATS_ADD(scp->host, sg_xfer, ASC_CEILING(slp->length, 512));
                   6808:         }
                   6809:     }
                   6810: 
                   6811:     ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
                   6812:     ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
                   6813: 
                   6814:     return ASC_NOERROR;
                   6815: }
                   6816: 
                   6817: /*
                   6818:  * Build a request structure for the Adv Library (Wide Board).
                   6819:  *
                   6820:  * If an adv_req_t can not be allocated to issue the request,
                   6821:  * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
                   6822:  */
                   6823: STATIC int
                   6824: adv_build_req(asc_board_t *boardp, Scsi_Cmnd *scp,
                   6825:     ADV_SCSI_REQ_Q **adv_scsiqpp)
                   6826: {
                   6827:     adv_req_t           *reqp;
                   6828:     ADV_SCSI_REQ_Q      *scsiqp;
                   6829:     int                 i;
                   6830: 
                   6831:     /*
                   6832:      * Allocate an adv_req_t structure from the board to execute
                   6833:      * the command.
                   6834:      */
                   6835:     if (boardp->adv_reqp == NULL) {
                   6836:         ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
                   6837:         ASC_STATS(scp->host, adv_build_noreq);
                   6838:         return ASC_BUSY;
                   6839:     } else {
                   6840:         reqp = boardp->adv_reqp;
                   6841:         boardp->adv_reqp = reqp->next_reqp;
                   6842:         reqp->next_reqp = NULL;
                   6843:     }
                   6844: 
                   6845:     /*
                   6846:      * Get 4-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
                   6847:      */
                   6848:     scsiqp = (ADV_SCSI_REQ_Q *) ADV_DWALIGN(&reqp->scsi_req_q);
                   6849:     memset(scsiqp, 0, sizeof(ADV_SCSI_REQ_Q));
                   6850: 
                   6851:     /*
                   6852:      * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
                   6853:      */
                   6854:     scsiqp->srb_ptr = (ulong) reqp;
                   6855: 
                   6856:     /*
                   6857:      * Set the adv_req_t 'cmndp' to point to the Scsi_Cmnd structure.
                   6858:      */
                   6859:     reqp->cmndp = scp;
                   6860: 
                   6861:     /*
                   6862:      * Build the ADV_SCSI_REQ_Q request.
                   6863:      */
                   6864: 
                   6865:     /*
                   6866:      * Set CDB length and copy it to the request structure.
                   6867:      */
                   6868:     ASC_ASSERT(scp->cmd_len <= ASC_MAX_CDB_LEN);
                   6869:     if (scp->cmd_len > ASC_MAX_CDB_LEN) {
                   6870:         scp->cmd_len = ASC_MAX_CDB_LEN;
                   6871:     }
                   6872:     scsiqp->cdb_len = scp->cmd_len;
                   6873:     for (i = 0; i < scp->cmd_len; i++) {
                   6874:         scsiqp->cdb[i] = scp->cmnd[i];
                   6875:     }
                   6876: 
                   6877:     scsiqp->target_id = scp->target;
                   6878:     scsiqp->target_lun = scp->lun;
                   6879: 
                   6880:     scsiqp->vsense_addr = (ulong) &scp->sense_buffer[0];
                   6881: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
                   6882:     scsiqp->sense_addr = (ulong) &scp->sense_buffer[0];
                   6883: #else /* version >= v2.0.0 */
                   6884:     scsiqp->sense_addr = virt_to_bus(&scp->sense_buffer[0]);
                   6885: #endif /* version >= v2.0.0 */
                   6886:     scsiqp->sense_len = sizeof(scp->sense_buffer);
                   6887: 
                   6888:     /*
                   6889:      * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
                   6890:      * buffer command.
                   6891:      */
                   6892:     scsiqp->data_cnt = scp->request_bufflen;
                   6893:     scsiqp->vdata_addr = (ulong) scp->request_buffer;
                   6894: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
                   6895:     scsiqp->data_addr = (ulong) scp->request_buffer;
                   6896: #else /* version >= v2.0.0 */
                   6897:     scsiqp->data_addr = virt_to_bus(scp->request_buffer);
                   6898: #endif /* version >= v2.0.0 */
                   6899: 
                   6900:     if (scp->use_sg == 0) {
                   6901:         /*
                   6902:          * CDB request of single contiguous buffer.
                   6903:          */
                   6904:         reqp->sgblkp = NULL;
                   6905:         scsiqp->sg_list_ptr = NULL;
                   6906:         ASC_STATS(scp->host, cont_cnt);
                   6907:         ASC_STATS_ADD(scp->host, cont_xfer,
                   6908:                       ASC_CEILING(scp->request_bufflen, 512));
                   6909:     } else {
                   6910:         /*
                   6911:          * CDB scatter-gather request list.
                   6912:          */
                   6913:         if (scp->use_sg > ADV_MAX_SG_LIST) {
                   6914:             ASC_PRINT3(
                   6915: "adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
                   6916:                 boardp->id, scp->use_sg, scp->host->sg_tablesize);
                   6917:             scp->result = HOST_BYTE(DID_ERROR);
                   6918:             asc_enqueue(&boardp->done, scp, ASC_BACK);
                   6919: 
                   6920:             /*
                   6921:              * Free the 'adv_req_t' structure by adding it back to the
                   6922:              * board free list.
                   6923:              */
                   6924:             reqp->next_reqp = boardp->adv_reqp;
                   6925:             boardp->adv_reqp = reqp;
                   6926: 
                   6927:             return ASC_ERROR;
                   6928:         }
                   6929: 
                   6930:         /*
                   6931:          * Allocate an 'adv_sgblk_t' structure from the board to
                   6932:          * execute the command.
                   6933:          */
                   6934:         if (boardp->adv_sgblkp == NULL) {
                   6935:             ASC_DBG(1, "adv_build_req: no free adv_sgblk_t\n");
                   6936:             ASC_STATS(scp->host, adv_build_nosg);
                   6937:             /*
                   6938:              * Free the 'adv_req_t' structure by adding it back to the
                   6939:              * board free list.
                   6940:              */
                   6941:             reqp->next_reqp = boardp->adv_reqp;
                   6942:             boardp->adv_reqp = reqp;
                   6943:             return ASC_BUSY;
                   6944:         } else {
                   6945:             reqp->sgblkp = boardp->adv_sgblkp;
                   6946:             boardp->adv_sgblkp = reqp->sgblkp->next_sgblkp;
                   6947:             reqp->sgblkp->next_sgblkp = NULL;
                   6948:         }
                   6949: 
                   6950:         /*
                   6951:          * Build scatter-gather list.
                   6952:          */
                   6953:         scsiqp->sg_list_ptr = (ADV_SG_BLOCK *)
                   6954:             ADV_DWALIGN(&reqp->sgblkp->sg_block[0]);
                   6955: 
                   6956:         memset(scsiqp->sg_list_ptr, 0, sizeof(ADV_SG_BLOCK) *
                   6957:             (ADV_NUM_SG_BLOCK + ADV_NUM_PAGE_CROSSING));
                   6958:          
                   6959:         if (adv_get_sglist(&boardp->dvc_var.adv_dvc_var, scsiqp, scp) ==
                   6960:             ADV_ERROR) {
                   6961: 
                   6962:             /*
                   6963:              * Free the adv_sgblk_t structure, if any, by adding it back
                   6964:              * to the board free list.
                   6965:              */
                   6966:             ASC_ASSERT(reqp->sgblkp != NULL);
                   6967:             reqp->sgblkp->next_sgblkp = boardp->adv_sgblkp;
                   6968:             boardp->adv_sgblkp = reqp->sgblkp;
                   6969: 
                   6970:             /*
                   6971:              * Free the adv_req_t structure by adding it back to the
                   6972:              * board free list.
                   6973:              */
                   6974:             reqp->next_reqp = boardp->adv_reqp;
                   6975:             boardp->adv_reqp = reqp;
                   6976: 
                   6977:             return ADV_ERROR;
                   6978:         }
                   6979: 
                   6980:         ASC_STATS(scp->host, sg_cnt);
                   6981:         ASC_STATS_ADD(scp->host, sg_elem, scp->use_sg);
                   6982:     }
                   6983: 
                   6984:     ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
                   6985:     ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
                   6986: 
                   6987:     *adv_scsiqpp = scsiqp;
                   6988: 
                   6989:     return ASC_NOERROR;
                   6990: }
                   6991: 
                   6992: /*
                   6993:  * Build scatter-gather list for Adv Library (Wide Board).
                   6994:  *
                   6995:  * Return:
                   6996:  *      ADV_SUCCESS(1) - SG List successfully created
                   6997:  *      ADV_ERROR(-1) - SG List creation failed
                   6998:  */
                   6999: STATIC int
                   7000: adv_get_sglist(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp,
                   7001:     Scsi_Cmnd *scp)
                   7002: {
                   7003:     ADV_SG_BLOCK        *sg_block;              /* virtual address of a SG */
                   7004:     ulong               sg_block_next_addr;     /* block and its next */
                   7005:     ulong               sg_block_physical_addr;
                   7006:     int                 sg_block_index, i;      /* how many SG entries */
                   7007:     struct scatterlist  *slp;
                   7008:     int                 sg_elem_cnt;
                   7009: 
                   7010:     slp = (struct scatterlist *) scp->request_buffer;
                   7011:     sg_elem_cnt = scp->use_sg;
                   7012: 
                   7013:     sg_block = scsiqp->sg_list_ptr;
                   7014:     sg_block_next_addr = (ulong) sg_block;    /* allow math operation */
                   7015:     sg_block_physical_addr =
                   7016: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
                   7017:         (ulong) scsiqp->sg_list_ptr;
                   7018: #else /* version >= v2.0.0 */
                   7019:         virt_to_bus(scsiqp->sg_list_ptr);
                   7020: #endif /* version >= v2.0.0 */
                   7021:     ADV_ASSERT(ADV_DWALIGN(sg_block_physical_addr) ==
                   7022:                    sg_block_physical_addr);
                   7023:     scsiqp->sg_real_addr = sg_block_physical_addr;
                   7024: 
                   7025:     sg_block_index = 0;
                   7026:     do
                   7027:     {
                   7028:         sg_block->first_entry_no = sg_block_index;
                   7029:         for (i = 0; i < NO_OF_SG_PER_BLOCK; i++)
                   7030:         {
                   7031:             sg_block->sg_list[i].sg_addr =
                   7032: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
                   7033:                 (ulong) slp->address;
                   7034: #else /* version >= v2.0.0 */
                   7035:                 virt_to_bus(slp->address);
                   7036: #endif /* version >= v2.0.0 */
                   7037:             sg_block->sg_list[i].sg_count = slp->length;
                   7038:             ASC_STATS_ADD(scp->host, sg_xfer, ASC_CEILING(slp->length, 512));
                   7039: 
                   7040:             if (--sg_elem_cnt == 0)
                   7041:             {   /* last entry, get out */
                   7042:                 scsiqp->sg_entry_cnt = sg_block_index + i + 1;
                   7043:                 sg_block->last_entry_no = sg_block_index + i;
                   7044:                 sg_block->sg_ptr = 0L;    /* next link = NULL */
                   7045:                 return ADV_SUCCESS;
                   7046:             }
                   7047:             slp++;
                   7048:         } 
                   7049:         sg_block_next_addr += sizeof(ADV_SG_BLOCK);
                   7050:         sg_block_physical_addr += sizeof(ADV_SG_BLOCK);
                   7051:         ADV_ASSERT(ADV_DWALIGN(sg_block_physical_addr) ==
                   7052:                        sg_block_physical_addr);
                   7053: 
                   7054:         sg_block_index += NO_OF_SG_PER_BLOCK;
                   7055:         sg_block->sg_ptr = (ADV_SG_BLOCK *) sg_block_physical_addr;
                   7056:         sg_block->last_entry_no = sg_block_index - 1;
                   7057:         sg_block = (ADV_SG_BLOCK *) sg_block_next_addr; /* virtual addr */
                   7058:     }
                   7059:     while (1);
                   7060:     /* NOTREACHED */
                   7061: }
                   7062: 
                   7063: /*
                   7064:  * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
                   7065:  *
                   7066:  * Interrupt callback function for the Narrow SCSI Asc Library.
                   7067:  */
                   7068: STATIC void
                   7069: asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
                   7070: {
                   7071:     asc_board_t         *boardp;
                   7072:     Scsi_Cmnd           *scp;
                   7073:     struct Scsi_Host    *shp;
                   7074:     int                 underrun = ASC_FALSE;
                   7075:     int                 i;
                   7076: 
                   7077:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
                   7078:     ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp %x, qdonep %x\n",
                   7079:         (unsigned) asc_dvc_varp, (unsigned) qdonep);
                   7080:     ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
                   7081: 
                   7082:     /*
                   7083:      * Get the Scsi_Cmnd structure and Scsi_Host structure for the
                   7084:      * command that has been completed.
                   7085:      */
                   7086:     scp = (Scsi_Cmnd *) qdonep->d2.srb_ptr;
                   7087:     ASC_DBG1(1, "asc_isr_callback: scp %x\n", (unsigned) scp);
                   7088: 
                   7089:     if (scp == NULL) {
                   7090:         ASC_PRINT("asc_isr_callback: scp is NULL\n");
                   7091:         return;
                   7092:     }
                   7093:     ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
                   7094: 
                   7095:     /*
                   7096:      * If the request's host pointer is not valid, display a
                   7097:      * message and return.
                   7098:      */
                   7099:     shp = scp->host;
                   7100:     for (i = 0; i < asc_board_count; i++) {
                   7101:         if (asc_host[i] == shp) {
                   7102:             break;
                   7103:         }
                   7104:     }
                   7105:     if (i == asc_board_count) {
                   7106:         ASC_PRINT2("asc_isr_callback: scp %x has bad host pointer, host %x\n",
                   7107:             (unsigned) scp, (unsigned) shp);
                   7108:         return;
                   7109:     }
                   7110: 
                   7111:     ASC_STATS(shp, callback);
                   7112:     ASC_DBG1(1, "asc_isr_callback: shp %x\n", (unsigned) shp);
                   7113: 
                   7114:     /*
                   7115:      * If the request isn't found on the active queue, it may
                   7116:      * have been removed to handle a reset or abort request.
                   7117:      * Display a message and return.
                   7118:      */
                   7119:     boardp = ASC_BOARDP(shp);
                   7120:     ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
                   7121:     if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
                   7122:         ASC_PRINT2("asc_isr_callback: board %d: scp %x not on active queue\n",
                   7123:             boardp->id, (unsigned) scp);
                   7124:         return;
                   7125:     }
                   7126: 
                   7127:     /*
                   7128:      * Check for an underrun condition.
                   7129:      */
                   7130:     if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 && 
                   7131:         qdonep->remain_bytes <= scp->request_bufflen != 0) {
                   7132:         ASC_DBG1(1, "asc_isr_callback: underrun condition %u bytes\n",
                   7133:         (unsigned) qdonep->remain_bytes);
                   7134:         underrun = ASC_TRUE;
                   7135:     }
                   7136: 
                   7137:     /*
                   7138:      * 'qdonep' contains the command's ending status.
                   7139:      */
                   7140:     switch (qdonep->d3.done_stat) {
                   7141:     case QD_NO_ERROR:
                   7142:         ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
                   7143:         switch (qdonep->d3.host_stat) {
                   7144:         case QHSTA_NO_ERROR:
                   7145:             scp->result = 0;
                   7146:             break;
                   7147:         default:
                   7148:             /* QHSTA error occurred */
                   7149:             scp->result = HOST_BYTE(DID_ERROR);
                   7150:             break;
                   7151:         }
                   7152: 
                   7153:         /*
                   7154:          * If an INQUIRY command completed successfully, then call
                   7155:          * the AscInquiryHandling() function to set-up the device.
                   7156:          */
                   7157:         if (scp->cmnd[0] == SCSICMD_Inquiry && scp->lun == 0 &&
                   7158:             (scp->request_bufflen - qdonep->remain_bytes) >= 8)
                   7159:         {
                   7160:             AscInquiryHandling(asc_dvc_varp, scp->target & 0x7,
                   7161:                 (ASC_SCSI_INQUIRY *) scp->request_buffer);
                   7162:         }
                   7163: 
                   7164:         /*
                   7165:          * If there was an underrun without any other error,
                   7166:          * set DID_ERROR to indicate the underrun error.
                   7167:          *
                   7168:          * Note: There is no way yet to indicate the number
                   7169:          * of underrun bytes.
                   7170:          */
                   7171:         if (scp->result == 0 && underrun == ASC_TRUE) {
                   7172:             scp->result = HOST_BYTE(DID_UNDERRUN);
                   7173:         }
                   7174:         break;
                   7175: 
                   7176:     case QD_WITH_ERROR:
                   7177:         ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
                   7178:         switch (qdonep->d3.host_stat) {
                   7179:         case QHSTA_NO_ERROR:
                   7180:             if (qdonep->d3.scsi_stat == SS_CHK_CONDITION) {
                   7181:                 ASC_DBG(2, "asc_isr_callback: SS_CHK_CONDITION\n");
                   7182:                 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
                   7183:                     sizeof(scp->sense_buffer));
                   7184:                 /*
                   7185:                  * Note: The 'status_byte()' macro used by target drivers
                   7186:                  * defined in scsi.h shifts the status byte returned by
                   7187:                  * host drivers right by 1 bit. This is why target drivers
                   7188:                  * also use right shifted status byte definitions. For
                   7189:                  * instance target drivers use CHECK_CONDITION, defined to
                   7190:                  * 0x1, instead of the SCSI defined check condition value
                   7191:                  * of 0x2. Host drivers are supposed to return the status
                   7192:                  * byte as it is defined by SCSI.
                   7193:                  */
                   7194:                 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
                   7195:                     STATUS_BYTE(qdonep->d3.scsi_stat); 
                   7196:             } else {
                   7197:                 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat); 
                   7198:             }
                   7199:             break;
                   7200: 
                   7201:         default:
                   7202:             /* QHSTA error occurred */
                   7203:             ASC_DBG1(1, "asc_isr_callback: host_stat %x\n",
                   7204:                 qdonep->d3.host_stat);
                   7205:             scp->result = HOST_BYTE(DID_BAD_TARGET);
                   7206:             break;
                   7207:         }
                   7208:         break;
                   7209: 
                   7210:     case QD_ABORTED_BY_HOST:
                   7211:         ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
                   7212:         scp->result = HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.scsi_msg) |
                   7213:                 STATUS_BYTE(qdonep->d3.scsi_stat);
                   7214:         break;
                   7215: 
                   7216:     default:
                   7217:         ASC_DBG1(1, "asc_isr_callback: done_stat %x\n", qdonep->d3.done_stat);
                   7218:         scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.scsi_msg) |
                   7219:                 STATUS_BYTE(qdonep->d3.scsi_stat);
                   7220:         break;
                   7221:     }
                   7222: 
                   7223:     /*
                   7224:      * If the 'init_tidmask' bit isn't already set for the target and the
                   7225:      * current request finished normally, then set the bit for the target
                   7226:      * to indicate that a device is present.
                   7227:      */
                   7228:     if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->target)) == 0 &&
                   7229:         qdonep->d3.done_stat == QD_NO_ERROR &&
                   7230:         qdonep->d3.host_stat == QHSTA_NO_ERROR) {
                   7231:         boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target);
                   7232:     }
                   7233: 
                   7234:     /* 
                   7235:      * Because interrupts may be enabled by the 'Scsi_Cmnd' done
                   7236:      * function, add the command to the end of the board's done queue.
                   7237:      * The done function for the command will be called from
                   7238:      * advansys_interrupt().
                   7239:      */
                   7240:     asc_enqueue(&boardp->done, scp, ASC_BACK);
                   7241: 
                   7242:     return;
                   7243: }
                   7244: 
                   7245: /*
                   7246:  * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
                   7247:  *
                   7248:  * Callback function for the Wide SCSI Adv Library.
                   7249:  */
                   7250: STATIC void
                   7251: adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
                   7252: {
                   7253:     asc_board_t         *boardp;
                   7254:     adv_req_t           *reqp;
                   7255:     Scsi_Cmnd           *scp;
                   7256:     struct Scsi_Host    *shp;
                   7257:     int                 underrun = ASC_FALSE;
                   7258:     int                 i;
                   7259: 
                   7260:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
                   7261:     ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp %x, scsiqp %x\n",
                   7262:         (unsigned) adv_dvc_varp, (unsigned) scsiqp);
                   7263:     ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
                   7264: 
                   7265:     /*
                   7266:      * Get the adv_req_t structure for the command that has been
                   7267:      * completed. The adv_req_t structure actually contains the
                   7268:      * completed ADV_SCSI_REQ_Q structure.
                   7269:      */
                   7270:     reqp = (adv_req_t *) scsiqp->srb_ptr;
                   7271:     ASC_DBG1(1, "adv_isr_callback: reqp %x\n", (unsigned) reqp);
                   7272:     if (reqp == NULL) {
                   7273:         ASC_PRINT("adv_isr_callback: reqp is NULL\n");
                   7274:         return;
                   7275:     }
                   7276: 
                   7277:     /*
                   7278:      * Get the Scsi_Cmnd structure and Scsi_Host structure for the
                   7279:      * command that has been completed.
                   7280:      *
                   7281:      * Note: The adv_req_t request structure and adv_sgblk_t structure,
                   7282:      * if any, * dropped, because a board structure pointer can not be
                   7283:      * determined.
                   7284:      */
                   7285:     scp = reqp->cmndp;
                   7286:     ASC_DBG1(1, "adv_isr_callback: scp %x\n", (unsigned) scp);
                   7287:     if (scp == NULL) {
                   7288:         ASC_PRINT("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
                   7289:         return;
                   7290:     }
                   7291:     ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
                   7292: 
                   7293:     /*
                   7294:      * If the request's host pointer is not valid, display a message
                   7295:      * and return.
                   7296:      */
                   7297:     shp = scp->host;
                   7298:     for (i = 0; i < asc_board_count; i++) {
                   7299:         if (asc_host[i] == shp) {
                   7300:             break;
                   7301:         }
                   7302:     }
                   7303:     /*
                   7304:      * Note: If the host structure is not found, the adv_req_t request
                   7305:      * structure and adv_sgblk_t structure, if any, is dropped.
                   7306:      */
                   7307:     if (i == asc_board_count) {
                   7308:         ASC_PRINT2("adv_isr_callback: scp %x has bad host pointer, host %x\n",
                   7309:             (unsigned) scp, (unsigned) shp);
                   7310:         return;
                   7311:     }
                   7312: 
                   7313:     ASC_STATS(shp, callback);
                   7314:     ASC_DBG1(1, "adv_isr_callback: shp %x\n", (unsigned) shp);
                   7315: 
                   7316:     /*
                   7317:      * If the request isn't found on the active queue, it may have been
                   7318:      * removed to handle a reset or abort request. Display a message and
                   7319:      * return.
                   7320:      *
                   7321:      * Note: Because the structure may still be in use don't attempt
                   7322:      * to free the adv_req_t and adv_sgblk_t, if any, structures.
                   7323:      */
                   7324:     boardp = ASC_BOARDP(shp);
                   7325:     ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
                   7326:     if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
                   7327:         ASC_PRINT2("adv_isr_callback: board %d: scp %x not on active queue\n",
                   7328:             boardp->id, (unsigned) scp);
                   7329:         return;
                   7330:     }
                   7331: 
                   7332:     /*
                   7333:      * Check for an underrun condition.
                   7334:      */
                   7335:     if (scp->request_bufflen != 0 && scsiqp->data_cnt != 0) {
                   7336:         ASC_DBG1(1, "adv_isr_callback: underrun condition %lu bytes\n",
                   7337:         scsiqp->data_cnt);
                   7338:         underrun = ASC_TRUE;
                   7339:     }
                   7340: 
                   7341:     /*
                   7342:      * 'done_status' contains the command's ending status.
                   7343:      */
                   7344:     switch (scsiqp->done_status) {
                   7345:     case QD_NO_ERROR:
                   7346:         ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
                   7347:         switch (scsiqp->host_status) {
                   7348:         case QHSTA_NO_ERROR:
                   7349:             scp->result = 0;
                   7350:             break;
                   7351:         default:
                   7352:             /* QHSTA error occurred. */
                   7353:             ASC_DBG1(2, "adv_isr_callback: host_status %x\n",
                   7354:                 scsiqp->host_status);
                   7355:             scp->result = HOST_BYTE(DID_ERROR);
                   7356:             break;
                   7357:         }
                   7358:         /*
                   7359:          * If there was an underrun without any other error,
                   7360:          * set DID_ERROR to indicate the underrun error.
                   7361:          *
                   7362:          * Note: There is no way yet to indicate the number
                   7363:          * of underrun bytes.
                   7364:          */
                   7365:         if (scp->result == 0 && underrun == ASC_TRUE) {
                   7366:                 scp->result = HOST_BYTE(DID_UNDERRUN);
                   7367:         }
                   7368:         break;
                   7369: 
                   7370:     case QD_WITH_ERROR:
                   7371:         ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
                   7372:         switch (scsiqp->host_status) {
                   7373:         case QHSTA_NO_ERROR:
                   7374:             if (scsiqp->scsi_status == SS_CHK_CONDITION) {
                   7375:                 ASC_DBG(2, "adv_isr_callback: SS_CHK_CONDITION\n");
                   7376:                 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
                   7377:                     sizeof(scp->sense_buffer));
                   7378:                 /*
                   7379:                  * Note: The 'status_byte()' macro used by target drivers
                   7380:                  * defined in scsi.h shifts the status byte returned by
                   7381:                  * host drivers right by 1 bit. This is why target drivers
                   7382:                  * also use right shifted status byte definitions. For
                   7383:                  * instance target drivers use CHECK_CONDITION, defined to
                   7384:                  * 0x1, instead of the SCSI defined check condition value
                   7385:                  * of 0x2. Host drivers are supposed to return the status
                   7386:                  * byte as it is defined by SCSI.
                   7387:                  */
                   7388:                 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
                   7389:                     STATUS_BYTE(scsiqp->scsi_status);
                   7390:             } else {
                   7391:                 scp->result = STATUS_BYTE(scsiqp->scsi_status);
                   7392:             }
                   7393:             break;
                   7394: 
                   7395:         default:
                   7396:             /* Some other QHSTA error occurred. */
                   7397:             ASC_DBG1(1, "adv_isr_callback: host_status %x\n",
                   7398:                 scsiqp->host_status);
                   7399:             scp->result = HOST_BYTE(DID_BAD_TARGET);
                   7400:             break;
                   7401:         }
                   7402:         break;
                   7403: 
                   7404:     case QD_ABORTED_BY_HOST:
                   7405:         ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
                   7406:         scp->result = HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
                   7407:         break;
                   7408: 
                   7409:     default:
                   7410:         ASC_DBG1(1, "adv_isr_callback: done_status %x\n", scsiqp->done_status);
                   7411:         scp->result = HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
                   7412:         break;
                   7413:     }
                   7414: 
                   7415:     /*
                   7416:      * If the 'init_tidmask' bit isn't already set for the target and the
                   7417:      * current request finished normally, then set the bit for the target
                   7418:      * to indicate that a device is present.
                   7419:      */
                   7420:     if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->target)) == 0 &&
                   7421:         scsiqp->done_status == QD_NO_ERROR &&
                   7422:         scsiqp->host_status == QHSTA_NO_ERROR) {
                   7423:         boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target);
                   7424:     }
                   7425: 
                   7426:     /* 
                   7427:      * Because interrupts may be enabled by the 'Scsi_Cmnd' done
                   7428:      * function, add the command to the end of the board's done queue.
                   7429:      * The done function for the command will be called from
                   7430:      * advansys_interrupt().
                   7431:      */
                   7432:     asc_enqueue(&boardp->done, scp, ASC_BACK);
                   7433: 
                   7434:     /*
                   7435:      * Free the adv_sgblk_t structure, if any, by adding it back
                   7436:      * to the board free list.
                   7437:      */
                   7438:     if (reqp->sgblkp != NULL) {
                   7439:         reqp->sgblkp->next_sgblkp = boardp->adv_sgblkp;
                   7440:         boardp->adv_sgblkp = reqp->sgblkp;
                   7441:     }
                   7442: 
                   7443:     /*
                   7444:      * Free the adv_req_t structure used with the command by adding
                   7445:      * it back to the board free list.
                   7446:      */
                   7447:     reqp->next_reqp = boardp->adv_reqp;
                   7448:     boardp->adv_reqp = reqp;
                   7449: 
                   7450:     ASC_DBG(1, "adv_isr_callback: done\n");
                   7451: 
                   7452:     return;
                   7453: }
                   7454: 
                   7455: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
                   7456: #ifdef ASC_CONFIG_PCI
                   7457: /*
                   7458:  * Search for an AdvanSys PCI device in the PCI configuration space.
                   7459:  */
                   7460: ASC_INITFUNC(
                   7461: STATIC int
                   7462: asc_srch_pci_dev(PCI_DEVICE *pciDevice)
                   7463: )
                   7464: {
                   7465:     int                        ret = PCI_DEVICE_NOT_FOUND;
                   7466: 
                   7467:     ASC_DBG(2, "asc_srch_pci_dev: begin\n");
                   7468: 
                   7469:     if (pci_scan_method == -1) {
                   7470:         pci_scan_method = asc_scan_method();
                   7471:     }
                   7472:     pciDevice->type = pci_scan_method;
                   7473:     ASC_DBG1(2, "asc_srch_pci_dev: type %d\n", pciDevice->type);
                   7474: 
                   7475:     ret = asc_pci_find_dev(pciDevice);
                   7476:     ASC_DBG1(2, "asc_srch_pci_dev: asc_pci_find_dev() return %d\n", ret);
                   7477:     if (ret == PCI_DEVICE_FOUND) {
                   7478:         pciDevice->slotNumber = pciDevice->slotFound + 1;
                   7479:         pciDevice->startSlot = pciDevice->slotFound + 1;
                   7480:     } else {
                   7481:         if (pciDevice->bridge > pciDevice->busNumber) {
                   7482:             ASC_DBG2(2, "asc_srch_pci_dev: bridge %x, busNumber %x\n",
                   7483:                 pciDevice->bridge, pciDevice->busNumber);
                   7484:             pciDevice->busNumber++;
                   7485:             pciDevice->slotNumber = 0;
                   7486:             pciDevice->startSlot = 0;
                   7487:             pciDevice->endSlot = 0x0f;
                   7488:             ret = asc_srch_pci_dev(pciDevice);
                   7489:             ASC_DBG1(2, "asc_srch_pci_dev: recursive call return %d\n", ret);
                   7490:         }
                   7491:     }
                   7492: 
                   7493:     ASC_DBG1(2, "asc_srch_pci_dev: return %d\n", ret);
                   7494:     return ret;
                   7495: }
                   7496: 
                   7497: /*
                   7498:  * Determine the access method to be used for 'pciDevice'.
                   7499:  */
                   7500: ASC_INITFUNC(
                   7501: STATIC uchar
                   7502: asc_scan_method(void)
                   7503: )
                   7504: {
                   7505:     ushort      data;
                   7506:     PCI_DATA    pciData;
                   7507:     uchar       type;
                   7508:     uchar       slot;
                   7509: 
                   7510:     ASC_DBG(2, "asc_scan_method: begin\n");
                   7511:     memset(&pciData, 0, sizeof(pciData));
                   7512:     for (type = 1; type < 3; type++) {
                   7513:         pciData.type = type;
                   7514:         for (slot = 0; slot < PCI_MAX_SLOT; slot++) {
                   7515:             pciData.slot = slot;
                   7516:             data = asc_get_cfg_word(&pciData);
                   7517:             if ((data != 0xFFFF) && (data != 0x0000)) {
                   7518:                 ASC_DBG2(4, "asc_scan_method: data %x, type %d\n", data, type);
                   7519:                 return (type);
                   7520:             }
                   7521:         }
                   7522:     }
                   7523:     ASC_DBG1(4, "asc_scan_method: type %d\n", type);
                   7524:     return (type);
                   7525: }
                   7526: 
                   7527: /*
                   7528:  * Check for an AdvanSys PCI device in 'pciDevice'.
                   7529:  *
                   7530:  * Return PCI_DEVICE_FOUND if found, otherwise return PCI_DEVICE_NOT_FOUND.
                   7531:  */
                   7532: ASC_INITFUNC(
                   7533: STATIC int
                   7534: asc_pci_find_dev(PCI_DEVICE *pciDevice)
                   7535: )
                   7536: {
                   7537:     PCI_DATA    pciData;
                   7538:     ushort      vendorid, deviceid;
                   7539:     uchar       classcode, subclass;
                   7540:     uchar       lslot;
                   7541: 
                   7542:     ASC_DBG(3, "asc_pci_find_dev: begin\n");
                   7543:     pciData.type = pciDevice->type;
                   7544:     pciData.bus = pciDevice->busNumber;
                   7545:     pciData.func = pciDevice->devFunc;
                   7546:     lslot = pciDevice->startSlot;
                   7547:     for (; lslot < pciDevice->endSlot; lslot++) {
                   7548:         pciData.slot = lslot;
                   7549:         pciData.offset = VENDORID_OFFSET;
                   7550:         vendorid = asc_get_cfg_word(&pciData);
                   7551:         ASC_DBG1(3, "asc_pci_find_dev: vendorid %x\n", vendorid);
                   7552:         if (vendorid != 0xffff) {
                   7553:             pciData.offset = DEVICEID_OFFSET;
                   7554:             deviceid = asc_get_cfg_word(&pciData);
                   7555:             ASC_DBG1(3, "asc_pci_find_dev: deviceid %x\n", deviceid);
                   7556:             if ((vendorid == ASC_PCI_VENDORID) &&
                   7557:                 ((deviceid == ASC_PCI_DEVICE_ID_1100) ||
                   7558:                  (deviceid == ASC_PCI_DEVICE_ID_1200) ||
                   7559:                  (deviceid == ASC_PCI_DEVICE_ID_1300) ||
                   7560:                  (deviceid == ASC_PCI_DEVICE_ID_2300))) {
                   7561:                 pciDevice->slotFound = lslot;
                   7562:                 ASC_DBG(3, "asc_pci_find_dev: PCI_DEVICE_FOUND\n");
                   7563:                 return PCI_DEVICE_FOUND;
                   7564:             } else {
                   7565:                 pciData.offset = SUBCLASS_OFFSET;
                   7566:                 subclass = asc_get_cfg_byte(&pciData);
                   7567:                 pciData.offset = CLASSCODE_OFFSET;
                   7568:                 classcode = asc_get_cfg_byte(&pciData);
                   7569:                 if ((classcode & PCI_BASE_CLASS_BRIDGE_DEVICE) &&
                   7570:                     (subclass & PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER)) {
                   7571:                     pciDevice->bridge++;
                   7572:                 }
                   7573:                 ASC_DBG2(3, "asc_pci_find_dev: subclass %x, classcode %x\n",
                   7574:                     subclass, classcode);
                   7575:             }
                   7576:         }
                   7577:     }
                   7578:     return PCI_DEVICE_NOT_FOUND;
                   7579: }
                   7580: 
                   7581: /*
                   7582:  * Read PCI configuration data into 'pciConfig'.
                   7583:  */
                   7584: ASC_INITFUNC(
                   7585: STATIC void
                   7586: asc_get_pci_cfg(PCI_DEVICE *pciDevice, PCI_CONFIG_SPACE *pciConfig)
                   7587: )
                   7588: {
                   7589:     PCI_DATA    pciData;
                   7590:     uchar       counter;
                   7591:     uchar       *localConfig;
                   7592: 
                   7593:     ASC_DBG1(4, "asc_get_pci_cfg: slotFound %d\n ",
                   7594:         pciDevice->slotFound);
                   7595: 
                   7596:     pciData.type = pciDevice->type;
                   7597:     pciData.bus = pciDevice->busNumber;
                   7598:     pciData.slot = pciDevice->slotFound;
                   7599:     pciData.func = pciDevice->devFunc;
                   7600:     localConfig = (uchar *) pciConfig;
                   7601: 
                   7602:     for (counter = 0; counter < sizeof(PCI_CONFIG_SPACE); counter++) {
                   7603:         pciData.offset = counter;
                   7604:         *localConfig = asc_get_cfg_byte(&pciData);
                   7605:         ASC_DBG1(4, "asc_get_pci_cfg: byte %x\n", *localConfig);
                   7606:         localConfig++;
                   7607:     }
                   7608:     ASC_DBG1(4, "asc_get_pci_cfg: counter %d\n", counter);
                   7609: }
                   7610: 
                   7611: /*
                   7612:  * Read a word (16 bits) from the PCI configuration space.
                   7613:  *
                   7614:  * The configuration mechanism is checked for the correct access method.
                   7615:  */
                   7616: ASC_INITFUNC(
                   7617: STATIC ushort
                   7618: asc_get_cfg_word(PCI_DATA *pciData)
                   7619: )
                   7620: {
                   7621:     ushort   tmp;
                   7622:     ulong    address;
                   7623:     ulong    lbus = pciData->bus;
                   7624:     ulong    lslot = pciData->slot;
                   7625:     ulong    lfunc = pciData->func;
                   7626:     uchar    t2CFA, t2CF8;
                   7627:     ulong    t1CF8, t1CFC;
                   7628: 
                   7629:     ASC_DBG4(4, "asc_get_cfg_word: type %d, bus %lu, slot %lu, func %lu\n",
                   7630:         pciData->type, lbus, lslot, lfunc);
                   7631: 
                   7632:     /*
                   7633:      * Check type of configuration mechanism.
                   7634:      */
                   7635:     if (pciData->type == 2) {
                   7636:         /*
                   7637:          * Save registers to be restored later.
                   7638:          */
                   7639:         t2CFA = inp(0xCFA);    /* save PCI bus register */
                   7640:         t2CF8 = inp(0xCF8);    /* save config space enable register */
                   7641: 
                   7642:         /*
                   7643:          * Write the bus and enable registers.
                   7644:          */
                   7645:         /* set for type 1 cycle, if needed */
                   7646:         outp(0xCFA, pciData->bus);
                   7647:         /* set the function number */
                   7648:         outp(0xCF8, 0x10 | (pciData->func << 1)) ;
                   7649: 
                   7650:         /*
                   7651:          * Read the configuration space type 2 locations.
                   7652:          */
                   7653:         tmp = (ushort) inpw(0xC000 | ((pciData->slot << 8) + pciData->offset));
                   7654: 
                   7655:         outp(0xCFA, t2CFA);    /* save PCI bus register */
                   7656:         outp(0xCF8, t2CF8);    /* save config space enable register */
                   7657:     } else {
                   7658:         /*
                   7659:          * Type 1 or 3 configuration mechanism.
                   7660:          *
                   7661:          * Save the CONFIG_ADDRESS and CONFIG_DATA register values.
                   7662:          */
                   7663:         t1CF8 = inpl(0xCF8);
                   7664:         t1CFC = inpl(0xCFC);
                   7665: 
                   7666:         /*
                   7667:          * enable <31>, bus = <23:16>, slot = <15:11>,
                   7668:          * func = <10:8>, reg = <7:2>
                   7669:          */
                   7670:         address = (ulong) ((lbus << 16) | (lslot << 11) |
                   7671:             (lfunc << 8) | (pciData->offset & 0xFC) | 0x80000000L);
                   7672: 
                   7673:         /*
                   7674:          * Write out the address to CONFIG_ADDRESS.
                   7675:          */
                   7676:         outpl(0xCF8, address);
                   7677: 
                   7678:         /*
                   7679:          * Read in word from CONFIG_DATA.
                   7680:          */
                   7681:         tmp = (ushort) ((inpl(0xCFC) >>
                   7682:                  ((pciData->offset & 2) * 8)) & 0xFFFF);
                   7683: 
                   7684:         /*
                   7685:          * Restore registers.
                   7686:          */
                   7687:         outpl(0xCF8, t1CF8);
                   7688:         outpl(0xCFC, t1CFC);
                   7689:     }
                   7690:     ASC_DBG1(4, "asc_get_cfg_word: config data: %x\n", tmp);
                   7691:     return tmp;
                   7692: }
                   7693: 
                   7694: /*
                   7695:  * Reads a byte from the PCI configuration space.
                   7696:  *
                   7697:  * The configuration mechanism is checked for the correct access method.
                   7698:  */
                   7699: ASC_INITFUNC(
                   7700: STATIC uchar
                   7701: asc_get_cfg_byte(PCI_DATA *pciData)
                   7702: )
                   7703: {
                   7704:     uchar tmp;
                   7705:     ulong address;
                   7706:     ulong lbus = pciData->bus, lslot = pciData->slot, lfunc = pciData->func;
                   7707:     uchar t2CFA, t2CF8;
                   7708:     ulong t1CF8, t1CFC;
                   7709: 
                   7710:     ASC_DBG1(4, "asc_get_cfg_byte: type: %d\n", pciData->type);
                   7711: 
                   7712:     /*
                   7713:      * Check type of configuration mechanism.
                   7714:      */
                   7715:     if (pciData->type == 2) {
                   7716:         /*
                   7717:          * Save registers to be restored later.
                   7718:          */
                   7719:         t2CFA = inp(0xCFA);    /* save PCI bus register */
                   7720:         t2CF8 = inp(0xCF8);    /* save config space enable register */
                   7721: 
                   7722:         /*
                   7723:          * Write the bus and enable registers.
                   7724:          */
                   7725:         /* set for type 1 cycle, if needed */
                   7726:         outp(0xCFA, pciData->bus);
                   7727:         /* set the function number */
                   7728:         outp(0xCF8, 0x10 | (pciData->func << 1));
                   7729: 
                   7730:         /*
                   7731:          * Read configuration space type 2 locations.
                   7732:          */
                   7733:         tmp = inp(0xC000 | ((pciData->slot << 8) + pciData->offset));
                   7734: 
                   7735:         /*
                   7736:          * Restore registers.
                   7737:          */
                   7738:         outp(0xCF8, t2CF8);    /* restore the enable register */
                   7739:         outp(0xCFA, t2CFA);    /* restore PCI bus register */
                   7740:     } else {
                   7741:         /*
                   7742:          * Type 1 or 3 configuration mechanism.
                   7743:          *
                   7744:          * Save CONFIG_ADDRESS and CONFIG_DATA register values.
                   7745:          */
                   7746:         t1CF8 = inpl(0xCF8);
                   7747:         t1CFC = inpl(0xCFC);
                   7748: 
                   7749:         /*
                   7750:          * enable <31>, bus = <23:16>, slot = <15:11>, func = <10:8>,
                   7751:          * reg = <7:2>
                   7752:          */
                   7753:         address = (ulong) ((lbus << 16) | (lslot << 11) |
                   7754:             (lfunc << 8) | (pciData->offset & 0xFC) | 0x80000000L);
                   7755: 
                   7756:         /*
                   7757:          * Write out address to CONFIG_ADDRESS.
                   7758:          */
                   7759:         outpl(0xCF8, address);
                   7760: 
                   7761:         /*
                   7762:          * Read in word from CONFIG_DATA.
                   7763:          */
                   7764:         tmp = (uchar) ((inpl(0xCFC) >> ((pciData->offset & 3) * 8)) & 0xFF);
                   7765: 
                   7766:         /*
                   7767:          * Restore registers.
                   7768:          */
                   7769:         outpl(0xCF8, t1CF8);
                   7770:         outpl(0xCFC, t1CFC);
                   7771:     }
                   7772:     ASC_DBG1(4, "asc_get_cfg_byte: config data: %x\n", tmp);
                   7773:     return tmp;
                   7774: }
                   7775: 
                   7776: /*
                   7777:  * Write a byte to the PCI configuration space.
                   7778:  */
                   7779: ASC_INITFUNC(
                   7780: STATIC void
                   7781: asc_put_cfg_byte(PCI_DATA *pciData, uchar byte_data)
                   7782: )
                   7783: {
                   7784:     ulong tmpl;
                   7785:     ulong address;
                   7786:     ulong lbus = pciData->bus, lslot = pciData->slot, lfunc = pciData->func;
                   7787:     uchar t2CFA, t2CF8;
                   7788:     ulong t1CF8, t1CFC;
                   7789: 
                   7790:     ASC_DBG2(4, "asc_put_cfg_byte: type: %d, byte_data %x\n",
                   7791:         pciData->type, byte_data);
                   7792: 
                   7793:     /*
                   7794:      * Check type of configuration mechanism.
                   7795:      */
                   7796:     if (pciData->type == 2) {
                   7797: 
                   7798:         /*
                   7799:          * Save registers to be restored later.
                   7800:          */
                   7801:         t2CFA = inp(0xCFA);    /* save PCI bus register */
                   7802:         t2CF8 = inp(0xCF8);    /* save config space enable register */
                   7803: 
                   7804:         /*
                   7805:          * Write bus and enable registers.
                   7806:          */
                   7807:         outp(0xCFA, pciData->bus);
                   7808: 
                   7809:         /*
                   7810:          * Set the function number.
                   7811:          */
                   7812:         outp(0xCF8, 0x10 | (pciData->func << 1));
                   7813: 
                   7814:         /*
                   7815:          * Write the configuration space type 2 locations.
                   7816:          */
                   7817:         outp(0xC000 | ((pciData->slot << 8) + pciData->offset), byte_data);
                   7818: 
                   7819:         /*
                   7820:          * Restore registers.
                   7821:          */
                   7822:         outp(0xCF8, t2CF8);    /* restore the enable register */
                   7823:         outp(0xCFA, t2CFA);    /* restore PCI bus register    */
                   7824:     } else {
                   7825: 
                   7826:         /*
                   7827:          * Type 1 or 3 configuration mechanism.
                   7828:          *
                   7829:          * Save the CONFIG_ADDRESS and CONFIG_DATA register values.
                   7830:          */
                   7831:         t1CF8 = inpl(0xCF8);
                   7832:         t1CFC = inpl(0xCFC);
                   7833: 
                   7834:         /*
                   7835:          * enable <31>, bus = <23:16>, slot = <15:11>, func = <10:8>,
                   7836:          * reg = <7:2>
                   7837:          */
                   7838:         address = (ulong) ((lbus << 16) | (lslot << 11) | (lfunc << 8) |
                   7839:                 (pciData->offset & 0xFC) | 0x80000000L);
                   7840:         /*
                   7841:          * Write out address to CONFIG_ADDRESS.
                   7842:          */
                   7843:         outpl(0xCF8, address);
                   7844: 
                   7845:         /*
                   7846:          * Write double word to CONFIG_DATA preserving the bytes
                   7847:          * in the double not written.
                   7848:          */
                   7849:         tmpl = inpl(0xCFC) & ~(0xFF << ((pciData->offset & 3) * 8));
                   7850:         outpl(0xCFC, tmpl | (byte_data << ((pciData->offset & 3) * 8)));
                   7851: 
                   7852:         /*
                   7853:          * Restore registers.
                   7854:          */
                   7855:         outpl(0xCF8, t1CF8);
                   7856:         outpl(0xCFC, t1CFC);
                   7857:     }
                   7858:     ASC_DBG(4, "asc_put_cfg_byte: end\n");
                   7859: }
                   7860: #endif /* ASC_CONFIG_PCI */
                   7861: #endif /* version < v2.1.93 */
                   7862: 
                   7863: /*
                   7864:  * Add a 'REQP' to the end of specified queue. Set 'tidmask'
                   7865:  * to indicate a command is queued for the device.
                   7866:  *
                   7867:  * 'flag' may be either ASC_FRONT or ASC_BACK.
                   7868:  *
                   7869:  * 'REQPNEXT(reqp)' returns reqp's next pointer.
                   7870:  */
                   7871: STATIC void
                   7872: asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
                   7873: {
                   7874:     int        tid;
                   7875: 
                   7876:     ASC_DBG3(3, "asc_enqueue: ascq %x, reqp %x, flag %d\n",
                   7877:         (unsigned) ascq, (unsigned) reqp, flag);
                   7878:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
                   7879:     ASC_ASSERT(reqp != NULL);
                   7880:     ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
                   7881:     tid = REQPTID(reqp);
                   7882:     ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
                   7883:     if (flag == ASC_FRONT) {
1.1.1.2   root     7884:         REQPNEXT(reqp) = (unsigned char *) ascq->q_first[tid];
1.1       root     7885:         ascq->q_first[tid] = reqp;
                   7886:         /* If the queue was empty, set the last pointer. */
                   7887:         if (ascq->q_last[tid] == NULL) {
                   7888:             ascq->q_last[tid] = reqp;
                   7889:         }
                   7890:     } else { /* ASC_BACK */
                   7891:         if (ascq->q_last[tid] != NULL) {
1.1.1.2   root     7892:             REQPNEXT(ascq->q_last[tid]) = (unsigned char *) reqp;
1.1       root     7893:         }
                   7894:         ascq->q_last[tid] = reqp;
                   7895:         REQPNEXT(reqp) = NULL;
                   7896:         /* If the queue was empty, set the first pointer. */
                   7897:         if (ascq->q_first[tid] == NULL) {
                   7898:             ascq->q_first[tid] = reqp;
                   7899:         }
                   7900:     }
                   7901:     /* The queue has at least one entry, set its bit. */
                   7902:     ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
                   7903: #ifdef ADVANSYS_STATS
                   7904:     /* Maintain request queue statistics. */
                   7905:     ascq->q_tot_cnt[tid]++;
                   7906:     ascq->q_cur_cnt[tid]++;
                   7907:     if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
                   7908:         ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
                   7909:         ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
                   7910:             tid, ascq->q_max_cnt[tid]);
                   7911:     }
                   7912:     REQPTIME(reqp) = REQTIMESTAMP();
                   7913: #endif /* ADVANSYS_STATS */
                   7914:     ASC_DBG1(3, "asc_enqueue: reqp %x\n", (unsigned) reqp);
                   7915:     return;
                   7916: }
                   7917: 
                   7918: /*
                   7919:  * Return first queued 'REQP' on the specified queue for
                   7920:  * the specified target device. Clear the 'tidmask' bit for
                   7921:  * the device if no more commands are left queued for it.
                   7922:  *
                   7923:  * 'REQPNEXT(reqp)' returns reqp's next pointer.
                   7924:  */
                   7925: STATIC REQP
                   7926: asc_dequeue(asc_queue_t *ascq, int tid)
                   7927: {
                   7928:     REQP    reqp;
                   7929: 
                   7930:     ASC_DBG2(3, "asc_dequeue: ascq %x, tid %d\n", (unsigned) ascq, tid);
                   7931:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
                   7932:     ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
                   7933:     if ((reqp = ascq->q_first[tid]) != NULL) {
                   7934:         ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
1.1.1.2   root     7935:         ascq->q_first[tid] = (REQP) REQPNEXT(reqp);
1.1       root     7936:         /* If the queue is empty, clear its bit and the last pointer. */
                   7937:         if (ascq->q_first[tid] == NULL) {
                   7938:             ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
                   7939:             ASC_ASSERT(ascq->q_last[tid] == reqp);
                   7940:             ascq->q_last[tid] = NULL;
                   7941:         }
                   7942: #ifdef ADVANSYS_STATS
                   7943:         /* Maintain request queue statistics. */
                   7944:         ascq->q_cur_cnt[tid]--;
                   7945:         ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
                   7946:         REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
                   7947: #endif /* ADVANSYS_STATS */
                   7948:     }
                   7949:     ASC_DBG1(3, "asc_dequeue: reqp %x\n", (unsigned) reqp);
                   7950:     return reqp;
                   7951: }
                   7952: 
                   7953: /*
                   7954:  * Return a pointer to a singly linked list of all the requests queued
                   7955:  * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
                   7956:  *
                   7957:  * If 'lastpp' is not NULL, '*lastpp' will be set to point to the 
                   7958:  * the last request returned in the singly linked list.
                   7959:  *
                   7960:  * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
                   7961:  * then all queued requests are concatenated into one list and
                   7962:  * returned.
                   7963:  *
                   7964:  * Note: If 'lastpp' is used to append a new list to the end of
                   7965:  * an old list, only change the old list last pointer if '*lastpp'
                   7966:  * (or the function return value) is not NULL, i.e. use a temporary
                   7967:  * variable for 'lastpp' and check its value after the function return
                   7968:  * before assigning it to the list last pointer.
                   7969:  *
                   7970:  * Unfortunately collecting queuing time statistics adds overhead to
                   7971:  * the function that isn't inherent to the function's algorithm.
                   7972:  */
                   7973: STATIC REQP
                   7974: asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
                   7975: {
                   7976:     REQP    firstp, lastp;
                   7977:     int     i;
                   7978: 
                   7979:     ASC_DBG2(3, "asc_dequeue_list: ascq %x, tid %d\n", (unsigned) ascq, tid);
                   7980:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
                   7981:     ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
                   7982: 
                   7983:     /*
                   7984:      * If 'tid' is not ASC_TID_ALL, return requests only for
                   7985:      * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
                   7986:      * requests for all tids.
                   7987:      */
                   7988:     if (tid != ASC_TID_ALL) {
                   7989:         /* Return all requests for the specified 'tid'. */
                   7990:         if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
                   7991:             /* List is empty; Set first and last return pointers to NULL. */
                   7992:             firstp = lastp = NULL;
                   7993:         } else {
                   7994:             firstp = ascq->q_first[tid];
                   7995:             lastp = ascq->q_last[tid];
                   7996:             ascq->q_first[tid] = ascq->q_last[tid] = NULL;
                   7997:             ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
                   7998: #ifdef ADVANSYS_STATS
                   7999:             {
                   8000:                 REQP reqp;
                   8001:                 ascq->q_cur_cnt[tid] = 0;
1.1.1.2   root     8002:                 for (reqp = firstp; reqp; reqp = (REQP) REQPNEXT(reqp)) {
1.1       root     8003:                     REQTIMESTAT("asc_dequeue_list", ascq, reqp, tid);
                   8004:                 }
                   8005:             }
                   8006: #endif /* ADVANSYS_STATS */
                   8007:         }
                   8008:     } else {
                   8009:         /* Return all requests for all tids. */
                   8010:         firstp = lastp = NULL;
                   8011:         for (i = 0; i <= ADV_MAX_TID; i++) {
                   8012:             if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
                   8013:                 if (firstp == NULL) {
                   8014:                     firstp = ascq->q_first[i];
                   8015:                     lastp = ascq->q_last[i];
                   8016:                 } else {
                   8017:                     ASC_ASSERT(lastp != NULL);
1.1.1.2   root     8018:                     REQPNEXT(lastp) = (unsigned char *) ascq->q_first[i];
1.1       root     8019:                     lastp = ascq->q_last[i];
                   8020:                 }
                   8021:                 ascq->q_first[i] = ascq->q_last[i] = NULL;
                   8022:                 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
                   8023: #ifdef ADVANSYS_STATS
                   8024:                 ascq->q_cur_cnt[i] = 0;
                   8025: #endif /* ADVANSYS_STATS */
                   8026:             }
                   8027:         }
                   8028: #ifdef ADVANSYS_STATS
                   8029:         {
                   8030:             REQP reqp;
1.1.1.2   root     8031:             for (reqp = firstp; reqp; reqp = (REQP) REQPNEXT(reqp)) {
1.1       root     8032:                 REQTIMESTAT("asc_dequeue_list", ascq, reqp, reqp->target);
                   8033:             }
                   8034:         }
                   8035: #endif /* ADVANSYS_STATS */
                   8036:     }
                   8037:     if (lastpp) {
                   8038:         *lastpp = lastp;
                   8039:     }
                   8040:     ASC_DBG1(3, "asc_dequeue_list: firstp %x\n", (unsigned) firstp);
                   8041:     return firstp;
                   8042: }
                   8043: 
                   8044: /*
                   8045:  * Remove the specified 'REQP' from the specified queue for
                   8046:  * the specified target device. Clear the 'tidmask' bit for the
                   8047:  * device if no more commands are left queued for it.
                   8048:  *
                   8049:  * 'REQPNEXT(reqp)' returns reqp's the next pointer.
                   8050:  *
                   8051:  * Return ASC_TRUE if the command was found and removed,
                   8052:  * otherwise return ASC_FALSE.
                   8053:  */
                   8054: STATIC int
                   8055: asc_rmqueue(asc_queue_t *ascq, REQP reqp)
                   8056: {
                   8057:     REQP        currp, prevp;
                   8058:     int         tid;
                   8059:     int         ret = ASC_FALSE;
                   8060: 
                   8061:     ASC_DBG2(3, "asc_rmqueue: ascq %x, reqp %x\n",
                   8062:         (unsigned) ascq, (unsigned) reqp);
                   8063:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
                   8064:     ASC_ASSERT(reqp != NULL);
                   8065: 
                   8066:     tid = REQPTID(reqp);
                   8067:     ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
                   8068: 
                   8069:     /*
                   8070:      * Handle the common case of 'reqp' being the first
                   8071:      * entry on the queue.
                   8072:      */
                   8073:     if (reqp == ascq->q_first[tid]) {
                   8074:         ret = ASC_TRUE;
1.1.1.2   root     8075:         ascq->q_first[tid] = (REQP) REQPNEXT(reqp);
1.1       root     8076:         /* If the queue is now empty, clear its bit and the last pointer. */
                   8077:         if (ascq->q_first[tid] == NULL) {
                   8078:             ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
                   8079:             ASC_ASSERT(ascq->q_last[tid] == reqp);
                   8080:             ascq->q_last[tid] = NULL;
                   8081:         }
                   8082:     } else if (ascq->q_first[tid] != NULL) {
                   8083:         ASC_ASSERT(ascq->q_last[tid] != NULL);
                   8084:         /*
                   8085:          * Because the case of 'reqp' being the first entry has been
                   8086:          * handled above and it is known the queue is not empty, if
                   8087:          * 'reqp' is found on the queue it is guaranteed the queue will
                   8088:          * not become empty and that 'q_first[tid]' will not be changed.
                   8089:          *
                   8090:          * Set 'prevp' to the first entry, 'currp' to the second entry,
                   8091:          * and search for 'reqp'.
                   8092:          */
1.1.1.2   root     8093:         for (prevp = ascq->q_first[tid], currp = (REQP) REQPNEXT(prevp);
                   8094:              currp; prevp = currp, currp = (REQP) REQPNEXT(currp)) {
1.1       root     8095:             if (currp == reqp) {
                   8096:                 ret = ASC_TRUE;
                   8097:                 REQPNEXT(prevp) = REQPNEXT(currp);
                   8098:                 REQPNEXT(reqp) = NULL;
                   8099:                 if (ascq->q_last[tid] == reqp) {
                   8100:                     ascq->q_last[tid] = prevp;
                   8101:                 }
                   8102:                 break;
                   8103:             }
                   8104:         }
                   8105:     }
                   8106: #ifdef ADVANSYS_STATS
                   8107:     /* Maintain request queue statistics. */
                   8108:     if (ret == ASC_TRUE) {
                   8109:         ascq->q_cur_cnt[tid]--;
                   8110:         REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
                   8111:     }
                   8112:     ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
                   8113: #endif /* ADVANSYS_STATS */
                   8114:     ASC_DBG2(3, "asc_rmqueue: reqp %x, ret %d\n", (unsigned) reqp, ret);
                   8115:     return ret;
                   8116: }
                   8117: 
                   8118: /*
                   8119:  * If the specified 'REQP' is queued on the specified queue for
                   8120:  * the specified target device, return ASC_TRUE.
                   8121:  */
                   8122: STATIC int
                   8123: asc_isqueued(asc_queue_t *ascq, REQP reqp)
                   8124: {
                   8125:     REQP        treqp;
                   8126:     int            tid;
                   8127:     int            ret = ASC_FALSE;
                   8128: 
                   8129:     ASC_DBG2(3, "asc_isqueued: ascq %x, reqp %x\n",
                   8130:         (unsigned) ascq, (unsigned) reqp);
                   8131:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
                   8132:     ASC_ASSERT(reqp != NULL);
                   8133: 
                   8134:     tid = REQPTID(reqp);
                   8135:     ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
                   8136: 
1.1.1.2   root     8137:     for (treqp = ascq->q_first[tid]; treqp; treqp = (REQP) REQPNEXT(treqp)) {
1.1       root     8138:         ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
                   8139:         if (treqp == reqp) {
                   8140:             ret = ASC_TRUE;
                   8141:             break;
                   8142:         }
                   8143:     }
                   8144:     ASC_DBG1(3, "asc_isqueued: ret %x\n", ret);
                   8145:     return ret;
                   8146: }
                   8147: 
                   8148: /*
                   8149:  * Execute as many queued requests as possible for the specified queue.
                   8150:  *
                   8151:  * Calls asc_execute_scsi_cmnd() to execute a REQP/Scsi_Cmnd.
                   8152:  */
                   8153: STATIC void
                   8154: asc_execute_queue(asc_queue_t *ascq)
                   8155: {
                   8156:     ADV_SCSI_BIT_ID_TYPE    scan_tidmask;
                   8157:     REQP                    reqp;
                   8158:     int                     i;
                   8159: 
                   8160:     ASC_DBG1(1, "asc_execute_queue: ascq %x\n", (unsigned) ascq);
                   8161:     ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
                   8162:     /*
                   8163:      * Execute queued commands for devices attached to
                   8164:      * the current board in round-robin fashion.
                   8165:      */
                   8166:     scan_tidmask = ascq->q_tidmask;
                   8167:     do {
                   8168:         for (i = 0; i <= ADV_MAX_TID; i++) {
                   8169:             if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
                   8170:                 if ((reqp = asc_dequeue(ascq, i)) == NULL) {
                   8171:                     scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
                   8172:                 } else if (asc_execute_scsi_cmnd((Scsi_Cmnd *) reqp)
                   8173:                             == ASC_BUSY) {
                   8174:                     scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
                   8175:                     /* Put the request back at front of the list. */
                   8176:                     asc_enqueue(ascq, reqp, ASC_FRONT);
                   8177:                 }
                   8178:             }
                   8179:         }
                   8180:     } while (scan_tidmask);
                   8181:     return;
                   8182: }
                   8183: 
                   8184: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
                   8185: /*
                   8186:  * asc_prt_board_devices()
                   8187:  *
                   8188:  * Print driver information for devices attached to the board.
                   8189:  *
                   8190:  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
                   8191:  * cf. asc_prt_line().
                   8192:  *
                   8193:  * Return the number of characters copied into 'cp'. No more than
                   8194:  * 'cplen' characters will be copied to 'cp'.
                   8195:  */
                   8196: STATIC int
                   8197: asc_prt_board_devices(struct Scsi_Host *shp, char *cp, int cplen)
                   8198: {
                   8199:     asc_board_t        *boardp;
                   8200:     int                leftlen;
                   8201:     int                totlen;
                   8202:     int                len;
                   8203:     int                chip_scsi_id;
                   8204:     int                i;
                   8205: 
                   8206:     boardp = ASC_BOARDP(shp);
                   8207:     leftlen = cplen;
                   8208:     totlen = len = 0;
                   8209: 
                   8210:     len = asc_prt_line(cp, leftlen,
                   8211: "\nDevice Information for AdvanSys SCSI Host %d:\n", shp->host_no);
                   8212:     ASC_PRT_NEXT();
                   8213: 
                   8214:     if (ASC_NARROW_BOARD(boardp)) {
                   8215:         chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
                   8216:     } else {
                   8217:         chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
                   8218:     }
                   8219: 
                   8220:     len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
                   8221:     ASC_PRT_NEXT();
                   8222:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   8223:         if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
                   8224:             len = asc_prt_line(cp, leftlen, " %X,", i);
                   8225:             ASC_PRT_NEXT();
                   8226:         }
                   8227:     }
                   8228:     len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
                   8229:     ASC_PRT_NEXT();
                   8230: 
                   8231:     return totlen;
                   8232: }
                   8233: 
                   8234: /*
                   8235:  * Display Wide Board BIOS Information.
                   8236:  */
                   8237: STATIC int
                   8238: asc_prt_adv_bios(struct Scsi_Host *shp, char *cp, int cplen)
                   8239: {
                   8240:     asc_board_t        *boardp;
                   8241:     int                leftlen;
                   8242:     int                totlen;
                   8243:     int                len;
                   8244:     int                upgrade = ASC_FALSE;
                   8245:     ushort             major, minor, letter;
                   8246: 
                   8247:     boardp = ASC_BOARDP(shp);
                   8248:     leftlen = cplen;
                   8249:     totlen = len = 0;
                   8250: 
                   8251:     len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
                   8252:     ASC_PRT_NEXT();
                   8253: 
                   8254:     /*
                   8255:      * If the BIOS saved a valid signature, then fill in
                   8256:      * the BIOS code segment base address.
                   8257:      */
                   8258:     if (boardp->bios_signature != 0x55AA) {
                   8259:         len = asc_prt_line(cp, leftlen, "Pre-3.1\n");
                   8260:         ASC_PRT_NEXT();
                   8261:         upgrade = ASC_TRUE;
                   8262:     } else {
                   8263:         major = (boardp->bios_version >> 12) & 0xF;
                   8264:         minor = (boardp->bios_version >> 8) & 0xF;
                   8265:         letter = (boardp->bios_version & 0xFF);
                   8266: 
                   8267:         len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
                   8268:             major, minor, letter >= 26 ? '?' : letter + 'A');
                   8269:         ASC_PRT_NEXT();
                   8270: 
                   8271:         /* Current available ROM BIOS release is 3.1C. */
                   8272:         if (major < 3 || (major <= 3 && minor < 1) ||
                   8273:             (major <= 3 && minor <= 1 && letter < ('C'- 'A'))) {
                   8274:             upgrade = ASC_TRUE;
                   8275:         }
                   8276:     }
                   8277:     if (upgrade == ASC_TRUE) {
                   8278:         len = asc_prt_line(cp, leftlen,
                   8279: "Newer version of ROM BIOS available: ftp://ftp.advansys.com/pub\n");
                   8280:             ASC_PRT_NEXT();
                   8281:     }
                   8282: 
                   8283:     return totlen;
                   8284: }
                   8285: 
                   8286: /*
                   8287:  * Add serial number to information bar if signature AAh
                   8288:  * is found in at bit 15-9 (7 bits) of word 1.
                   8289:  *
                   8290:  * Serial Number consists fo 12 alpha-numeric digits.
                   8291:  *
                   8292:  *       1 - Product type (A,B,C,D..)  Word0: 15-13 (3 bits)
                   8293:  *       2 - MFG Location (A,B,C,D..)  Word0: 12-10 (3 bits)
                   8294:  *     3-4 - Product ID (0-99)         Word0: 9-0 (10 bits)
                   8295:  *       5 - Product revision (A-J)    Word0:  "         "
                   8296:  *
                   8297:  *           Signature                 Word1: 15-9 (7 bits)
                   8298:  *       6 - Year (0-9)                Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
                   8299:  *     7-8 - Week of the year (1-52)   Word1: 5-0 (6 bits)
                   8300:  *
                   8301:  *    9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
                   8302:  *
                   8303:  * Note 1: Only production cards will have a serial number.
                   8304:  *
                   8305:  * Note 2: Signature is most significant 7 bits (0xFE).
                   8306:  *
                   8307:  * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
                   8308:  */
                   8309: STATIC int
                   8310: asc_get_eeprom_string(ushort *serialnum, uchar *cp)
                   8311: {
                   8312:     ushort      w, num;
                   8313: 
                   8314:     if ((serialnum[1] & 0xFE00) != ((ushort) 0xAA << 8)) {
                   8315:         return ASC_FALSE;
                   8316:     } else {
                   8317:         /*
                   8318:          * First word - 6 digits.
                   8319:          */
                   8320:         w = serialnum[0];
                   8321: 
                   8322:         /* Product type - 1st digit. */
                   8323:         if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
                   8324:             /* Product type is P=Prototype */
                   8325:             *cp += 0x8;
                   8326:         }
                   8327:         cp++;
                   8328: 
                   8329:         /* Manufacturing location - 2nd digit. */
                   8330:         *cp++ = 'A' + ((w & 0x1C00) >> 10);
                   8331: 
                   8332:         /* Product ID - 3rd, 4th digits. */
                   8333:         num = w & 0x3FF;
                   8334:         *cp++ = '0' + (num / 100);
                   8335:         num %= 100;
                   8336:         *cp++ = '0' + (num / 10);
                   8337: 
                   8338:         /* Product revision - 5th digit. */
                   8339:         *cp++ = 'A' + (num % 10);
                   8340: 
                   8341:         /*
                   8342:          * Second word
                   8343:          */
                   8344:         w = serialnum[1];
                   8345: 
                   8346:         /*
                   8347:          * Year - 6th digit.
                   8348:          *
                   8349:          * If bit 15 of third word is set, then the
                   8350:          * last digit of the year is greater than 7.
                   8351:          */
                   8352:         if (serialnum[2] & 0x8000) {
                   8353:             *cp++ = '8' + ((w & 0x1C0) >> 6);
                   8354:         } else {
                   8355:             *cp++ = '0' + ((w & 0x1C0) >> 6);
                   8356:         }
                   8357: 
                   8358:         /* Week of year - 7th, 8th digits. */
                   8359:         num = w & 0x003F;
                   8360:         *cp++ = '0' + num / 10;
                   8361:         num %= 10;
                   8362:         *cp++ = '0' + num;
                   8363: 
                   8364:         /*
                   8365:          * Third word
                   8366:          */
                   8367:         w = serialnum[2] & 0x7FFF;
                   8368: 
                   8369:         /* Serial number - 9th digit. */
                   8370:         *cp++ = 'A' + (w / 1000);
                   8371: 
                   8372:         /* 10th, 11th, 12th digits. */
                   8373:         num = w % 1000;
                   8374:         *cp++ = '0' + num / 100;
                   8375:         num %= 100;
                   8376:         *cp++ = '0' + num / 10;
                   8377:         num %= 10;
                   8378:         *cp++ = '0' + num;
                   8379: 
                   8380:         *cp = '\0';     /* Null Terminate the string. */
                   8381:         return ASC_TRUE;
                   8382:     }
                   8383: }
                   8384: 
                   8385: /*
                   8386:  * asc_prt_asc_board_eeprom()
                   8387:  *
                   8388:  * Print board EEPROM configuration.
                   8389:  *
                   8390:  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
                   8391:  * cf. asc_prt_line().
                   8392:  *
                   8393:  * Return the number of characters copied into 'cp'. No more than
                   8394:  * 'cplen' characters will be copied to 'cp'.
                   8395:  */
                   8396: STATIC int
                   8397: asc_prt_asc_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
                   8398: {
                   8399:     asc_board_t        *boardp;
                   8400:     ASC_DVC_VAR        *asc_dvc_varp;
                   8401:     int                leftlen;
                   8402:     int                totlen;
                   8403:     int                len;
                   8404:     ASCEEP_CONFIG      *ep;
                   8405:     int                i;
                   8406:     int                isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
                   8407:     uchar              serialstr[13];
                   8408: 
                   8409:     boardp = ASC_BOARDP(shp);
                   8410:     asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
                   8411:     ep = &boardp->eep_config.asc_eep;
                   8412: 
                   8413:     leftlen = cplen;
                   8414:     totlen = len = 0;
                   8415: 
                   8416:     len = asc_prt_line(cp, leftlen,
                   8417: "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
                   8418:     ASC_PRT_NEXT();
                   8419: 
                   8420:     if (asc_get_eeprom_string((ushort *) &ep->adapter_info[0], serialstr) ==
                   8421:         ASC_TRUE) {
                   8422:         len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
                   8423:         ASC_PRT_NEXT();
                   8424:     } else {
                   8425:         if (ep->adapter_info[5] == 0xBB) {
                   8426:             len = asc_prt_line(cp, leftlen,
                   8427:                 " Default Settings Used for EEPROM-less Adapter.\n");
                   8428:             ASC_PRT_NEXT();
                   8429:         } else {
                   8430:             len = asc_prt_line(cp, leftlen,
                   8431:                 " Serial Number Signature Not Present.\n");
                   8432:             ASC_PRT_NEXT();
                   8433:         }
                   8434:     }
                   8435: 
                   8436:     len = asc_prt_line(cp, leftlen,
                   8437: " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
                   8438:         ep->chip_scsi_id, ep->max_total_qng, ep->max_tag_qng);
                   8439:     ASC_PRT_NEXT();
                   8440: 
                   8441:     len = asc_prt_line(cp, leftlen,
                   8442: " cntl %x, no_scam %x\n",
                   8443:         ep->cntl, ep->no_scam);
                   8444:     ASC_PRT_NEXT();
                   8445: 
                   8446:     len = asc_prt_line(cp, leftlen,
                   8447: " Target ID:           ");
                   8448:     ASC_PRT_NEXT();
                   8449:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   8450:         len = asc_prt_line(cp, leftlen, " %d", i);
                   8451:         ASC_PRT_NEXT();
                   8452:     }
                   8453:     len = asc_prt_line(cp, leftlen, "\n");
                   8454:     ASC_PRT_NEXT();
                   8455: 
                   8456:     len = asc_prt_line(cp, leftlen,
                   8457: " Disconnects:         ");
                   8458:     ASC_PRT_NEXT();
                   8459:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   8460:         len = asc_prt_line(cp, leftlen, " %c",
                   8461:             (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   8462:         ASC_PRT_NEXT();
                   8463:     }
                   8464:     len = asc_prt_line(cp, leftlen, "\n");
                   8465:     ASC_PRT_NEXT();
                   8466: 
                   8467:     len = asc_prt_line(cp, leftlen,
                   8468: " Command Queuing:     ");
                   8469:     ASC_PRT_NEXT();
                   8470:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   8471:         len = asc_prt_line(cp, leftlen, " %c",
                   8472:             (ep->use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   8473:         ASC_PRT_NEXT();
                   8474:     }
                   8475:     len = asc_prt_line(cp, leftlen, "\n");
                   8476:     ASC_PRT_NEXT();
                   8477: 
                   8478:     len = asc_prt_line(cp, leftlen,
                   8479: " Start Motor:         ");
                   8480:     ASC_PRT_NEXT();
                   8481:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   8482:         len = asc_prt_line(cp, leftlen, " %c",
                   8483:             (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   8484:         ASC_PRT_NEXT();
                   8485:     }
                   8486:     len = asc_prt_line(cp, leftlen, "\n");
                   8487:     ASC_PRT_NEXT();
                   8488: 
                   8489:     len = asc_prt_line(cp, leftlen,
                   8490: " Synchronous Transfer:");
                   8491:     ASC_PRT_NEXT();
                   8492:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   8493:         len = asc_prt_line(cp, leftlen, " %c",
                   8494:             (ep->init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   8495:         ASC_PRT_NEXT();
                   8496:     }
                   8497:     len = asc_prt_line(cp, leftlen, "\n");
                   8498:     ASC_PRT_NEXT();
                   8499: 
                   8500:     if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
                   8501:         len = asc_prt_line(cp, leftlen,
                   8502: " Host ISA DMA speed:   %d MB/S\n",
                   8503:             isa_dma_speed[ep->isa_dma_speed]);
                   8504:         ASC_PRT_NEXT();
                   8505:     }
                   8506: 
                   8507:      return totlen;
                   8508: }
                   8509: 
                   8510: /*
                   8511:  * asc_prt_adv_board_eeprom()
                   8512:  *
                   8513:  * Print board EEPROM configuration.
                   8514:  *
                   8515:  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
                   8516:  * cf. asc_prt_line().
                   8517:  *
                   8518:  * Return the number of characters copied into 'cp'. No more than
                   8519:  * 'cplen' characters will be copied to 'cp'.
                   8520:  */
                   8521: STATIC int
                   8522: asc_prt_adv_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
                   8523: {
                   8524:     asc_board_t        *boardp;
                   8525:     ADV_DVC_VAR        *adv_dvc_varp;
                   8526:     int                leftlen;
                   8527:     int                totlen;
                   8528:     int                len;
                   8529:     int                i;
                   8530:     char               *termstr;
                   8531:     uchar              serialstr[13];
                   8532:     ADVEEP_CONFIG      *ep;
                   8533: 
                   8534:     boardp = ASC_BOARDP(shp);
                   8535:     adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
                   8536:     ep = &boardp->eep_config.adv_eep;
                   8537: 
                   8538:     leftlen = cplen;
                   8539:     totlen = len = 0;
                   8540: 
                   8541:     len = asc_prt_line(cp, leftlen,
                   8542: "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
                   8543:     ASC_PRT_NEXT();
                   8544: 
                   8545:     if (asc_get_eeprom_string(&ep->serial_number_word1, serialstr) ==
                   8546:         ASC_TRUE) {
                   8547:         len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
                   8548:         ASC_PRT_NEXT();
                   8549:     } else {
                   8550:         len = asc_prt_line(cp, leftlen,
                   8551:             " Serial Number Signature Not Present.\n");
                   8552:         ASC_PRT_NEXT();
                   8553:     }
                   8554: 
                   8555:     len = asc_prt_line(cp, leftlen,
                   8556: " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
                   8557:         ep->adapter_scsi_id, ep->max_host_qng, ep->max_dvc_qng);
                   8558:     ASC_PRT_NEXT();
                   8559: 
                   8560:     switch (ep->termination) {
                   8561:         case 1:
                   8562:             termstr = "Low Off/High Off";
                   8563:             break;
                   8564:         case 2:
                   8565:             termstr = "Low Off/High On";
                   8566:             break;
                   8567:         case 3:
                   8568:             termstr = "Low On/High On";
                   8569:             break;
                   8570:         default:
                   8571:         case 0:
                   8572:             termstr = "Automatic";
                   8573:             break;
                   8574:     }
                   8575: 
                   8576:     len = asc_prt_line(cp, leftlen,
                   8577: " termination: %u (%s), bios_ctrl: %x\n",
                   8578:         ep->termination, termstr, ep->bios_ctrl);
                   8579:     ASC_PRT_NEXT();
                   8580: 
                   8581:     len = asc_prt_line(cp, leftlen,
                   8582: " Target ID:           ");
                   8583:     ASC_PRT_NEXT();
                   8584:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   8585:         len = asc_prt_line(cp, leftlen, " %X", i);
                   8586:         ASC_PRT_NEXT();
                   8587:     }
                   8588:     len = asc_prt_line(cp, leftlen, "\n");
                   8589:     ASC_PRT_NEXT();
                   8590: 
                   8591:     len = asc_prt_line(cp, leftlen,
                   8592: " Disconnects:         ");
                   8593:     ASC_PRT_NEXT();
                   8594:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   8595:         len = asc_prt_line(cp, leftlen, " %c",
                   8596:             (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   8597:         ASC_PRT_NEXT();
                   8598:     }
                   8599:     len = asc_prt_line(cp, leftlen, "\n");
                   8600:     ASC_PRT_NEXT();
                   8601: 
                   8602:     len = asc_prt_line(cp, leftlen,
                   8603: " Command Queuing:     ");
                   8604:     ASC_PRT_NEXT();
                   8605:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   8606:         len = asc_prt_line(cp, leftlen, " %c",
                   8607:             (ep->tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   8608:         ASC_PRT_NEXT();
                   8609:     }
                   8610:     len = asc_prt_line(cp, leftlen, "\n");
                   8611:     ASC_PRT_NEXT();
                   8612: 
                   8613:     len = asc_prt_line(cp, leftlen,
                   8614: " Start Motor:         ");
                   8615:     ASC_PRT_NEXT();
                   8616:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   8617:         len = asc_prt_line(cp, leftlen, " %c",
                   8618:             (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   8619:         ASC_PRT_NEXT();
                   8620:     }
                   8621:     len = asc_prt_line(cp, leftlen, "\n");
                   8622:     ASC_PRT_NEXT();
                   8623: 
                   8624:     len = asc_prt_line(cp, leftlen,
                   8625: " Synchronous Transfer:");
                   8626:     ASC_PRT_NEXT();
                   8627:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   8628:         len = asc_prt_line(cp, leftlen, " %c",
                   8629:             (ep->sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   8630:         ASC_PRT_NEXT();
                   8631:     }
                   8632:     len = asc_prt_line(cp, leftlen, "\n");
                   8633:     ASC_PRT_NEXT();
                   8634: 
                   8635:     len = asc_prt_line(cp, leftlen,
                   8636: " Ultra Transfer:      ");
                   8637:     ASC_PRT_NEXT();
                   8638:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   8639:         len = asc_prt_line(cp, leftlen, " %c",
                   8640:             (ep->ultra_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   8641:         ASC_PRT_NEXT();
                   8642:     }
                   8643:     len = asc_prt_line(cp, leftlen, "\n");
                   8644:     ASC_PRT_NEXT();
                   8645: 
                   8646:     len = asc_prt_line(cp, leftlen,
                   8647: " Wide Transfer:       ");
                   8648:     ASC_PRT_NEXT();
                   8649:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   8650:         len = asc_prt_line(cp, leftlen, " %c",
                   8651:             (ep->wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   8652:         ASC_PRT_NEXT();
                   8653:     }
                   8654:     len = asc_prt_line(cp, leftlen, "\n");
                   8655:     ASC_PRT_NEXT();
                   8656: 
                   8657:     return totlen;
                   8658: }
                   8659: 
                   8660: /*
                   8661:  * asc_prt_driver_conf()
                   8662:  *
                   8663:  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
                   8664:  * cf. asc_prt_line().
                   8665:  *
                   8666:  * Return the number of characters copied into 'cp'. No more than
                   8667:  * 'cplen' characters will be copied to 'cp'.
                   8668:  */
                   8669: STATIC int
                   8670: asc_prt_driver_conf(struct Scsi_Host *shp, char *cp, int cplen)
                   8671: {
                   8672:     asc_board_t            *boardp;
                   8673:     int                    leftlen;
                   8674:     int                    totlen;
                   8675:     int                    len;
                   8676:     int                    chip_scsi_id;
                   8677: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
                   8678:     int                    i;
                   8679: #endif /* version >= v1.3.89 */
                   8680: 
                   8681:     boardp = ASC_BOARDP(shp);
                   8682: 
                   8683:     leftlen = cplen;
                   8684:     totlen = len = 0;
                   8685: 
                   8686:     len = asc_prt_line(cp, leftlen,
                   8687: "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
                   8688:         shp->host_no);
                   8689:     ASC_PRT_NEXT();
                   8690: 
                   8691:     len = asc_prt_line(cp, leftlen,
                   8692: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89)
                   8693: " host_busy %u, last_reset %u, max_id %u, max_lun %u\n",
                   8694:         shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun);
                   8695: #else /* version >= v1.3.89 */
                   8696: " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
                   8697:         shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun,
                   8698:         shp->max_channel);
                   8699: #endif /* version >= v1.3.89 */
                   8700:     ASC_PRT_NEXT();
                   8701:     
                   8702:     len = asc_prt_line(cp, leftlen,
                   8703: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,57)
                   8704: " can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
                   8705:         shp->can_queue, shp->this_id, shp->sg_tablesize, shp->cmd_per_lun);
                   8706: #else /* version >= v1.3.57 */
                   8707: " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
                   8708:         shp->unique_id, shp->can_queue, shp->this_id, shp->sg_tablesize,
                   8709:         shp->cmd_per_lun);
                   8710: #endif /* version >= v1.3.57 */
                   8711:     ASC_PRT_NEXT();
                   8712: 
                   8713:     len = asc_prt_line(cp, leftlen,
                   8714: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,57)
                   8715: " unchecked_isa_dma %d, loaded_as_module %d\n",
                   8716:         shp->unchecked_isa_dma, shp->loaded_as_module);
                   8717: #else /* version >= v1.3.57 */
                   8718: " unchecked_isa_dma %d, use_clustering %d, loaded_as_module %d\n",
                   8719:         shp->unchecked_isa_dma, shp->use_clustering, shp->loaded_as_module);
                   8720: #endif /* version >= v1.3.57 */
                   8721:     ASC_PRT_NEXT();
                   8722: 
                   8723:     len = asc_prt_line(cp, leftlen, " flags %x, last_reset %x, jiffies %x\n",
                   8724:         boardp->flags, boardp->last_reset, jiffies);
                   8725:     ASC_PRT_NEXT();
                   8726: 
                   8727:     if (ASC_NARROW_BOARD(boardp)) {
                   8728:         chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
                   8729:     } else {
                   8730:         chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
                   8731:     }
                   8732: 
                   8733: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
                   8734:     if (boardp->flags & ASC_SELECT_QUEUE_DEPTHS) {
                   8735:         len = asc_prt_line(cp, leftlen, " queue_depth:");
                   8736:         ASC_PRT_NEXT();
                   8737:         for (i = 0; i <= ADV_MAX_TID; i++) {
                   8738:             if ((chip_scsi_id == i) ||
                   8739:                 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   8740:                 continue;
                   8741:             }
                   8742:             if (boardp->device[i] == NULL) {
                   8743:                 continue;
                   8744:             }
                   8745:             len = asc_prt_line(cp, leftlen, " %X:%d",
                   8746:                 i, boardp->device[i]->queue_depth);
                   8747:             ASC_PRT_NEXT();
                   8748:         }
                   8749:         len = asc_prt_line(cp, leftlen, "\n");
                   8750:         ASC_PRT_NEXT();
                   8751:     }
                   8752: #endif /* version >= v1.3.89 */
                   8753: 
                   8754: #if ASC_QUEUE_FLOW_CONTROL
                   8755:     if (ASC_NARROW_BOARD(boardp)) {
                   8756:         len = asc_prt_line(cp, leftlen, " queue_curr_depth:");
                   8757:         ASC_PRT_NEXT();
                   8758:         /* Use ASC_MAX_TID for Narrow Board. */
                   8759:         for (i = 0; i <= ASC_MAX_TID; i++) {
                   8760:             if ((boardp->asc_dvc_cfg.chip_scsi_id == i) ||
                   8761:                 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   8762:                 continue;
                   8763:             }
                   8764:             if (boardp->device[i] == NULL) {
                   8765:                 continue;
                   8766:             }
                   8767:             len = asc_prt_line(cp, leftlen, " %d:%d",
                   8768:                 i, boardp->device[i]->queue_curr_depth);
                   8769:             ASC_PRT_NEXT();
                   8770:         }
                   8771:         len = asc_prt_line(cp, leftlen, "\n");
                   8772:         ASC_PRT_NEXT();
                   8773: 
                   8774:         len = asc_prt_line(cp, leftlen, " queue_count:");
                   8775:         ASC_PRT_NEXT();
                   8776:         /* Use ASC_MAX_TID for Narrow Board. */
                   8777:         for (i = 0; i <= ASC_MAX_TID; i++) {
                   8778:             if ((boardp->asc_dvc_cfg.chip_scsi_id == i) ||
                   8779:                 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   8780:                 continue;
                   8781:             }
                   8782:             if (boardp->device[i] == NULL) {
                   8783:                 continue;
                   8784:             }
                   8785:             len = asc_prt_line(cp, leftlen, " %d:%d",
                   8786:                 i, boardp->device[i]->queue_count);
                   8787:             ASC_PRT_NEXT();
                   8788:         }
                   8789:         len = asc_prt_line(cp, leftlen, "\n");
                   8790:         ASC_PRT_NEXT();
                   8791:     }
                   8792: #endif /* ASC_QUEUE_FLOW_CONTROL */
                   8793: 
                   8794:     return totlen;
                   8795: }
                   8796: 
                   8797: /*
                   8798:  * asc_prt_asc_board_info()
                   8799:  *
                   8800:  * Print dynamic board configuration information.
                   8801:  *
                   8802:  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
                   8803:  * cf. asc_prt_line().
                   8804:  *
                   8805:  * Return the number of characters copied into 'cp'. No more than
                   8806:  * 'cplen' characters will be copied to 'cp'.
                   8807:  */
                   8808: STATIC int
                   8809: asc_prt_asc_board_info(struct Scsi_Host *shp, char *cp, int cplen)
                   8810: {
                   8811:     asc_board_t            *boardp;
                   8812:     int                    leftlen;
                   8813:     int                    totlen;
                   8814:     int                    len;
                   8815:     ASC_DVC_VAR            *v;
                   8816:     ASC_DVC_CFG            *c;
                   8817:     int                    i;
                   8818: 
                   8819:     boardp = ASC_BOARDP(shp);
                   8820:     v = &boardp->dvc_var.asc_dvc_var;
                   8821:     c = &boardp->dvc_cfg.asc_dvc_cfg;
                   8822: 
                   8823:     leftlen = cplen;
                   8824:     totlen = len = 0;
                   8825: 
                   8826:     len = asc_prt_line(cp, leftlen,
                   8827: "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
                   8828:     shp->host_no);
                   8829:     ASC_PRT_NEXT();
                   8830: 
                   8831:     len = asc_prt_line(cp, leftlen,
                   8832: " chip_version %u, lib_version %x, lib_serial_no %u, mcode_date %x\n",
                   8833:         c->chip_version, c->lib_version, c->lib_serial_no, c->mcode_date);
                   8834:     ASC_PRT_NEXT();
                   8835: 
                   8836:     len = asc_prt_line(cp, leftlen,
                   8837: " mcode_version %x, err_code %u\n",
                   8838:          c->mcode_version, v->err_code);
                   8839:     ASC_PRT_NEXT();
                   8840: 
                   8841:     /* Current number of commands waiting for the host. */
                   8842:     len = asc_prt_line(cp, leftlen,
                   8843: " Total Command Pending: %d\n", v->cur_total_qng);
                   8844:     ASC_PRT_NEXT();
                   8845: 
                   8846:     len = asc_prt_line(cp, leftlen,
                   8847: " Command Queuing:");
                   8848:     ASC_PRT_NEXT();
                   8849:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   8850:         if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
                   8851:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   8852:             continue;
                   8853:         }
                   8854:         len = asc_prt_line(cp, leftlen, " %d:%c",
                   8855:             i, (v->use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   8856:         ASC_PRT_NEXT();
                   8857:     }
                   8858:     len = asc_prt_line(cp, leftlen, "\n");
                   8859:     ASC_PRT_NEXT();
                   8860: 
                   8861:     /* Current number of commands waiting for a device. */
                   8862:     len = asc_prt_line(cp, leftlen,
                   8863: " Command Queue Pending:");
                   8864:     ASC_PRT_NEXT();
                   8865:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   8866:         if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
                   8867:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   8868:             continue;
                   8869:         }
                   8870:         len = asc_prt_line(cp, leftlen, " %d:%u", i, v->cur_dvc_qng[i]);
                   8871:         ASC_PRT_NEXT();
                   8872:     }
                   8873:     len = asc_prt_line(cp, leftlen, "\n");
                   8874:     ASC_PRT_NEXT();
                   8875: 
                   8876:     /* Current limit on number of commands that can be sent to a device. */
                   8877:     len = asc_prt_line(cp, leftlen,
                   8878: " Command Queue Limit:");
                   8879:     ASC_PRT_NEXT();
                   8880:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   8881:         if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
                   8882:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   8883:             continue;
                   8884:         }
                   8885:         len = asc_prt_line(cp, leftlen, " %d:%u", i, v->max_dvc_qng[i]);
                   8886:         ASC_PRT_NEXT();
                   8887:     }
                   8888:     len = asc_prt_line(cp, leftlen, "\n");
                   8889:     ASC_PRT_NEXT();
                   8890: 
                   8891:     /* Indicate whether the device has returned queue full status. */
                   8892:     len = asc_prt_line(cp, leftlen,
                   8893: " Command Queue Full:");
                   8894:     ASC_PRT_NEXT();
                   8895:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   8896:         if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
                   8897:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   8898:             continue;
                   8899:         }
                   8900:         if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
                   8901:             len = asc_prt_line(cp, leftlen, " %d:Y-%d",
                   8902:                 i, boardp->queue_full_cnt[i]);
                   8903:         } else {
                   8904:             len = asc_prt_line(cp, leftlen, " %d:N", i);
                   8905:         }
                   8906:         ASC_PRT_NEXT();
                   8907:     }
                   8908:     len = asc_prt_line(cp, leftlen, "\n");
                   8909:     ASC_PRT_NEXT();
                   8910: 
                   8911:     len = asc_prt_line(cp, leftlen,
                   8912: " Synchronous Transfer:");
                   8913:     ASC_PRT_NEXT();
                   8914:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   8915:         if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
                   8916:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   8917:             continue;
                   8918:         }
                   8919:         len = asc_prt_line(cp, leftlen, " %d:%c",
                   8920:             i, (v->sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   8921:         ASC_PRT_NEXT();
                   8922:     }
                   8923:     len = asc_prt_line(cp, leftlen, "\n");
                   8924:     ASC_PRT_NEXT();
                   8925: 
                   8926:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   8927:         uchar syn_period_ix;
                   8928: 
                   8929:         if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) ||
                   8930:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   8931:             continue;
                   8932:         }
                   8933:         if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
                   8934:             continue;
                   8935:         }
                   8936:         syn_period_ix = (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index - 1);
                   8937:         len = asc_prt_line(cp, leftlen, "  %d:", i);
                   8938:         ASC_PRT_NEXT();
                   8939: 
                   8940:         len = asc_prt_line(cp, leftlen,
                   8941:             " Transfer Period Factor: %d (%d.%d Mhz),",
                   8942:             v->sdtr_period_tbl[syn_period_ix],
                   8943:             250 / v->sdtr_period_tbl[syn_period_ix],
                   8944:             ASC_TENTHS(250, v->sdtr_period_tbl[syn_period_ix]));
                   8945:         ASC_PRT_NEXT();
                   8946: 
                   8947:         len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d\n",
                   8948:             boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET);
                   8949:         ASC_PRT_NEXT();
                   8950:     }
                   8951: 
                   8952:     return totlen;
                   8953: }
                   8954: 
                   8955: /*
                   8956:  * asc_prt_adv_board_info()
                   8957:  *
                   8958:  * Print dynamic board configuration information.
                   8959:  *
                   8960:  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
                   8961:  * cf. asc_prt_line().
                   8962:  *
                   8963:  * Return the number of characters copied into 'cp'. No more than
                   8964:  * 'cplen' characters will be copied to 'cp'.
                   8965:  */
                   8966: STATIC int
                   8967: asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen)
                   8968: {
                   8969:     asc_board_t            *boardp;
                   8970:     int                    leftlen;
                   8971:     int                    totlen;
                   8972:     int                    len;
                   8973:     int                    i;
                   8974:     ADV_DVC_VAR            *v;
                   8975:     ADV_DVC_CFG            *c;
                   8976:     AdvPortAddr            iop_base;
                   8977:     ushort                 chip_scsi_id;
                   8978:     ushort                 lramword;
                   8979:     uchar                  lrambyte;
                   8980:     ushort                 sdtr_able;
                   8981:     ushort                 period;
                   8982: 
                   8983:     boardp = ASC_BOARDP(shp);
                   8984:     v = &boardp->dvc_var.adv_dvc_var;
                   8985:     c = &boardp->dvc_cfg.adv_dvc_cfg;
                   8986:     iop_base = v->iop_base;
                   8987:     chip_scsi_id = v->chip_scsi_id;
                   8988: 
                   8989:     leftlen = cplen;
                   8990:     totlen = len = 0;
                   8991: 
                   8992:     len = asc_prt_line(cp, leftlen,
                   8993: "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
                   8994:     shp->host_no);
                   8995:     ASC_PRT_NEXT();
                   8996: 
                   8997:     len = asc_prt_line(cp, leftlen,
                   8998: " iop_base %lx, cable_detect: %X, err_code %u, idle_cmd_done %u\n",
                   8999:          v->iop_base,
                   9000:          AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1) & CABLE_DETECT,
                   9001:          v->err_code, v->idle_cmd_done);
                   9002:     ASC_PRT_NEXT();
                   9003: 
                   9004:     len = asc_prt_line(cp, leftlen,
                   9005: " chip_version %u, lib_version %x, mcode_date %x, mcode_version %x\n",
                   9006:         c->chip_version, c->lib_version, c->mcode_date, c->mcode_version);
                   9007:     ASC_PRT_NEXT();
                   9008: 
                   9009:     AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, lramword);
                   9010:     len = asc_prt_line(cp, leftlen,
                   9011: " Queuing Enabled:");
                   9012:     ASC_PRT_NEXT();
                   9013:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   9014:         if ((chip_scsi_id == i) ||
                   9015:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   9016:             continue;
                   9017:         }
                   9018: 
                   9019:         len = asc_prt_line(cp, leftlen, " %X:%c",
                   9020:             i, (lramword & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   9021:         ASC_PRT_NEXT();
                   9022:     }
                   9023:     len = asc_prt_line(cp, leftlen, "\n");
                   9024:     ASC_PRT_NEXT();
                   9025: 
                   9026:     len = asc_prt_line(cp, leftlen,
                   9027: " Queue Limit:");
                   9028:     ASC_PRT_NEXT();
                   9029:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   9030:         if ((chip_scsi_id == i) ||
                   9031:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   9032:             continue;
                   9033:         }
                   9034: 
                   9035:         AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i, lrambyte);
                   9036: 
                   9037:         len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
                   9038:         ASC_PRT_NEXT();
                   9039:     }
                   9040:     len = asc_prt_line(cp, leftlen, "\n");
                   9041:     ASC_PRT_NEXT();
                   9042: 
                   9043:     len = asc_prt_line(cp, leftlen,
                   9044: " Command Pending:");
                   9045:     ASC_PRT_NEXT();
                   9046:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   9047:         if ((chip_scsi_id == i) ||
                   9048:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   9049:             continue;
                   9050:         }
                   9051: 
                   9052:         AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i, lrambyte);
                   9053: 
                   9054:         len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
                   9055:         ASC_PRT_NEXT();
                   9056:     }
                   9057:     len = asc_prt_line(cp, leftlen, "\n");
                   9058:     ASC_PRT_NEXT();
                   9059: 
                   9060:     AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, lramword);
                   9061:     len = asc_prt_line(cp, leftlen,
                   9062: " Wide Enabled:");
                   9063:     ASC_PRT_NEXT();
                   9064:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   9065:         if ((chip_scsi_id == i) ||
                   9066:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   9067:             continue;
                   9068:         }
                   9069: 
                   9070:         len = asc_prt_line(cp, leftlen, " %X:%c",
                   9071:             i, (lramword & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   9072:         ASC_PRT_NEXT();
                   9073:     }
                   9074:     len = asc_prt_line(cp, leftlen, "\n");
                   9075:     ASC_PRT_NEXT();
                   9076: 
                   9077:     len = asc_prt_line(cp, leftlen,
                   9078: " Transfer Bit Width:");
                   9079:     ASC_PRT_NEXT();
                   9080:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   9081:         if ((chip_scsi_id == i) ||
                   9082:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   9083:             continue;
                   9084:         }
                   9085: 
                   9086:         AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
                   9087:             lramword);
                   9088:         len = asc_prt_line(cp, leftlen, " %X:%d",
                   9089:             i, (lramword & 0x8000) ? 16 : 8);
                   9090:         ASC_PRT_NEXT();
                   9091:     }
                   9092:     len = asc_prt_line(cp, leftlen, "\n");
                   9093:     ASC_PRT_NEXT();
                   9094: 
                   9095:     AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
                   9096:     len = asc_prt_line(cp, leftlen,
                   9097: " Synchronous Enabled:");
                   9098:     ASC_PRT_NEXT();
                   9099:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   9100:         if ((chip_scsi_id == i) ||
                   9101:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   9102:             continue;
                   9103:         }
                   9104: 
                   9105:         len = asc_prt_line(cp, leftlen, " %X:%c",
                   9106:             i, (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
                   9107:         ASC_PRT_NEXT();
                   9108:     }
                   9109:     len = asc_prt_line(cp, leftlen, "\n");
                   9110:     ASC_PRT_NEXT();
                   9111: 
                   9112:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   9113: 
                   9114:         AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
                   9115:             lramword);
                   9116:         lramword &= ~0x8000;
                   9117: 
                   9118:         if ((chip_scsi_id == i) ||
                   9119:             ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0) ||
                   9120:             (lramword == 0)) {
                   9121:             continue;
                   9122:         }
                   9123: 
                   9124:         len = asc_prt_line(cp, leftlen, "  %X:", i);
                   9125:         ASC_PRT_NEXT();
                   9126:         
                   9127:         period = (((lramword >> 8) * 25) + 50)/4;
                   9128: 
                   9129:         len = asc_prt_line(cp, leftlen,
                   9130:             " Transfer Period Factor: %d (%d.%d Mhz),",
                   9131:             period, 250/period, ASC_TENTHS(250, period));
                   9132:         ASC_PRT_NEXT();
                   9133: 
                   9134:         len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d\n",
                   9135:             lramword & 0x1F);
                   9136:         ASC_PRT_NEXT();
                   9137:     }
                   9138: 
                   9139:     return totlen;
                   9140: }
                   9141: 
                   9142: /*
                   9143:  * asc_proc_copy() 
                   9144:  *
                   9145:  * Copy proc information to a read buffer taking into account the current
                   9146:  * read offset in the file and the remaining space in the read buffer.
                   9147:  */
                   9148: STATIC int
                   9149: asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
                   9150:               char *cp, int cplen)
                   9151: {
                   9152:     int cnt = 0;
                   9153:     
                   9154:     ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
                   9155:             (unsigned) offset, (unsigned) advoffset, cplen);
                   9156:     if (offset <= advoffset) {
                   9157:         /* Read offset below current offset, copy everything. */
                   9158:         cnt = ASC_MIN(cplen, leftlen);
                   9159:         ASC_DBG3(2, "asc_proc_copy: curbuf %x, cp %x, cnt %d\n",
                   9160:                 (unsigned) curbuf, (unsigned) cp, cnt);
                   9161:         memcpy(curbuf, cp, cnt);
                   9162:     } else if (offset < advoffset + cplen) {
                   9163:         /* Read offset within current range, partial copy. */
                   9164:         cnt = (advoffset + cplen) - offset;
                   9165:         cp = (cp + cplen) - cnt;
                   9166:         cnt = ASC_MIN(cnt, leftlen);
                   9167:         ASC_DBG3(2, "asc_proc_copy: curbuf %x, cp %x, cnt %d\n",
                   9168:                 (unsigned) curbuf, (unsigned) cp, cnt);
                   9169:         memcpy(curbuf, cp, cnt);
                   9170:     }
                   9171:     return cnt;
                   9172: }
                   9173: 
                   9174: /*
                   9175:  * asc_prt_line()
                   9176:  *
                   9177:  * If 'cp' is NULL print to the console, otherwise print to a buffer.
                   9178:  *
                   9179:  * Return 0 if printing to the console, otherwise return the number of
                   9180:  * bytes written to the buffer.
                   9181:  *
                   9182:  * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
                   9183:  * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
                   9184:  */
                   9185: STATIC int
                   9186: asc_prt_line(char *buf, int buflen, char *fmt, ...)
                   9187: {
                   9188:     va_list        args;
                   9189:     int            ret;
                   9190:     char        s[ASC_PRTLINE_SIZE];
                   9191: 
                   9192:     va_start(args, fmt);
                   9193:     ret = vsprintf(s, fmt, args);
                   9194:     ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
                   9195:     if (buf == NULL) {
1.1.1.2   root     9196:         (void) printk("%s", s);
1.1       root     9197:         ret = 0;
                   9198:     } else {
                   9199:         ret = ASC_MIN(buflen, ret);
                   9200:         memcpy(buf, s, ret);
                   9201:     }
                   9202:     va_end(args);
                   9203:     return ret;
                   9204: }
                   9205: #endif /* version >= v1.3.0 */
                   9206: 
                   9207: 
                   9208: /*
                   9209:  * --- Functions Required by the Asc Library
                   9210:  */
                   9211: 
                   9212: /*
                   9213:  * Delay for 'n' milliseconds. Don't use the 'jiffies'
                   9214:  * global variable which is incremented once every 5 ms
                   9215:  * from a timer interrupt, because this function may be
                   9216:  * called when interrupts are disabled.
                   9217:  */
                   9218: STATIC void
                   9219: DvcSleepMilliSecond(ulong n)
                   9220: {
                   9221:     ulong i;
                   9222: 
                   9223:     ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", n);
                   9224:     for (i = 0; i < n; i++) {
                   9225:         udelay(1000);
                   9226:     }
                   9227: }
                   9228: 
1.1.1.2   root     9229: STATIC long
1.1       root     9230: DvcEnterCritical(void)
                   9231: {
1.1.1.2   root     9232:     long   flags;
1.1       root     9233: 
                   9234:     save_flags(flags);
                   9235:     cli();
                   9236:     return flags;
                   9237: }
                   9238: 
                   9239: STATIC void
1.1.1.2   root     9240: DvcLeaveCritical(long flags)
1.1       root     9241: {
                   9242:     restore_flags(flags);
                   9243: }
                   9244: 
                   9245: STATIC ulong
                   9246: DvcGetSGList(ASC_DVC_VAR *asc_dvc_sg, uchar *buf_addr, ulong buf_len,
                   9247:              ASC_SG_HEAD *asc_sg_head_ptr)
                   9248: {
                   9249:     ulong buf_size;
                   9250: 
                   9251:     buf_size = buf_len;
                   9252:     asc_sg_head_ptr->entry_cnt = 1;
                   9253: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
                   9254:     asc_sg_head_ptr->sg_list[0].addr = (ulong) buf_addr;
                   9255: #else /* version >= v2.0.0 */
                   9256:     asc_sg_head_ptr->sg_list[0].addr = virt_to_bus(buf_addr);
                   9257: #endif /* version >= v2.0.0 */
                   9258:     asc_sg_head_ptr->sg_list[0].bytes = buf_size;
                   9259:     return buf_size;
                   9260: }
                   9261: 
                   9262: /*
                   9263:  * void
                   9264:  * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, ushort *outbuf, int words)
                   9265:  *
                   9266:  * Calling/Exit State:
                   9267:  *    none
                   9268:  *
                   9269:  * Description:
                   9270:  *     Output an ASC_SCSI_Q structure to the chip
                   9271:  */
                   9272: STATIC void
                   9273: DvcPutScsiQ(PortAddr iop_base, ushort s_addr, ushort *outbuf, int words)
                   9274: {
                   9275:     int    i;
                   9276: 
                   9277:     ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", (uchar *) outbuf, 2 * words);
                   9278:     AscSetChipLramAddr(iop_base, s_addr);
                   9279:     for (i = 0; i < words; i++, outbuf++) {
                   9280:         if (i == 2 || i == 10) {
                   9281:             continue;
                   9282:         }
                   9283:         AscSetChipLramDataNoSwap(iop_base, *outbuf);
                   9284:     }
                   9285: }
                   9286: 
                   9287: /*
                   9288:  * void
                   9289:  * DvcGetQinfo(PortAddr iop_base, ushort s_addr, ushort *inbuf, int words)
                   9290:  *
                   9291:  * Calling/Exit State:
                   9292:  *    none
                   9293:  *
                   9294:  * Description:
                   9295:  *     Input an ASC_QDONE_INFO structure from the chip
                   9296:  */
                   9297: STATIC void
                   9298: DvcGetQinfo(PortAddr iop_base, ushort s_addr, ushort *inbuf, int words)
                   9299: {
                   9300:     int    i;
                   9301: 
                   9302:     AscSetChipLramAddr(iop_base, s_addr);
                   9303:     for (i = 0; i < words; i++, inbuf++) {
                   9304:         if (i == 5) {
                   9305:             continue;
                   9306:         }
                   9307:         *inbuf = AscGetChipLramDataNoSwap(iop_base);
                   9308:     }
                   9309:     ASC_DBG_PRT_HEX(2, "DvcGetQinfo", (uchar *) inbuf, 2 * words);
                   9310: }
                   9311: 
                   9312: /*
                   9313:  * void    DvcOutPortWords(ushort iop_base, ushort &outbuf, int words)
                   9314:  *
                   9315:  * Calling/Exit State:
                   9316:  *    none
                   9317:  *
                   9318:  * Description:
                   9319:  *     output a buffer to an i/o port address
                   9320:  */
                   9321: STATIC void
                   9322: DvcOutPortWords(ushort iop_base, ushort *outbuf, int words)
                   9323: {
                   9324:     int    i;
                   9325: 
                   9326:     for (i = 0; i < words; i++, outbuf++)
                   9327:         outpw(iop_base, *outbuf);
                   9328: }
                   9329: 
                   9330: /*
                   9331:  * void    DvcInPortWords(ushort iop_base, ushort &outbuf, int words)
                   9332:  *
                   9333:  * Calling/Exit State:
                   9334:  *    none
                   9335:  *
                   9336:  * Description:
                   9337:  *     input a buffer from an i/o port address
                   9338:  */
                   9339: STATIC void
                   9340: DvcInPortWords(ushort iop_base, ushort *inbuf, int words)
                   9341: {
                   9342:     int    i;
                   9343: 
                   9344:     for (i = 0; i < words; i++, inbuf++)
                   9345:         *inbuf = inpw(iop_base);
                   9346: }
                   9347: 
                   9348: /*
                   9349:  * void DvcOutPortDWords(PortAddr port, ulong *pdw, int dwords)
                   9350:  *
                   9351:  * Calling/Exit State:
                   9352:  *    none
                   9353:  *
                   9354:  * Description:
                   9355:  *     output a buffer of 32-bit integers to an i/o port address in
                   9356:  *  16 bit integer units
                   9357:  */
                   9358: STATIC void  
                   9359: DvcOutPortDWords(PortAddr port, ulong *pdw, int dwords)
                   9360: {
                   9361:     int        i;
                   9362:     int        words;
                   9363:     ushort    *pw;
                   9364: 
                   9365:     pw = (ushort *) pdw;
                   9366:     words = dwords << 1;
                   9367:     for(i = 0; i < words; i++, pw++) {
                   9368:         outpw(port, *pw);
                   9369:     }
                   9370:     return;
                   9371: }
                   9372: 
                   9373: /*
                   9374:  * Read a PCI configuration byte.
                   9375:  */
                   9376: ASC_INITFUNC(
                   9377: STATIC uchar
                   9378: DvcReadPCIConfigByte(
                   9379:         ASC_DVC_VAR asc_ptr_type *asc_dvc, 
                   9380:         ushort offset)
                   9381: )
                   9382: {
                   9383: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
                   9384: #ifdef ASC_CONFIG_PCI
                   9385:     PCI_DATA    pciData;
                   9386: 
                   9387:     pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
                   9388:     pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
                   9389:     pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
                   9390:     pciData.offset = offset;
                   9391:     pciData.type = pci_scan_method;
                   9392:     return asc_get_cfg_byte(&pciData);
                   9393: #else /* ASC_CONFIG_PCI */
                   9394:     return 0;
                   9395: #endif /* ASC_CONFIG_PCI */
                   9396: #else /* version >= v2.1.93 */ 
                   9397: #ifdef CONFIG_PCI
                   9398:     uchar byte_data;
                   9399:     pcibios_read_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
                   9400:         PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
                   9401:             ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
                   9402:         offset, &byte_data);
                   9403:     return byte_data;
                   9404: #else /* CONFIG_PCI */
                   9405:     return 0;
                   9406: #endif /* CONFIG_PCI */
                   9407: #endif /* version >= v2.1.93 */ 
                   9408: }
                   9409: 
                   9410: /*
                   9411:  * Write a PCI configuration byte.
                   9412:  */
                   9413: ASC_INITFUNC(
                   9414: STATIC void
                   9415: DvcWritePCIConfigByte(
                   9416:         ASC_DVC_VAR asc_ptr_type *asc_dvc, 
                   9417:         ushort offset, 
                   9418:         uchar  byte_data)
                   9419: )
                   9420: {
                   9421: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
                   9422: #ifdef ASC_CONFIG_PCI
                   9423:     PCI_DATA    pciData;
                   9424: 
                   9425:     pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
                   9426:     pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
                   9427:     pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
                   9428:     pciData.offset = offset;
                   9429:     pciData.type = pci_scan_method;
                   9430:     asc_put_cfg_byte(&pciData, byte_data);
                   9431: #endif /* ASC_CONFIG_PCI */
                   9432: #else /* version >= v2.1.93 */ 
                   9433: #ifdef CONFIG_PCI
                   9434:     pcibios_write_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
                   9435:         PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
                   9436:             ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
                   9437:         offset, byte_data);
                   9438: #endif /* CONFIG_PCI */
                   9439: #endif /* version >= v2.1.93 */ 
                   9440: }
                   9441: 
                   9442: /*
                   9443:  * Return the BIOS address of the adapter at the specified
                   9444:  * I/O port and with the specified bus type.
                   9445:  */
                   9446: ASC_INITFUNC(
                   9447: STATIC ushort
                   9448: AscGetChipBiosAddress(
                   9449:         PortAddr iop_base,
                   9450:         ushort bus_type
                   9451: )
                   9452: )
                   9453: {
                   9454:     ushort  cfg_lsw ;
                   9455:     ushort  bios_addr ;
                   9456: 
                   9457:     /*
                   9458:      * The PCI BIOS is re-located by the motherboard BIOS. Because
                   9459:      * of this the driver can not determine where a PCI BIOS is
                   9460:      * loaded and executes.
                   9461:      */
                   9462:     if (bus_type & ASC_IS_PCI)
                   9463:     {
                   9464:         return(0);
                   9465:     }
                   9466: 
                   9467:     if((bus_type & ASC_IS_EISA) != 0)
                   9468:     {
                   9469:         cfg_lsw = AscGetEisaChipCfg(iop_base) ;
                   9470:         cfg_lsw &= 0x000F ;
                   9471:         bios_addr = (ushort)(ASC_BIOS_MIN_ADDR  +
                   9472:                                 (cfg_lsw * ASC_BIOS_BANK_SIZE)) ;
                   9473:         return(bios_addr) ;
                   9474:     }/* if */
                   9475: 
                   9476:     cfg_lsw = AscGetChipCfgLsw(iop_base) ;
                   9477: 
                   9478:     /*
                   9479:     *  ISA PnP uses the top bit as the 32K BIOS flag
                   9480:     */
                   9481:     if (bus_type == ASC_IS_ISAPNP)
                   9482:     {
                   9483:         cfg_lsw &= 0x7FFF;
                   9484:     }/* if */
                   9485: 
                   9486:     bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) +
                   9487:             ASC_BIOS_MIN_ADDR) ;
                   9488:     return(bios_addr) ;
                   9489: }
                   9490: 
                   9491: 
                   9492: /*
                   9493:  * --- Functions Required by the Adv Library
                   9494:  */
                   9495: 
                   9496: /*
                   9497:  * DvcGetPhyAddr()
                   9498:  *
                   9499:  * Return the physical address of 'vaddr' and set '*lenp' to the
                   9500:  * number of physically contiguous bytes that follow 'vaddr'.
                   9501:  * 'flag' indicates the type of structure whose physical address
                   9502:  * is being translated.
                   9503:  *
                   9504:  * Note: Because Linux currently doesn't page the kernel and all
                   9505:  * kernel buffers are physically contiguous, leave '*lenp' unchanged.
                   9506:  */
                   9507: ulong
                   9508: DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
                   9509:         uchar *vaddr, long *lenp, int flag)
                   9510: {
                   9511:     ulong                paddr;
                   9512: 
                   9513: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
                   9514:     paddr = (ulong) vaddr;
                   9515: #else /* version >= v2.0.0 */
                   9516:     paddr = virt_to_bus(vaddr);
                   9517: #endif /* version >= v2.0.0 */
                   9518: 
                   9519:     ASC_DBG4(4,
                   9520:         "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n", 
                   9521:         (ulong) vaddr, (ulong) lenp, (ulong) *((ulong *) lenp), paddr);
                   9522: 
                   9523:     return paddr;
                   9524: }
                   9525: 
                   9526: /*
                   9527:  * Read a PCI configuration byte.
                   9528:  */
                   9529: ASC_INITFUNC(
                   9530: STATIC uchar
                   9531: DvcAdvReadPCIConfigByte(
                   9532:         ADV_DVC_VAR *asc_dvc, 
                   9533:         ushort offset)
                   9534: )
                   9535: {
                   9536: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
                   9537: #ifdef ASC_CONFIG_PCI
                   9538:     PCI_DATA    pciData;
                   9539: 
                   9540:     pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
                   9541:     pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
                   9542:     pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
                   9543:     pciData.offset = offset;
                   9544:     pciData.type = pci_scan_method;
                   9545:     return asc_get_cfg_byte(&pciData);
                   9546: #else /* ASC_CONFIG_PCI */
                   9547:     return 0;
                   9548: #endif /* ASC_CONFIG_PCI */
                   9549: #else /* version >= v2.1.93 */ 
                   9550: #ifdef CONFIG_PCI
                   9551:     uchar byte_data;
                   9552:     pcibios_read_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
                   9553:         PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
                   9554:             ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
                   9555:         offset, &byte_data);
                   9556:     return byte_data;
                   9557: #else /* CONFIG_PCI */
                   9558:     return 0;
                   9559: #endif /* CONFIG_PCI */
                   9560: #endif /* version >= v2.1.93 */ 
                   9561: }
                   9562: 
                   9563: /*
                   9564:  * Write a PCI configuration byte.
                   9565:  */
                   9566: ASC_INITFUNC(
                   9567: STATIC void
                   9568: DvcAdvWritePCIConfigByte(
                   9569:         ADV_DVC_VAR *asc_dvc, 
                   9570:         ushort offset, 
                   9571:         uchar  byte_data)
                   9572: )
                   9573: {
                   9574: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
                   9575: #ifdef ASC_CONFIG_PCI
                   9576:     PCI_DATA    pciData;
                   9577: 
                   9578:     pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
                   9579:     pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
                   9580:     pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
                   9581:     pciData.offset = offset;
                   9582:     pciData.type = pci_scan_method;
                   9583:     asc_put_cfg_byte(&pciData, byte_data);
                   9584: #endif /* ASC_CONFIG_PCI */
                   9585: #else /* version >= v2.1.93 */ 
                   9586: #ifdef CONFIG_PCI
                   9587:     pcibios_write_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
                   9588:         PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
                   9589:             ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
                   9590:         offset, byte_data);
                   9591: #endif /* CONFIG_PCI */
                   9592: #endif /* version >= v2.1.93 */ 
                   9593: }
                   9594: 
                   9595: /*
                   9596:  * --- Tracing and Debugging Functions
                   9597:  */
                   9598: 
                   9599: #ifdef ADVANSYS_STATS
                   9600: /*
                   9601:  * asc_prt_board_stats()
                   9602:  *
                   9603:  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
                   9604:  * cf. asc_prt_line().
                   9605:  *
                   9606:  * Return the number of characters copied into 'cp'. No more than
                   9607:  * 'cplen' characters will be copied to 'cp'.
                   9608:  */
                   9609: STATIC int
                   9610: asc_prt_board_stats(struct Scsi_Host *shp, char *cp, int cplen)
                   9611: {
                   9612:     int                    leftlen;
                   9613:     int                    totlen;
                   9614:     int                    len;
                   9615:     struct asc_stats       *s;
                   9616:     int                    i;
                   9617:     ushort                 chip_scsi_id;
                   9618:     asc_board_t            *boardp;
                   9619:     asc_queue_t            *active;
                   9620:     asc_queue_t            *waiting;
                   9621: 
                   9622:     leftlen = cplen;
                   9623:     totlen = len = 0;
                   9624: 
                   9625:     boardp = ASC_BOARDP(shp);
                   9626:     s = &boardp->asc_stats;
                   9627: 
                   9628:     len = asc_prt_line(cp, leftlen,
                   9629: "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", shp->host_no);
                   9630:     ASC_PRT_NEXT();
                   9631:     
                   9632:     len = asc_prt_line(cp, leftlen,
                   9633: " command %lu, queuecommand %lu, abort %lu, reset %lu, biosparam %lu\n",
                   9634:         s->command, s->queuecommand, s->abort, s->reset, s->biosparam);
                   9635:     ASC_PRT_NEXT();
                   9636: 
                   9637:     len = asc_prt_line(cp, leftlen,
                   9638: " interrupt %lu, callback %lu, done %lu\n",
                   9639:         s->interrupt, s->callback, s->done);
                   9640:     ASC_PRT_NEXT();
                   9641: 
                   9642:     len = asc_prt_line(cp, leftlen,
                   9643: " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
                   9644:         s->exe_noerror, s->exe_busy, s->exe_error, s->exe_unknown);
                   9645:     ASC_PRT_NEXT();
                   9646: 
                   9647:     if (ASC_NARROW_BOARD(boardp)) {
                   9648:         len = asc_prt_line(cp, leftlen,
                   9649: " build_error %lu\n",
                   9650:          s->build_error);
                   9651:     } else {
                   9652:         len = asc_prt_line(cp, leftlen,
                   9653: " build_error %lu, build_noreq %lu, build_nosg %lu\n",
                   9654:          s->build_error, s->adv_build_noreq, s->adv_build_nosg);
                   9655:     }
                   9656:     ASC_PRT_NEXT();
                   9657: 
                   9658:     /*
                   9659:      * Display data transfer statistics.
                   9660:      */
                   9661:     if (s->cont_cnt > 0) {
                   9662:         len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
                   9663:         ASC_PRT_NEXT();
                   9664: 
                   9665:         len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
                   9666:                     s->cont_xfer/2,
                   9667:                     ASC_TENTHS(s->cont_xfer, 2));
                   9668:         ASC_PRT_NEXT();
                   9669: 
                   9670:         /* Contiguous transfer average size */
                   9671:         len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
                   9672:                     (s->cont_xfer/2)/s->cont_cnt,
                   9673:                     ASC_TENTHS((s->cont_xfer/2), s->cont_cnt));
                   9674:         ASC_PRT_NEXT();
                   9675:     }
                   9676: 
                   9677:     if (s->sg_cnt > 0) {
                   9678: 
                   9679:         len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
                   9680:                     s->sg_cnt, s->sg_elem);
                   9681:         ASC_PRT_NEXT();
                   9682: 
                   9683:         len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
                   9684:                     s->sg_xfer/2,
                   9685:                     ASC_TENTHS(s->sg_xfer, 2));
                   9686:         ASC_PRT_NEXT();
                   9687: 
                   9688:         /* Scatter gather transfer statistics */
                   9689:         len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
                   9690:                     s->sg_elem/s->sg_cnt,
                   9691:                     ASC_TENTHS(s->sg_elem, s->sg_cnt));
                   9692:         ASC_PRT_NEXT();
                   9693: 
                   9694:         len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
                   9695:                     (s->sg_xfer/2)/s->sg_elem,
                   9696:                     ASC_TENTHS((s->sg_xfer/2), s->sg_elem));
                   9697:         ASC_PRT_NEXT();
                   9698: 
                   9699:         len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
                   9700:                     (s->sg_xfer/2)/s->sg_cnt,
                   9701:                     ASC_TENTHS((s->sg_xfer/2), s->sg_cnt));
                   9702:         ASC_PRT_NEXT();
                   9703:     }
                   9704: 
                   9705:     /*
                   9706:      * Display request queuing statistics.
                   9707:      */
                   9708:     len = asc_prt_line(cp, leftlen,
                   9709: " Active and Waiting Request Queues (Time Unit: %d HZ):\n", HZ);
                   9710:     ASC_PRT_NEXT();
                   9711: 
                   9712:     active = &ASC_BOARDP(shp)->active;
                   9713:     waiting = &ASC_BOARDP(shp)->waiting;
                   9714: 
                   9715:     if (ASC_NARROW_BOARD(boardp)) {
                   9716:         chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
                   9717:     } else {
                   9718:         chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
                   9719:     }
                   9720: 
                   9721:     for (i = 0; i <= ADV_MAX_TID; i++) {
                   9722: 
                   9723:         if ((chip_scsi_id == i) ||
                   9724:             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
                   9725:             continue;
                   9726:         }
                   9727: 
                   9728:         if (active->q_tot_cnt[i] > 0 || waiting->q_tot_cnt[i] > 0) {
                   9729:             len = asc_prt_line(cp, leftlen, " target %d\n", i);
                   9730:             ASC_PRT_NEXT();
                   9731: 
                   9732:             len = asc_prt_line(cp, leftlen,
                   9733: "   active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
                   9734:                 active->q_cur_cnt[i], active->q_max_cnt[i],
                   9735:                 active->q_tot_cnt[i],
                   9736:                 active->q_min_tim[i], active->q_max_tim[i],
                   9737:                 (active->q_tot_cnt[i] == 0) ? 0 :
                   9738:                 (active->q_tot_tim[i]/active->q_tot_cnt[i]),
                   9739:                 (active->q_tot_cnt[i] == 0) ? 0 :
                   9740:                 ASC_TENTHS(active->q_tot_tim[i], active->q_tot_cnt[i]));
                   9741:             ASC_PRT_NEXT();
                   9742: 
                   9743:             len = asc_prt_line(cp, leftlen,
                   9744: "   waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
                   9745:                 waiting->q_cur_cnt[i], waiting->q_max_cnt[i],
                   9746:                 waiting->q_tot_cnt[i],
                   9747:                 waiting->q_min_tim[i], waiting->q_max_tim[i],
                   9748:                 (waiting->q_tot_cnt[i] == 0) ? 0 :
                   9749:                 (waiting->q_tot_tim[i]/waiting->q_tot_cnt[i]),
                   9750:                 (waiting->q_tot_cnt[i] == 0) ? 0 :
                   9751:                 ASC_TENTHS(waiting->q_tot_tim[i], waiting->q_tot_cnt[i]));
                   9752:             ASC_PRT_NEXT();
                   9753:         }
                   9754:     }
                   9755: 
                   9756:      return totlen;
                   9757: }
                   9758: #endif /* ADVANSYS_STATS */
                   9759: 
                   9760: #ifdef ADVANSYS_DEBUG
                   9761: /*
                   9762:  * asc_prt_scsi_host()
                   9763:  */
                   9764: STATIC void 
                   9765: asc_prt_scsi_host(struct Scsi_Host *s)
                   9766: {
                   9767:     asc_board_t         *boardp;
                   9768: 
                   9769:     boardp = ASC_BOARDP(s);
                   9770: 
                   9771:     printk("Scsi_Host at addr %x\n", (unsigned) s);
                   9772:     printk(
                   9773: " next %x, extra_bytes %u, host_busy %u, host_no %d, last_reset %d,\n",
                   9774:         (unsigned) s->next, s->extra_bytes, s->host_busy, s->host_no,
                   9775:         (unsigned) s->last_reset);
                   9776: 
                   9777:     printk(
                   9778: " host_wait %x, host_queue %x, hostt %x, block %x,\n",
                   9779:         (unsigned) s->host_wait, (unsigned) s->host_queue,
                   9780:         (unsigned) s->hostt, (unsigned) s->block);
                   9781: 
                   9782:     printk(
                   9783: " wish_block %d, base %x, io_port %d, n_io_port %d, irq %d, dma_channel %d,\n",
                   9784:         s->wish_block, (unsigned) s->base, s->io_port, s->n_io_port,
                   9785:         s->irq, s->dma_channel);
                   9786: 
                   9787:     printk(
                   9788: " this_id %d, can_queue %d,\n", s->this_id, s->can_queue);
                   9789: 
                   9790:     printk(
                   9791: " cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d, loaded_as_module %d\n",
                   9792:         s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma,
                   9793:         s->loaded_as_module);
                   9794: 
                   9795:     if (ASC_NARROW_BOARD(boardp)) {
                   9796:         asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
                   9797:         asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
                   9798:     } else {
                   9799:         asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
                   9800:         asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
                   9801:     }
                   9802: }
                   9803: 
                   9804: /*
                   9805:  * asc_prt_scsi_cmnd()
                   9806:  */
                   9807: STATIC void 
                   9808: asc_prt_scsi_cmnd(Scsi_Cmnd *s)
                   9809: {
                   9810:     printk("Scsi_Cmnd at addr %x\n", (unsigned) s);
                   9811: 
                   9812: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
                   9813:     printk(
                   9814: " host %x, device %x, target %u, lun %u\n",
                   9815:         (unsigned) s->host, (unsigned) s->device, s->target, s->lun);
                   9816: #else /* version >= v1.3.0 */
                   9817:     printk(
                   9818: " host %x, device %x, target %u, lun %u, channel %u,\n",
                   9819:         (unsigned) s->host, (unsigned) s->device, s->target, s->lun,
                   9820:         s->channel);
                   9821: #endif /* version >= v1.3.0 */
                   9822: 
                   9823:     asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
                   9824: 
                   9825:     printk(
                   9826: " use_sg %u, sglist_len %u, abort_reason %x\n",
                   9827:         s->use_sg, s->sglist_len, s->abort_reason);
                   9828: 
                   9829: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89)
                   9830:     printk(
                   9831: " retries %d, allowed %d\n",
                   9832:          s->retries, s->allowed);
                   9833: #else /* version >= v1.3.89 */
                   9834:     printk(
                   9835: " serial_number %x, serial_number_at_timeout %x, retries %d, allowed %d\n",
                   9836:         (unsigned) s->serial_number, (unsigned) s->serial_number_at_timeout,
                   9837:          s->retries, s->allowed);
                   9838: #endif /* version >= v1.3.89 */
                   9839: 
                   9840:     printk(
                   9841: " timeout_per_command %d, timeout_total %d, timeout %d\n",
                   9842:         s->timeout_per_command, s->timeout_total, s->timeout);
                   9843: 
                   9844:     printk(
                   9845: " internal_timeout %u, flags %u, this_count %d\n",
                   9846:         s->internal_timeout, s->flags, s->this_count);
                   9847: 
                   9848:     printk(
                   9849: " scsi_done %x, done %x, host_scribble %x, result %x\n",
                   9850:         (unsigned) s->scsi_done, (unsigned) s->done,
                   9851:         (unsigned) s->host_scribble, s->result);
                   9852: 
                   9853:     printk(
                   9854: " tag %u, pid %u\n",
                   9855:         (unsigned) s->tag, (unsigned) s->pid);
                   9856: }
                   9857: 
                   9858: /*
                   9859:  * asc_prt_asc_dvc_var()
                   9860:  */
                   9861: STATIC void 
                   9862: asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
                   9863: {
                   9864:     printk("ASC_DVC_VAR at addr %x\n", (unsigned) h);
                   9865: 
                   9866:     printk(
                   9867: " iop_base %x, err_code %x, dvc_cntl %x, bug_fix_cntl %d,\n",
                   9868:         h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
                   9869: 
                   9870:     printk(
                   9871: " bus_type %d, isr_callback %x, exe_callback %x, init_sdtr %x,\n",
                   9872:         h->bus_type, (unsigned) h->isr_callback, (unsigned) h->exe_callback,
                   9873:         (unsigned) h->init_sdtr);
                   9874: 
                   9875:     printk(
                   9876: " sdtr_done %x, use_tagged_qng %x, unit_not_ready %x, chip_no %x,\n",
                   9877:         (unsigned) h->sdtr_done, (unsigned) h->use_tagged_qng,
                   9878:         (unsigned) h->unit_not_ready, (unsigned) h->chip_no);
                   9879:         
                   9880:     printk(
                   9881: " queue_full_or_busy %x, start_motor %x, scsi_reset_wait %x, irq_no %x,\n",
                   9882:         (unsigned) h->queue_full_or_busy, (unsigned) h->start_motor,
                   9883:         (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
                   9884: 
                   9885:     printk(
                   9886: " is_in_int %x, max_total_qng %x, cur_total_qng %x, in_critical_cnt %x,\n",
                   9887:         (unsigned) h->is_in_int, (unsigned) h->max_total_qng,
                   9888:         (unsigned) h->cur_total_qng, (unsigned) h->in_critical_cnt);
                   9889: 
                   9890:     printk(
                   9891: " last_q_shortage %x, init_state %x, no_scam %x, pci_fix_asyn_xfer %x,\n",
                   9892:         (unsigned) h->last_q_shortage, (unsigned) h->init_state,
                   9893:         (unsigned) h->no_scam, (unsigned) h->pci_fix_asyn_xfer);
                   9894: 
                   9895:     printk(
                   9896: " cfg %x, saved_ptr2func %x\n",
                   9897:         (unsigned) h->cfg, (unsigned) h->saved_ptr2func);
                   9898: }
                   9899: 
                   9900: /*
                   9901:  * asc_prt_asc_dvc_cfg()
                   9902:  */
                   9903: STATIC void 
                   9904: asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
                   9905: {
                   9906:     printk("ASC_DVC_CFG at addr %x\n", (unsigned) h);
                   9907: 
                   9908:     printk(
                   9909: " can_tagged_qng %x, cmd_qng_enabled %x, disc_enable %x, sdtr_enable %x,\n",
                   9910:             h->can_tagged_qng, h->cmd_qng_enabled, h->disc_enable,
                   9911:             h->sdtr_enable);
                   9912: 
                   9913:     printk(
                   9914: " chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
                   9915:              h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
                   9916:              h->chip_version);
                   9917: 
                   9918:     printk(
                   9919: " pci_device_id %d, lib_serial_no %x, lib_version %x, mcode_date %x,\n",
                   9920:           h->pci_device_id, h->lib_serial_no, h->lib_version, h->mcode_date);
                   9921: 
                   9922:     printk(
                   9923: " mcode_version %d, overrun_buf %x\n",
                   9924:             h->mcode_version, (unsigned) h->overrun_buf);
                   9925: }
                   9926: 
                   9927: /*
                   9928:  * asc_prt_asc_scsi_q()
                   9929:  */
                   9930: STATIC void 
                   9931: asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
                   9932: {
                   9933:     ASC_SG_HEAD    *sgp;
                   9934:     int i;
                   9935: 
                   9936:     printk("ASC_SCSI_Q at addr %x\n", (unsigned) q);
                   9937: 
                   9938:     printk(
                   9939: " target_ix %u, target_lun %u, srb_ptr %x, tag_code %u,\n",
                   9940:             q->q2.target_ix, q->q1.target_lun,
                   9941:             (unsigned) q->q2.srb_ptr, q->q2.tag_code);
                   9942: 
                   9943:     printk(
                   9944: " data_addr %x, data_cnt %lu, sense_addr %x, sense_len %u,\n",
                   9945:             (unsigned) q->q1.data_addr, q->q1.data_cnt,
                   9946:             (unsigned) q->q1.sense_addr, q->q1.sense_len);
                   9947: 
                   9948:     printk(
                   9949: " cdbptr %x, cdb_len %u, sg_head %x, sg_queue_cnt %u\n",
                   9950:             (unsigned) q->cdbptr, q->q2.cdb_len,
                   9951:             (unsigned) q->sg_head, q->q1.sg_queue_cnt);
                   9952: 
                   9953:     if (q->sg_head) {
                   9954:         sgp = q->sg_head;
                   9955:         printk("ASC_SG_HEAD at addr %x\n", (unsigned) sgp);
                   9956:         printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, sgp->queue_cnt);
                   9957:         for (i = 0; i < sgp->entry_cnt; i++) {
                   9958:             printk(" [%u]: addr %x, bytes %lu\n",
                   9959:                 i, (unsigned) sgp->sg_list[i].addr, sgp->sg_list[i].bytes);
                   9960:         }
                   9961: 
                   9962:     }
                   9963: }
                   9964: 
                   9965: /*
                   9966:  * asc_prt_asc_qdone_info()
                   9967:  */
                   9968: STATIC void 
                   9969: asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
                   9970: {
                   9971:     printk("ASC_QDONE_INFO at addr %x\n", (unsigned) q);
                   9972:     printk(
                   9973: " srb_ptr %x, target_ix %u, cdb_len %u, tag_code %u, done_stat %x\n",
                   9974:             (unsigned) q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
                   9975:             q->d2.tag_code, q->d3.done_stat);
                   9976:     printk(
                   9977: " host_stat %x, scsi_stat %x, scsi_msg %x\n",
                   9978:             q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
                   9979: }
                   9980: 
                   9981: /*
                   9982:  * asc_prt_adv_dvc_var()
                   9983:  *
                   9984:  * Display an ADV_DVC_VAR structure.
                   9985:  */
                   9986: STATIC void 
                   9987: asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
                   9988: {
                   9989:     printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong) h);
                   9990: 
                   9991:     printk(
                   9992: "  iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
                   9993:         (ulong) h->iop_base, h->err_code, (unsigned) h->ultra_able);
                   9994: 
                   9995:     printk(
                   9996: "  isr_callback 0x%x, sdtr_able 0x%x, wdtr_able 0x%x\n",
                   9997:         (unsigned) h->isr_callback, (unsigned) h->wdtr_able,
                   9998:         (unsigned) h->sdtr_able);
                   9999: 
                   10000:     printk(
                   10001: "  start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
                   10002:         (unsigned) h->start_motor,
                   10003:         (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
                   10004: 
                   10005:     printk(
                   10006: "  max_host_qng 0x%x, cur_host_qng 0x%x, max_dvc_qng 0x%x\n",
                   10007:         (unsigned) h->max_host_qng, (unsigned) h->cur_host_qng,
                   10008:         (unsigned) h->max_dvc_qng);
                   10009: 
                   10010:     printk(
                   10011: "  no_scam 0x%x, tagqng_able 0x%x, chip_scsi_id 0x%x, cfg 0x%lx\n",
                   10012:         (unsigned) h->no_scam, (unsigned) h->tagqng_able,
                   10013:         (unsigned) h->chip_scsi_id, (ulong) h->cfg);
                   10014: 
                   10015: }
                   10016: 
                   10017: /*
                   10018:  * asc_prt_adv_dvc_cfg()
                   10019:  *
                   10020:  * Display an ADV_DVC_CFG structure.
                   10021:  */
                   10022: STATIC void 
                   10023: asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
                   10024: {
                   10025:     printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong) h);
                   10026: 
                   10027:     printk(
                   10028: "  disc_enable 0x%x, termination 0x%x\n",
                   10029:         h->disc_enable, h->termination);
                   10030: 
                   10031:     printk(
                   10032: "  chip_version 0x%x, mcode_date 0x%x\n",
                   10033:         h->chip_version, h->mcode_date);
                   10034: 
                   10035:     printk(
                   10036: "  mcode_version 0x%x, pci_device_id 0x%x, lib_version 0x%x\n",
                   10037:        h->mcode_version, h->pci_device_id, h->lib_version);
                   10038: 
                   10039:     printk(
                   10040: "  control_flag 0x%x, pci_slot_info 0x%x\n",
                   10041:        h->control_flag, h->pci_slot_info);
                   10042: }
                   10043: 
                   10044: /*
                   10045:  * asc_prt_adv_scsi_req_q()
                   10046:  *
                   10047:  * Display an ADV_SCSI_REQ_Q structure.
                   10048:  */
                   10049: STATIC void 
                   10050: asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
                   10051: {
                   10052:     int                 i;
                   10053:     struct asc_sg_block *sg_ptr;
                   10054: 
                   10055:     printk("ADV_SCSI_REQ_Q at addr %x\n", (unsigned) q);
                   10056: 
                   10057:     printk(
                   10058: "  target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
                   10059:             q->target_id, q->target_lun, q->srb_ptr, q->a_flag);
                   10060: 
                   10061:     printk("  cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
                   10062:             q->cntl, q->data_addr, q->vdata_addr);
                   10063: 
                   10064:     printk(
                   10065: "  data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
                   10066:             q->data_cnt, q->sense_addr, q->sense_len);
                   10067: 
                   10068:     printk(
                   10069: "  cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
                   10070:             q->cdb_len, q->done_status, q->host_status, q->scsi_status);
                   10071: 
                   10072:     printk(
                   10073: "  vsense_addr 0x%lx, scsiq_ptr 0x%lx, ux_wk_data_cnt %lu\n",
                   10074:             (ulong) q->vsense_addr, (ulong) q->scsiq_ptr,
                   10075:             (ulong) q->ux_wk_data_cnt);
                   10076: 
                   10077:     printk(
                   10078: "  sg_list_ptr 0x%lx, sg_real_addr 0x%lx, sg_entry_cnt %u\n",
                   10079:             (ulong) q->sg_list_ptr, (ulong) q->sg_real_addr, q->sg_entry_cnt);
                   10080: 
                   10081:     printk(
                   10082: "  ux_sg_ix %u, orig_sense_len %u\n",
                   10083:             q->ux_sg_ix, q->orig_sense_len);
                   10084: 
                   10085:     /* Display the request's ADV_SG_BLOCK structures. */
                   10086:     for (sg_ptr = q->sg_list_ptr, i = 0; sg_ptr != NULL;
                   10087:         sg_ptr = sg_ptr->sg_ptr, i++) {
                   10088:         /*
                   10089:          * 'sg_ptr' is a physical address. Convert it to a virtual
                   10090:          * address by indexing 'i' into the virtual address array
                   10091:          * 'sg_list_ptr'.
                   10092:          *
                   10093:          * At the end of the each iteration of the loop 'sg_ptr' is
                   10094:          * converted back into a physical address by setting 'sg_ptr'
                   10095:          *  to the next pointer 'sg_ptr->sg_ptr'.
                   10096:          */
                   10097:         sg_ptr = &(((ADV_SG_BLOCK *) (q->sg_list_ptr))[i]);
                   10098:         asc_prt_adv_sgblock(i, sg_ptr);
                   10099:     }
                   10100: }
                   10101: 
                   10102: /*
                   10103:  * asc_prt_adv_sgblock()
                   10104:  *
                   10105:  * Display an ADV_SG_BLOCK structure.
                   10106:  */
                   10107: STATIC void
                   10108: asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
                   10109: {
                   10110:     int i, s;
                   10111: 
                   10112:     /* Calculate starting entry number for the current block. */
                   10113:     s = sgblockno * NO_OF_SG_PER_BLOCK;
                   10114: 
                   10115:     printk(" ADV_SG_BLOCK at addr 0x%lx (sgblockno %lu)\n",
                   10116:         (ulong) b, (ulong) sgblockno);
                   10117:     printk(
                   10118: "  first_entry_no %lu, last_entry_no %lu, sg_ptr 0x%lx\n",
                   10119:         (ulong) b->first_entry_no, (ulong) b->last_entry_no, (ulong) b->sg_ptr);
                   10120:     ASC_ASSERT(b->first_entry_no - s >= 0);
                   10121:     ASC_ASSERT(b->last_entry_no - s >= 0);
                   10122:     ASC_ASSERT(b->last_entry_no - s <= NO_OF_SG_PER_BLOCK);
                   10123:     ASC_ASSERT(b->first_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 <= b->last_entry_no - s);
                   10126:     for (i = b->first_entry_no - s; i <= b->last_entry_no - s; i++) {
                   10127:         printk("  [%lu]: sg_addr 0x%lx, sg_count 0x%lx\n",
                   10128:             (ulong) i, (ulong) b->sg_list[i].sg_addr,
                   10129:             (ulong) b->sg_list[i].sg_count);
                   10130:     }
                   10131: }
                   10132: 
                   10133: /*
                   10134:  * asc_prt_hex()
                   10135:  *
                   10136:  * Print hexadecimal output in 4 byte groupings 32 bytes 
                   10137:  * or 8 double-words per line.
                   10138:  */
                   10139: STATIC void 
                   10140: asc_prt_hex(char *f, uchar *s, int l)
                   10141: {
                   10142:     int            i;
                   10143:     int            j;
                   10144:     int            k;
                   10145:     int            m;
                   10146: 
                   10147:     printk("%s: (%d bytes)\n", f, l);
                   10148: 
                   10149:     for (i = 0; i < l; i += 32) {
                   10150:         
                   10151:         /* Display a maximum of 8 double-words per line. */
                   10152:         if ((k = (l - i) / 4) >= 8) {
                   10153:             k = 8;
                   10154:             m = 0;
                   10155:         } else {
                   10156:             m = (l - i) % 4 ;
                   10157:         }
                   10158: 
                   10159:         for (j = 0; j < k; j++) {
                   10160:             printk(" %2.2X%2.2X%2.2X%2.2X",
                   10161:                 (unsigned) s[i+(j*4)], (unsigned) s[i+(j*4)+1],
                   10162:                 (unsigned) s[i+(j*4)+2], (unsigned) s[i+(j*4)+3]);
                   10163:         }
                   10164: 
                   10165:         switch (m) {
                   10166:         case 0:
                   10167:         default:
                   10168:             break;
                   10169:         case 1:
                   10170:             printk(" %2.2X",
                   10171:                 (unsigned) s[i+(j*4)]);
                   10172:             break;
                   10173:         case 2:
                   10174:             printk(" %2.2X%2.2X",
                   10175:                 (unsigned) s[i+(j*4)],
                   10176:                 (unsigned) s[i+(j*4)+1]);
                   10177:             break;
                   10178:         case 3:
                   10179:             printk(" %2.2X%2.2X%2.2X",
                   10180:                 (unsigned) s[i+(j*4)+1],
                   10181:                 (unsigned) s[i+(j*4)+2],
                   10182:                 (unsigned) s[i+(j*4)+3]);
                   10183:             break;
                   10184:         }
                   10185: 
                   10186:         printk("\n");
                   10187:     }
                   10188: }
                   10189: #endif /* ADVANSYS_DEBUG */
                   10190: 
                   10191: #ifdef ADVANSYS_ASSERT
                   10192: /*
                   10193:  * interrupts_enabled()
                   10194:  *
                   10195:  * Return 1 if interrupts are enabled, otherwise return 0.
                   10196:  */
                   10197: STATIC int
                   10198: interrupts_enabled(void)
                   10199: {
1.1.1.2   root     10200:     long flags;
1.1       root     10201: 
                   10202:     save_flags(flags);
                   10203:     if (flags & 0x0200) {
                   10204:         return ASC_TRUE;
                   10205:     } else {
                   10206:         return ASC_FALSE;
                   10207:     }
                   10208: }
                   10209: #endif /* ADVANSYS_ASSERT */
                   10210: 
                   10211: 
                   10212: /*
                   10213:  * --- Asc Library Functions
                   10214:  */
                   10215: 
                   10216: ASC_INITFUNC(
                   10217: STATIC ushort
                   10218: AscGetEisaChipCfg(
                   10219:                      PortAddr iop_base
                   10220: )
                   10221: )
                   10222: {
                   10223:     PortAddr            eisa_cfg_iop;
                   10224: 
                   10225:     eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
                   10226:       (PortAddr) (ASC_EISA_CFG_IOP_MASK);
                   10227:     return (inpw(eisa_cfg_iop));
                   10228: }
                   10229: 
                   10230: ASC_INITFUNC(
                   10231: STATIC uchar
                   10232: AscSetChipScsiID(
                   10233:                     PortAddr iop_base,
                   10234:                     uchar new_host_id
                   10235: )
                   10236: )
                   10237: {
                   10238:     ushort              cfg_lsw;
                   10239: 
                   10240:     if (AscGetChipScsiID(iop_base) == new_host_id) {
                   10241:         return (new_host_id);
                   10242:     }
                   10243:     cfg_lsw = AscGetChipCfgLsw(iop_base);
                   10244:     cfg_lsw &= 0xF8FF;
                   10245:     cfg_lsw |= (ushort) ((new_host_id & ASC_MAX_TID) << 8);
                   10246:     AscSetChipCfgLsw(iop_base, cfg_lsw);
                   10247:     return (AscGetChipScsiID(iop_base));
                   10248: }
                   10249: 
                   10250: ASC_INITFUNC(
                   10251: STATIC uchar
                   10252: AscGetChipScsiCtrl(
                   10253:                       PortAddr iop_base
                   10254: )
                   10255: )
                   10256: {
                   10257:     uchar               sc;
                   10258: 
                   10259:     AscSetBank(iop_base, 1);
                   10260:     sc = inp(iop_base + IOP_REG_SC);
                   10261:     AscSetBank(iop_base, 0);
                   10262:     return (sc);
                   10263: }
                   10264: 
                   10265: ASC_INITFUNC(
                   10266: STATIC uchar
                   10267: AscGetChipVersion(
                   10268:                      PortAddr iop_base,
                   10269:                      ushort bus_type
                   10270: )
                   10271: )
                   10272: {
                   10273:     if ((bus_type & ASC_IS_EISA) != 0) {
                   10274:         PortAddr            eisa_iop;
                   10275:         uchar               revision;
                   10276:         eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
                   10277:           (PortAddr) ASC_EISA_REV_IOP_MASK;
                   10278:         revision = inp(eisa_iop);
                   10279:         return ((uchar) ((ASC_CHIP_MIN_VER_EISA - 1) + revision));
                   10280:     }
                   10281:     return (AscGetChipVerNo(iop_base));
                   10282: }
                   10283: 
                   10284: ASC_INITFUNC(
                   10285: STATIC ushort
                   10286: AscGetChipBusType(
                   10287:                      PortAddr iop_base
                   10288: )
                   10289: )
                   10290: {
                   10291:     ushort              chip_ver;
                   10292: 
                   10293:     chip_ver = AscGetChipVerNo(iop_base);
                   10294:     if (
                   10295:            (chip_ver >= ASC_CHIP_MIN_VER_VL)
                   10296:            && (chip_ver <= ASC_CHIP_MAX_VER_VL)
                   10297: ) {
                   10298:         if (
                   10299:                ((iop_base & 0x0C30) == 0x0C30)
                   10300:                || ((iop_base & 0x0C50) == 0x0C50)
                   10301: ) {
                   10302:             return (ASC_IS_EISA);
                   10303:         }
                   10304:         return (ASC_IS_VL);
                   10305:     }
                   10306:     if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
                   10307:         (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
                   10308:         if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
                   10309:             return (ASC_IS_ISAPNP);
                   10310:         }
                   10311:         return (ASC_IS_ISA);
                   10312:     } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
                   10313:                (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
                   10314:         return (ASC_IS_PCI);
                   10315:     }
                   10316:     return (0);
                   10317: }
                   10318: 
                   10319: ASC_INITFUNC(
                   10320: STATIC ulong
                   10321: AscLoadMicroCode(
                   10322:                     PortAddr iop_base,
                   10323:                     ushort s_addr,
                   10324:                     ushort *mcode_buf,
                   10325:                     ushort mcode_size
                   10326: )
                   10327: )
                   10328: {
                   10329:     ulong               chksum;
                   10330:     ushort              mcode_word_size;
                   10331:     ushort              mcode_chksum;
                   10332: 
                   10333:     mcode_word_size = (ushort) (mcode_size >> 1);
                   10334:     AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
                   10335:     AscMemWordCopyToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
                   10336:     chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
                   10337:     mcode_chksum = (ushort) AscMemSumLramWord(iop_base,
                   10338:                                               (ushort) ASC_CODE_SEC_BEG,
                   10339:           (ushort) ((mcode_size - s_addr - (ushort) ASC_CODE_SEC_BEG) / 2));
                   10340:     AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
                   10341:     AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
                   10342:     return (chksum);
                   10343: }
                   10344: 
                   10345: ASC_INITFUNC(
                   10346: STATIC int
                   10347: AscFindSignature(
                   10348:                     PortAddr iop_base
                   10349: )
                   10350: )
                   10351: {
                   10352:     ushort              sig_word;
                   10353: 
                   10354:     if (AscGetChipSignatureByte(iop_base) == (uchar) ASC_1000_ID1B) {
                   10355:         sig_word = AscGetChipSignatureWord(iop_base);
                   10356:         if ((sig_word == (ushort) ASC_1000_ID0W) ||
                   10357:             (sig_word == (ushort) ASC_1000_ID0W_FIX)) {
                   10358:             return (1);
                   10359:         }
                   10360:     }
                   10361:     return (0);
                   10362: }
                   10363: 
                   10364: STATIC uchar _isa_pnp_inited ASC_INITDATA = 0;
                   10365: STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] ASC_INITDATA =
                   10366: {
                   10367:     0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
                   10368:     ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
                   10369: };
                   10370: 
                   10371: ASC_INITFUNC(
                   10372: STATIC PortAddr
                   10373: AscSearchIOPortAddr(
                   10374:                        PortAddr iop_beg,
                   10375:                        ushort bus_type
                   10376: )
                   10377: )
                   10378: {
                   10379:     if (bus_type & ASC_IS_VL) {
                   10380:         while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
                   10381:             if (AscGetChipVersion(iop_beg, bus_type) <= ASC_CHIP_MAX_VER_VL) {
                   10382:                 return (iop_beg);
                   10383:             }
                   10384:         }
                   10385:         return (0);
                   10386:     }
                   10387:     if (bus_type & ASC_IS_ISA) {
                   10388:         if (_isa_pnp_inited == 0) {
                   10389:             AscSetISAPNPWaitForKey();
                   10390:             _isa_pnp_inited++;
                   10391:         }
                   10392:         while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
                   10393:             if ((AscGetChipVersion(iop_beg, bus_type) & ASC_CHIP_VER_ISA_BIT) != 0) {
                   10394:                 return (iop_beg);
                   10395:             }
                   10396:         }
                   10397:         return (0);
                   10398:     }
                   10399:     if (bus_type & ASC_IS_EISA) {
                   10400:         if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) {
                   10401:             return (iop_beg);
                   10402:         }
                   10403:         return (0);
                   10404:     }
                   10405:     return (0);
                   10406: }
                   10407: 
                   10408: ASC_INITFUNC(
                   10409: STATIC PortAddr
                   10410: AscSearchIOPortAddr11(
                   10411:                          PortAddr s_addr
                   10412: )
                   10413: )
                   10414: {
                   10415:     int                 i;
                   10416:     PortAddr            iop_base;
                   10417: 
                   10418:     for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) {
                   10419:         if (_asc_def_iop_base[i] > s_addr) {
                   10420:             break;
                   10421:         }
                   10422:     }
                   10423:     for (; i < ASC_IOADR_TABLE_MAX_IX; i++) {
                   10424:         iop_base = _asc_def_iop_base[i];
                   10425:         if (check_region(iop_base, ASC_IOADR_GAP) != 0) {
                   10426:             ASC_DBG1(1,
                   10427:                "AscSearchIOPortAddr11: check_region() failed I/O port %x\n",
                   10428:                      iop_base);
                   10429:             continue;
                   10430:         }
                   10431:         ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port %x\n", iop_base);
                   10432:         if (AscFindSignature(iop_base)) {
                   10433:             return (iop_base);
                   10434:         }
                   10435:     }
                   10436:     return (0);
                   10437: }
                   10438: 
                   10439: ASC_INITFUNC(
                   10440: STATIC void
                   10441: AscToggleIRQAct(
                   10442:                    PortAddr iop_base
                   10443: )
                   10444: )
                   10445: {
                   10446:     AscSetChipStatus(iop_base, CIW_IRQ_ACT);
                   10447:     AscSetChipStatus(iop_base, 0);
                   10448:     return;
                   10449: }
                   10450: 
                   10451: ASC_INITFUNC(
                   10452: STATIC void
                   10453: AscSetISAPNPWaitForKey(
                   10454:     void)
                   10455: )
                   10456: {
                   10457:     outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
                   10458:     outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
                   10459:     return;
                   10460: }
                   10461: 
                   10462: ASC_INITFUNC(
                   10463: STATIC uchar
                   10464: AscGetChipIRQ(
                   10465:                  PortAddr iop_base,
                   10466:                  ushort bus_type
                   10467: )
                   10468: )
                   10469: {
                   10470:     ushort              cfg_lsw;
                   10471:     uchar               chip_irq;
                   10472: 
                   10473:     if ((bus_type & ASC_IS_EISA) != 0) {
                   10474:         cfg_lsw = AscGetEisaChipCfg(iop_base);
                   10475:         chip_irq = (uchar) (((cfg_lsw >> 8) & 0x07) + 10);
                   10476:         if ((chip_irq == 13) || (chip_irq > 15)) {
                   10477:             return (0);
                   10478:         }
                   10479:         return (chip_irq);
                   10480:     }
                   10481:     if ((bus_type & ASC_IS_VL) != 0) {
                   10482:         cfg_lsw = AscGetChipCfgLsw(iop_base);
                   10483:         chip_irq = (uchar) (((cfg_lsw >> 2) & 0x07));
                   10484:         if ((chip_irq == 0) ||
                   10485:             (chip_irq == 4) ||
                   10486:             (chip_irq == 7)) {
                   10487:             return (0);
                   10488:         }
                   10489:         return ((uchar) (chip_irq + (ASC_MIN_IRQ_NO - 1)));
                   10490:     }
                   10491:     cfg_lsw = AscGetChipCfgLsw(iop_base);
                   10492:     chip_irq = (uchar) (((cfg_lsw >> 2) & 0x03));
                   10493:     if (chip_irq == 3)
                   10494:         chip_irq += (uchar) 2;
                   10495:     return ((uchar) (chip_irq + ASC_MIN_IRQ_NO));
                   10496: }
                   10497: 
                   10498: ASC_INITFUNC(
                   10499: STATIC uchar
                   10500: AscSetChipIRQ(
                   10501:                  PortAddr iop_base,
                   10502:                  uchar irq_no,
                   10503:                  ushort bus_type
                   10504: )
                   10505: )
                   10506: {
                   10507:     ushort              cfg_lsw;
                   10508: 
                   10509:     if ((bus_type & ASC_IS_VL) != 0) {
                   10510:         if (irq_no != 0) {
                   10511:             if ((irq_no < ASC_MIN_IRQ_NO) || (irq_no > ASC_MAX_IRQ_NO)) {
                   10512:                 irq_no = 0;
                   10513:             } else {
                   10514:                 irq_no -= (uchar) ((ASC_MIN_IRQ_NO - 1));
                   10515:             }
                   10516:         }
                   10517:         cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE3);
                   10518:         cfg_lsw |= (ushort) 0x0010;
                   10519:         AscSetChipCfgLsw(iop_base, cfg_lsw);
                   10520:         AscToggleIRQAct(iop_base);
                   10521:         cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE0);
                   10522:         cfg_lsw |= (ushort) ((irq_no & 0x07) << 2);
                   10523:         AscSetChipCfgLsw(iop_base, cfg_lsw);
                   10524:         AscToggleIRQAct(iop_base);
                   10525:         return (AscGetChipIRQ(iop_base, bus_type));
                   10526:     }
                   10527:     if ((bus_type & (ASC_IS_ISA)) != 0) {
                   10528:         if (irq_no == 15)
                   10529:             irq_no -= (uchar) 2;
                   10530:         irq_no -= (uchar) ASC_MIN_IRQ_NO;
                   10531:         cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFF3);
                   10532:         cfg_lsw |= (ushort) ((irq_no & 0x03) << 2);
                   10533:         AscSetChipCfgLsw(iop_base, cfg_lsw);
                   10534:         return (AscGetChipIRQ(iop_base, bus_type));
                   10535:     }
                   10536:     return (0);
                   10537: }
                   10538: 
                   10539: ASC_INITFUNC(
                   10540: STATIC void
                   10541: AscEnableIsaDma(
                   10542:                    uchar dma_channel
                   10543: )
                   10544: )
                   10545: {
                   10546:     if (dma_channel < 4) {
                   10547:         outp(0x000B, (ushort) (0xC0 | dma_channel));
                   10548:         outp(0x000A, dma_channel);
                   10549:     } else if (dma_channel < 8) {
                   10550:         outp(0x00D6, (ushort) (0xC0 | (dma_channel - 4)));
                   10551:         outp(0x00D4, (ushort) (dma_channel - 4));
                   10552:     }
                   10553:     return;
                   10554: }
                   10555: 
                   10556: STATIC int 
                   10557: AscIsrChipHalted(
                   10558:                     REG ASC_DVC_VAR asc_ptr_type * asc_dvc
                   10559: )
                   10560: {
                   10561:     EXT_MSG             ext_msg;
                   10562:     EXT_MSG             out_msg;
                   10563:     ushort              halt_q_addr;
                   10564:     int                 sdtr_accept;
                   10565:     ushort              int_halt_code;
                   10566:     ASC_SCSI_BIT_ID_TYPE scsi_busy;
                   10567:     ASC_SCSI_BIT_ID_TYPE target_id;
                   10568:     PortAddr            iop_base;
                   10569:     uchar               tag_code;
                   10570:     uchar               q_status;
                   10571:     uchar               halt_qp;
                   10572:     uchar               sdtr_data;
                   10573:     uchar               target_ix;
                   10574:     uchar               q_cntl, tid_no;
                   10575:     uchar               cur_dvc_qng;
                   10576:     uchar               asyn_sdtr;
                   10577:     uchar               scsi_status;
                   10578:     asc_board_t            *boardp;
                   10579: 
                   10580:     ASC_ASSERT(asc_dvc->drv_ptr != 0);
                   10581:     boardp = (asc_board_t *) asc_dvc->drv_ptr;
                   10582: 
                   10583:     iop_base = asc_dvc->iop_base;
                   10584:     int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
                   10585: 
                   10586:     halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
                   10587:     halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
                   10588:     target_ix = AscReadLramByte(iop_base,
                   10589:                    (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TARGET_IX));
                   10590:     q_cntl = AscReadLramByte(iop_base,
                   10591:                         (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL));
                   10592:     tid_no = ASC_TIX_TO_TID(target_ix);
                   10593:     target_id = (uchar) ASC_TID_TO_TARGET_ID(tid_no);
                   10594:     if (asc_dvc->pci_fix_asyn_xfer & target_id) {
                   10595: 
                   10596:         asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
                   10597:     } else {
                   10598:         asyn_sdtr = 0;
                   10599:     }
                   10600:     if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
                   10601:         if (asc_dvc->pci_fix_asyn_xfer & target_id) {
                   10602:             AscSetChipSDTR(iop_base, 0, tid_no);
                   10603:             boardp->sdtr_data[tid_no] = 0;
                   10604:         }
                   10605:         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
                   10606:         return (0);
                   10607:     } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
                   10608:         if (asc_dvc->pci_fix_asyn_xfer & target_id) {
                   10609:             AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
                   10610:             boardp->sdtr_data[tid_no] = asyn_sdtr;
                   10611:         }
                   10612:         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
                   10613:         return (0);
                   10614:     } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
                   10615: 
                   10616:         AscMemWordCopyFromLram(iop_base,
                   10617:                                ASCV_MSGIN_BEG,
                   10618:                                (ushort *) & ext_msg,
                   10619:                                (ushort) (sizeof (EXT_MSG) >> 1));
                   10620: 
                   10621:         if (ext_msg.msg_type == MS_EXTEND &&
                   10622:             ext_msg.msg_req == MS_SDTR_CODE &&
                   10623:             ext_msg.msg_len == MS_SDTR_LEN) {
                   10624:             sdtr_accept = TRUE;
                   10625:             if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
                   10626: 
                   10627:                 sdtr_accept = FALSE;
                   10628:                 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
                   10629:             }
                   10630:             if ((ext_msg.xfer_period <
                   10631:                  asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index]) ||
                   10632:                 (ext_msg.xfer_period >
                   10633:                  asc_dvc->sdtr_period_tbl[asc_dvc->max_sdtr_index])) {
                   10634:                 sdtr_accept = FALSE;
                   10635:                 ext_msg.xfer_period =
                   10636:                     asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index];
                   10637:             }
                   10638:             if (sdtr_accept) {
                   10639:                 sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
                   10640:                                            ext_msg.req_ack_offset);
                   10641:                 if ((sdtr_data == 0xFF)) {
                   10642: 
                   10643:                     q_cntl |= QC_MSG_OUT;
                   10644:                     asc_dvc->init_sdtr &= ~target_id;
                   10645:                     asc_dvc->sdtr_done &= ~target_id;
                   10646:                     AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
                   10647:                     boardp->sdtr_data[tid_no] = asyn_sdtr;
                   10648:                 }
                   10649:             }
                   10650:             if (ext_msg.req_ack_offset == 0) {
                   10651: 
                   10652:                 q_cntl &= ~QC_MSG_OUT;
                   10653:                 asc_dvc->init_sdtr &= ~target_id;
                   10654:                 asc_dvc->sdtr_done &= ~target_id;
                   10655:                 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
                   10656:             } else {
                   10657:                 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
                   10658: 
                   10659:                     q_cntl &= ~QC_MSG_OUT;
                   10660:                     asc_dvc->sdtr_done |= target_id;
                   10661:                     asc_dvc->init_sdtr |= target_id;
                   10662:                     asc_dvc->pci_fix_asyn_xfer &= ~target_id;
                   10663:                     sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
                   10664:                                                ext_msg.req_ack_offset);
                   10665:                     AscSetChipSDTR(iop_base, sdtr_data, tid_no);
                   10666:                     boardp->sdtr_data[tid_no] = sdtr_data;
                   10667:                 } else {
                   10668: 
                   10669:                     q_cntl |= QC_MSG_OUT;
                   10670:                     AscMsgOutSDTR(asc_dvc,
                   10671:                                   ext_msg.xfer_period,
                   10672:                                   ext_msg.req_ack_offset);
                   10673:                     asc_dvc->pci_fix_asyn_xfer &= ~target_id;
                   10674:                     sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
                   10675:                                                ext_msg.req_ack_offset);
                   10676:                     AscSetChipSDTR(iop_base, sdtr_data, tid_no);
                   10677:                     boardp->sdtr_data[tid_no] = sdtr_data;
                   10678:                     asc_dvc->sdtr_done |= target_id;
                   10679:                     asc_dvc->init_sdtr |= target_id;
                   10680:                 }
                   10681:             }
                   10682: 
                   10683:             AscWriteLramByte(iop_base,
                   10684:                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
                   10685:                              q_cntl);
                   10686:             AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
                   10687:             return (0);
                   10688:         } else if (ext_msg.msg_type == MS_EXTEND &&
                   10689:                    ext_msg.msg_req == MS_WDTR_CODE &&
                   10690:                    ext_msg.msg_len == MS_WDTR_LEN) {
                   10691: 
                   10692:             ext_msg.wdtr_width = 0;
                   10693:             AscMemWordCopyToLram(iop_base,
                   10694:                                  ASCV_MSGOUT_BEG,
                   10695:                                  (ushort *) & ext_msg,
                   10696:                                  (ushort) (sizeof (EXT_MSG) >> 1));
                   10697:             q_cntl |= QC_MSG_OUT;
                   10698:             AscWriteLramByte(iop_base,
                   10699:                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
                   10700:                              q_cntl);
                   10701:             AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
                   10702:             return (0);
                   10703:         } else {
                   10704: 
                   10705:             ext_msg.msg_type = M1_MSG_REJECT;
                   10706:             AscMemWordCopyToLram(iop_base,
                   10707:                                  ASCV_MSGOUT_BEG,
                   10708:                                  (ushort *) & ext_msg,
                   10709:                                  (ushort) (sizeof (EXT_MSG) >> 1));
                   10710:             q_cntl |= QC_MSG_OUT;
                   10711:             AscWriteLramByte(iop_base,
                   10712:                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
                   10713:                              q_cntl);
                   10714:             AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
                   10715:             return (0);
                   10716:         }
                   10717:     } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
                   10718: 
                   10719:         q_cntl |= QC_REQ_SENSE;
                   10720: 
                   10721:         if ((asc_dvc->init_sdtr & target_id) != 0) {
                   10722: 
                   10723:             asc_dvc->sdtr_done &= ~target_id;
                   10724: 
                   10725:             sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
                   10726:             q_cntl |= QC_MSG_OUT;
                   10727:             AscMsgOutSDTR(asc_dvc,
                   10728:                           asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
                   10729:                            (uchar) (asc_dvc->max_sdtr_index - 1)],
                   10730:                           (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
                   10731:         }
                   10732: 
                   10733:         AscWriteLramByte(iop_base,
                   10734:                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
                   10735:                          q_cntl);
                   10736: 
                   10737:         tag_code = AscReadLramByte(iop_base,
                   10738:                     (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE));
                   10739:         tag_code &= 0xDC;
                   10740:         if (
                   10741:                (asc_dvc->pci_fix_asyn_xfer & target_id)
                   10742:                && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
                   10743: ) {
                   10744: 
                   10745:             tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
                   10746:                          | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
                   10747: 
                   10748:         }
                   10749:         AscWriteLramByte(iop_base,
                   10750:                      (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE),
                   10751:                          tag_code);
                   10752: 
                   10753:         q_status = AscReadLramByte(iop_base,
                   10754:                       (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS));
                   10755:         q_status |= (QS_READY | QS_BUSY);
                   10756:         AscWriteLramByte(iop_base,
                   10757:                        (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
                   10758:                          q_status);
                   10759: 
                   10760:         scsi_busy = AscReadLramByte(iop_base,
                   10761:                                     (ushort) ASCV_SCSIBUSY_B);
                   10762:         scsi_busy &= ~target_id;
                   10763:         AscWriteLramByte(iop_base, (ushort) ASCV_SCSIBUSY_B, scsi_busy);
                   10764: 
                   10765:         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
                   10766:         return (0);
                   10767:     } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
                   10768: 
                   10769:         AscMemWordCopyFromLram(iop_base,
                   10770:                                ASCV_MSGOUT_BEG,
                   10771:                                (ushort *) & out_msg,
                   10772:                                (ushort) (sizeof (EXT_MSG) >> 1));
                   10773: 
                   10774:         if ((out_msg.msg_type == MS_EXTEND) &&
                   10775:             (out_msg.msg_len == MS_SDTR_LEN) &&
                   10776:             (out_msg.msg_req == MS_SDTR_CODE)) {
                   10777: 
                   10778:             asc_dvc->init_sdtr &= ~target_id;
                   10779:             asc_dvc->sdtr_done &= ~target_id;
                   10780:             AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
                   10781:             boardp->sdtr_data[tid_no] = asyn_sdtr;
                   10782:         }
                   10783:         q_cntl &= ~QC_MSG_OUT;
                   10784:         AscWriteLramByte(iop_base,
                   10785:                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
                   10786:                          q_cntl);
                   10787:         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
                   10788:         return (0);
                   10789:     } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
                   10790: 
                   10791:         scsi_status = AscReadLramByte(iop_base,
                   10792:           (ushort) ((ushort) halt_q_addr + (ushort) ASC_SCSIQ_SCSI_STATUS));
                   10793:         cur_dvc_qng = AscReadLramByte(iop_base,
                   10794:                      (ushort) ((ushort) ASC_QADR_BEG + (ushort) target_ix));
                   10795:         if ((cur_dvc_qng > 0) &&
                   10796:             (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
                   10797: 
                   10798:             scsi_busy = AscReadLramByte(iop_base,
                   10799:                                         (ushort) ASCV_SCSIBUSY_B);
                   10800:             scsi_busy |= target_id;
                   10801:             AscWriteLramByte(iop_base,
                   10802:                              (ushort) ASCV_SCSIBUSY_B, scsi_busy);
                   10803:             asc_dvc->queue_full_or_busy |= target_id;
                   10804: 
                   10805:             if (scsi_status == SS_QUEUE_FULL) {
                   10806:                 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
                   10807:                     cur_dvc_qng -= 1;
                   10808:                     asc_dvc->max_dvc_qng[tid_no] = cur_dvc_qng;
                   10809: 
                   10810:                     AscWriteLramByte(iop_base,
                   10811:                           (ushort) ((ushort) ASCV_MAX_DVC_QNG_BEG +
                   10812:                            (ushort) tid_no),
                   10813:                           cur_dvc_qng);
                   10814: 
                   10815:                     /*
                   10816:                      * Set the device queue depth to the number of
                   10817:                      * active requests when the QUEUE FULL condition
                   10818:                      * was encountered.
                   10819:                      */
                   10820:                     boardp->queue_full |= target_id;
                   10821:                     boardp->queue_full_cnt[tid_no] = cur_dvc_qng;
                   10822: #if ASC_QUEUE_FLOW_CONTROL
                   10823:                     if (boardp->device[tid_no] != NULL &&
                   10824:                         boardp->device[tid_no]->queue_curr_depth >
                   10825:                         cur_dvc_qng) {
                   10826:                         boardp->device[tid_no]->queue_curr_depth =
                   10827:                             cur_dvc_qng;
                   10828:                     }
                   10829: #endif /* ASC_QUEUE_FLOW_CONTROL */
                   10830:                 }
                   10831:             }
                   10832:         }
                   10833:         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
                   10834:         return (0);
                   10835:     }
                   10836:     return (0);
                   10837: }
                   10838: 
                   10839: STATIC uchar
                   10840: _AscCopyLramScsiDoneQ(
                   10841:                          PortAddr iop_base,
                   10842:                          ushort q_addr,
                   10843:                          REG ASC_QDONE_INFO * scsiq,
                   10844:                          ulong max_dma_count
                   10845: )
                   10846: {
                   10847:     ushort              _val;
                   10848:     uchar               sg_queue_cnt;
                   10849: 
                   10850:     DvcGetQinfo(iop_base,
                   10851:                 (ushort) (q_addr + (ushort) ASC_SCSIQ_DONE_INFO_BEG),
                   10852:                 (ushort *) scsiq,
                   10853:               (ushort) ((sizeof (ASC_SCSIQ_2) + sizeof (ASC_SCSIQ_3)) / 2));
                   10854:     _val = AscReadLramWord(iop_base,
                   10855:                            (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS));
                   10856:     scsiq->q_status = (uchar) _val;
                   10857:     scsiq->q_no = (uchar) (_val >> 8);
                   10858:     _val = AscReadLramWord(iop_base,
                   10859:                            (ushort) (q_addr + (ushort) ASC_SCSIQ_B_CNTL));
                   10860:     scsiq->cntl = (uchar) _val;
                   10861:     sg_queue_cnt = (uchar) (_val >> 8);
                   10862:     _val = AscReadLramWord(iop_base,
                   10863:                         (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SENSE_LEN));
                   10864:     scsiq->sense_len = (uchar) _val;
                   10865:     scsiq->extra_bytes = (uchar) (_val >> 8);
                   10866:     scsiq->remain_bytes = AscReadLramWord(iop_base,
                   10867:                  (ushort) (q_addr + (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT));
                   10868:     scsiq->remain_bytes &= max_dma_count;
                   10869:     return (sg_queue_cnt);
                   10870: }
                   10871: 
                   10872: STATIC int
                   10873: AscIsrQDone(
                   10874:                REG ASC_DVC_VAR asc_ptr_type * asc_dvc
                   10875: )
                   10876: {
                   10877:     uchar               next_qp;
                   10878:     uchar               n_q_used;
                   10879:     uchar               sg_list_qp;
                   10880:     uchar               sg_queue_cnt;
                   10881:     uchar               q_cnt;
                   10882:     uchar               done_q_tail;
                   10883:     uchar               tid_no;
                   10884:     ASC_SCSI_BIT_ID_TYPE scsi_busy;
                   10885:     ASC_SCSI_BIT_ID_TYPE target_id;
                   10886:     PortAddr            iop_base;
                   10887:     ushort              q_addr;
                   10888:     ushort              sg_q_addr;
                   10889:     uchar               cur_target_qng;
                   10890:     ASC_QDONE_INFO      scsiq_buf;
                   10891:     REG ASC_QDONE_INFO *scsiq;
                   10892:     int                 false_overrun;
                   10893:     ASC_ISR_CALLBACK    asc_isr_callback;
                   10894: 
                   10895:     iop_base = asc_dvc->iop_base;
                   10896:     asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
                   10897:     n_q_used = 1;
                   10898:     scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
                   10899:     done_q_tail = (uchar) AscGetVarDoneQTail(iop_base);
                   10900:     q_addr = ASC_QNO_TO_QADDR(done_q_tail);
                   10901:     next_qp = AscReadLramByte(iop_base,
                   10902:                               (ushort) (q_addr + (ushort) ASC_SCSIQ_B_FWD));
                   10903:     if (next_qp != ASC_QLINK_END) {
                   10904:         AscPutVarDoneQTail(iop_base, next_qp);
                   10905:         q_addr = ASC_QNO_TO_QADDR(next_qp);
                   10906:         sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
                   10907:             asc_dvc->max_dma_count);
                   10908:         AscWriteLramByte(iop_base,
                   10909:                          (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
                   10910:              (uchar) (scsiq->q_status & (uchar) ~ (QS_READY | QS_ABORTED)));
                   10911:         tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
                   10912:         target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
                   10913:         if ((scsiq->cntl & QC_SG_HEAD) != 0) {
                   10914:             sg_q_addr = q_addr;
                   10915:             sg_list_qp = next_qp;
                   10916:             for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
                   10917:                 sg_list_qp = AscReadLramByte(iop_base,
                   10918:                            (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_FWD));
                   10919:                 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
                   10920:                 if (sg_list_qp == ASC_QLINK_END) {
                   10921:                     AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SG_Q_LINKS);
                   10922:                     scsiq->d3.done_stat = QD_WITH_ERROR;
                   10923:                     scsiq->d3.host_stat = QHSTA_D_QDONE_SG_LIST_CORRUPTED;
                   10924:                     goto FATAL_ERR_QDONE;
                   10925:                 }
                   10926:                 AscWriteLramByte(iop_base,
                   10927:                          (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
                   10928:                                  QS_FREE);
                   10929:             }
                   10930:             n_q_used = sg_queue_cnt + 1;
                   10931:             AscPutVarDoneQTail(iop_base, sg_list_qp);
                   10932:         }
                   10933:         if (asc_dvc->queue_full_or_busy & target_id) {
                   10934:             cur_target_qng = AscReadLramByte(iop_base,
                   10935:             (ushort) ((ushort) ASC_QADR_BEG + (ushort) scsiq->d2.target_ix));
                   10936:             if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
                   10937:                 scsi_busy = AscReadLramByte(iop_base,
                   10938:                                             (ushort) ASCV_SCSIBUSY_B);
                   10939:                 scsi_busy &= ~target_id;
                   10940:                 AscWriteLramByte(iop_base,
                   10941:                                  (ushort) ASCV_SCSIBUSY_B, scsi_busy);
                   10942:                 asc_dvc->queue_full_or_busy &= ~target_id;
                   10943:             }
                   10944:         }
                   10945:         if (asc_dvc->cur_total_qng >= n_q_used) {
                   10946:             asc_dvc->cur_total_qng -= n_q_used;
                   10947:             if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
                   10948:                 asc_dvc->cur_dvc_qng[tid_no]--;
                   10949:             }
                   10950:         } else {
                   10951:             AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
                   10952:             scsiq->d3.done_stat = QD_WITH_ERROR;
                   10953:             goto FATAL_ERR_QDONE;
                   10954:         }
                   10955:         if ((scsiq->d2.srb_ptr == 0UL) ||
                   10956:             ((scsiq->q_status & QS_ABORTED) != 0)) {
                   10957:             return (0x11);
                   10958:         } else if (scsiq->q_status == QS_DONE) {
                   10959:             false_overrun = FALSE;
                   10960:             if (scsiq->extra_bytes != 0) {
                   10961:                 scsiq->remain_bytes += (ulong) scsiq->extra_bytes;
                   10962:             }
                   10963:             if (scsiq->d3.done_stat == QD_WITH_ERROR) {
                   10964:                 if (scsiq->d3.host_stat == QHSTA_M_DATA_OVER_RUN) {
                   10965:                     if ((scsiq->cntl & (QC_DATA_IN | QC_DATA_OUT)) == 0) {
                   10966:                         scsiq->d3.done_stat = QD_NO_ERROR;
                   10967:                         scsiq->d3.host_stat = QHSTA_NO_ERROR;
                   10968:                     } else if (false_overrun) {
                   10969:                         scsiq->d3.done_stat = QD_NO_ERROR;
                   10970:                         scsiq->d3.host_stat = QHSTA_NO_ERROR;
                   10971:                     }
                   10972:                 } else if (scsiq->d3.host_stat ==
                   10973:                            QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
                   10974:                     AscStopChip(iop_base);
                   10975:                     AscSetChipControl(iop_base,
                   10976:                         (uchar) (CC_SCSI_RESET | CC_HALT));
                   10977:                     DvcDelayNanoSecond(asc_dvc, 60000);
                   10978:                     AscSetChipControl(iop_base, CC_HALT);
                   10979:                     AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
                   10980:                     AscSetChipStatus(iop_base, 0);
                   10981:                     AscSetChipControl(iop_base, 0);
                   10982:                 }
                   10983:             }
                   10984:             if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
                   10985:                 (*asc_isr_callback) (asc_dvc, scsiq);
                   10986:             } else {
                   10987:                 if ((AscReadLramByte(iop_base,
                   10988:                           (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG)) ==
                   10989:                      SCSICMD_StartStopUnit)) {
                   10990:                     asc_dvc->unit_not_ready &= ~target_id;
                   10991:                     if (scsiq->d3.done_stat != QD_NO_ERROR) {
                   10992:                         asc_dvc->start_motor &= ~target_id;
                   10993:                     }
                   10994:                 }
                   10995:             }
                   10996:             return (1);
                   10997:         } else {
                   10998:             AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
                   10999:           FATAL_ERR_QDONE:
                   11000:             if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
                   11001:                 (*asc_isr_callback) (asc_dvc, scsiq);
                   11002:             }
                   11003:             return (0x80);
                   11004:         }
                   11005:     }
                   11006:     return (0);
                   11007: }
                   11008: 
                   11009: STATIC int
                   11010: AscISR(
                   11011:           REG ASC_DVC_VAR asc_ptr_type * asc_dvc
                   11012: )
                   11013: {
                   11014:     ASC_CS_TYPE         chipstat;
                   11015:     PortAddr            iop_base;
                   11016:     ushort              saved_ram_addr;
                   11017:     uchar               ctrl_reg;
                   11018:     uchar               saved_ctrl_reg;
                   11019:     int                 int_pending;
                   11020:     int                 status;
                   11021:     uchar               host_flag;
                   11022: 
                   11023:     iop_base = asc_dvc->iop_base;
                   11024:     int_pending = FALSE;
                   11025:     if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
                   11026:         || (asc_dvc->isr_callback == 0)
                   11027: ) {
                   11028:         return (ERR);
                   11029:     }
                   11030:     if (asc_dvc->in_critical_cnt != 0) {
                   11031:         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
                   11032:         return (ERR);
                   11033:     }
                   11034:     if (asc_dvc->is_in_int) {
                   11035:         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
                   11036:         return (ERR);
                   11037:     }
                   11038:     asc_dvc->is_in_int = TRUE;
                   11039:     ctrl_reg = AscGetChipControl(iop_base);
                   11040:     saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
                   11041:                                    CC_SINGLE_STEP | CC_DIAG | CC_TEST));
                   11042:     chipstat = AscGetChipStatus(iop_base);
                   11043:     if (chipstat & CSW_SCSI_RESET_LATCH) {
                   11044:         if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
                   11045:             int_pending = TRUE;
                   11046:             asc_dvc->sdtr_done = 0;
                   11047:             saved_ctrl_reg &= (uchar) (~CC_HALT);
                   11048:             while (AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) ;
                   11049:             AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
                   11050:             AscSetChipControl(iop_base, CC_HALT);
                   11051:             AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
                   11052:             AscSetChipStatus(iop_base, 0);
                   11053:             chipstat = AscGetChipStatus(iop_base);
                   11054:         }
                   11055:     }
                   11056:     saved_ram_addr = AscGetChipLramAddr(iop_base);
                   11057:     host_flag = AscReadLramByte(iop_base,
                   11058:         ASCV_HOST_FLAG_B) & (uchar) (~ASC_HOST_FLAG_IN_ISR);
                   11059:     AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
                   11060:                      (uchar) (host_flag | (uchar) ASC_HOST_FLAG_IN_ISR));
                   11061:     if ((chipstat & CSW_INT_PENDING)
                   11062:         || (int_pending)
                   11063: ) {
                   11064:         AscAckInterrupt(iop_base);
                   11065:         int_pending = TRUE;
                   11066:         if ((chipstat & CSW_HALTED) &&
                   11067:             (ctrl_reg & CC_SINGLE_STEP)) {
                   11068:             if (AscIsrChipHalted(asc_dvc) == ERR) {
                   11069:                 goto ISR_REPORT_QDONE_FATAL_ERROR;
                   11070:             } else {
                   11071:                 saved_ctrl_reg &= (uchar) (~CC_HALT);
                   11072:             }
                   11073:         } else {
                   11074:           ISR_REPORT_QDONE_FATAL_ERROR:
                   11075:             if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
                   11076:                 while (((status = AscIsrQDone(asc_dvc)) & 0x01) != 0) {
                   11077:                 }
                   11078:             } else {
                   11079:                 do {
                   11080:                     if ((status = AscIsrQDone(asc_dvc)) == 1) {
                   11081:                         break;
                   11082:                     }
                   11083:                 } while (status == 0x11);
                   11084:             }
                   11085:             if ((status & 0x80) != 0)
                   11086:                 int_pending = ERR;
                   11087:         }
                   11088:     }
                   11089:     AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
                   11090:     AscSetChipLramAddr(iop_base, saved_ram_addr);
                   11091:     AscSetChipControl(iop_base, saved_ctrl_reg);
                   11092:     asc_dvc->is_in_int = FALSE;
                   11093:     return (int_pending);
                   11094: }
                   11095: 
                   11096: STATIC uchar _asc_mcode_buf[] ASC_INITDATA =
                   11097: {
                   11098:   0x01,  0x03,  0x01,  0x19,  0x0F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   11099:   0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   11100:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  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,  0x91,  0x10,  0x0A,  0x05,  0x01,  0x00,  0x00,  0x00,  0x00,  0xFF,  0x00,  0x00,
                   11103:   0x00,  0x00,  0x00,  0x00,  0xFF,  0x80,  0xFF,  0xFF,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   11104:   0x00,  0x00,  0x00,  0x23,  0x00,  0x24,  0x00,  0x00,  0x00,  0x07,  0x00,  0xFF,  0x00,  0x00,  0x00,  0x00,
                   11105:   0xFF,  0xFF,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xE2,  0x88,  0x00,  0x00,  0x00,  0x00,
                   11106:   0x80,  0x73,  0x48,  0x04,  0x36,  0x00,  0x00,  0xA2,  0xC2,  0x00,  0x80,  0x73,  0x03,  0x23,  0x36,  0x40,
                   11107:   0xB6,  0x00,  0x36,  0x00,  0x05,  0xD6,  0x0C,  0xD2,  0x12,  0xDA,  0x00,  0xA2,  0xC2,  0x00,  0x92,  0x80,
                   11108:   0x1E,  0x98,  0x50,  0x00,  0xF5,  0x00,  0x48,  0x98,  0xDF,  0x23,  0x36,  0x60,  0xB6,  0x00,  0x92,  0x80,
                   11109:   0x4F,  0x00,  0xF5,  0x00,  0x48,  0x98,  0xEF,  0x23,  0x36,  0x60,  0xB6,  0x00,  0x92,  0x80,  0x80,  0x62,
                   11110:   0x92,  0x80,  0x00,  0x46,  0x17,  0xEE,  0x13,  0xEA,  0x02,  0x01,  0x09,  0xD8,  0xCD,  0x04,  0x4D,  0x00,
                   11111:   0x00,  0xA3,  0xD6,  0x00,  0xA6,  0x97,  0x7F,  0x23,  0x04,  0x61,  0x84,  0x01,  0xE6,  0x84,  0xD2,  0xC1,
                   11112:   0x80,  0x73,  0xCD,  0x04,  0x4D,  0x00,  0x00,  0xA3,  0xE2,  0x01,  0xA6,  0x97,  0xCE,  0x81,  0x00,  0x33,
                   11113:   0x02,  0x00,  0xC0,  0x88,  0x80,  0x73,  0x80,  0x77,  0x00,  0x01,  0x01,  0xA1,  0x02,  0x01,  0x4F,  0x00,
                   11114:   0x84,  0x97,  0x07,  0xA6,  0x0C,  0x01,  0x00,  0x33,  0x03,  0x00,  0xC0,  0x88,  0x03,  0x03,  0x03,  0xDE,
                   11115:   0x00,  0x33,  0x05,  0x00,  0xC0,  0x88,  0xCE,  0x00,  0x69,  0x60,  0xCE,  0x00,  0x02,  0x03,  0x4A,  0x60,
                   11116:   0x00,  0xA2,  0x80,  0x01,  0x80,  0x63,  0x07,  0xA6,  0x2C,  0x01,  0x80,  0x81,  0x03,  0x03,  0x80,  0x63,
                   11117:   0xE2,  0x00,  0x07,  0xA6,  0x3C,  0x01,  0x00,  0x33,  0x04,  0x00,  0xC0,  0x88,  0x03,  0x07,  0x02,  0x01,
                   11118:   0x04,  0xCA,  0x0D,  0x23,  0x68,  0x98,  0x4D,  0x04,  0x04,  0x85,  0x05,  0xD8,  0x0D,  0x23,  0x68,  0x98,
                   11119:   0xCD,  0x04,  0x15,  0x23,  0xF6,  0x88,  0xFB,  0x23,  0x02,  0x61,  0x82,  0x01,  0x80,  0x63,  0x02,  0x03,
                   11120:   0x06,  0xA3,  0x6A,  0x01,  0x00,  0x33,  0x0A,  0x00,  0xC0,  0x88,  0x4E,  0x00,  0x07,  0xA3,  0x76,  0x01,
                   11121:   0x00,  0x33,  0x0B,  0x00,  0xC0,  0x88,  0xCD,  0x04,  0x36,  0x2D,  0x00,  0x33,  0x1A,  0x00,  0xC0,  0x88,
                   11122:   0x50,  0x04,  0x90,  0x81,  0x06,  0xAB,  0x8A,  0x01,  0x90,  0x81,  0x4E,  0x00,  0x07,  0xA3,  0x9A,  0x01,
                   11123:   0x50,  0x00,  0x00,  0xA3,  0x44,  0x01,  0x00,  0x05,  0x84,  0x81,  0x46,  0x97,  0x02,  0x01,  0x05,  0xC6,
                   11124:   0x04,  0x23,  0xA0,  0x01,  0x15,  0x23,  0xA1,  0x01,  0xC6,  0x81,  0xFD,  0x23,  0x02,  0x61,  0x82,  0x01,
                   11125:   0x0A,  0xDA,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA0,  0xBC,  0x01,  0x80,  0x63,  0xCD,  0x04,  0x36,  0x2D,
                   11126:   0x00,  0x33,  0x1B,  0x00,  0xC0,  0x88,  0x06,  0x23,  0x68,  0x98,  0xCD,  0x04,  0xE6,  0x84,  0x06,  0x01,
                   11127:   0x00,  0xA2,  0xDC,  0x01,  0x57,  0x60,  0x00,  0xA0,  0xE2,  0x01,  0xE6,  0x84,  0x80,  0x23,  0xA0,  0x01,
                   11128:   0xE6,  0x84,  0x80,  0x73,  0x4B,  0x00,  0x06,  0x61,  0x00,  0xA2,  0x08,  0x02,  0x04,  0x01,  0x0C,  0xDE,
                   11129:   0x02,  0x01,  0x03,  0xCC,  0x4F,  0x00,  0x84,  0x97,  0x04,  0x82,  0x08,  0x23,  0x02,  0x41,  0x82,  0x01,
                   11130:   0x4F,  0x00,  0x62,  0x97,  0x48,  0x04,  0x84,  0x80,  0xF0,  0x97,  0x00,  0x46,  0x56,  0x00,  0x03,  0xC0,
                   11131:   0x01,  0x23,  0xE8,  0x00,  0x81,  0x73,  0x06,  0x29,  0x03,  0x42,  0x06,  0xE2,  0x03,  0xEE,  0x67,  0xEB,
                   11132:   0x11,  0x23,  0xF6,  0x88,  0x04,  0x98,  0xF4,  0x80,  0x80,  0x73,  0x80,  0x77,  0x07,  0xA4,  0x32,  0x02,
                   11133:   0x7C,  0x95,  0x06,  0xA6,  0x3C,  0x02,  0x03,  0xA6,  0x4C,  0x04,  0xC0,  0x88,  0x04,  0x01,  0x03,  0xD8,
                   11134:   0xB2,  0x98,  0x6A,  0x96,  0x4E,  0x82,  0xFE,  0x95,  0x80,  0x67,  0x83,  0x03,  0x80,  0x63,  0xB6,  0x2D,
                   11135:   0x02,  0xA6,  0x78,  0x02,  0x07,  0xA6,  0x66,  0x02,  0x06,  0xA6,  0x6A,  0x02,  0x03,  0xA6,  0x6E,  0x02,
                   11136:   0x00,  0x33,  0x10,  0x00,  0xC0,  0x88,  0x7C,  0x95,  0x50,  0x82,  0x60,  0x96,  0x50,  0x82,  0x04,  0x23,
                   11137:   0xA0,  0x01,  0x14,  0x23,  0xA1,  0x01,  0x3C,  0x84,  0x04,  0x01,  0x0C,  0xDC,  0xE0,  0x23,  0x25,  0x61,
                   11138:   0xEF,  0x00,  0x14,  0x01,  0x4F,  0x04,  0xA8,  0x01,  0x6F,  0x00,  0xA5,  0x01,  0x03,  0x23,  0xA4,  0x01,
                   11139:   0x06,  0x23,  0x9C,  0x01,  0x24,  0x2B,  0x1C,  0x01,  0x02,  0xA6,  0xB6,  0x02,  0x07,  0xA6,  0x66,  0x02,
                   11140:   0x06,  0xA6,  0x6A,  0x02,  0x03,  0xA6,  0x20,  0x04,  0x01,  0xA6,  0xC0,  0x02,  0x00,  0xA6,  0xC0,  0x02,
                   11141:   0x00,  0x33,  0x12,  0x00,  0xC0,  0x88,  0x00,  0x0E,  0x80,  0x63,  0x00,  0x43,  0x00,  0xA0,  0x98,  0x02,
                   11142:   0x4D,  0x04,  0x04,  0x01,  0x0B,  0xDC,  0xE7,  0x23,  0x04,  0x61,  0x84,  0x01,  0x10,  0x31,  0x12,  0x35,
                   11143:   0x14,  0x01,  0xEC,  0x00,  0x6C,  0x38,  0x00,  0x3F,  0x00,  0x00,  0xF6,  0x82,  0x18,  0x23,  0x04,  0x61,
                   11144:   0x18,  0xA0,  0xEE,  0x02,  0x04,  0x01,  0x9C,  0xC8,  0x00,  0x33,  0x1F,  0x00,  0xC0,  0x88,  0x08,  0x31,
                   11145:   0x0A,  0x35,  0x0C,  0x39,  0x0E,  0x3D,  0x7E,  0x98,  0xB6,  0x2D,  0x01,  0xA6,  0x20,  0x03,  0x00,  0xA6,
                   11146:   0x20,  0x03,  0x07,  0xA6,  0x18,  0x03,  0x06,  0xA6,  0x1C,  0x03,  0x03,  0xA6,  0x20,  0x04,  0x02,  0xA6,
                   11147:   0x78,  0x02,  0x00,  0x33,  0x33,  0x00,  0xC0,  0x88,  0x7C,  0x95,  0xFA,  0x82,  0x60,  0x96,  0xFA,  0x82,
                   11148:   0x82,  0x98,  0x80,  0x42,  0x7E,  0x98,  0x60,  0xE4,  0x04,  0x01,  0x29,  0xC8,  0x31,  0x05,  0x07,  0x01,
                   11149:   0x00,  0xA2,  0x60,  0x03,  0x00,  0x43,  0x87,  0x01,  0x05,  0x05,  0x86,  0x98,  0x7E,  0x98,  0x00,  0xA6,
                   11150:   0x22,  0x03,  0x07,  0xA6,  0x58,  0x03,  0x03,  0xA6,  0x3C,  0x04,  0x06,  0xA6,  0x5C,  0x03,  0x01,  0xA6,
                   11151:   0x22,  0x03,  0x00,  0x33,  0x25,  0x00,  0xC0,  0x88,  0x7C,  0x95,  0x3E,  0x83,  0x60,  0x96,  0x3E,  0x83,
                   11152:   0x04,  0x01,  0x0C,  0xCE,  0x03,  0xC8,  0x00,  0x33,  0x42,  0x00,  0xC0,  0x88,  0x00,  0x01,  0x05,  0x05,
                   11153:   0xFF,  0xA2,  0x7E,  0x03,  0xB1,  0x01,  0x08,  0x23,  0xB2,  0x01,  0x3A,  0x83,  0x05,  0x05,  0x15,  0x01,
                   11154:   0x00,  0xA2,  0x9E,  0x03,  0xEC,  0x00,  0x6E,  0x00,  0x95,  0x01,  0x6C,  0x38,  0x00,  0x3F,  0x00,  0x00,
                   11155:   0x01,  0xA6,  0x9A,  0x03,  0x00,  0xA6,  0x9A,  0x03,  0x12,  0x84,  0x80,  0x42,  0x7E,  0x98,  0x01,  0xA6,
                   11156:   0xA8,  0x03,  0x00,  0xA6,  0xC0,  0x03,  0x12,  0x84,  0xA6,  0x98,  0x80,  0x42,  0x01,  0xA6,  0xA8,  0x03,
                   11157:   0x07,  0xA6,  0xB6,  0x03,  0xD8,  0x83,  0x7C,  0x95,  0xAC,  0x83,  0x00,  0x33,  0x2F,  0x00,  0xC0,  0x88,
                   11158:   0xA6,  0x98,  0x80,  0x42,  0x00,  0xA6,  0xC0,  0x03,  0x07,  0xA6,  0xCE,  0x03,  0xD8,  0x83,  0x7C,  0x95,
                   11159:   0xC4,  0x83,  0x00,  0x33,  0x26,  0x00,  0xC0,  0x88,  0x38,  0x2B,  0x80,  0x32,  0x80,  0x36,  0x04,  0x23,
                   11160:   0xA0,  0x01,  0x12,  0x23,  0xA1,  0x01,  0x12,  0x84,  0x06,  0xF0,  0x06,  0xA4,  0xF6,  0x03,  0x80,  0x6B,
                   11161:   0x05,  0x23,  0x83,  0x03,  0x80,  0x63,  0x03,  0xA6,  0x10,  0x04,  0x07,  0xA6,  0x08,  0x04,  0x06,  0xA6,
                   11162:   0x0C,  0x04,  0x00,  0x33,  0x17,  0x00,  0xC0,  0x88,  0x7C,  0x95,  0xF6,  0x83,  0x60,  0x96,  0xF6,  0x83,
                   11163:   0x20,  0x84,  0x06,  0xF0,  0x06,  0xA4,  0x20,  0x04,  0x80,  0x6B,  0x05,  0x23,  0x83,  0x03,  0x80,  0x63,
                   11164:   0xB6,  0x2D,  0x03,  0xA6,  0x3C,  0x04,  0x07,  0xA6,  0x34,  0x04,  0x06,  0xA6,  0x38,  0x04,  0x00,  0x33,
                   11165:   0x30,  0x00,  0xC0,  0x88,  0x7C,  0x95,  0x20,  0x84,  0x60,  0x96,  0x20,  0x84,  0x1D,  0x01,  0x06,  0xCC,
                   11166:   0x00,  0x33,  0x00,  0x84,  0xC0,  0x20,  0x00,  0x23,  0xEA,  0x00,  0x81,  0x62,  0xA2,  0x0D,  0x80,  0x63,
                   11167:   0x07,  0xA6,  0x5A,  0x04,  0x00,  0x33,  0x18,  0x00,  0xC0,  0x88,  0x03,  0x03,  0x80,  0x63,  0xA3,  0x01,
                   11168:   0x07,  0xA4,  0x64,  0x04,  0x23,  0x01,  0x00,  0xA2,  0x86,  0x04,  0x0A,  0xA0,  0x76,  0x04,  0xE0,  0x00,
                   11169:   0x00,  0x33,  0x1D,  0x00,  0xC0,  0x88,  0x0B,  0xA0,  0x82,  0x04,  0xE0,  0x00,  0x00,  0x33,  0x1E,  0x00,
                   11170:   0xC0,  0x88,  0x42,  0x23,  0xF6,  0x88,  0x00,  0x23,  0x22,  0xA3,  0xE6,  0x04,  0x08,  0x23,  0x22,  0xA3,
                   11171:   0xA2,  0x04,  0x28,  0x23,  0x22,  0xA3,  0xAE,  0x04,  0x02,  0x23,  0x22,  0xA3,  0xC4,  0x04,  0x42,  0x23,
                   11172:   0xF6,  0x88,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA0,  0xAE,  0x04,  0x45,  0x23,  0xF6,  0x88,  0x04,  0x98,
                   11173:   0x00,  0xA2,  0xC0,  0x04,  0xB2,  0x98,  0x00,  0x33,  0x00,  0x82,  0xC0,  0x20,  0x81,  0x62,  0xF0,  0x81,
                   11174:   0x47,  0x23,  0xF6,  0x88,  0x04,  0x01,  0x0B,  0xDE,  0x04,  0x98,  0xB2,  0x98,  0x00,  0x33,  0x00,  0x81,
                   11175:   0xC0,  0x20,  0x81,  0x62,  0x14,  0x01,  0x00,  0xA0,  0x08,  0x02,  0x43,  0x23,  0xF6,  0x88,  0x04,  0x23,
                   11176:   0xA0,  0x01,  0x44,  0x23,  0xA1,  0x01,  0x80,  0x73,  0x4D,  0x00,  0x03,  0xA3,  0xF4,  0x04,  0x00,  0x33,
                   11177:   0x27,  0x00,  0xC0,  0x88,  0x04,  0x01,  0x04,  0xDC,  0x02,  0x23,  0xA2,  0x01,  0x04,  0x23,  0xA0,  0x01,
                   11178:   0x04,  0x98,  0x26,  0x95,  0x4B,  0x00,  0xF6,  0x00,  0x4F,  0x04,  0x4F,  0x00,  0x00,  0xA3,  0x22,  0x05,
                   11179:   0x00,  0x05,  0x76,  0x00,  0x06,  0x61,  0x00,  0xA2,  0x1C,  0x05,  0x0A,  0x85,  0x46,  0x97,  0xCD,  0x04,
                   11180:   0x24,  0x85,  0x48,  0x04,  0x84,  0x80,  0x02,  0x01,  0x03,  0xDA,  0x80,  0x23,  0x82,  0x01,  0x34,  0x85,
                   11181:   0x02,  0x23,  0xA0,  0x01,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA2,  0x40,  0x05,  0x1D,  0x01,  0x04,  0xD6,
                   11182:   0xFF,  0x23,  0x86,  0x41,  0x4B,  0x60,  0xCB,  0x00,  0xFF,  0x23,  0x80,  0x01,  0x49,  0x00,  0x81,  0x01,
                   11183:   0x04,  0x01,  0x02,  0xC8,  0x30,  0x01,  0x80,  0x01,  0xF7,  0x04,  0x03,  0x01,  0x49,  0x04,  0x80,  0x01,
                   11184:   0xC9,  0x00,  0x00,  0x05,  0x00,  0x01,  0xFF,  0xA0,  0x60,  0x05,  0x77,  0x04,  0x01,  0x23,  0xEA,  0x00,
                   11185:   0x5D,  0x00,  0xFE,  0xC7,  0x00,  0x62,  0x00,  0x23,  0xEA,  0x00,  0x00,  0x63,  0x07,  0xA4,  0xF8,  0x05,
                   11186:   0x03,  0x03,  0x02,  0xA0,  0x8E,  0x05,  0xF4,  0x85,  0x00,  0x33,  0x2D,  0x00,  0xC0,  0x88,  0x04,  0xA0,
                   11187:   0xB8,  0x05,  0x80,  0x63,  0x00,  0x23,  0xDF,  0x00,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA2,  0xA4,  0x05,
                   11188:   0x1D,  0x01,  0x06,  0xD6,  0x02,  0x23,  0x02,  0x41,  0x82,  0x01,  0x50,  0x00,  0x62,  0x97,  0x04,  0x85,
                   11189:   0x04,  0x23,  0x02,  0x41,  0x82,  0x01,  0x04,  0x85,  0x08,  0xA0,  0xBE,  0x05,  0xF4,  0x85,  0x03,  0xA0,
                   11190:   0xC4,  0x05,  0xF4,  0x85,  0x01,  0xA0,  0xCE,  0x05,  0x88,  0x00,  0x80,  0x63,  0xCC,  0x86,  0x07,  0xA0,
                   11191:   0xEE,  0x05,  0x5F,  0x00,  0x00,  0x2B,  0xDF,  0x08,  0x00,  0xA2,  0xE6,  0x05,  0x80,  0x67,  0x80,  0x63,
                   11192:   0x01,  0xA2,  0x7A,  0x06,  0x7C,  0x85,  0x06,  0x23,  0x68,  0x98,  0x48,  0x23,  0xF6,  0x88,  0x07,  0x23,
                   11193:   0x80,  0x00,  0x06,  0x87,  0x80,  0x63,  0x7C,  0x85,  0x00,  0x23,  0xDF,  0x00,  0x00,  0x63,  0x4A,  0x00,
                   11194:   0x06,  0x61,  0x00,  0xA2,  0x36,  0x06,  0x1D,  0x01,  0x16,  0xD4,  0xC0,  0x23,  0x07,  0x41,  0x83,  0x03,
                   11195:   0x80,  0x63,  0x06,  0xA6,  0x1C,  0x06,  0x00,  0x33,  0x37,  0x00,  0xC0,  0x88,  0x1D,  0x01,  0x01,  0xD6,
                   11196:   0x20,  0x23,  0x63,  0x60,  0x83,  0x03,  0x80,  0x63,  0x02,  0x23,  0xDF,  0x00,  0x07,  0xA6,  0x7C,  0x05,
                   11197:   0xEF,  0x04,  0x6F,  0x00,  0x00,  0x63,  0x4B,  0x00,  0x06,  0x41,  0xCB,  0x00,  0x52,  0x00,  0x06,  0x61,
                   11198:   0x00,  0xA2,  0x4E,  0x06,  0x1D,  0x01,  0x03,  0xCA,  0xC0,  0x23,  0x07,  0x41,  0x00,  0x63,  0x1D,  0x01,
                   11199:   0x04,  0xCC,  0x00,  0x33,  0x00,  0x83,  0xC0,  0x20,  0x81,  0x62,  0x80,  0x23,  0x07,  0x41,  0x00,  0x63,
                   11200:   0x80,  0x67,  0x08,  0x23,  0x83,  0x03,  0x80,  0x63,  0x00,  0x63,  0x01,  0x23,  0xDF,  0x00,  0x06,  0xA6,
                   11201:   0x84,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x80,  0x67,  0x80,  0x63,  0x00,  0x33,  0x00,  0x40,  0xC0,  0x20,
                   11202:   0x81,  0x62,  0x00,  0x63,  0x00,  0x00,  0xFE,  0x95,  0x83,  0x03,  0x80,  0x63,  0x06,  0xA6,  0x94,  0x06,
                   11203:   0x07,  0xA6,  0x7C,  0x05,  0x00,  0x00,  0x01,  0xA0,  0x14,  0x07,  0x00,  0x2B,  0x40,  0x0E,  0x80,  0x63,
                   11204:   0x01,  0x00,  0x06,  0xA6,  0xAA,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x40,  0x0E,  0x80,  0x63,  0x00,  0x43,
                   11205:   0x00,  0xA0,  0xA2,  0x06,  0x06,  0xA6,  0xBC,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x80,  0x67,  0x40,  0x0E,
                   11206:   0x80,  0x63,  0x07,  0xA6,  0x7C,  0x05,  0x00,  0x23,  0xDF,  0x00,  0x00,  0x63,  0x07,  0xA6,  0xD6,  0x06,
                   11207:   0x00,  0x33,  0x2A,  0x00,  0xC0,  0x88,  0x03,  0x03,  0x80,  0x63,  0x89,  0x00,  0x0A,  0x2B,  0x07,  0xA6,
                   11208:   0xE8,  0x06,  0x00,  0x33,  0x29,  0x00,  0xC0,  0x88,  0x00,  0x43,  0x00,  0xA2,  0xF4,  0x06,  0xC0,  0x0E,
                   11209:   0x80,  0x63,  0xDE,  0x86,  0xC0,  0x0E,  0x00,  0x33,  0x00,  0x80,  0xC0,  0x20,  0x81,  0x62,  0x04,  0x01,
                   11210:   0x02,  0xDA,  0x80,  0x63,  0x7C,  0x85,  0x80,  0x7B,  0x80,  0x63,  0x06,  0xA6,  0x8C,  0x06,  0x00,  0x33,
                   11211:   0x2C,  0x00,  0xC0,  0x88,  0x0C,  0xA2,  0x2E,  0x07,  0xFE,  0x95,  0x83,  0x03,  0x80,  0x63,  0x06,  0xA6,
                   11212:   0x2C,  0x07,  0x07,  0xA6,  0x7C,  0x05,  0x00,  0x33,  0x3D,  0x00,  0xC0,  0x88,  0x00,  0x00,  0x80,  0x67,
                   11213:   0x83,  0x03,  0x80,  0x63,  0x0C,  0xA0,  0x44,  0x07,  0x07,  0xA6,  0x7C,  0x05,  0xBF,  0x23,  0x04,  0x61,
                   11214:   0x84,  0x01,  0xE6,  0x84,  0x00,  0x63,  0xF0,  0x04,  0x01,  0x01,  0xF1,  0x00,  0x00,  0x01,  0xF2,  0x00,
                   11215:   0x01,  0x05,  0x80,  0x01,  0x72,  0x04,  0x71,  0x00,  0x81,  0x01,  0x70,  0x04,  0x80,  0x05,  0x81,  0x05,
                   11216:   0x00,  0x63,  0xF0,  0x04,  0xF2,  0x00,  0x72,  0x04,  0x01,  0x01,  0xF1,  0x00,  0x70,  0x00,  0x81,  0x01,
                   11217:   0x70,  0x04,  0x71,  0x00,  0x81,  0x01,  0x72,  0x00,  0x80,  0x01,  0x71,  0x04,  0x70,  0x00,  0x80,  0x01,
                   11218:   0x70,  0x04,  0x00,  0x63,  0xF0,  0x04,  0xF2,  0x00,  0x72,  0x04,  0x00,  0x01,  0xF1,  0x00,  0x70,  0x00,
                   11219:   0x80,  0x01,  0x70,  0x04,  0x71,  0x00,  0x80,  0x01,  0x72,  0x00,  0x81,  0x01,  0x71,  0x04,  0x70,  0x00,
                   11220:   0x81,  0x01,  0x70,  0x04,  0x00,  0x63,  0x00,  0x23,  0xB3,  0x01,  0x83,  0x05,  0xA3,  0x01,  0xA2,  0x01,
                   11221:   0xA1,  0x01,  0x01,  0x23,  0xA0,  0x01,  0x00,  0x01,  0xC8,  0x00,  0x03,  0xA1,  0xC4,  0x07,  0x00,  0x33,
                   11222:   0x07,  0x00,  0xC0,  0x88,  0x80,  0x05,  0x81,  0x05,  0x04,  0x01,  0x11,  0xC8,  0x48,  0x00,  0xB0,  0x01,
                   11223:   0xB1,  0x01,  0x08,  0x23,  0xB2,  0x01,  0x05,  0x01,  0x48,  0x04,  0x00,  0x43,  0x00,  0xA2,  0xE4,  0x07,
                   11224:   0x00,  0x05,  0xDA,  0x87,  0x00,  0x01,  0xC8,  0x00,  0xFF,  0x23,  0x80,  0x01,  0x05,  0x05,  0x00,  0x63,
                   11225:   0xF7,  0x04,  0x1A,  0x09,  0xF6,  0x08,  0x6E,  0x04,  0x00,  0x02,  0x80,  0x43,  0x76,  0x08,  0x80,  0x02,
                   11226:   0x77,  0x04,  0x00,  0x63,  0xF7,  0x04,  0x1A,  0x09,  0xF6,  0x08,  0x6E,  0x04,  0x00,  0x02,  0x00,  0xA0,
                   11227:   0x14,  0x08,  0x16,  0x88,  0x00,  0x43,  0x76,  0x08,  0x80,  0x02,  0x77,  0x04,  0x00,  0x63,  0xF3,  0x04,
                   11228:   0x00,  0x23,  0xF4,  0x00,  0x74,  0x00,  0x80,  0x43,  0xF4,  0x00,  0xCF,  0x40,  0x00,  0xA2,  0x44,  0x08,
                   11229:   0x74,  0x04,  0x02,  0x01,  0xF7,  0xC9,  0xF6,  0xD9,  0x00,  0x01,  0x01,  0xA1,  0x24,  0x08,  0x04,  0x98,
                   11230:   0x26,  0x95,  0x24,  0x88,  0x73,  0x04,  0x00,  0x63,  0xF3,  0x04,  0x75,  0x04,  0x5A,  0x88,  0x02,  0x01,
                   11231:   0x04,  0xD8,  0x46,  0x97,  0x04,  0x98,  0x26,  0x95,  0x4A,  0x88,  0x75,  0x00,  0x00,  0xA3,  0x64,  0x08,
                   11232:   0x00,  0x05,  0x4E,  0x88,  0x73,  0x04,  0x00,  0x63,  0x80,  0x7B,  0x80,  0x63,  0x06,  0xA6,  0x76,  0x08,
                   11233:   0x00,  0x33,  0x3E,  0x00,  0xC0,  0x88,  0x80,  0x67,  0x83,  0x03,  0x80,  0x63,  0x00,  0x63,  0x38,  0x2B,
                   11234:   0x9C,  0x88,  0x38,  0x2B,  0x92,  0x88,  0x32,  0x09,  0x31,  0x05,  0x92,  0x98,  0x05,  0x05,  0xB2,  0x09,
                   11235:   0x00,  0x63,  0x00,  0x32,  0x00,  0x36,  0x00,  0x3A,  0x00,  0x3E,  0x00,  0x63,  0x80,  0x32,  0x80,  0x36,
                   11236:   0x80,  0x3A,  0x80,  0x3E,  0x00,  0x63,  0x38,  0x2B,  0x40,  0x32,  0x40,  0x36,  0x40,  0x3A,  0x40,  0x3E,
                   11237:   0x00,  0x63,  0x5A,  0x20,  0xC9,  0x40,  0x00,  0xA0,  0xB2,  0x08,  0x5D,  0x00,  0xFE,  0xC3,  0x00,  0x63,
                   11238:   0x80,  0x73,  0xE6,  0x20,  0x02,  0x23,  0xE8,  0x00,  0x82,  0x73,  0xFF,  0xFD,  0x80,  0x73,  0x13,  0x23,
                   11239:   0xF6,  0x88,  0x66,  0x20,  0xC0,  0x20,  0x04,  0x23,  0xA0,  0x01,  0xA1,  0x23,  0xA1,  0x01,  0x81,  0x62,
                   11240:   0xE0,  0x88,  0x80,  0x73,  0x80,  0x77,  0x68,  0x00,  0x00,  0xA2,  0x80,  0x00,  0x03,  0xC2,  0xF1,  0xC7,
                   11241:   0x41,  0x23,  0xF6,  0x88,  0x11,  0x23,  0xA1,  0x01,  0x04,  0x23,  0xA0,  0x01,  0xE6,  0x84,
                   11242: };
                   11243: 
                   11244: STATIC ushort _asc_mcode_size ASC_INITDATA = sizeof(_asc_mcode_buf);
                   11245: STATIC ulong _asc_mcode_chksum ASC_INITDATA = 0x012B5442UL;
                   11246: 
                   11247: #define ASC_SYN_OFFSET_ONE_DISABLE_LIST  16
                   11248: STATIC uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] =
                   11249: {
                   11250:     SCSICMD_Inquiry,
                   11251:     SCSICMD_RequestSense,
                   11252:     SCSICMD_ReadCapacity,
                   11253:     SCSICMD_ReadTOC,
                   11254:     SCSICMD_ModeSelect6,
                   11255:     SCSICMD_ModeSense6,
                   11256:     SCSICMD_ModeSelect10,
                   11257:     SCSICMD_ModeSense10,
                   11258:     0xFF,
                   11259:     0xFF,
                   11260:     0xFF,
                   11261:     0xFF,
                   11262:     0xFF,
                   11263:     0xFF,
                   11264:     0xFF,
                   11265:     0xFF
                   11266: };
                   11267: 
                   11268: STATIC int
                   11269: AscExeScsiQueue(
                   11270:                    REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   11271:                    REG ASC_SCSI_Q * scsiq
                   11272: )
                   11273: {
                   11274:     PortAddr            iop_base;
                   11275:     int                 last_int_level;
                   11276:     int                 sta;
                   11277:     int                 n_q_required;
                   11278:     int                 disable_syn_offset_one_fix;
                   11279:     int                 i;
                   11280:     ulong               addr;
                   11281:     ASC_EXE_CALLBACK    asc_exe_callback;
                   11282:     ushort              sg_entry_cnt = 0;
                   11283:     ushort              sg_entry_cnt_minus_one = 0;
                   11284:     uchar               target_ix;
                   11285:     uchar               tid_no;
                   11286:     uchar               sdtr_data;
                   11287:     uchar               extra_bytes;
                   11288:     uchar               scsi_cmd;
                   11289:     uchar               disable_cmd;
                   11290:     ASC_SG_HEAD *sg_head;
                   11291:     ulong               data_cnt;
                   11292: 
                   11293:     iop_base = asc_dvc->iop_base;
                   11294:     sg_head = scsiq->sg_head;
                   11295:     asc_exe_callback = (ASC_EXE_CALLBACK) asc_dvc->exe_callback;
                   11296:     if (asc_dvc->err_code != 0)
                   11297:         return (ERR);
                   11298:     if (scsiq == (ASC_SCSI_Q *) 0L) {
                   11299:         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
                   11300:         return (ERR);
                   11301:     }
                   11302:     scsiq->q1.q_no = 0;
                   11303:     if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
                   11304:         scsiq->q1.extra_bytes = 0;
                   11305:     }
                   11306:     sta = 0;
                   11307:     target_ix = scsiq->q2.target_ix;
                   11308:     tid_no = ASC_TIX_TO_TID(target_ix);
                   11309:     n_q_required = 1;
                   11310:     if (scsiq->cdbptr[0] == SCSICMD_RequestSense) {
                   11311:         if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
                   11312:             asc_dvc->sdtr_done &= ~scsiq->q1.target_id ;
                   11313:             sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
                   11314:             AscMsgOutSDTR(asc_dvc,
                   11315:                           asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
                   11316:                           (uchar) (asc_dvc->max_sdtr_index - 1)],
                   11317:                           (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
                   11318:             scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
                   11319:         }
                   11320:     }
                   11321:     last_int_level = DvcEnterCritical();
                   11322:     if (asc_dvc->in_critical_cnt != 0) {
                   11323:         DvcLeaveCritical(last_int_level);
                   11324:         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
                   11325:         return (ERR);
                   11326:     }
                   11327:     asc_dvc->in_critical_cnt++;
                   11328:     if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
                   11329:         if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
                   11330:             asc_dvc->in_critical_cnt--;
                   11331:             DvcLeaveCritical(last_int_level);
                   11332:             return (ERR);
                   11333:         }
                   11334:         if (sg_entry_cnt > ASC_MAX_SG_LIST) {
                   11335:             return (ERR);
                   11336:         }
                   11337:         if (sg_entry_cnt == 1) {
                   11338:             scsiq->q1.data_addr = sg_head->sg_list[0].addr;
                   11339:             scsiq->q1.data_cnt = sg_head->sg_list[0].bytes;
                   11340:             scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
                   11341:         }
                   11342:         sg_entry_cnt_minus_one = sg_entry_cnt - 1;
                   11343:     }
                   11344:     scsi_cmd = scsiq->cdbptr[0];
                   11345:     disable_syn_offset_one_fix = FALSE;
                   11346:     if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
                   11347:         !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
                   11348:         if (scsiq->q1.cntl & QC_SG_HEAD) {
                   11349:             data_cnt = 0;
                   11350:             for (i = 0; i < sg_entry_cnt; i++) {
                   11351:                 data_cnt += sg_head->sg_list[i].bytes;
                   11352:             }
                   11353:         } else {
                   11354:             data_cnt = scsiq->q1.data_cnt;
                   11355:         }
                   11356:         if (data_cnt != 0UL) {
                   11357:             if (data_cnt < 512UL) {
                   11358:                 disable_syn_offset_one_fix = TRUE;
                   11359:             } else {
                   11360:                 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST; i++) {
                   11361:                     disable_cmd = _syn_offset_one_disable_cmd[i];
                   11362:                     if (disable_cmd == 0xFF) {
                   11363:                         break;
                   11364:                     }
                   11365:                     if (scsi_cmd == disable_cmd) {
                   11366:                         disable_syn_offset_one_fix = TRUE;
                   11367:                         break;
                   11368:                     }
                   11369:                 }
                   11370:             }
                   11371:         }
                   11372:     }
                   11373:     if (disable_syn_offset_one_fix) {
                   11374:         scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
                   11375:         scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
                   11376:                                ASC_TAG_FLAG_DISABLE_DISCONNECT);
                   11377:     } else {
                   11378:         scsiq->q2.tag_code &= 0x23;
                   11379:     }
                   11380:     if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
                   11381:         if (asc_dvc->bug_fix_cntl) {
                   11382:             if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
                   11383:                 if ((scsi_cmd == SCSICMD_Read6) ||
                   11384:                     (scsi_cmd == SCSICMD_Read10)) {
                   11385:                     addr = sg_head->sg_list[sg_entry_cnt_minus_one].addr +
                   11386:                       sg_head->sg_list[sg_entry_cnt_minus_one].bytes;
                   11387:                     extra_bytes = (uchar) ((ushort) addr & 0x0003);
                   11388:                     if ((extra_bytes != 0) &&
                   11389:                         ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
                   11390:                          == 0)) {
                   11391:                         scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
                   11392:                         scsiq->q1.extra_bytes = extra_bytes;
                   11393:                         sg_head->sg_list[sg_entry_cnt_minus_one].bytes -=
                   11394:                             (ulong) extra_bytes;
                   11395:                     }
                   11396:                 }
                   11397:             }
                   11398:         }
                   11399:         sg_head->entry_to_copy = sg_head->entry_cnt;
                   11400:         n_q_required = AscSgListToQueue(sg_entry_cnt);
                   11401:         if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
                   11402:             (uint) n_q_required) || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
                   11403:             if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
                   11404:                                         n_q_required)) == 1) {
                   11405:                 asc_dvc->in_critical_cnt--;
                   11406:                 if (asc_exe_callback != 0) {
                   11407:                     (*asc_exe_callback) (asc_dvc, scsiq);
                   11408:                 }
                   11409:                 DvcLeaveCritical(last_int_level);
                   11410:                 return (sta);
                   11411:             }
                   11412:         }
                   11413:     } else {
                   11414:         if (asc_dvc->bug_fix_cntl) {
                   11415:             if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
                   11416:                 if ((scsi_cmd == SCSICMD_Read6) ||
                   11417:                     (scsi_cmd == SCSICMD_Read10)) {
                   11418:                     addr = scsiq->q1.data_addr + scsiq->q1.data_cnt;
                   11419:                     extra_bytes = (uchar) ((ushort) addr & 0x0003);
                   11420:                     if ((extra_bytes != 0) &&
                   11421:                         ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
                   11422:                           == 0)) {
                   11423:                         if (((ushort) scsiq->q1.data_cnt & 0x01FF) == 0) {
                   11424:                             scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
                   11425:                             scsiq->q1.data_cnt -= (ulong) extra_bytes;
                   11426:                             scsiq->q1.extra_bytes = extra_bytes;
                   11427:                         }
                   11428:                     }
                   11429:                 }
                   11430:             }
                   11431:         }
                   11432:         n_q_required = 1;
                   11433:         if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
                   11434:             ((scsiq->q1.cntl & QC_URGENT) != 0)) {
                   11435:             if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
                   11436:                                         n_q_required)) == 1) {
                   11437:                 asc_dvc->in_critical_cnt--;
                   11438:                 if (asc_exe_callback != 0) {
                   11439:                     (*asc_exe_callback) (asc_dvc, scsiq);
                   11440:                 }
                   11441:                 DvcLeaveCritical(last_int_level);
                   11442:                 return (sta);
                   11443:             }
                   11444:         }
                   11445:     }
                   11446:     asc_dvc->in_critical_cnt--;
                   11447:     DvcLeaveCritical(last_int_level);
                   11448:     return (sta);
                   11449: }
                   11450: 
                   11451: STATIC int
                   11452: AscSendScsiQueue(
                   11453:                     REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   11454:                     REG ASC_SCSI_Q * scsiq,
                   11455:                     uchar n_q_required
                   11456: )
                   11457: {
                   11458:     PortAddr            iop_base;
                   11459:     uchar               free_q_head;
                   11460:     uchar               next_qp;
                   11461:     uchar               tid_no;
                   11462:     uchar               target_ix;
                   11463:     int                 sta;
                   11464: 
                   11465:     iop_base = asc_dvc->iop_base;
                   11466:     target_ix = scsiq->q2.target_ix;
                   11467:     tid_no = ASC_TIX_TO_TID(target_ix);
                   11468:     sta = 0;
                   11469:     free_q_head = (uchar) AscGetVarFreeQHead(iop_base);
                   11470:     if (n_q_required > 1) {
                   11471:         if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
                   11472:                                        free_q_head, (uchar) (n_q_required)))
                   11473:             != (uchar) ASC_QLINK_END) {
                   11474:             asc_dvc->last_q_shortage = 0;
                   11475:             scsiq->sg_head->queue_cnt = n_q_required - 1;
                   11476:             scsiq->q1.q_no = free_q_head;
                   11477:             if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
                   11478:                                               free_q_head)) == 1) {
                   11479:                 AscPutVarFreeQHead(iop_base, next_qp);
                   11480:                 asc_dvc->cur_total_qng += (uchar) (n_q_required);
                   11481:                 asc_dvc->cur_dvc_qng[tid_no]++;
                   11482:             }
                   11483:             return (sta);
                   11484:         }
                   11485:     } else if (n_q_required == 1) {
                   11486:         if ((next_qp = AscAllocFreeQueue(iop_base,
                   11487:                                          free_q_head)) != ASC_QLINK_END) {
                   11488:             scsiq->q1.q_no = free_q_head;
                   11489:             if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
                   11490:                                         free_q_head)) == 1) {
                   11491:                 AscPutVarFreeQHead(iop_base, next_qp);
                   11492:                 asc_dvc->cur_total_qng++;
                   11493:                 asc_dvc->cur_dvc_qng[tid_no]++;
                   11494:             }
                   11495:             return (sta);
                   11496:         }
                   11497:     }
                   11498:     return (sta);
                   11499: }
                   11500: 
                   11501: STATIC int
                   11502: AscSgListToQueue(
                   11503:                     int sg_list
                   11504: )
                   11505: {
                   11506:     int                 n_sg_list_qs;
                   11507: 
                   11508:     n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
                   11509:     if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
                   11510:         n_sg_list_qs++;
                   11511:     return (n_sg_list_qs + 1);
                   11512: }
                   11513: 
                   11514: 
                   11515: STATIC uint
                   11516: AscGetNumOfFreeQueue(
                   11517:                         REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   11518:                         uchar target_ix,
                   11519:                         uchar n_qs
                   11520: )
                   11521: {
                   11522:     uint                cur_used_qs;
                   11523:     uint                cur_free_qs;
                   11524:     ASC_SCSI_BIT_ID_TYPE target_id;
                   11525:     uchar               tid_no;
                   11526: 
                   11527:     target_id = ASC_TIX_TO_TARGET_ID(target_ix);
                   11528:     tid_no = ASC_TIX_TO_TID(target_ix);
                   11529:     if ((asc_dvc->unit_not_ready & target_id) ||
                   11530:         (asc_dvc->queue_full_or_busy & target_id)) {
                   11531:         return (0);
                   11532:     }
                   11533:     if (n_qs == 1) {
                   11534:         cur_used_qs = (uint) asc_dvc->cur_total_qng +
                   11535:           (uint) asc_dvc->last_q_shortage +
                   11536:           (uint) ASC_MIN_FREE_Q;
                   11537:     } else {
                   11538:         cur_used_qs = (uint) asc_dvc->cur_total_qng +
                   11539:           (uint) ASC_MIN_FREE_Q;
                   11540:     }
                   11541:     if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
                   11542:         cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
                   11543:         if (asc_dvc->cur_dvc_qng[tid_no] >=
                   11544:             asc_dvc->max_dvc_qng[tid_no]) {
                   11545:             return (0);
                   11546:         }
                   11547:         return (cur_free_qs);
                   11548:     }
                   11549:     if (n_qs > 1) {
                   11550:         if ((n_qs > asc_dvc->last_q_shortage) && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
                   11551:             asc_dvc->last_q_shortage = n_qs;
                   11552:         }
                   11553:     }
                   11554:     return (0);
                   11555: }
                   11556: 
                   11557: STATIC int
                   11558: AscPutReadyQueue(
                   11559:                     REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   11560:                     REG ASC_SCSI_Q * scsiq,
                   11561:                     uchar q_no
                   11562: )
                   11563: {
                   11564:     ushort              q_addr;
                   11565:     uchar               tid_no;
                   11566:     uchar               sdtr_data;
                   11567:     uchar               syn_period_ix;
                   11568:     uchar               syn_offset;
                   11569:     PortAddr            iop_base;
                   11570: 
                   11571:     iop_base = asc_dvc->iop_base;
                   11572:     if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
                   11573:         ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
                   11574:         tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
                   11575:         sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
                   11576:         syn_period_ix = (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
                   11577:         syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
                   11578:         AscMsgOutSDTR(asc_dvc,
                   11579:                       asc_dvc->sdtr_period_tbl[syn_period_ix],
                   11580:                       syn_offset);
                   11581:         scsiq->q1.cntl |= QC_MSG_OUT;
                   11582:     }
                   11583:     q_addr = ASC_QNO_TO_QADDR(q_no);
                   11584:     if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
                   11585:         scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
                   11586:     }
                   11587:     scsiq->q1.status = QS_FREE;
                   11588:     AscMemWordCopyToLram(iop_base,
                   11589:                          (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG),
                   11590:                          (ushort *) scsiq->cdbptr,
                   11591:                          (ushort) ((ushort) scsiq->q2.cdb_len >> 1));
                   11592:     DvcPutScsiQ(iop_base,
                   11593:                 (ushort) (q_addr + (ushort) ASC_SCSIQ_CPY_BEG),
                   11594:                 (ushort *) & scsiq->q1.cntl,
                   11595:       (ushort) ((((sizeof (ASC_SCSIQ_1) + sizeof (ASC_SCSIQ_2)) / 2) - 1)));
                   11596:     AscWriteLramWord(iop_base,
                   11597:                      (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
                   11598:              (ushort) (((ushort) scsiq->q1.q_no << 8) | (ushort) QS_READY));
                   11599:     return (1);
                   11600: }
                   11601: 
                   11602: STATIC int
                   11603: AscPutReadySgListQueue(
                   11604:                           REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   11605:                           REG ASC_SCSI_Q * scsiq,
                   11606:                           uchar q_no
                   11607: )
                   11608: {
                   11609:     int                 sta;
                   11610:     int                 i;
                   11611:     ASC_SG_HEAD *sg_head;
                   11612:     ASC_SG_LIST_Q       scsi_sg_q;
                   11613:     ulong               saved_data_addr;
                   11614:     ulong               saved_data_cnt;
                   11615:     PortAddr            iop_base;
                   11616:     ushort              sg_list_dwords;
                   11617:     ushort              sg_index;
                   11618:     ushort              sg_entry_cnt;
                   11619:     ushort              q_addr;
                   11620:     uchar               next_qp;
                   11621: 
                   11622:     iop_base = asc_dvc->iop_base;
                   11623:     sg_head = scsiq->sg_head;
                   11624:     saved_data_addr = scsiq->q1.data_addr;
                   11625:     saved_data_cnt = scsiq->q1.data_cnt;
                   11626:     scsiq->q1.data_addr = sg_head->sg_list[0].addr;
                   11627:     scsiq->q1.data_cnt = sg_head->sg_list[0].bytes;
                   11628:     sg_entry_cnt = sg_head->entry_cnt - 1;
                   11629:     if (sg_entry_cnt != 0) {
                   11630:         scsiq->q1.cntl |= QC_SG_HEAD;
                   11631:         q_addr = ASC_QNO_TO_QADDR(q_no);
                   11632:         sg_index = 1;
                   11633:         scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
                   11634:         scsi_sg_q.sg_head_qp = q_no;
                   11635:         scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
                   11636:         for (i = 0; i < sg_head->queue_cnt; i++) {
                   11637:             scsi_sg_q.seq_no = i + 1;
                   11638:             if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
                   11639:                 sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
                   11640:                 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
                   11641:                 if (i == 0) {
                   11642:                     scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q;
                   11643:                     scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q;
                   11644:                 } else {
                   11645:                     scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
                   11646:                     scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
                   11647:                 }
                   11648:             } else {
                   11649:                 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
                   11650:                 sg_list_dwords = sg_entry_cnt << 1;
                   11651:                 if (i == 0) {
                   11652:                     scsi_sg_q.sg_list_cnt = sg_entry_cnt;
                   11653:                     scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt;
                   11654:                 } else {
                   11655:                     scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
                   11656:                     scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
                   11657:                 }
                   11658:                 sg_entry_cnt = 0;
                   11659:             }
                   11660:             next_qp = AscReadLramByte(iop_base,
                   11661:                                       (ushort) (q_addr + ASC_SCSIQ_B_FWD));
                   11662:             scsi_sg_q.q_no = next_qp;
                   11663:             q_addr = ASC_QNO_TO_QADDR(next_qp);
                   11664:             AscMemWordCopyToLram(iop_base,
                   11665:                                  (ushort) (q_addr + ASC_SCSIQ_SGHD_CPY_BEG),
                   11666:                                  (ushort *) & scsi_sg_q,
                   11667:                                  (ushort) (sizeof (ASC_SG_LIST_Q) >> 1));
                   11668:             AscMemDWordCopyToLram(iop_base,
                   11669:                                   (ushort) (q_addr + ASC_SGQ_LIST_BEG),
                   11670:                               (ulong *) & sg_head->sg_list[sg_index],
                   11671:                                   (ushort) sg_list_dwords);
                   11672:             sg_index += ASC_SG_LIST_PER_Q;
                   11673:         }
                   11674:     } else {
                   11675:         scsiq->q1.cntl &= ~QC_SG_HEAD;
                   11676:     }
                   11677:     sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
                   11678:     scsiq->q1.data_addr = saved_data_addr;
                   11679:     scsiq->q1.data_cnt = saved_data_cnt;
                   11680:     return (sta);
                   11681: }
                   11682: 
                   11683: STATIC int
                   11684: AscAbortSRB(
                   11685:                REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   11686:                ulong srb_ptr
                   11687: )
                   11688: {
                   11689:     int                 sta;
                   11690:     ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready;
                   11691:     PortAddr            iop_base;
                   11692: 
                   11693:     iop_base = asc_dvc->iop_base;
                   11694:     sta = ERR;
                   11695:     saved_unit_not_ready = asc_dvc->unit_not_ready;
                   11696:     asc_dvc->unit_not_ready = 0xFF;
                   11697:     AscWaitISRDone(asc_dvc);
                   11698:     if (AscStopQueueExe(iop_base) == 1) {
                   11699:         if (AscRiscHaltedAbortSRB(asc_dvc, srb_ptr) == 1) {
                   11700:             sta = 1;
                   11701:             AscCleanUpBusyQueue(iop_base);
                   11702:             AscStartQueueExe(iop_base);
                   11703:         } else {
                   11704:             sta = 0;
                   11705:             AscStartQueueExe(iop_base);
                   11706:         }
                   11707:     }
                   11708:     asc_dvc->unit_not_ready = saved_unit_not_ready;
                   11709:     return (sta);
                   11710: }
                   11711: 
                   11712: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
                   11713: STATIC int
                   11714: AscResetDevice(
                   11715:                   REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   11716:                   uchar target_ix
                   11717: )
                   11718: {
                   11719:     PortAddr            iop_base;
                   11720:     int                 sta;
                   11721:     uchar               tid_no;
                   11722: 
                   11723:     ASC_SCSI_BIT_ID_TYPE target_id;
                   11724:     int                 i;
                   11725:     ASC_SCSI_REQ_Q      scsiq_buf;
                   11726:     ASC_SCSI_REQ_Q *scsiq;
                   11727:     uchar       *buf;
                   11728:     ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready;
                   11729:     iop_base = asc_dvc->iop_base;
                   11730:     tid_no = ASC_TIX_TO_TID(target_ix);
                   11731:     target_id = ASC_TID_TO_TARGET_ID(tid_no);
                   11732:     saved_unit_not_ready = asc_dvc->unit_not_ready;
                   11733:     asc_dvc->unit_not_ready = target_id;
                   11734:     sta = ERR;
                   11735:     AscWaitTixISRDone(asc_dvc, target_ix);
                   11736:     if (AscStopQueueExe(iop_base) == 1) {
                   11737:         if (AscRiscHaltedAbortTIX(asc_dvc, target_ix) == 1) {
                   11738:             AscCleanUpBusyQueue(iop_base);
                   11739:             AscStartQueueExe(iop_base);
                   11740:             AscWaitTixISRDone(asc_dvc, target_ix);
                   11741:             sta = TRUE;
                   11742:             scsiq = (ASC_SCSI_REQ_Q *) & scsiq_buf;
                   11743:             buf = (uchar *) & scsiq_buf;
                   11744:             for (i = 0; i < sizeof (ASC_SCSI_REQ_Q); i++) {
                   11745:                 *buf++ = 0x00;
                   11746:             }
                   11747:             scsiq->r1.status = (uchar) QS_READY;
                   11748:             scsiq->r2.cdb_len = 6;
                   11749:             scsiq->r2.tag_code = M2_QTAG_MSG_SIMPLE;
                   11750:             scsiq->r1.target_id = target_id;
                   11751:             scsiq->r2.target_ix = ASC_TIDLUN_TO_IX(tid_no, 0);
                   11752:             scsiq->cdbptr = (uchar *) scsiq->cdb;
                   11753:             scsiq->r1.cntl = QC_NO_CALLBACK | QC_MSG_OUT | QC_URGENT;
                   11754:             AscWriteLramByte(asc_dvc->iop_base, ASCV_MSGOUT_BEG,
                   11755:                              M1_BUS_DVC_RESET);
                   11756:             asc_dvc->unit_not_ready &= ~target_id;
                   11757:             asc_dvc->sdtr_done |= target_id;
                   11758:             if (AscExeScsiQueue(asc_dvc, (ASC_SCSI_Q *) scsiq)
                   11759:                 == 1) {
                   11760:                 asc_dvc->unit_not_ready = target_id;
                   11761:                 DvcSleepMilliSecond(1000);
                   11762:                 _AscWaitQDone(iop_base, (ASC_SCSI_Q *) scsiq);
                   11763:                 if (AscStopQueueExe(iop_base) == 1) {
                   11764:                     AscCleanUpDiscQueue(iop_base);
                   11765:                     AscStartQueueExe(iop_base);
                   11766:                     if (asc_dvc->pci_fix_asyn_xfer & target_id) {
                   11767:                         AscSetRunChipSynRegAtID(iop_base, tid_no,
                   11768:                                              ASYN_SDTR_DATA_FIX_PCI_REV_AB);
                   11769:                     }
                   11770:                     AscWaitTixISRDone(asc_dvc, target_ix);
                   11771:                 }
                   11772:             } else {
                   11773:                 sta = 0;
                   11774:             }
                   11775:             asc_dvc->sdtr_done &= ~target_id;
                   11776:         } else {
                   11777:             sta = ERR;
                   11778:             AscStartQueueExe(iop_base);
                   11779:         }
                   11780:     }
                   11781:     asc_dvc->unit_not_ready = saved_unit_not_ready;
                   11782:     return (sta);
                   11783: }
                   11784: #endif /* version >= v1.3.89 */
                   11785: 
                   11786: STATIC int
                   11787: AscResetSB(
                   11788:               REG ASC_DVC_VAR asc_ptr_type * asc_dvc
                   11789: )
                   11790: {
                   11791:     int                 sta;
                   11792:     int                 i;
                   11793:     PortAddr            iop_base;
                   11794: 
                   11795:     iop_base = asc_dvc->iop_base;
                   11796:     asc_dvc->unit_not_ready = 0xFF;
                   11797:     sta = TRUE;
                   11798:     AscWaitISRDone(asc_dvc);
                   11799:     AscStopQueueExe(iop_base);
                   11800:     asc_dvc->sdtr_done = 0;
                   11801:     AscResetChipAndScsiBus(asc_dvc);
                   11802:     DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
                   11803:     AscReInitLram(asc_dvc);
                   11804:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   11805:         asc_dvc->cur_dvc_qng[i] = 0;
                   11806:         if (asc_dvc->pci_fix_asyn_xfer & (ASC_SCSI_BIT_ID_TYPE) (0x01 << i)) {
                   11807:             AscSetChipSynRegAtID(iop_base, i, ASYN_SDTR_DATA_FIX_PCI_REV_AB);
                   11808:         }
                   11809:     }
                   11810:     asc_dvc->err_code = 0;
                   11811:     AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
                   11812:     if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
                   11813:         sta = ERR;
                   11814:     }
                   11815:     if (AscStartChip(iop_base) == 0) {
                   11816:         sta = ERR;
                   11817:     }
                   11818:     AscStartQueueExe(iop_base);
                   11819:     asc_dvc->unit_not_ready = 0;
                   11820:     asc_dvc->queue_full_or_busy = 0;
                   11821:     return (sta);
                   11822: }
                   11823: 
                   11824: STATIC int
                   11825: AscSetRunChipSynRegAtID(
                   11826:                            PortAddr iop_base,
                   11827:                            uchar tid_no,
                   11828:                            uchar sdtr_data
                   11829: )
                   11830: {
                   11831:     int                 sta = FALSE;
                   11832: 
                   11833:     if (AscHostReqRiscHalt(iop_base)) {
                   11834:         sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
                   11835:         AscStartChip(iop_base);
                   11836:         return (sta);
                   11837:     }
                   11838:     return (sta);
                   11839: }
                   11840: 
                   11841: STATIC int
                   11842: AscSetChipSynRegAtID(
                   11843:                         PortAddr iop_base,
                   11844:                         uchar id,
                   11845:                         uchar sdtr_data
                   11846: )
                   11847: {
                   11848:     ASC_SCSI_BIT_ID_TYPE org_id;
                   11849:     int                 i;
                   11850:     int                 sta = TRUE;
                   11851: 
                   11852:     AscSetBank(iop_base, 1);
                   11853:     org_id = AscReadChipDvcID(iop_base);
                   11854:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   11855:         if (org_id == (0x01 << i))
                   11856:             break;
                   11857:     }
                   11858:     org_id = i;
                   11859:     AscWriteChipDvcID(iop_base, id);
                   11860:     if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
                   11861:         AscSetBank(iop_base, 0);
                   11862:         AscSetChipSyn(iop_base, sdtr_data);
                   11863:         if (AscGetChipSyn(iop_base) != sdtr_data) {
                   11864:             sta = FALSE;
                   11865:         }
                   11866:     } else {
                   11867:         sta = FALSE;
                   11868:     }
                   11869:     AscSetBank(iop_base, 1);
                   11870:     AscWriteChipDvcID(iop_base, org_id);
                   11871:     AscSetBank(iop_base, 0);
                   11872:     return (sta);
                   11873: }
                   11874: 
                   11875: STATIC int
                   11876: AscReInitLram(
                   11877:                  REG ASC_DVC_VAR asc_ptr_type * asc_dvc
                   11878: )
                   11879: {
                   11880:     AscInitLram(asc_dvc);
                   11881:     AscInitQLinkVar(asc_dvc);
                   11882:     return (0);
                   11883: }
                   11884: 
                   11885: STATIC ushort
                   11886: AscInitLram(
                   11887:                REG ASC_DVC_VAR asc_ptr_type * asc_dvc
                   11888: )
                   11889: {
                   11890:     uchar               i;
                   11891:     ushort              s_addr;
                   11892:     PortAddr            iop_base;
                   11893:     ushort              warn_code;
                   11894: 
                   11895:     iop_base = asc_dvc->iop_base;
                   11896:     warn_code = 0;
                   11897:     AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
                   11898:                (ushort) (((int) (asc_dvc->max_total_qng + 2 + 1) * 64) >> 1)
                   11899: );
                   11900:     i = ASC_MIN_ACTIVE_QNO;
                   11901:     s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
                   11902:     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
                   11903:                      (uchar) (i + 1));
                   11904:     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
                   11905:                      (uchar) (asc_dvc->max_total_qng));
                   11906:     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
                   11907:                      (uchar) i);
                   11908:     i++;
                   11909:     s_addr += ASC_QBLK_SIZE;
                   11910:     for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
                   11911:         AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
                   11912:                          (uchar) (i + 1));
                   11913:         AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
                   11914:                          (uchar) (i - 1));
                   11915:         AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
                   11916:                          (uchar) i);
                   11917:     }
                   11918:     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
                   11919:                      (uchar) ASC_QLINK_END);
                   11920:     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
                   11921:                      (uchar) (asc_dvc->max_total_qng - 1));
                   11922:     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
                   11923:                      (uchar) asc_dvc->max_total_qng);
                   11924:     i++;
                   11925:     s_addr += ASC_QBLK_SIZE;
                   11926:     for (; i <= (uchar) (asc_dvc->max_total_qng + 3);
                   11927:          i++, s_addr += ASC_QBLK_SIZE) {
                   11928:         AscWriteLramByte(iop_base,
                   11929:                          (ushort) (s_addr + (ushort) ASC_SCSIQ_B_FWD), i);
                   11930:         AscWriteLramByte(iop_base,
                   11931:                          (ushort) (s_addr + (ushort) ASC_SCSIQ_B_BWD), i);
                   11932:         AscWriteLramByte(iop_base,
                   11933:                          (ushort) (s_addr + (ushort) ASC_SCSIQ_B_QNO), i);
                   11934:     }
                   11935:     return (warn_code);
                   11936: }
                   11937: 
                   11938: STATIC ushort
                   11939: AscInitQLinkVar(
                   11940:                    REG ASC_DVC_VAR asc_ptr_type * asc_dvc
                   11941: )
                   11942: {
                   11943:     PortAddr            iop_base;
                   11944:     int                 i;
                   11945:     ushort              lram_addr;
                   11946: 
                   11947:     iop_base = asc_dvc->iop_base;
                   11948:     AscPutRiscVarFreeQHead(iop_base, 1);
                   11949:     AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
                   11950:     AscPutVarFreeQHead(iop_base, 1);
                   11951:     AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
                   11952:     AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
                   11953:                      (uchar) ((int) asc_dvc->max_total_qng + 1));
                   11954:     AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
                   11955:                      (uchar) ((int) asc_dvc->max_total_qng + 2));
                   11956:     AscWriteLramByte(iop_base, (ushort) ASCV_TOTAL_READY_Q_B,
                   11957:                      asc_dvc->max_total_qng);
                   11958:     AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
                   11959:     AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
                   11960:     AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
                   11961:     AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
                   11962:     AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
                   11963:     AscPutQDoneInProgress(iop_base, 0);
                   11964:     lram_addr = ASC_QADR_BEG;
                   11965:     for (i = 0; i < 32; i++, lram_addr += 2) {
                   11966:         AscWriteLramWord(iop_base, lram_addr, 0);
                   11967:     }
                   11968:     return (0);
                   11969: }
                   11970: 
                   11971: STATIC int
                   11972: AscSetLibErrorCode(
                   11973:                       REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   11974:                       ushort err_code
                   11975: )
                   11976: {
                   11977:     if (asc_dvc->err_code == 0) {
                   11978:         asc_dvc->err_code = err_code;
                   11979:         AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
                   11980:                          err_code);
                   11981:     }
                   11982:     return (err_code);
                   11983: }
                   11984: 
                   11985: 
                   11986: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
                   11987: STATIC int
                   11988: _AscWaitQDone(
                   11989:                  PortAddr iop_base,
                   11990:                  REG ASC_SCSI_Q * scsiq
                   11991: )
                   11992: {
                   11993:     ushort              q_addr;
                   11994:     uchar               q_status;
                   11995:     int                 count = 0;
                   11996: 
                   11997:     while (scsiq->q1.q_no == 0) ;
                   11998:     q_addr = ASC_QNO_TO_QADDR(scsiq->q1.q_no);
                   11999:     do {
                   12000:         q_status = AscReadLramByte(iop_base, q_addr + ASC_SCSIQ_B_STATUS);
                   12001:         DvcSleepMilliSecond(100L);
                   12002:         if (count++ > 30) {
                   12003:             return (0);
                   12004:         }
                   12005:     } while ((q_status & QS_READY) != 0);
                   12006:     return (1);
                   12007: }
                   12008: #endif /* version >= v1.3.89 */
                   12009: 
                   12010: STATIC uchar 
                   12011: AscMsgOutSDTR(
                   12012:                  REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   12013:                  uchar sdtr_period,
                   12014:                  uchar sdtr_offset
                   12015: )
                   12016: {
                   12017:     EXT_MSG             sdtr_buf;
                   12018:     uchar               sdtr_period_index;
                   12019:     PortAddr            iop_base;
                   12020: 
                   12021:     iop_base = asc_dvc->iop_base;
                   12022:     sdtr_buf.msg_type = MS_EXTEND;
                   12023:     sdtr_buf.msg_len = MS_SDTR_LEN;
                   12024:     sdtr_buf.msg_req = MS_SDTR_CODE;
                   12025:     sdtr_buf.xfer_period = sdtr_period;
                   12026:     sdtr_offset &= ASC_SYN_MAX_OFFSET;
                   12027:     sdtr_buf.req_ack_offset = sdtr_offset;
                   12028:     if ((sdtr_period_index =
                   12029:          AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
                   12030:         asc_dvc->max_sdtr_index) {
                   12031:         AscMemWordCopyToLram(iop_base,
                   12032:                              ASCV_MSGOUT_BEG,
                   12033:                              (ushort *) & sdtr_buf,
                   12034:                              (ushort) (sizeof (EXT_MSG) >> 1));
                   12035:         return ((sdtr_period_index << 4) | sdtr_offset);
                   12036:     } else {
                   12037: 
                   12038:         sdtr_buf.req_ack_offset = 0;
                   12039:         AscMemWordCopyToLram(iop_base,
                   12040:                              ASCV_MSGOUT_BEG,
                   12041:                              (ushort *) & sdtr_buf,
                   12042:                              (ushort) (sizeof (EXT_MSG) >> 1));
                   12043:         return (0);
                   12044:     }
                   12045: }
                   12046: 
                   12047: STATIC uchar
                   12048: AscCalSDTRData(
                   12049:                   REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   12050:                   uchar sdtr_period,
                   12051:                   uchar syn_offset
                   12052: )
                   12053: {
                   12054:     uchar               byte;
                   12055:     uchar               sdtr_period_ix;
                   12056: 
                   12057:     sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
                   12058:     if (
                   12059:            (sdtr_period_ix > asc_dvc->max_sdtr_index)
                   12060: ) {
                   12061:         return (0xFF);
                   12062:     }
                   12063:     byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
                   12064:     return (byte);
                   12065: }
                   12066: 
                   12067: STATIC void
                   12068: AscSetChipSDTR(
                   12069:                   PortAddr iop_base,
                   12070:                   uchar sdtr_data,
                   12071:                   uchar tid_no
                   12072: )
                   12073: {
                   12074:     AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
                   12075:     AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
                   12076:     return;
                   12077: }
                   12078: 
                   12079: STATIC uchar
                   12080: AscGetSynPeriodIndex(
                   12081:                         ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   12082:                         ruchar syn_time
                   12083: )
                   12084: {
                   12085:     ruchar             *period_table;
                   12086:     int                 max_index;
                   12087:     int                 min_index;
                   12088:     int                 i;
                   12089: 
                   12090:     period_table = asc_dvc->sdtr_period_tbl;
                   12091:     max_index = (int) asc_dvc->max_sdtr_index;
                   12092:     min_index = (int)asc_dvc->host_init_sdtr_index ;
                   12093:     if ((syn_time <= period_table[max_index])) {
                   12094:         for (i = min_index; i < (max_index - 1); i++) {
                   12095:             if (syn_time <= period_table[i]) {
                   12096:                 return ((uchar) i);
                   12097:             }
                   12098:         }
                   12099:         return ((uchar) max_index);
                   12100:     } else {
                   12101:         return ((uchar) (max_index + 1));
                   12102:     }
                   12103: }
                   12104: 
                   12105: STATIC uchar
                   12106: AscAllocFreeQueue(
                   12107:                      PortAddr iop_base,
                   12108:                      uchar free_q_head
                   12109: )
                   12110: {
                   12111:     ushort              q_addr;
                   12112:     uchar               next_qp;
                   12113:     uchar               q_status;
                   12114: 
                   12115:     q_addr = ASC_QNO_TO_QADDR(free_q_head);
                   12116:     q_status = (uchar) AscReadLramByte(iop_base,
                   12117:                                     (ushort) (q_addr + ASC_SCSIQ_B_STATUS));
                   12118:     next_qp = AscReadLramByte(iop_base,
                   12119:                               (ushort) (q_addr + ASC_SCSIQ_B_FWD));
                   12120:     if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
                   12121:         return (next_qp);
                   12122:     }
                   12123:     return (ASC_QLINK_END);
                   12124: }
                   12125: 
                   12126: STATIC uchar
                   12127: AscAllocMultipleFreeQueue(
                   12128:                              PortAddr iop_base,
                   12129:                              uchar free_q_head,
                   12130:                              uchar n_free_q
                   12131: )
                   12132: {
                   12133:     uchar               i;
                   12134: 
                   12135:     for (i = 0; i < n_free_q; i++) {
                   12136:         if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
                   12137:             == ASC_QLINK_END) {
                   12138:             return (ASC_QLINK_END);
                   12139:         }
                   12140:     }
                   12141:     return (free_q_head);
                   12142: }
                   12143: 
                   12144: STATIC int
                   12145: AscRiscHaltedAbortSRB(
                   12146:                          REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   12147:                          ulong srb_ptr
                   12148: )
                   12149: {
                   12150:     PortAddr            iop_base;
                   12151:     ushort              q_addr;
                   12152:     uchar               q_no;
                   12153:     ASC_QDONE_INFO      scsiq_buf;
                   12154:     ASC_QDONE_INFO *scsiq;
                   12155:     ASC_ISR_CALLBACK    asc_isr_callback;
                   12156:     int                 last_int_level;
                   12157: 
                   12158:     iop_base = asc_dvc->iop_base;
                   12159:     asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
                   12160:     last_int_level = DvcEnterCritical();
                   12161:     scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
                   12162:     for (q_no = ASC_MIN_ACTIVE_QNO; q_no <= asc_dvc->max_total_qng;
                   12163:          q_no++) {
                   12164:         q_addr = ASC_QNO_TO_QADDR(q_no);
                   12165:         scsiq->d2.srb_ptr = AscReadLramDWord(iop_base,
                   12166:                            (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR));
                   12167:         if (scsiq->d2.srb_ptr == srb_ptr) {
                   12168:             _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count);
                   12169:             if (((scsiq->q_status & QS_READY) != 0)
                   12170:                  && ((scsiq->q_status & QS_ABORTED) == 0)
                   12171:                  && ((scsiq->cntl & QCSG_SG_XFER_LIST) == 0)) {
                   12172:                 scsiq->q_status |= QS_ABORTED;
                   12173:                 scsiq->d3.done_stat = QD_ABORTED_BY_HOST;
                   12174:                 AscWriteLramDWord(iop_base,
                   12175:                             (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR),
                   12176:                                   0L);
                   12177:                 AscWriteLramByte(iop_base,
                   12178:                             (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
                   12179:                                  scsiq->q_status);
                   12180:                 (*asc_isr_callback) (asc_dvc, scsiq);
                   12181:                 return (1);
                   12182:             }
                   12183:         }
                   12184:     }
                   12185:     DvcLeaveCritical(last_int_level);
                   12186:     return (0);
                   12187: }
                   12188: 
                   12189: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
                   12190: STATIC int
                   12191: AscRiscHaltedAbortTIX(
                   12192:                          REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   12193:                          uchar target_ix
                   12194: )
                   12195: {
                   12196:     PortAddr            iop_base;
                   12197:     ushort              q_addr;
                   12198:     uchar               q_no;
                   12199:     ASC_QDONE_INFO      scsiq_buf;
                   12200:     ASC_QDONE_INFO *scsiq;
                   12201:     ASC_ISR_CALLBACK    asc_isr_callback;
                   12202:     int                 last_int_level;
                   12203: 
                   12204:     iop_base = asc_dvc->iop_base;
                   12205:     asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
                   12206:     last_int_level = DvcEnterCritical();
                   12207:     scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
                   12208:     for (q_no = ASC_MIN_ACTIVE_QNO; q_no <= asc_dvc->max_total_qng;
                   12209:          q_no++) {
                   12210:         q_addr = ASC_QNO_TO_QADDR(q_no);
                   12211:         _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count);
                   12212:         if (((scsiq->q_status & QS_READY) != 0) &&
                   12213:             ((scsiq->q_status & QS_ABORTED) == 0) &&
                   12214:             ((scsiq->cntl & QCSG_SG_XFER_LIST) == 0)) {
                   12215:             if (scsiq->d2.target_ix == target_ix) {
                   12216:                 scsiq->q_status |= QS_ABORTED;
                   12217:                 scsiq->d3.done_stat = QD_ABORTED_BY_HOST;
                   12218:                 AscWriteLramDWord(iop_base,
                   12219:                             (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR),
                   12220:                                   0L);
                   12221:                 AscWriteLramByte(iop_base,
                   12222:                             (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
                   12223:                                  scsiq->q_status);
                   12224:                 (*asc_isr_callback) (asc_dvc, scsiq);
                   12225:             }
                   12226:         }
                   12227:     }
                   12228:     DvcLeaveCritical(last_int_level);
                   12229:     return (1);
                   12230: }
                   12231: #endif /* version >= v1.3.89 */
                   12232: 
                   12233: STATIC int
                   12234: AscHostReqRiscHalt(
                   12235:                       PortAddr iop_base
                   12236: )
                   12237: {
                   12238:     int                 count = 0;
                   12239:     int                 sta = 0;
                   12240:     uchar               saved_stop_code;
                   12241: 
                   12242:     if (AscIsChipHalted(iop_base))
                   12243:         return (1);
                   12244:     saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
                   12245:     AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
                   12246:                      ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP
                   12247: );
                   12248:     do {
                   12249:         if (AscIsChipHalted(iop_base)) {
                   12250:             sta = 1;
                   12251:             break;
                   12252:         }
                   12253:         DvcSleepMilliSecond(100);
                   12254:     } while (count++ < 20);
                   12255:     AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
                   12256:     return (sta);
                   12257: }
                   12258: 
                   12259: STATIC int
                   12260: AscStopQueueExe(
                   12261:                    PortAddr iop_base
                   12262: )
                   12263: {
                   12264:     int                 count = 0;
                   12265: 
                   12266:     if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
                   12267:         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
                   12268:                          ASC_STOP_REQ_RISC_STOP);
                   12269:         do {
                   12270:             if (
                   12271:                    AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
                   12272:                    ASC_STOP_ACK_RISC_STOP) {
                   12273:                 return (1);
                   12274:             }
                   12275:             DvcSleepMilliSecond(100);
                   12276:         } while (count++ < 20);
                   12277:     }
                   12278:     return (0);
                   12279: }
                   12280: 
                   12281: STATIC int
                   12282: AscStartQueueExe(
                   12283:                     PortAddr iop_base
                   12284: )
                   12285: {
                   12286:     if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
                   12287:         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
                   12288:     }
                   12289:     return (1);
                   12290: }
                   12291: 
                   12292: STATIC int
                   12293: AscCleanUpBusyQueue(
                   12294:                        PortAddr iop_base
                   12295: )
                   12296: {
                   12297:     int                 count;
                   12298:     uchar               stop_code;
                   12299: 
                   12300:     count = 0;
                   12301:     if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
                   12302:         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
                   12303:                          ASC_STOP_CLEAN_UP_BUSY_Q);
                   12304:         do {
                   12305:             stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
                   12306:             if ((stop_code & ASC_STOP_CLEAN_UP_BUSY_Q) == 0)
                   12307:                 break;
                   12308:             DvcSleepMilliSecond(100);
                   12309:         } while (count++ < 20);
                   12310:     }
                   12311:     return (1);
                   12312: }
                   12313: 
                   12314: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
                   12315: STATIC int
                   12316: AscCleanUpDiscQueue(
                   12317:                        PortAddr iop_base
                   12318: )
                   12319: {
                   12320:     int                 count;
                   12321:     uchar               stop_code;
                   12322: 
                   12323:     count = 0;
                   12324:     if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
                   12325:         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
                   12326:                          ASC_STOP_CLEAN_UP_DISC_Q);
                   12327:         do {
                   12328:             stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
                   12329:             if ((stop_code & ASC_STOP_CLEAN_UP_DISC_Q) == 0)
                   12330:                 break;
                   12331:             DvcSleepMilliSecond(100);
                   12332:         } while (count++ < 20);
                   12333:     }
                   12334:     return (1);
                   12335: }
                   12336: #endif /* version >= v1.3.89 */
                   12337: 
                   12338: STATIC int
                   12339: AscWaitTixISRDone(
                   12340:                      ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   12341:                      uchar target_ix
                   12342: )
                   12343: {
                   12344:     uchar               cur_req;
                   12345:     uchar               tid_no;
                   12346:     int                 i = 0;
                   12347: 
                   12348:     tid_no = ASC_TIX_TO_TID(target_ix);
                   12349:     while (i++ < 10) {
                   12350:         if ((cur_req = asc_dvc->cur_dvc_qng[tid_no]) == 0) {
                   12351:             break;
                   12352:         }
                   12353:         DvcSleepMilliSecond(1000L);
                   12354:         if (asc_dvc->cur_dvc_qng[tid_no] == cur_req) {
                   12355:             break;
                   12356:         }
                   12357:     }
                   12358:     return (1);
                   12359: }
                   12360: 
                   12361: STATIC int
                   12362: AscWaitISRDone(
                   12363:                   REG ASC_DVC_VAR asc_ptr_type * asc_dvc
                   12364: )
                   12365: {
                   12366:     int                 tid;
                   12367: 
                   12368:     for (tid = 0; tid <= ASC_MAX_TID; tid++) {
                   12369:         AscWaitTixISRDone(asc_dvc, ASC_TID_TO_TIX(tid));
                   12370:     }
                   12371:     return (1);
                   12372: }
                   12373: 
                   12374: STATIC ulong
                   12375: AscGetOnePhyAddr(
                   12376:                     REG ASC_DVC_VAR asc_ptr_type * asc_dvc,
                   12377:                     uchar * buf_addr,
                   12378:                     ulong buf_size
                   12379: )
                   12380: {
                   12381:     ASC_MIN_SG_HEAD     sg_head;
                   12382: 
                   12383:     sg_head.entry_cnt = ASC_MIN_SG_LIST;
                   12384:     if (DvcGetSGList(asc_dvc, (uchar *) buf_addr,
                   12385:                   buf_size, (ASC_SG_HEAD *) & sg_head) != buf_size) {
                   12386:         return (0L);
                   12387:     }
                   12388:     if (sg_head.entry_cnt > 1) {
                   12389:         return (0L);
                   12390:     }
                   12391:     return (sg_head.sg_list[0].addr);
                   12392: }
                   12393: 
                   12394: STATIC void
                   12395: DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
                   12396: {
                   12397:     udelay(micro_sec);
                   12398: }
                   12399: 
                   12400: STATIC void
                   12401: DvcDelayNanoSecond(ASC_DVC_VAR asc_ptr_type * asc_dvc, ulong nano_sec)
                   12402: {
                   12403:     udelay((nano_sec + 999)/1000);
                   12404: }
                   12405: 
                   12406: ASC_INITFUNC(
                   12407: STATIC ulong
                   12408: AscGetEisaProductID(
                   12409:                        PortAddr iop_base
                   12410: )
                   12411: )
                   12412: {
                   12413:     PortAddr            eisa_iop;
                   12414:     ushort              product_id_high, product_id_low;
                   12415:     ulong               product_id;
                   12416: 
                   12417:     eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK;
                   12418:     product_id_low = inpw(eisa_iop);
                   12419:     product_id_high = inpw(eisa_iop + 2);
                   12420:     product_id = ((ulong) product_id_high << 16) | (ulong) product_id_low;
                   12421:     return (product_id);
                   12422: }
                   12423: 
                   12424: ASC_INITFUNC(
                   12425: STATIC PortAddr
                   12426: AscSearchIOPortAddrEISA(
                   12427:                            PortAddr iop_base
                   12428: )
                   12429: )
                   12430: {
                   12431:     ulong               eisa_product_id;
                   12432: 
                   12433:     if (iop_base == 0) {
                   12434:         iop_base = ASC_EISA_MIN_IOP_ADDR;
                   12435:     } else {
                   12436:         if (iop_base == ASC_EISA_MAX_IOP_ADDR)
                   12437:             return (0);
                   12438:         if ((iop_base & 0x0050) == 0x0050) {
                   12439:             iop_base += ASC_EISA_BIG_IOP_GAP;
                   12440:         } else {
                   12441:             iop_base += ASC_EISA_SMALL_IOP_GAP;
                   12442:         }
                   12443:     }
                   12444:     while (iop_base <= ASC_EISA_MAX_IOP_ADDR) {
                   12445:         eisa_product_id = AscGetEisaProductID(iop_base);
                   12446:         if ((eisa_product_id == ASC_EISA_ID_740) ||
                   12447:             (eisa_product_id == ASC_EISA_ID_750)) {
                   12448:             if (AscFindSignature(iop_base)) {
                   12449:                 inpw(iop_base + 4);
                   12450:                 return (iop_base);
                   12451:             }
                   12452:         }
                   12453:         if (iop_base == ASC_EISA_MAX_IOP_ADDR)
                   12454:             return (0);
                   12455:         if ((iop_base & 0x0050) == 0x0050) {
                   12456:             iop_base += ASC_EISA_BIG_IOP_GAP;
                   12457:         } else {
                   12458:             iop_base += ASC_EISA_SMALL_IOP_GAP;
                   12459:         }
                   12460:     }
                   12461:     return (0);
                   12462: }
                   12463: 
                   12464: STATIC int
                   12465: AscStartChip(
                   12466:                 PortAddr iop_base
                   12467: )
                   12468: {
                   12469:     AscSetChipControl(iop_base, 0);
                   12470:     if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
                   12471:         return (0);
                   12472:     }
                   12473:     return (1);
                   12474: }
                   12475: 
                   12476: STATIC int
                   12477: AscStopChip(
                   12478:                PortAddr iop_base
                   12479: )
                   12480: {
                   12481:     uchar               cc_val;
                   12482: 
                   12483:     cc_val = AscGetChipControl(iop_base) & (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
                   12484:     AscSetChipControl(iop_base, (uchar) (cc_val | CC_HALT));
                   12485:     AscSetChipIH(iop_base, INS_HALT);
                   12486:     AscSetChipIH(iop_base, INS_RFLAG_WTM);
                   12487:     if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
                   12488:         return (0);
                   12489:     }
                   12490:     return (1);
                   12491: }
                   12492: 
                   12493: STATIC int
                   12494: AscIsChipHalted(
                   12495:                    PortAddr iop_base
                   12496: )
                   12497: {
                   12498:     if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
                   12499:         if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
                   12500:             return (1);
                   12501:         }
                   12502:     }
                   12503:     return (0);
                   12504: }
                   12505: 
                   12506: STATIC void
                   12507: AscSetChipIH(
                   12508:                 PortAddr iop_base,
                   12509:                 ushort ins_code
                   12510: )
                   12511: {
                   12512:     AscSetBank(iop_base, 1);
                   12513:     AscWriteChipIH(iop_base, ins_code);
                   12514:     AscSetBank(iop_base, 0);
                   12515:     return;
                   12516: }
                   12517: 
                   12518: STATIC void
                   12519: AscAckInterrupt(
                   12520:                    PortAddr iop_base
                   12521: )
                   12522: {
                   12523:     uchar               host_flag;
                   12524:     uchar               risc_flag;
                   12525:     ushort              loop;
                   12526: 
                   12527:     loop = 0;
                   12528:     do {
                   12529:         risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
                   12530:         if (loop++ > 0x7FFF) {
                   12531:             break;
                   12532:         }
                   12533:     } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
                   12534:     host_flag = AscReadLramByte(iop_base, ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
                   12535:     AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
                   12536:                      (uchar) (host_flag | ASC_HOST_FLAG_ACK_INT));
                   12537:     AscSetChipStatus(iop_base, CIW_INT_ACK);
                   12538:     loop = 0;
                   12539:     while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
                   12540:         AscSetChipStatus(iop_base, CIW_INT_ACK);
                   12541:         if (loop++ > 3) {
                   12542:             break;
                   12543:         }
                   12544:     }
                   12545:     AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
                   12546:     return;
                   12547: }
                   12548: 
                   12549: STATIC void
                   12550: AscDisableInterrupt(
                   12551:                        PortAddr iop_base
                   12552: )
                   12553: {
                   12554:     ushort              cfg;
                   12555: 
                   12556:     cfg = AscGetChipCfgLsw(iop_base);
                   12557:     AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
                   12558:     return;
                   12559: }
                   12560: 
                   12561: STATIC void
                   12562: AscEnableInterrupt(
                   12563:                       PortAddr iop_base
                   12564: )
                   12565: {
                   12566:     ushort              cfg;
                   12567: 
                   12568:     cfg = AscGetChipCfgLsw(iop_base);
                   12569:     AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
                   12570:     return;
                   12571: }
                   12572: 
                   12573: 
                   12574: 
                   12575: STATIC void
                   12576: AscSetBank(
                   12577:               PortAddr iop_base,
                   12578:               uchar bank
                   12579: )
                   12580: {
                   12581:     uchar               val;
                   12582: 
                   12583:     val = AscGetChipControl(iop_base) &
                   12584:       (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET | CC_CHIP_RESET));
                   12585:     if (bank == 1) {
                   12586:         val |= CC_BANK_ONE;
                   12587:     } else if (bank == 2) {
                   12588:         val |= CC_DIAG | CC_BANK_ONE;
                   12589:     } else {
                   12590:         val &= ~CC_BANK_ONE;
                   12591:     }
                   12592:     AscSetChipControl(iop_base, val);
                   12593:     return;
                   12594: }
                   12595: 
                   12596: STATIC int
                   12597: AscResetChipAndScsiBus(
                   12598:                           ASC_DVC_VAR *asc_dvc
                   12599: )
                   12600: {
                   12601:     PortAddr    iop_base;
                   12602: 
                   12603:     iop_base = asc_dvc->iop_base;
                   12604:     while (AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) ;
                   12605:     AscStopChip(iop_base);
                   12606:     AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
                   12607:     DvcDelayNanoSecond(asc_dvc, 60000);
                   12608:     AscSetChipIH(iop_base, INS_RFLAG_WTM);
                   12609:     AscSetChipIH(iop_base, INS_HALT);
                   12610:     AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
                   12611:     AscSetChipControl(iop_base, CC_HALT);
                   12612:     DvcSleepMilliSecond(200);
                   12613:     AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
                   12614:     AscSetChipStatus(iop_base, 0);
                   12615:     return (AscIsChipHalted(iop_base));
                   12616: }
                   12617: 
                   12618: ASC_INITFUNC(
                   12619: STATIC ulong
                   12620: AscGetMaxDmaCount(
                   12621:                      ushort bus_type
                   12622: )
                   12623: )
                   12624: {
                   12625:     if (bus_type & ASC_IS_ISA)
                   12626:         return (ASC_MAX_ISA_DMA_COUNT);
                   12627:     else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
                   12628:         return (ASC_MAX_VL_DMA_COUNT);
                   12629:     return (ASC_MAX_PCI_DMA_COUNT);
                   12630: }
                   12631: 
                   12632: ASC_INITFUNC(
                   12633: STATIC ushort
                   12634: AscGetIsaDmaChannel(
                   12635:                        PortAddr iop_base
                   12636: )
                   12637: )
                   12638: {
                   12639:     ushort              channel;
                   12640: 
                   12641:     channel = AscGetChipCfgLsw(iop_base) & 0x0003;
                   12642:     if (channel == 0x03)
                   12643:         return (0);
                   12644:     else if (channel == 0x00)
                   12645:         return (7);
                   12646:     return (channel + 4);
                   12647: }
                   12648: 
                   12649: ASC_INITFUNC(
                   12650: STATIC ushort
                   12651: AscSetIsaDmaChannel(
                   12652:                        PortAddr iop_base,
                   12653:                        ushort dma_channel
                   12654: )
                   12655: )
                   12656: {
                   12657:     ushort              cfg_lsw;
                   12658:     uchar               value;
                   12659: 
                   12660:     if ((dma_channel >= 5) && (dma_channel <= 7)) {
                   12661:         if (dma_channel == 7)
                   12662:             value = 0x00;
                   12663:         else
                   12664:             value = dma_channel - 4;
                   12665:         cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
                   12666:         cfg_lsw |= value;
                   12667:         AscSetChipCfgLsw(iop_base, cfg_lsw);
                   12668:         return (AscGetIsaDmaChannel(iop_base));
                   12669:     }
                   12670:     return (0);
                   12671: }
                   12672: 
                   12673: ASC_INITFUNC(
                   12674: STATIC uchar
                   12675: AscSetIsaDmaSpeed(
                   12676:                      PortAddr iop_base,
                   12677:                      uchar speed_value
                   12678: )
                   12679: )
                   12680: {
                   12681:     speed_value &= 0x07;
                   12682:     AscSetBank(iop_base, 1);
                   12683:     AscWriteChipDmaSpeed(iop_base, speed_value);
                   12684:     AscSetBank(iop_base, 0);
                   12685:     return (AscGetIsaDmaSpeed(iop_base));
                   12686: }
                   12687: 
                   12688: ASC_INITFUNC(
                   12689: STATIC uchar
                   12690: AscGetIsaDmaSpeed(
                   12691:                      PortAddr iop_base
                   12692: )
                   12693: )
                   12694: {
                   12695:     uchar               speed_value;
                   12696: 
                   12697:     AscSetBank(iop_base, 1);
                   12698:     speed_value = AscReadChipDmaSpeed(iop_base);
                   12699:     speed_value &= 0x07;
                   12700:     AscSetBank(iop_base, 0);
                   12701:     return (speed_value);
                   12702: }
                   12703: 
                   12704: ASC_INITFUNC(
                   12705: STATIC ushort
                   12706: AscReadPCIConfigWord(
                   12707:     ASC_DVC_VAR asc_ptr_type *asc_dvc,
                   12708:     ushort pci_config_offset)
                   12709: )
                   12710: {
                   12711:     uchar       lsb, msb;
                   12712: 
                   12713:     lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset);
                   12714:     msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1);
                   12715:     return ((ushort) ((msb << 8) | lsb));
                   12716: }
                   12717: 
                   12718: ASC_INITFUNC(
                   12719: STATIC ushort 
                   12720: AscInitGetConfig(
                   12721:         ASC_DVC_VAR asc_ptr_type * asc_dvc
                   12722: )
                   12723: )
                   12724: {
                   12725:     ushort              warn_code;
                   12726:     PortAddr            iop_base;
                   12727:     ushort              PCIDeviceID;
                   12728:     ushort              PCIVendorID;
                   12729:     uchar               PCIRevisionID;
                   12730:     uchar               prevCmdRegBits;
                   12731: 
                   12732:     warn_code = 0;
                   12733:     iop_base = asc_dvc->iop_base;
                   12734:     asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
                   12735:     if (asc_dvc->err_code != 0) {
                   12736:         return (UW_ERR);
                   12737:     }
                   12738:     if (asc_dvc->bus_type == ASC_IS_PCI) {
                   12739:         PCIVendorID = AscReadPCIConfigWord(asc_dvc,
                   12740:                                     AscPCIConfigVendorIDRegister);
                   12741: 
                   12742:         PCIDeviceID = AscReadPCIConfigWord(asc_dvc,
                   12743:                                     AscPCIConfigDeviceIDRegister);
                   12744: 
                   12745:         PCIRevisionID = DvcReadPCIConfigByte(asc_dvc,
                   12746:                                     AscPCIConfigRevisionIDRegister);
                   12747: 
                   12748:         if (PCIVendorID != ASC_PCI_VENDORID) {
                   12749:             warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
                   12750:         }
                   12751:         prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc,
                   12752:                                     AscPCIConfigCommandRegister);
                   12753: 
                   12754:         if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster) !=
                   12755:             AscPCICmdRegBits_IOMemBusMaster) {
                   12756:             DvcWritePCIConfigByte(asc_dvc,
                   12757:                             AscPCIConfigCommandRegister,
                   12758:                             (prevCmdRegBits |
                   12759:                              AscPCICmdRegBits_IOMemBusMaster));
                   12760: 
                   12761:             if ((DvcReadPCIConfigByte(asc_dvc,
                   12762:                                 AscPCIConfigCommandRegister)
                   12763:                  & AscPCICmdRegBits_IOMemBusMaster)
                   12764:                 != AscPCICmdRegBits_IOMemBusMaster) {
                   12765:                 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
                   12766:             }
                   12767:         }
                   12768:         if ((PCIDeviceID == ASC_PCI_DEVICEID_1200A) ||
                   12769:             (PCIDeviceID == ASC_PCI_DEVICEID_1200B)) {
                   12770:             DvcWritePCIConfigByte(asc_dvc,
                   12771:                             AscPCIConfigLatencyTimer, 0x00);
                   12772:             if (DvcReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer)
                   12773:                 != 0x00) {
                   12774:                 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
                   12775:             }
                   12776:         } else if (PCIDeviceID == ASC_PCI_DEVICEID_ULTRA) {
                   12777:             if (DvcReadPCIConfigByte(asc_dvc,
                   12778:                                 AscPCIConfigLatencyTimer) < 0x20) {
                   12779:                 DvcWritePCIConfigByte(asc_dvc,
                   12780:                                     AscPCIConfigLatencyTimer, 0x20);
                   12781: 
                   12782:                 if (DvcReadPCIConfigByte(asc_dvc,
                   12783:                                     AscPCIConfigLatencyTimer) < 0x20) {
                   12784:                     warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
                   12785:                 }
                   12786:             }
                   12787:         }
                   12788:     }
                   12789: 
                   12790:     if (AscFindSignature(iop_base)) {
                   12791:         warn_code |= AscInitAscDvcVar(asc_dvc);
                   12792:         warn_code |= AscInitFromEEP(asc_dvc);
                   12793:         asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
                   12794:         if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) {
                   12795:             asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
                   12796:         }
                   12797:     } else {
                   12798:         asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
                   12799:     }
                   12800:     return(warn_code);
                   12801: }
                   12802: 
                   12803: ASC_INITFUNC(
                   12804: STATIC ushort
                   12805: AscInitSetConfig(
                   12806:                     ASC_DVC_VAR asc_ptr_type * asc_dvc
                   12807: )
                   12808: )
                   12809: {
                   12810:     ushort              warn_code = 0;
                   12811: 
                   12812:     asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
                   12813:     if (asc_dvc->err_code != 0)
                   12814:         return (UW_ERR);
                   12815:     if (AscFindSignature(asc_dvc->iop_base)) {
                   12816:         warn_code |= AscInitFromAscDvcVar(asc_dvc);
                   12817:         asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
                   12818:     } else {
                   12819:         asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
                   12820:     }
                   12821:     return (warn_code);
                   12822: }
                   12823: 
                   12824: ASC_INITFUNC(
                   12825: STATIC ushort
                   12826: AscInitFromAscDvcVar(
                   12827:                         ASC_DVC_VAR asc_ptr_type * asc_dvc
                   12828: )
                   12829: )
                   12830: {
                   12831:     PortAddr            iop_base;
                   12832:     ushort              cfg_msw;
                   12833:     ushort              warn_code;
                   12834:     ushort              pci_device_id;
                   12835: 
                   12836:     iop_base = asc_dvc->iop_base;
                   12837:     pci_device_id = asc_dvc->cfg->pci_device_id;
                   12838:     warn_code = 0;
                   12839:     cfg_msw = AscGetChipCfgMsw(iop_base);
                   12840:     if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
                   12841:         cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
                   12842:         warn_code |= ASC_WARN_CFG_MSW_RECOVER;
                   12843:         AscSetChipCfgMsw(iop_base, cfg_msw);
                   12844:     }
                   12845:     if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
                   12846:         asc_dvc->cfg->cmd_qng_enabled) {
                   12847:         asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
                   12848:         warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
                   12849:     }
                   12850:     if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
                   12851:         warn_code |= ASC_WARN_AUTO_CONFIG;
                   12852:     }
                   12853:     if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
                   12854:         if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
                   12855:             != asc_dvc->irq_no) {
                   12856:             asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
                   12857:         }
                   12858:     }
                   12859:     if (asc_dvc->bus_type & ASC_IS_PCI) {
                   12860:         cfg_msw &= 0xFFC0;
                   12861:         AscSetChipCfgMsw(iop_base, cfg_msw);
                   12862:         if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
                   12863:         } else {
                   12864:             if ((pci_device_id == ASC_PCI_DEVICE_ID_REV_A) ||
                   12865:                 (pci_device_id == ASC_PCI_DEVICE_ID_REV_B)) {
                   12866:                 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
                   12867:                 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
                   12868:             }
                   12869:         }
                   12870:     } else if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
                   12871:         if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
                   12872:             == ASC_CHIP_VER_ASYN_BUG) {
                   12873:             asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
                   12874:         }
                   12875:     }
                   12876:     if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
                   12877:         asc_dvc->cfg->chip_scsi_id) {
                   12878:         asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
                   12879:     }
                   12880:     if (asc_dvc->bus_type & ASC_IS_ISA) {
                   12881:         AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
                   12882:         AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
                   12883:     }
                   12884:     return (warn_code);
                   12885: }
                   12886: 
                   12887: ASC_INITFUNC(
                   12888: STATIC ushort
                   12889: AscInitAsc1000Driver(
                   12890:                         ASC_DVC_VAR asc_ptr_type * asc_dvc
                   12891: )
                   12892: )
                   12893: {
                   12894:     ushort              warn_code;
                   12895:     PortAddr            iop_base;
                   12896:     extern ushort       _asc_mcode_size;
                   12897:     extern ulong        _asc_mcode_chksum;
                   12898:     extern uchar        _asc_mcode_buf[];
                   12899: 
                   12900:     iop_base = asc_dvc->iop_base;
                   12901:     warn_code = 0;
                   12902:     if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
                   12903:         !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
                   12904:         AscResetChipAndScsiBus(asc_dvc);
                   12905:         DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
                   12906:     }
                   12907:     asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
                   12908:     if (asc_dvc->err_code != 0)
                   12909:         return (UW_ERR);
                   12910:     if (!AscFindSignature(asc_dvc->iop_base)) {
                   12911:         asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
                   12912:         return (warn_code);
                   12913:     }
                   12914:     AscDisableInterrupt(iop_base);
                   12915:     warn_code |= AscInitLram(asc_dvc);
                   12916:     if (asc_dvc->err_code != 0)
                   12917:         return (UW_ERR);
                   12918:     if (AscLoadMicroCode(iop_base, 0, (ushort *) _asc_mcode_buf,
                   12919:                          _asc_mcode_size) != _asc_mcode_chksum) {
                   12920:         asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
                   12921:         return (warn_code);
                   12922:     }
                   12923:     warn_code |= AscInitMicroCodeVar(asc_dvc);
                   12924:     asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
                   12925:     AscEnableInterrupt(iop_base);
                   12926:     return (warn_code);
                   12927: }
                   12928: 
                   12929: ASC_INITFUNC(
                   12930: STATIC ushort
                   12931: AscInitAscDvcVar(
                   12932:                     ASC_DVC_VAR asc_ptr_type * asc_dvc
                   12933: )
                   12934: )
                   12935: {
                   12936:     int                 i;
                   12937:     PortAddr            iop_base;
                   12938:     ushort              warn_code;
                   12939:     uchar               chip_version;
                   12940: 
                   12941:     iop_base = asc_dvc->iop_base;
                   12942:     warn_code = 0;
                   12943:     asc_dvc->err_code = 0;
                   12944:     if ((asc_dvc->bus_type &
                   12945:          (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
                   12946:         asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
                   12947:     }
                   12948:     AscSetChipControl(iop_base, CC_HALT);
                   12949:     AscSetChipStatus(iop_base, 0);
                   12950:     asc_dvc->bug_fix_cntl = 0;
                   12951:     asc_dvc->pci_fix_asyn_xfer = 0;
                   12952:     asc_dvc->pci_fix_asyn_xfer_always = 0;
                   12953:     asc_dvc->init_state = 0;
                   12954:     asc_dvc->sdtr_done = 0;
                   12955:     asc_dvc->cur_total_qng = 0;
                   12956:     asc_dvc->is_in_int = 0;
                   12957:     asc_dvc->in_critical_cnt = 0;
                   12958:     asc_dvc->last_q_shortage = 0;
                   12959:     asc_dvc->use_tagged_qng = 0;
                   12960:     asc_dvc->no_scam = 0;
                   12961:     asc_dvc->unit_not_ready = 0;
                   12962:     asc_dvc->queue_full_or_busy = 0;
                   12963:     asc_dvc->redo_scam = 0 ;
                   12964:     asc_dvc->res2 = 0 ;
                   12965:     asc_dvc->host_init_sdtr_index = 0 ;
                   12966:     asc_dvc->res7 = 0 ;
                   12967:     asc_dvc->res8 = 0 ;
                   12968:     asc_dvc->cfg->can_tagged_qng = 0 ;
                   12969:     asc_dvc->cfg->cmd_qng_enabled = 0;
                   12970:     asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
                   12971:     asc_dvc->init_sdtr = 0;
                   12972:     asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
                   12973:     asc_dvc->scsi_reset_wait = 3;
                   12974:     asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
                   12975:     asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
                   12976:     asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
                   12977:     asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
                   12978:     asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
                   12979:     asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
                   12980:     asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
                   12981:       ASC_LIB_VERSION_MINOR;
                   12982:     chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
                   12983:     asc_dvc->cfg->chip_version = chip_version;
                   12984:     asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
                   12985:     asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
                   12986:     asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
                   12987:     asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
                   12988:     asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
                   12989:     asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
                   12990:     asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
                   12991:     asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
                   12992:     asc_dvc->max_sdtr_index = 7;
                   12993:     if ((asc_dvc->bus_type & ASC_IS_PCI) &&
                   12994:         (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
                   12995:         asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
                   12996:         asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
                   12997:         asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
                   12998:         asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
                   12999:         asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
                   13000:         asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
                   13001:         asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
                   13002:         asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
                   13003:         asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
                   13004:         asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
                   13005:         asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
                   13006:         asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
                   13007:         asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
                   13008:         asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
                   13009:         asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
                   13010:         asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
                   13011:         asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
                   13012:         asc_dvc->max_sdtr_index = 15;
                   13013:         if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150)
                   13014:         {
                   13015:             AscSetExtraControl(iop_base,
                   13016:                 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
                   13017:         } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
                   13018:             AscSetExtraControl(iop_base,
                   13019:                 (SEC_ACTIVE_NEGATE | SEC_ENABLE_FILTER));
                   13020:         }
                   13021:     }
                   13022:     if (asc_dvc->bus_type == ASC_IS_PCI) {
                   13023:            AscSetExtraControl(iop_base, (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
                   13024:     }
                   13025: 
                   13026:     asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
                   13027:     if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
                   13028:         AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
                   13029:         asc_dvc->bus_type = ASC_IS_ISAPNP;
                   13030:     }
                   13031:     if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
                   13032:         asc_dvc->cfg->isa_dma_channel = (uchar) AscGetIsaDmaChannel(iop_base);
                   13033:     }
                   13034:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   13035:         asc_dvc->cur_dvc_qng[i] = 0;
                   13036:         asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
                   13037:         asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *) 0L;
                   13038:         asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *) 0L;
                   13039:         asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
                   13040:     }
                   13041:     return (warn_code);
                   13042: }
                   13043: 
                   13044: ASC_INITFUNC(
                   13045: STATIC ushort
                   13046: AscInitFromEEP(
                   13047:                   ASC_DVC_VAR asc_ptr_type * asc_dvc
                   13048: )
                   13049: )
                   13050: {
                   13051:     ASCEEP_CONFIG       eep_config_buf;
                   13052:     ASCEEP_CONFIG       *eep_config;
                   13053:     PortAddr            iop_base;
                   13054:     ushort              chksum;
                   13055:     ushort              warn_code;
                   13056:     ushort              cfg_msw, cfg_lsw;
                   13057:     int                 i;
                   13058:     int                 write_eep = 0;
                   13059: 
                   13060:     iop_base = asc_dvc->iop_base;
                   13061:     warn_code = 0;
                   13062:     AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
                   13063:     AscStopQueueExe(iop_base);
                   13064:     if ((AscStopChip(iop_base) == FALSE) ||
                   13065:         (AscGetChipScsiCtrl(iop_base) != 0)) {
                   13066:         asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
                   13067:         AscResetChipAndScsiBus(asc_dvc);
                   13068:         DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
                   13069:     }
                   13070:     if (AscIsChipHalted(iop_base) == FALSE) {
                   13071:         asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
                   13072:         return (warn_code);
                   13073:     }
                   13074:     AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
                   13075:     if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
                   13076:         asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
                   13077:         return (warn_code);
                   13078:     }
                   13079:     eep_config = (ASCEEP_CONFIG *) & eep_config_buf;
                   13080:     cfg_msw = AscGetChipCfgMsw(iop_base);
                   13081:     cfg_lsw = AscGetChipCfgLsw(iop_base);
                   13082:     if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
                   13083:         cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
                   13084:         warn_code |= ASC_WARN_CFG_MSW_RECOVER;
                   13085:         AscSetChipCfgMsw(iop_base, cfg_msw);
                   13086:     }
                   13087:     chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
                   13088:     if (chksum == 0) {
                   13089:         chksum = 0xaa55;
                   13090:     }
                   13091:     if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
                   13092:         warn_code |= ASC_WARN_AUTO_CONFIG;
                   13093:         if (asc_dvc->cfg->chip_version == 3) {
                   13094:             if (eep_config->cfg_lsw != cfg_lsw) {
                   13095:                 warn_code |= ASC_WARN_EEPROM_RECOVER;
                   13096:                 eep_config->cfg_lsw = AscGetChipCfgLsw(iop_base);
                   13097:             }
                   13098:             if (eep_config->cfg_msw != cfg_msw) {
                   13099:                 warn_code |= ASC_WARN_EEPROM_RECOVER;
                   13100:                 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
                   13101:             }
                   13102:         }
                   13103:     }
                   13104:     eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
                   13105:     eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
                   13106:     if (chksum != eep_config->chksum) {
                   13107:             if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
                   13108:                     ASC_CHIP_VER_PCI_ULTRA_3050 )
                   13109:             {
                   13110:                 eep_config->init_sdtr = 0xFF;
                   13111:                 eep_config->disc_enable = 0xFF;
                   13112:                 eep_config->start_motor = 0xFF;
                   13113:                 eep_config->use_cmd_qng = 0;
                   13114:                 eep_config->max_total_qng = 0xF0;
                   13115:                 eep_config->max_tag_qng = 0x20;
                   13116:                 eep_config->cntl = 0xBFFF;
                   13117:                 eep_config->chip_scsi_id = 7;
                   13118:                 eep_config->no_scam = 0;
                   13119:                 eep_config->adapter_info[0] = 0;
                   13120:                 eep_config->adapter_info[1] = 0;
                   13121:                 eep_config->adapter_info[2] = 0;
                   13122:                 eep_config->adapter_info[3] = 0;
                   13123:                 eep_config->adapter_info[4] = 0;
                   13124:                 /* Indicate EEPROM-less board. */
                   13125:                 eep_config->adapter_info[5] = 0xBB;
                   13126:             } else {
                   13127:                 write_eep = 1 ;
                   13128:                 warn_code |= ASC_WARN_EEPROM_CHKSUM ;
                   13129:             }
                   13130:     }
                   13131:     asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr ;
                   13132:     asc_dvc->cfg->disc_enable = eep_config->disc_enable;
                   13133:     asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
                   13134:     asc_dvc->cfg->isa_dma_speed = eep_config->isa_dma_speed;
                   13135:     asc_dvc->start_motor = eep_config->start_motor;
                   13136:     asc_dvc->dvc_cntl = eep_config->cntl;
                   13137:     asc_dvc->no_scam = eep_config->no_scam;
                   13138:     asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
                   13139:     asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
                   13140:     asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
                   13141:     asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
                   13142:     asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
                   13143:     asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
                   13144:     if (!AscTestExternalLram(asc_dvc)) {
                   13145:         if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA)) {
                   13146:             eep_config->max_total_qng = ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
                   13147:             eep_config->max_tag_qng = ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
                   13148:         } else {
                   13149:             eep_config->cfg_msw |= 0x0800;
                   13150:             cfg_msw |= 0x0800;
                   13151:             AscSetChipCfgMsw(iop_base, cfg_msw);
                   13152:             eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
                   13153:             eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
                   13154:         }
                   13155:     } else {
                   13156:     }
                   13157:     if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
                   13158:         eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
                   13159:     }
                   13160:     if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
                   13161:         eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
                   13162:     }
                   13163:     if (eep_config->max_tag_qng > eep_config->max_total_qng) {
                   13164:         eep_config->max_tag_qng = eep_config->max_total_qng;
                   13165:     }
                   13166:     if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
                   13167:         eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
                   13168:     }
                   13169:     asc_dvc->max_total_qng = eep_config->max_total_qng;
                   13170:     if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
                   13171:         eep_config->use_cmd_qng) {
                   13172:         eep_config->disc_enable = eep_config->use_cmd_qng;
                   13173:         warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
                   13174:     }
                   13175:     if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
                   13176:         asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
                   13177:     }
                   13178:     eep_config->chip_scsi_id &= ASC_MAX_TID;
                   13179:     asc_dvc->cfg->chip_scsi_id = eep_config->chip_scsi_id;
                   13180:     if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
                   13181:         !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
                   13182:         asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
                   13183:     }
                   13184: 
                   13185:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   13186:         asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
                   13187:         asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
                   13188:         asc_dvc->cfg->sdtr_period_offset[i] =
                   13189:             (uchar) (ASC_DEF_SDTR_OFFSET |
                   13190:                      (asc_dvc->host_init_sdtr_index << 4));
                   13191:     }
                   13192:     eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
                   13193:     if (write_eep) {
                   13194:         (void) AscSetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
                   13195:     }
                   13196:     return (warn_code);
                   13197: }
                   13198: 
                   13199: ASC_INITFUNC(
                   13200: STATIC ushort
                   13201: AscInitMicroCodeVar(
                   13202:                        ASC_DVC_VAR asc_ptr_type * asc_dvc
                   13203: )
                   13204: )
                   13205: {
                   13206:     int                 i;
                   13207:     ushort              warn_code;
                   13208:     PortAddr            iop_base;
                   13209:     ulong               phy_addr;
                   13210: 
                   13211:     iop_base = asc_dvc->iop_base;
                   13212:     warn_code = 0;
                   13213:     for (i = 0; i <= ASC_MAX_TID; i++) {
                   13214:         AscPutMCodeInitSDTRAtID(iop_base, i,
                   13215:                                 asc_dvc->cfg->sdtr_period_offset[i]
                   13216: );
                   13217:     }
                   13218:     AscInitQLinkVar(asc_dvc);
                   13219:     AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
                   13220:                      asc_dvc->cfg->disc_enable);
                   13221:     AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
                   13222:                      ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
                   13223:     if ((phy_addr = AscGetOnePhyAddr(asc_dvc,
                   13224:                                  (uchar *) asc_dvc->cfg->overrun_buf,
                   13225:                                      ASC_OVERRUN_BSIZE)) == 0L) {
                   13226:         asc_dvc->err_code |= ASC_IERR_GET_PHY_ADDR;
                   13227:     } else {
                   13228:         phy_addr = (phy_addr & 0xFFFFFFF8UL) + 8;
                   13229:         AscWriteLramDWord(iop_base, ASCV_OVERRUN_PADDR_D, phy_addr);
                   13230:         AscWriteLramDWord(iop_base, ASCV_OVERRUN_BSIZE_D,
                   13231:                           ASC_OVERRUN_BSIZE - 8);
                   13232:     }
                   13233:     asc_dvc->cfg->mcode_date = AscReadLramWord(iop_base,
                   13234:                                                (ushort) ASCV_MC_DATE_W);
                   13235:     asc_dvc->cfg->mcode_version = AscReadLramWord(iop_base,
                   13236:                                                   (ushort) ASCV_MC_VER_W);
                   13237:     AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
                   13238:     if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
                   13239:         asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
                   13240:         return (warn_code);
                   13241:     }
                   13242:     if (AscStartChip(iop_base) != 1) {
                   13243:         asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
                   13244:         return (warn_code);
                   13245:     }
                   13246:     return (warn_code);
                   13247: }
                   13248: 
                   13249: ASC_INITFUNC(
                   13250: STATIC int
                   13251: AscTestExternalLram(
                   13252:                        ASC_DVC_VAR asc_ptr_type * asc_dvc
                   13253: )
                   13254: )
                   13255: {
                   13256:     PortAddr            iop_base;
                   13257:     ushort              q_addr;
                   13258:     ushort              saved_word;
                   13259:     int                 sta;
                   13260: 
                   13261:     iop_base = asc_dvc->iop_base;
                   13262:     sta = 0;
                   13263:     q_addr = ASC_QNO_TO_QADDR(241);
                   13264:     saved_word = AscReadLramWord(iop_base, q_addr);
                   13265:     AscSetChipLramAddr(iop_base, q_addr);
                   13266:     AscSetChipLramData(iop_base, 0x55AA);
                   13267:     DvcSleepMilliSecond(10);
                   13268:     AscSetChipLramAddr(iop_base, q_addr);
                   13269:     if (AscGetChipLramData(iop_base) == 0x55AA) {
                   13270:         sta = 1;
                   13271:         AscWriteLramWord(iop_base, q_addr, saved_word);
                   13272:     }
                   13273:     return (sta);
                   13274: }
                   13275: 
                   13276: ASC_INITFUNC(
                   13277: STATIC int
                   13278: AscWriteEEPCmdReg(
                   13279:                      PortAddr iop_base,
                   13280:                      uchar cmd_reg
                   13281: )
                   13282: )
                   13283: {
                   13284:     uchar               read_back;
                   13285:     int                 retry;
                   13286: 
                   13287:     retry = 0;
                   13288:     while (TRUE) {
                   13289:         AscSetChipEEPCmd(iop_base, cmd_reg);
                   13290:         DvcSleepMilliSecond(1);
                   13291:         read_back = AscGetChipEEPCmd(iop_base);
                   13292:         if (read_back == cmd_reg) {
                   13293:             return (1);
                   13294:         }
                   13295:         if (retry++ > ASC_EEP_MAX_RETRY) {
                   13296:             return (0);
                   13297:         }
                   13298:     }
                   13299: }
                   13300: 
                   13301: ASC_INITFUNC(
                   13302: STATIC int
                   13303: AscWriteEEPDataReg(
                   13304:                       PortAddr iop_base,
                   13305:                       ushort data_reg
                   13306: )
                   13307: )
                   13308: {
                   13309:     ushort              read_back;
                   13310:     int                 retry;
                   13311: 
                   13312:     retry = 0;
                   13313:     while (TRUE) {
                   13314:         AscSetChipEEPData(iop_base, data_reg);
                   13315:         DvcSleepMilliSecond(1);
                   13316:         read_back = AscGetChipEEPData(iop_base);
                   13317:         if (read_back == data_reg) {
                   13318:             return (1);
                   13319:         }
                   13320:         if (retry++ > ASC_EEP_MAX_RETRY) {
                   13321:             return (0);
                   13322:         }
                   13323:     }
                   13324: }
                   13325: 
                   13326: ASC_INITFUNC(
                   13327: STATIC void
                   13328: AscWaitEEPRead(
                   13329:                   void
                   13330: )
                   13331: )
                   13332: {
                   13333:     DvcSleepMilliSecond(1);
                   13334:     return;
                   13335: }
                   13336: 
                   13337: ASC_INITFUNC(
                   13338: STATIC void
                   13339: AscWaitEEPWrite(
                   13340:                    void
                   13341: )
                   13342: )
                   13343: {
                   13344:     DvcSleepMilliSecond(20);
                   13345:     return;
                   13346: }
                   13347: 
                   13348: ASC_INITFUNC(
                   13349: STATIC ushort
                   13350: AscReadEEPWord(
                   13351:                   PortAddr iop_base,
                   13352:                   uchar addr
                   13353: )
                   13354: )
                   13355: {
                   13356:     ushort              read_wval;
                   13357:     uchar               cmd_reg;
                   13358: 
                   13359:     AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
                   13360:     AscWaitEEPRead();
                   13361:     cmd_reg = addr | ASC_EEP_CMD_READ;
                   13362:     AscWriteEEPCmdReg(iop_base, cmd_reg);
                   13363:     AscWaitEEPRead();
                   13364:     read_wval = AscGetChipEEPData(iop_base);
                   13365:     AscWaitEEPRead();
                   13366:     return (read_wval);
                   13367: }
                   13368: 
                   13369: ASC_INITFUNC(
                   13370: STATIC ushort
                   13371: AscWriteEEPWord(
                   13372:                    PortAddr iop_base,
                   13373:                    uchar addr,
                   13374:                    ushort word_val
                   13375: )
                   13376: )
                   13377: {
                   13378:     ushort              read_wval;
                   13379: 
                   13380:     read_wval = AscReadEEPWord(iop_base, addr);
                   13381:     if (read_wval != word_val) {
                   13382:         AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
                   13383:         AscWaitEEPRead();
                   13384:         AscWriteEEPDataReg(iop_base, word_val);
                   13385:         AscWaitEEPRead();
                   13386:         AscWriteEEPCmdReg(iop_base,
                   13387:                           (uchar) ((uchar) ASC_EEP_CMD_WRITE | addr));
                   13388:         AscWaitEEPWrite();
                   13389:         AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
                   13390:         AscWaitEEPRead();
                   13391:         return (AscReadEEPWord(iop_base, addr));
                   13392:     }
                   13393:     return (read_wval);
                   13394: }
                   13395: 
                   13396: ASC_INITFUNC(
                   13397: STATIC ushort
                   13398: AscGetEEPConfig(
                   13399:                    PortAddr iop_base,
                   13400:                    ASCEEP_CONFIG * cfg_buf, ushort bus_type
                   13401: )
                   13402: )
                   13403: {
                   13404:     ushort              wval;
                   13405:     ushort              sum;
                   13406:     ushort      *wbuf;
                   13407:     int                 cfg_beg;
                   13408:     int                 cfg_end;
                   13409:     int                 s_addr;
                   13410:     int                 isa_pnp_wsize;
                   13411: 
                   13412:     wbuf = (ushort *) cfg_buf;
                   13413:     sum = 0;
                   13414:     isa_pnp_wsize = 0;
                   13415:     for (s_addr = 0; s_addr < (2 + isa_pnp_wsize); s_addr++, wbuf++) {
                   13416:         wval = AscReadEEPWord(iop_base, (uchar) s_addr);
                   13417:         sum += wval;
                   13418:         *wbuf = wval;
                   13419:     }
                   13420:     if (bus_type & ASC_IS_VL) {
                   13421:         cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
                   13422:         cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
                   13423:     } else {
                   13424:         cfg_beg = ASC_EEP_DVC_CFG_BEG;
                   13425:         cfg_end = ASC_EEP_MAX_DVC_ADDR;
                   13426:     }
                   13427:     for (s_addr = cfg_beg; s_addr <= (cfg_end - 1);
                   13428:          s_addr++, wbuf++) {
                   13429:         wval = AscReadEEPWord(iop_base, (uchar) s_addr);
                   13430:         sum += wval;
                   13431:         *wbuf = wval;
                   13432:     }
                   13433:     *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
                   13434:     return (sum);
                   13435: }
                   13436: 
                   13437: ASC_INITFUNC(
                   13438: STATIC int
                   13439: AscSetEEPConfigOnce(
                   13440:                        PortAddr iop_base,
                   13441:                        ASCEEP_CONFIG * cfg_buf, ushort bus_type
                   13442: )
                   13443: )
                   13444: {
                   13445:     int                 n_error;
                   13446:     ushort      *wbuf;
                   13447:     ushort              sum;
                   13448:     int                 s_addr;
                   13449:     int                 cfg_beg;
                   13450:     int                 cfg_end;
                   13451: 
                   13452:     wbuf = (ushort *) cfg_buf;
                   13453:     n_error = 0;
                   13454:     sum = 0;
                   13455:     for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
                   13456:         sum += *wbuf;
                   13457:         if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
                   13458:             n_error++;
                   13459:         }
                   13460:     }
                   13461:     if (bus_type & ASC_IS_VL) {
                   13462:         cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
                   13463:         cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
                   13464:     } else {
                   13465:         cfg_beg = ASC_EEP_DVC_CFG_BEG;
                   13466:         cfg_end = ASC_EEP_MAX_DVC_ADDR;
                   13467:     }
                   13468:     for (s_addr = cfg_beg; s_addr <= (cfg_end - 1);
                   13469:          s_addr++, wbuf++) {
                   13470:         sum += *wbuf;
                   13471:         if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
                   13472:             n_error++;
                   13473:         }
                   13474:     }
                   13475:     *wbuf = sum;
                   13476:     if (sum != AscWriteEEPWord(iop_base, (uchar) s_addr, sum)) {
                   13477:         n_error++;
                   13478:     }
                   13479:     wbuf = (ushort *) cfg_buf;
                   13480:     for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
                   13481:         if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
                   13482:             n_error++;
                   13483:         }
                   13484:     }
                   13485:     for (s_addr = cfg_beg; s_addr <= cfg_end;
                   13486:          s_addr++, wbuf++) {
                   13487:         if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
                   13488:             n_error++;
                   13489:         }
                   13490:     }
                   13491:     return (n_error);
                   13492: }
                   13493: 
                   13494: ASC_INITFUNC(
                   13495: STATIC int
                   13496: AscSetEEPConfig(
                   13497:                    PortAddr iop_base,
                   13498:                    ASCEEP_CONFIG * cfg_buf, ushort bus_type
                   13499: )
                   13500: )
                   13501: {
                   13502:     int            retry;
                   13503:     int            n_error;
                   13504: 
                   13505:     retry = 0;
                   13506:     while (TRUE) {
                   13507:         if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
                   13508:                                            bus_type)) == 0) {
                   13509:             break;
                   13510:         }
                   13511:         if (++retry > ASC_EEP_MAX_RETRY) {
                   13512:             break;
                   13513:         }
                   13514:     }
                   13515:     return (n_error);
                   13516: }
                   13517: 
                   13518: STATIC void
                   13519: AscAsyncFix(
                   13520:                ASC_DVC_VAR asc_ptr_type *asc_dvc,
                   13521:                uchar tid_no,
                   13522:                ASC_SCSI_INQUIRY *inq)
                   13523: {
                   13524:     uchar                dvc_type;
                   13525:     ASC_SCSI_BIT_ID_TYPE tid_bits;
                   13526: 
                   13527:     dvc_type = inq->byte0.peri_dvc_type;
                   13528:     tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
                   13529: 
                   13530:     if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) {
                   13531:         if (!(asc_dvc->init_sdtr & tid_bits)) {
                   13532:             if ((dvc_type == SCSI_TYPE_CDROM) &&
                   13533:                 (AscCompareString((uchar *) inq->vendor_id,
                   13534:                     (uchar *) "HP ", 3) == 0)) {
                   13535:                 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
                   13536:             }
                   13537:             asc_dvc->pci_fix_asyn_xfer |= tid_bits;
                   13538:             if ((dvc_type == SCSI_TYPE_PROC) ||
                   13539:                 (dvc_type == SCSI_TYPE_SCANNER)) {
                   13540:                 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
                   13541:             }
                   13542:             if ((dvc_type == SCSI_TYPE_SASD) &&
                   13543:                 (AscCompareString((uchar *) inq->vendor_id,
                   13544:                  (uchar *) "TANDBERG", 8) == 0) &&
                   13545:                 (AscCompareString((uchar *) inq->product_id,
                   13546:                  (uchar *) " TDC 36", 7) == 0)) {
                   13547:                 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
                   13548:             }
                   13549:             if ((dvc_type == SCSI_TYPE_SASD) &&
                   13550:                 (AscCompareString((uchar *) inq->vendor_id,
                   13551:                  (uchar *) "WANGTEK ", 8) == 0)) {
                   13552:                 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
                   13553:             }
                   13554: 
                   13555:             if ((dvc_type == SCSI_TYPE_CDROM) &&
                   13556:                 (AscCompareString((uchar *) inq->vendor_id,
                   13557:                  (uchar *) "NEC     ", 8) == 0) &&
                   13558:                 (AscCompareString((uchar *) inq->product_id,
                   13559:                  (uchar *) "CD-ROM DRIVE    ", 16) == 0)) {
                   13560:                 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
                   13561:             }
                   13562: 
                   13563:             if ((dvc_type == SCSI_TYPE_CDROM) &&
                   13564:                 (AscCompareString((uchar *) inq->vendor_id,
                   13565:                  (uchar *) "YAMAHA", 6) == 0) &&
                   13566:                 (AscCompareString((uchar *) inq->product_id,
                   13567:                  (uchar *) "CDR400", 6) == 0)) {
                   13568:                 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
                   13569:             }
                   13570:             if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
                   13571:                 AscSetRunChipSynRegAtID(asc_dvc->iop_base, tid_no,
                   13572:                                         ASYN_SDTR_DATA_FIX_PCI_REV_AB);
                   13573:             }
                   13574:         }
                   13575:     }
                   13576:     return;
                   13577: }
                   13578: 
                   13579: STATIC int
                   13580: AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq)
                   13581: {
                   13582:     if ((inq->add_len >= 32) &&
                   13583:         (AscCompareString((uchar *) inq->vendor_id,
                   13584:             (uchar *) "QUANTUM XP34301", 15) == 0) &&
                   13585:         (AscCompareString((uchar *) inq->product_rev_level,
                   13586:             (uchar *) "1071", 4) == 0))
                   13587:     {
                   13588:         return 0;
                   13589:     }
                   13590:     return 1;
                   13591: }
                   13592: 
                   13593: STATIC void
                   13594: AscInquiryHandling(ASC_DVC_VAR asc_ptr_type *asc_dvc,
                   13595:                    uchar tid_no, ASC_SCSI_INQUIRY *inq)
                   13596: {
                   13597:     ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no);
                   13598:     ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng;
                   13599: 
                   13600:     orig_init_sdtr = asc_dvc->init_sdtr;
                   13601:     orig_use_tagged_qng = asc_dvc->use_tagged_qng;
                   13602: 
                   13603:     asc_dvc->init_sdtr &= ~tid_bit;
                   13604:     asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
                   13605:     asc_dvc->use_tagged_qng &= ~tid_bit;
                   13606: 
                   13607:     if (inq->byte3.rsp_data_fmt >= 2 || inq->byte2.ansi_apr_ver >= 2) {
                   13608:         if ((asc_dvc->cfg->sdtr_enable & tid_bit) && inq->byte7.Sync) {
                   13609:             asc_dvc->init_sdtr |= tid_bit;
                   13610:         }
                   13611:         if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) && inq->byte7.CmdQue) {
                   13612:             if (AscTagQueuingSafe(inq)) {
                   13613:                 asc_dvc->use_tagged_qng |= tid_bit;
                   13614:                 asc_dvc->cfg->can_tagged_qng |= tid_bit;
                   13615:             }
                   13616:         }
                   13617:     }
                   13618:     if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) {
                   13619:         AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
                   13620:                          asc_dvc->cfg->disc_enable);
                   13621:         AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
                   13622:                          asc_dvc->use_tagged_qng);
                   13623:         AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
                   13624:                          asc_dvc->cfg->can_tagged_qng);
                   13625: 
                   13626:         asc_dvc->max_dvc_qng[tid_no] =
                   13627:           asc_dvc->cfg->max_tag_qng[tid_no];
                   13628:         AscWriteLramByte(asc_dvc->iop_base,
                   13629:                          (ushort) (ASCV_MAX_DVC_QNG_BEG + tid_no),
                   13630:                          asc_dvc->max_dvc_qng[tid_no]);
                   13631:     }
                   13632:     if (orig_init_sdtr != asc_dvc->init_sdtr) {
                   13633:         AscAsyncFix(asc_dvc, tid_no, inq);
                   13634:     }
                   13635:     return;
                   13636: }
                   13637: 
                   13638: STATIC int
                   13639: AscCompareString(
                   13640:                     ruchar * str1,
                   13641:                     ruchar * str2,
                   13642:                     int len
                   13643: )
                   13644: {
                   13645:     int                 i;
                   13646:     int                 diff;
                   13647: 
                   13648:     for (i = 0; i < len; i++) {
                   13649:         diff = (int) (str1[i] - str2[i]);
                   13650:         if (diff != 0)
                   13651:             return (diff);
                   13652:     }
                   13653:     return (0);
                   13654: }
                   13655: 
                   13656: STATIC uchar
                   13657: AscReadLramByte(
                   13658:                    PortAddr iop_base,
                   13659:                    ushort addr
                   13660: )
                   13661: {
                   13662:     uchar               byte_data;
                   13663:     ushort              word_data;
                   13664: 
                   13665:     if (isodd_word(addr)) {
                   13666:         AscSetChipLramAddr(iop_base, addr - 1);
                   13667:         word_data = AscGetChipLramData(iop_base);
                   13668:         byte_data = (uchar) ((word_data >> 8) & 0xFF);
                   13669:     } else {
                   13670:         AscSetChipLramAddr(iop_base, addr);
                   13671:         word_data = AscGetChipLramData(iop_base);
                   13672:         byte_data = (uchar) (word_data & 0xFF);
                   13673:     }
                   13674:     return (byte_data);
                   13675: }
                   13676: 
                   13677: STATIC ushort
                   13678: AscReadLramWord(
                   13679:                    PortAddr iop_base,
                   13680:                    ushort addr
                   13681: )
                   13682: {
                   13683:     ushort              word_data;
                   13684: 
                   13685:     AscSetChipLramAddr(iop_base, addr);
                   13686:     word_data = AscGetChipLramData(iop_base);
                   13687:     return (word_data);
                   13688: }
                   13689: 
                   13690: STATIC ulong
                   13691: AscReadLramDWord(
                   13692:                     PortAddr iop_base,
                   13693:                     ushort addr
                   13694: )
                   13695: {
                   13696:     ushort              val_low, val_high;
                   13697:     ulong               dword_data;
                   13698: 
                   13699:     AscSetChipLramAddr(iop_base, addr);
                   13700:     val_low = AscGetChipLramData(iop_base);
                   13701:     val_high = AscGetChipLramData(iop_base);
                   13702:     dword_data = ((ulong) val_high << 16) | (ulong) val_low;
                   13703:     return (dword_data);
                   13704: }
                   13705: 
                   13706: STATIC void
                   13707: AscWriteLramWord(
                   13708:                     PortAddr iop_base,
                   13709:                     ushort addr,
                   13710:                     ushort word_val
                   13711: )
                   13712: {
                   13713:     AscSetChipLramAddr(iop_base, addr);
                   13714:     AscSetChipLramData(iop_base, word_val);
                   13715:     return;
                   13716: }
                   13717: 
                   13718: STATIC void
                   13719: AscWriteLramDWord(
                   13720:                      PortAddr iop_base,
                   13721:                      ushort addr,
                   13722:                      ulong dword_val
                   13723: )
                   13724: {
                   13725:     ushort              word_val;
                   13726: 
                   13727:     AscSetChipLramAddr(iop_base, addr);
                   13728:     word_val = (ushort) dword_val;
                   13729:     AscSetChipLramData(iop_base, word_val);
                   13730:     word_val = (ushort) (dword_val >> 16);
                   13731:     AscSetChipLramData(iop_base, word_val);
                   13732:     return;
                   13733: }
                   13734: 
                   13735: STATIC void
                   13736: AscWriteLramByte(
                   13737:                     PortAddr iop_base,
                   13738:                     ushort addr,
                   13739:                     uchar byte_val
                   13740: )
                   13741: {
                   13742:     ushort              word_data;
                   13743: 
                   13744:     if (isodd_word(addr)) {
                   13745:         addr--;
                   13746:         word_data = AscReadLramWord(iop_base, addr);
                   13747:         word_data &= 0x00FF;
                   13748:         word_data |= (((ushort) byte_val << 8) & 0xFF00);
                   13749:     } else {
                   13750:         word_data = AscReadLramWord(iop_base, addr);
                   13751:         word_data &= 0xFF00;
                   13752:         word_data |= ((ushort) byte_val & 0x00FF);
                   13753:     }
                   13754:     AscWriteLramWord(iop_base, addr, word_data);
                   13755:     return;
                   13756: }
                   13757: 
                   13758: STATIC void
                   13759: AscMemWordCopyToLram(
                   13760:                         PortAddr iop_base,
                   13761:                         ushort s_addr,
                   13762:                         ushort * s_buffer,
                   13763:                         int words
                   13764: )
                   13765: {
                   13766:     AscSetChipLramAddr(iop_base, s_addr);
                   13767:     DvcOutPortWords(iop_base + IOP_RAM_DATA, s_buffer, words);
                   13768:     return;
                   13769: }
                   13770: 
                   13771: STATIC void
                   13772: AscMemDWordCopyToLram(
                   13773:                          PortAddr iop_base,
                   13774:                          ushort s_addr,
                   13775:                          ulong * s_buffer,
                   13776:                          int dwords
                   13777: )
                   13778: {
                   13779:     AscSetChipLramAddr(iop_base, s_addr);
                   13780:     DvcOutPortDWords(iop_base + IOP_RAM_DATA, s_buffer, dwords);
                   13781:     return;
                   13782: }
                   13783: 
                   13784: STATIC void
                   13785: AscMemWordCopyFromLram(
                   13786:                           PortAddr iop_base,
                   13787:                           ushort s_addr,
                   13788:                           ushort * d_buffer,
                   13789:                           int words
                   13790: )
                   13791: {
                   13792:     AscSetChipLramAddr(iop_base, s_addr);
                   13793:     DvcInPortWords(iop_base + IOP_RAM_DATA, d_buffer, words);
                   13794:     return;
                   13795: }
                   13796: 
                   13797: STATIC ulong
                   13798: AscMemSumLramWord(
                   13799:                      PortAddr iop_base,
                   13800:                      ushort s_addr,
                   13801:                      rint words
                   13802: )
                   13803: {
                   13804:     ulong               sum;
                   13805:     int                 i;
                   13806: 
                   13807:     sum = 0L;
                   13808:     for (i = 0; i < words; i++, s_addr += 2) {
                   13809:         sum += AscReadLramWord(iop_base, s_addr);
                   13810:     }
                   13811:     return (sum);
                   13812: }
                   13813: 
                   13814: STATIC void
                   13815: AscMemWordSetLram(
                   13816:                      PortAddr iop_base,
                   13817:                      ushort s_addr,
                   13818:                      ushort set_wval,
                   13819:                      rint words
                   13820: )
                   13821: {
                   13822:     rint             i;
                   13823: 
                   13824:     AscSetChipLramAddr(iop_base, s_addr);
                   13825:     for (i = 0; i < words; i++) {
                   13826:         AscSetChipLramData(iop_base, set_wval);
                   13827:     }
                   13828:     return;
                   13829: }
                   13830: 
                   13831: 
                   13832: /*
                   13833:  * --- Adv Library Functions
                   13834:  */
                   13835: 
                   13836: /* a_qswap.h */
                   13837: STATIC unsigned char _adv_mcode_buf[] ASC_INITDATA = {
                   13838:   0x9C,  0xF0,  0x80,  0x01,  0x00,  0xF0,  0x44,  0x0A,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   13839:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   13840:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x72,  0x01,  0xD6,  0x11,  0x00,  0x00,  0x70,  0x01,
                   13841:   0x30,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x90,  0x10,  0x2D,  0x03,  0x00,  0x00,  0x00,  0x00,
                   13842:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   13843:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   13844:   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:   0x48,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   13850:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   13851:   0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,
                   13852:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   13853:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   13854:   0x00,  0x00,  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,  0x78,  0x56,  0x34,  0x12,
                   13857:   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
                   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,  0x04,  0xF7,  0x70,  0x01,  0x0C,  0x1C,  0x06,  0xF7,  0x02,  0x00,  0x00,  0xF2,  0xD6,  0x0A,
                   13862:   0x04,  0xF7,  0x70,  0x01,  0x06,  0xF7,  0x02,  0x00,  0x3E,  0x57,  0x3C,  0x56,  0x0C,  0x1C,  0x00,  0xFC,
                   13863:   0xA6,  0x00,  0x01,  0x58,  0xAA,  0x13,  0x20,  0xF0,  0xA6,  0x03,  0x06,  0xEC,  0xB9,  0x00,  0x0E,  0x47,
                   13864:   0x03,  0xE6,  0x10,  0x00,  0xCE,  0x45,  0x02,  0x13,  0x3E,  0x57,  0x06,  0xEA,  0xB9,  0x00,  0x47,  0x4B,
                   13865:   0x03,  0xF6,  0xE0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x01,  0x48,  0x4E,  0x12,  0x03,  0xF6,  0xC0,  0x00,
                   13866:   0x00,  0xF2,  0x68,  0x0A,  0x41,  0x58,  0x03,  0xF6,  0xD0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x49,  0x44,
                   13867:   0x59,  0xF0,  0x0A,  0x02,  0x03,  0xF6,  0xE0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x44,  0x58,  0x00,  0xF2,
                   13868:   0xE2,  0x0D,  0x02,  0xCC,  0x4A,  0xE4,  0x01,  0x00,  0x55,  0xF0,  0x08,  0x03,  0x45,  0xF4,  0x02,  0x00,
                   13869:   0x83,  0x5A,  0x04,  0xCC,  0x01,  0x4A,  0x12,  0x12,  0x00,  0xF2,  0xE2,  0x0D,  0x00,  0xCD,  0x48,  0xE4,
                   13870:   0x01,  0x00,  0xE9,  0x13,  0x00,  0xF2,  0xC6,  0x0F,  0xFA,  0x10,  0x0E,  0x47,  0x03,  0xE6,  0x10,  0x00,
                   13871:   0xCE,  0x45,  0x02,  0x13,  0x3E,  0x57,  0xCE,  0x47,  0x97,  0x13,  0x04,  0xEC,  0xB4,  0x00,  0x00,  0xF2,
                   13872:   0xE2,  0x0D,  0x00,  0xCD,  0x48,  0xE4,  0x00,  0x00,  0x12,  0x12,  0x3E,  0x57,  0x06,  0xCC,  0x45,  0xF4,
                   13873:   0x02,  0x00,  0x83,  0x5A,  0x00,  0xCC,  0x00,  0xEA,  0xB4,  0x00,  0x92,  0x10,  0x00,  0xF0,  0x8C,  0x01,
                   13874:   0x43,  0xF0,  0x5C,  0x02,  0x44,  0xF0,  0x60,  0x02,  0x45,  0xF0,  0x64,  0x02,  0x46,  0xF0,  0x68,  0x02,
                   13875:   0x47,  0xF0,  0x6E,  0x02,  0x48,  0xF0,  0x9E,  0x02,  0xB9,  0x54,  0x62,  0x10,  0x00,  0x1C,  0x5A,  0x10,
                   13876:   0x02,  0x1C,  0x56,  0x10,  0x1E,  0x1C,  0x52,  0x10,  0x00,  0xF2,  0x1E,  0x11,  0x50,  0x10,  0x06,  0xFC,
                   13877:   0xA8,  0x00,  0x03,  0xF6,  0xBE,  0x00,  0x00,  0xF2,  0x4E,  0x0A,  0x8C,  0x10,  0x01,  0xF6,  0x01,  0x00,
                   13878:   0x01,  0xFA,  0xA8,  0x00,  0x00,  0xF2,  0x2C,  0x0B,  0x06,  0x10,  0xB9,  0x54,  0x01,  0xFA,  0xA8,  0x00,
                   13879:   0x03,  0xF6,  0xBE,  0x00,  0x00,  0xF2,  0x58,  0x0A,  0x01,  0xFC,  0xA8,  0x00,  0x20,  0x10,  0x58,  0x1C,
                   13880:   0x00,  0xF2,  0x1C,  0x0B,  0x5A,  0x1C,  0x01,  0xF6,  0x01,  0x00,  0x38,  0x54,  0x00,  0xFA,  0xA6,  0x00,
                   13881:   0x01,  0xFA,  0xA8,  0x00,  0x20,  0x1C,  0x00,  0xF0,  0x72,  0x01,  0x01,  0xF6,  0x01,  0x00,  0x38,  0x54,
                   13882:   0x00,  0xFA,  0xA6,  0x00,  0x01,  0xFA,  0xA8,  0x00,  0x20,  0x1C,  0x00,  0xF0,  0x80,  0x01,  0x03,  0xF6,
                   13883:   0xE0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x01,  0x48,  0x0A,  0x13,  0x00,  0xF2,  0x38,  0x10,  0x00,  0xF2,
                   13884:   0x54,  0x0F,  0x24,  0x10,  0x03,  0xF6,  0xC0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x02,  0xF6,  0xD0,  0x00,
                   13885:   0x02,  0x57,  0x03,  0x59,  0x01,  0xCC,  0x49,  0x44,  0x5B,  0xF0,  0x04,  0x03,  0x00,  0xF2,  0x9C,  0x0F,
                   13886:   0x00,  0xF0,  0x80,  0x01,  0x00,  0xF2,  0x14,  0x10,  0x0C,  0x1C,  0x02,  0x4B,  0xBF,  0x57,  0x9E,  0x43,
                   13887:   0x77,  0x57,  0x07,  0x4B,  0x20,  0xF0,  0xA6,  0x03,  0x40,  0x1C,  0x1E,  0xF0,  0x30,  0x03,  0x26,  0xF0,
                   13888:   0x2C,  0x03,  0xA0,  0xF0,  0x1A,  0x03,  0x11,  0xF0,  0xA6,  0x03,  0x12,  0x10,  0x9F,  0xF0,  0x3E,  0x03,
                   13889:   0x46,  0x1C,  0x82,  0xE7,  0x05,  0x00,  0x9E,  0xE7,  0x11,  0x00,  0x00,  0xF0,  0x06,  0x0A,  0x0C,  0x1C,
                   13890:   0x48,  0x1C,  0x46,  0x1C,  0x38,  0x54,  0x00,  0xEC,  0xBA,  0x00,  0x08,  0x44,  0x00,  0xEA,  0xBA,  0x00,
                   13891:   0x03,  0xF6,  0xC0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x08,  0x44,  0x00,  0x4C,  0x82,  0xE7,  0x02,  0x00,
                   13892:   0x00,  0xF2,  0x12,  0x11,  0x00,  0xF2,  0x12,  0x11,  0x85,  0xF0,  0x70,  0x03,  0x00,  0xF2,  0x60,  0x0B,
                   13893:   0x06,  0xF0,  0x80,  0x03,  0x09,  0xF0,  0x24,  0x09,  0x1E,  0xF0,  0xFC,  0x09,  0x00,  0xF0,  0x02,  0x0A,
                   13894:   0x00,  0xFC,  0xBE,  0x00,  0x98,  0x57,  0x55,  0xF0,  0xAC,  0x04,  0x01,  0xE6,  0x0C,  0x00,  0x00,  0xF2,
                   13895:   0x4E,  0x0D,  0x00,  0xF2,  0x12,  0x11,  0x00,  0xF2,  0xBC,  0x11,  0x00,  0xF2,  0xC8,  0x11,  0x01,  0xF0,
                   13896:   0x7C,  0x02,  0x00,  0xF0,  0x8A,  0x02,  0x46,  0x1C,  0x0C,  0x1C,  0x67,  0x1B,  0xBF,  0x57,  0x77,  0x57,
                   13897:   0x02,  0x4B,  0x48,  0x1C,  0x32,  0x1C,  0x00,  0xF2,  0x92,  0x0D,  0x30,  0x1C,  0x96,  0xF0,  0xBC,  0x03,
                   13898:   0xB1,  0xF0,  0xC0,  0x03,  0x1E,  0xF0,  0xFC,  0x09,  0x85,  0xF0,  0x02,  0x0A,  0x00,  0xFC,  0xBE,  0x00,
                   13899:   0x98,  0x57,  0x14,  0x12,  0x01,  0xE6,  0x0C,  0x00,  0x00,  0xF2,  0x4E,  0x0D,  0x00,  0xF2,  0x12,  0x11,
                   13900:   0x01,  0xF0,  0x7C,  0x02,  0x00,  0xF0,  0x8A,  0x02,  0x03,  0xF6,  0xE0,  0x00,  0x00,  0xF2,  0x68,  0x0A,
                   13901:   0x01,  0x48,  0x55,  0xF0,  0x98,  0x04,  0x03,  0x82,  0x03,  0xFC,  0xA0,  0x00,  0x9B,  0x57,  0x40,  0x12,
                   13902:   0x69,  0x18,  0x00,  0xF2,  0x12,  0x11,  0x85,  0xF0,  0x42,  0x04,  0x69,  0x08,  0x00,  0xF2,  0x12,  0x11,
                   13903:   0x85,  0xF0,  0x02,  0x0A,  0x68,  0x08,  0x4C,  0x44,  0x28,  0x12,  0x44,  0x48,  0x03,  0xF6,  0xE0,  0x00,
                   13904:   0x00,  0xF2,  0x68,  0x0A,  0x45,  0x58,  0x00,  0xF2,  0xF6,  0x0D,  0x00,  0xCC,  0x01,  0x48,  0x55,  0xF0,
                   13905:   0x98,  0x04,  0x4C,  0x44,  0xEF,  0x13,  0x00,  0xF2,  0xC6,  0x0F,  0x00,  0xF2,  0x14,  0x10,  0x08,  0x10,
                   13906:   0x68,  0x18,  0x45,  0x5A,  0x00,  0xF2,  0xF6,  0x0D,  0x04,  0x80,  0x18,  0xE4,  0x10,  0x00,  0x28,  0x12,
                   13907:   0x01,  0xE6,  0x06,  0x00,  0x04,  0x80,  0x18,  0xE4,  0x01,  0x00,  0x04,  0x12,  0x01,  0xE6,  0x0D,  0x00,
                   13908:   0x00,  0xF2,  0x4E,  0x0D,  0x00,  0xF2,  0x12,  0x11,  0x04,  0xE6,  0x02,  0x00,  0x9E,  0xE7,  0x15,  0x00,
                   13909:   0x01,  0xF0,  0x1C,  0x0A,  0x00,  0xF0,  0x02,  0x0A,  0x69,  0x08,  0x05,  0x80,  0x48,  0xE4,  0x00,  0x00,
                   13910:   0x0C,  0x12,  0x00,  0xE6,  0x11,  0x00,  0x00,  0xEA,  0xB8,  0x00,  0x00,  0xF2,  0xB6,  0x10,  0x82,  0xE7,
                   13911:   0x02,  0x00,  0x1C,  0x90,  0x40,  0x5C,  0x00,  0x16,  0x01,  0xE6,  0x06,  0x00,  0x00,  0xF2,  0x4E,  0x0D,
                   13912:   0x01,  0xF0,  0x80,  0x01,  0x1E,  0xF0,  0x80,  0x01,  0x00,  0xF0,  0xA0,  0x04,  0x42,  0x5B,  0x06,  0xF7,
                   13913:   0x03,  0x00,  0x46,  0x59,  0xBF,  0x57,  0x77,  0x57,  0x01,  0xE6,  0x80,  0x00,  0x07,  0x80,  0x31,  0x44,
                   13914:   0x04,  0x80,  0x18,  0xE4,  0x20,  0x00,  0x56,  0x13,  0x20,  0x80,  0x48,  0xE4,  0x03,  0x00,  0x4E,  0x12,
                   13915:   0x00,  0xFC,  0xA2,  0x00,  0x98,  0x57,  0x55,  0xF0,  0x1C,  0x05,  0x31,  0xE4,  0x40,  0x00,  0x00,  0xFC,
                   13916:   0xA0,  0x00,  0x98,  0x57,  0x36,  0x12,  0x4C,  0x1C,  0x00,  0xF2,  0x12,  0x11,  0x89,  0x48,  0x00,  0xF2,
                   13917:   0x12,  0x11,  0x86,  0xF0,  0x2E,  0x05,  0x82,  0xE7,  0x06,  0x00,  0x1B,  0x80,  0x48,  0xE4,  0x22,  0x00,
                   13918:   0x5B,  0xF0,  0x0C,  0x05,  0x48,  0xE4,  0x20,  0x00,  0x59,  0xF0,  0x10,  0x05,  0x00,  0xE6,  0x20,  0x00,
                   13919:   0x09,  0x48,  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0x2E,  0x05,  0x83,  0x80,  0x04,  0x10,  0x00,  0xF2,
                   13920:   0xA2,  0x0D,  0x00,  0xE6,  0x01,  0x00,  0x00,  0xEA,  0x26,  0x01,  0x01,  0xEA,  0x27,  0x01,  0x04,  0x80,
                   13921:   0x18,  0xE4,  0x10,  0x00,  0x36,  0x12,  0xB9,  0x54,  0x00,  0xF2,  0xF6,  0x0E,  0x01,  0xE6,  0x06,  0x00,
                   13922:   0x04,  0x80,  0x18,  0xE4,  0x01,  0x00,  0x04,  0x12,  0x01,  0xE6,  0x0D,  0x00,  0x00,  0xF2,  0x4E,  0x0D,
                   13923:   0x00,  0xF2,  0x12,  0x11,  0x00,  0xF2,  0xBC,  0x11,  0x00,  0xF2,  0xC8,  0x11,  0x04,  0xE6,  0x02,  0x00,
                   13924:   0x9E,  0xE7,  0x15,  0x00,  0x01,  0xF0,  0x1C,  0x0A,  0x00,  0xF0,  0x02,  0x0A,  0x00,  0xFC,  0x20,  0x01,
                   13925:   0x98,  0x57,  0x34,  0x12,  0x00,  0xFC,  0x24,  0x01,  0x98,  0x57,  0x2C,  0x13,  0xB9,  0x54,  0x00,  0xF2,
                   13926:   0xF6,  0x0E,  0x86,  0xF0,  0xA8,  0x05,  0x03,  0xF6,  0x01,  0x00,  0x00,  0xF2,  0x8C,  0x0E,  0x85,  0xF0,
                   13927:   0x9E,  0x05,  0x82,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x60,  0x0B,  0x82,  0xE7,  0x02,  0x00,  0x00,  0xFC,
                   13928:   0x24,  0x01,  0xB0,  0x57,  0x00,  0xFA,  0x24,  0x01,  0x00,  0xFC,  0x9E,  0x00,  0x98,  0x57,  0x5A,  0x12,
                   13929:   0x00,  0xFC,  0xB6,  0x00,  0x98,  0x57,  0x52,  0x13,  0x03,  0xE6,  0x0C,  0x00,  0x00,  0xFC,  0x9C,  0x00,
                   13930:   0x98,  0x57,  0x04,  0x13,  0x03,  0xE6,  0x19,  0x00,  0x05,  0xE6,  0x08,  0x00,  0x00,  0xF6,  0x00,  0x01,
                   13931:   0x00,  0x57,  0x00,  0x57,  0x03,  0x58,  0x00,  0xDC,  0x18,  0xF4,  0x00,  0x80,  0x04,  0x13,  0x05,  0xE6,
                   13932:   0x0F,  0x00,  0xB9,  0x54,  0x00,  0xF2,  0xF6,  0x0E,  0x86,  0xF0,  0x0A,  0x06,  0x00,  0xF2,  0xBA,  0x0E,
                   13933:   0x85,  0xF0,  0x00,  0x06,  0x82,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x60,  0x0B,  0x82,  0xE7,  0x02,  0x00,
                   13934:   0x00,  0xFC,  0xB6,  0x00,  0xB0,  0x57,  0x00,  0xFA,  0xB6,  0x00,  0x01,  0xF6,  0x01,  0x00,  0x00,  0xF2,
                   13935:   0xF6,  0x0E,  0x9C,  0x32,  0x4E,  0x1C,  0x32,  0x1C,  0x00,  0xF2,  0x92,  0x0D,  0x30,  0x1C,  0x82,  0xE7,
                   13936:   0x04,  0x00,  0xB1,  0xF0,  0x22,  0x06,  0x0A,  0xF0,  0x3E,  0x06,  0x05,  0xF0,  0xD6,  0x06,  0x06,  0xF0,
                   13937:   0xDC,  0x06,  0x09,  0xF0,  0x24,  0x09,  0x1E,  0xF0,  0xFC,  0x09,  0x00,  0xF0,  0x02,  0x0A,  0x04,  0x80,
                   13938:   0x18,  0xE4,  0x20,  0x00,  0x30,  0x12,  0x09,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x21,  0x80,
                   13939:   0x18,  0xE4,  0xE0,  0x00,  0x09,  0x48,  0x00,  0xF2,  0x12,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF2,
                   13940:   0x12,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x99,  0xA4,  0x00,  0xF2,  0x12,  0x11,
                   13941:   0x09,  0xE7,  0x00,  0x00,  0x9A,  0x10,  0x04,  0x80,  0x18,  0xE4,  0x02,  0x00,  0x34,  0x12,  0x09,  0xE7,
                   13942:   0x1B,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x21,  0x80,  0x18,  0xE4,  0xE0,  0x00,  0x09,  0x48,  0x00,  0xF2,
                   13943:   0x12,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF2,
                   13944:   0x12,  0x11,  0x09,  0xE7,  0x01,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x09,  0xE7,  0x00,  0x00,  0x00,  0xF0,
                   13945:   0x0C,  0x09,  0xBB,  0x55,  0x9A,  0x81,  0x03,  0xF7,  0x20,  0x00,  0x09,  0x6F,  0x93,  0x45,  0x55,  0xF0,
                   13946:   0xE2,  0x06,  0xB1,  0xF0,  0xC2,  0x06,  0x0A,  0xF0,  0xBA,  0x06,  0x09,  0xF0,  0x24,  0x09,  0x1E,  0xF0,
                   13947:   0xFC,  0x09,  0x00,  0xF0,  0x02,  0x0A,  0x00,  0xF2,  0x60,  0x0B,  0x47,  0x10,  0x09,  0xE7,  0x08,  0x00,
                   13948:   0x41,  0x10,  0x05,  0x80,  0x48,  0xE4,  0x00,  0x00,  0x1E,  0x12,  0x00,  0xE6,  0x11,  0x00,  0x00,  0xEA,
                   13949:   0xB8,  0x00,  0x00,  0xF2,  0xB6,  0x10,  0x2C,  0x90,  0xAE,  0x90,  0x08,  0x50,  0x8A,  0x50,  0x38,  0x54,
                   13950:   0x1F,  0x40,  0x00,  0xF2,  0xB4,  0x0D,  0x08,  0x10,  0x08,  0x90,  0x8A,  0x90,  0x30,  0x50,  0xB2,  0x50,
                   13951:   0x9C,  0x32,  0x0C,  0x92,  0x8E,  0x92,  0x38,  0x54,  0x04,  0x80,  0x30,  0xE4,  0x08,  0x00,  0x04,  0x40,
                   13952:   0x0C,  0x1C,  0x00,  0xF6,  0x03,  0x00,  0xB1,  0xF0,  0x26,  0x07,  0x9E,  0xF0,  0x3A,  0x07,  0x01,  0x48,
                   13953:   0x55,  0xF0,  0xFC,  0x09,  0x0C,  0x1C,  0x10,  0x44,  0xED,  0x10,  0x0B,  0xF0,  0x5E,  0x07,  0x0C,  0xF0,
                   13954:   0x62,  0x07,  0x05,  0xF0,  0x52,  0x07,  0x06,  0xF0,  0x58,  0x07,  0x09,  0xF0,  0x24,  0x09,  0x00,  0xF0,
                   13955:   0x02,  0x0A,  0x00,  0xF2,  0x60,  0x0B,  0xCF,  0x10,  0x09,  0xE7,  0x08,  0x00,  0xC9,  0x10,  0x2E,  0x1C,
                   13956:   0x02,  0x10,  0x2C,  0x1C,  0xAA,  0xF0,  0x64,  0x07,  0xAC,  0xF0,  0x72,  0x07,  0x40,  0x10,  0x34,  0x1C,
                   13957:   0xF3,  0x10,  0xAD,  0xF0,  0x7C,  0x07,  0xC8,  0x10,  0x36,  0x1C,  0xE9,  0x10,  0x2B,  0xF0,  0x82,  0x08,
                   13958:   0x6B,  0x18,  0x18,  0xF4,  0x00,  0xFE,  0x20,  0x12,  0x01,  0x58,  0xD2,  0xF0,  0x82,  0x08,  0x76,  0x18,
                   13959:   0x18,  0xF4,  0x03,  0x00,  0xEC,  0x12,  0x00,  0xFC,  0x22,  0x01,  0x18,  0xF4,  0x01,  0x00,  0xE2,  0x12,
                   13960:   0x0B,  0xF0,  0x64,  0x07,  0x0C,  0xF0,  0x64,  0x07,  0x36,  0x1C,  0x34,  0x1C,  0xB7,  0x10,  0x38,  0x54,
                   13961:   0xB9,  0x54,  0x84,  0x80,  0x19,  0xE4,  0x20,  0x00,  0xB2,  0x13,  0x85,  0x80,  0x81,  0x48,  0x66,  0x12,
                   13962:   0x04,  0x80,  0x18,  0xE4,  0x08,  0x00,  0x58,  0x13,  0x1F,  0x80,  0x08,  0x44,  0xC8,  0x44,  0x9F,  0x12,
                   13963:   0x1F,  0x40,  0x34,  0x91,  0xB6,  0x91,  0x44,  0x55,  0xE5,  0x55,  0x02,  0xEC,  0xB8,  0x00,  0x02,  0x49,
                   13964:   0xBB,  0x55,  0x82,  0x81,  0xC0,  0x55,  0x48,  0xF4,  0x0F,  0x00,  0x5A,  0xF0,  0x1A,  0x08,  0x4A,  0xE4,
                   13965:   0x17,  0x00,  0xD5,  0xF0,  0xFA,  0x07,  0x02,  0xF6,  0x0F,  0x00,  0x02,  0xF4,  0x02,  0x00,  0x02,  0xEA,
                   13966:   0xB8,  0x00,  0x04,  0x91,  0x86,  0x91,  0x02,  0x4B,  0x2C,  0x90,  0x08,  0x50,  0x2E,  0x90,  0x0A,  0x50,
                   13967:   0x2C,  0x51,  0xAE,  0x51,  0x00,  0xF2,  0xB6,  0x10,  0x38,  0x54,  0x00,  0xF2,  0xB4,  0x0D,  0x56,  0x10,
                   13968:   0x34,  0x91,  0xB6,  0x91,  0x0C,  0x10,  0x04,  0x80,  0x18,  0xE4,  0x08,  0x00,  0x41,  0x12,  0x0C,  0x91,
                   13969:   0x8E,  0x91,  0x04,  0x80,  0x18,  0xE4,  0xF7,  0x00,  0x04,  0x40,  0x30,  0x90,  0xB2,  0x90,  0x36,  0x10,
                   13970:   0x02,  0x80,  0x48,  0xE4,  0x10,  0x00,  0x31,  0x12,  0x82,  0xE7,  0x10,  0x00,  0x84,  0x80,  0x19,  0xE4,
                   13971:   0x20,  0x00,  0x10,  0x13,  0x0C,  0x90,  0x8E,  0x90,  0x5D,  0xF0,  0x78,  0x07,  0x0C,  0x58,  0x8D,  0x58,
                   13972:   0x00,  0xF0,  0x64,  0x07,  0x38,  0x54,  0xB9,  0x54,  0x19,  0x80,  0xF1,  0x10,  0x3A,  0x55,  0x19,  0x81,
                   13973:   0xBB,  0x55,  0x10,  0x90,  0x92,  0x90,  0x10,  0x58,  0x91,  0x58,  0x14,  0x59,  0x95,  0x59,  0x00,  0xF0,
                   13974:   0x64,  0x07,  0x04,  0x80,  0x18,  0xE4,  0x20,  0x00,  0x06,  0x12,  0x6C,  0x19,  0x19,  0x41,  0x7C,  0x10,
                   13975:   0x6C,  0x19,  0x0C,  0x51,  0xED,  0x19,  0x8E,  0x51,  0x6B,  0x18,  0x18,  0xF4,  0x00,  0xFF,  0x02,  0x13,
                   13976:   0x6A,  0x10,  0x01,  0x58,  0xD2,  0xF0,  0xC0,  0x08,  0x76,  0x18,  0x18,  0xF4,  0x03,  0x00,  0x0A,  0x12,
                   13977:   0x00,  0xFC,  0x22,  0x01,  0x18,  0xF4,  0x01,  0x00,  0x06,  0x13,  0x9E,  0xE7,  0x16,  0x00,  0x4C,  0x10,
                   13978:   0xD1,  0xF0,  0xCA,  0x08,  0x9E,  0xE7,  0x17,  0x00,  0x42,  0x10,  0xD0,  0xF0,  0xD4,  0x08,  0x9E,  0xE7,
                   13979:   0x19,  0x00,  0x38,  0x10,  0xCF,  0xF0,  0xDE,  0x08,  0x9E,  0xE7,  0x20,  0x00,  0x2E,  0x10,  0xCE,  0xF0,
                   13980:   0xE8,  0x08,  0x9E,  0xE7,  0x21,  0x00,  0x24,  0x10,  0xCD,  0xF0,  0xF2,  0x08,  0x9E,  0xE7,  0x22,  0x00,
                   13981:   0x1A,  0x10,  0xCC,  0xF0,  0x04,  0x09,  0x84,  0x80,  0x19,  0xE4,  0x04,  0x00,  0x06,  0x12,  0x9E,  0xE7,
                   13982:   0x12,  0x00,  0x08,  0x10,  0xCB,  0xF0,  0x0C,  0x09,  0x9E,  0xE7,  0x24,  0x00,  0xB1,  0xF0,  0x0C,  0x09,
                   13983:   0x05,  0xF0,  0x1E,  0x09,  0x09,  0xF0,  0x24,  0x09,  0x1E,  0xF0,  0xFC,  0x09,  0xE4,  0x10,  0x00,  0xF2,
                   13984:   0x60,  0x0B,  0xE9,  0x10,  0x9C,  0x32,  0x82,  0xE7,  0x20,  0x00,  0x32,  0x1C,  0xE9,  0x09,  0x00,  0xF2,
                   13985:   0x12,  0x11,  0x85,  0xF0,  0x02,  0x0A,  0x69,  0x08,  0x01,  0xF0,  0x44,  0x09,  0x1E,  0xF0,  0xFC,  0x09,
                   13986:   0x00,  0xF0,  0x38,  0x09,  0x30,  0x44,  0x06,  0x12,  0x9E,  0xE7,  0x42,  0x00,  0xB8,  0x10,  0x04,  0xF6,
                   13987:   0x01,  0x00,  0xB3,  0x45,  0x74,  0x12,  0x04,  0x80,  0x18,  0xE4,  0x20,  0x00,  0x22,  0x13,  0x4B,  0xE4,
                   13988:   0x02,  0x00,  0x36,  0x12,  0x4B,  0xE4,  0x28,  0x00,  0xAC,  0x13,  0x00,  0xF2,  0xBC,  0x11,  0x00,  0xF2,
                   13989:   0xC8,  0x11,  0x03,  0xF6,  0xD0,  0x00,  0xFA,  0x14,  0x82,  0xE7,  0x01,  0x00,  0x00,  0xF0,  0x80,  0x01,
                   13990:   0x9E,  0xE7,  0x44,  0x00,  0x4B,  0xE4,  0x02,  0x00,  0x06,  0x12,  0x03,  0xE6,  0x02,  0x00,  0x76,  0x10,
                   13991:   0x00,  0xF2,  0xA2,  0x0D,  0x03,  0xE6,  0x02,  0x00,  0x6C,  0x10,  0x00,  0xF2,  0xA2,  0x0D,  0x19,  0x82,
                   13992:   0x34,  0x46,  0x0A,  0x13,  0x03,  0xE6,  0x02,  0x00,  0x9E,  0xE7,  0x43,  0x00,  0x68,  0x10,  0x04,  0x80,
                   13993:   0x30,  0xE4,  0x20,  0x00,  0x04,  0x40,  0x00,  0xF2,  0xBC,  0x11,  0x00,  0xF2,  0xC8,  0x11,  0x82,  0xE7,
                   13994:   0x01,  0x00,  0x06,  0xF7,  0x02,  0x00,  0x00,  0xF0,  0x08,  0x03,  0x04,  0x80,  0x18,  0xE4,  0x20,  0x00,
                   13995:   0x06,  0x12,  0x03,  0xE6,  0x02,  0x00,  0x3E,  0x10,  0x04,  0x80,  0x18,  0xE4,  0x02,  0x00,  0x3A,  0x12,
                   13996:   0x04,  0x80,  0x18,  0xE4,  0xFD,  0x00,  0x04,  0x40,  0x1C,  0x1C,  0x9D,  0xF0,  0xEA,  0x09,  0x1C,  0x1C,
                   13997:   0x9D,  0xF0,  0xF0,  0x09,  0xC1,  0x10,  0x9E,  0xE7,  0x13,  0x00,  0x0A,  0x10,  0x9E,  0xE7,  0x41,  0x00,
                   13998:   0x04,  0x10,  0x9E,  0xE7,  0x24,  0x00,  0x00,  0xFC,  0xBE,  0x00,  0x98,  0x57,  0xD5,  0xF0,  0x8A,  0x02,
                   13999:   0x04,  0xE6,  0x04,  0x00,  0x06,  0x10,  0x04,  0xE6,  0x04,  0x00,  0x9D,  0x41,  0x1C,  0x42,  0x9F,  0xE7,
                   14000:   0x00,  0x00,  0x06,  0xF7,  0x02,  0x00,  0x03,  0xF6,  0xE0,  0x00,  0x3C,  0x14,  0x44,  0x58,  0x45,  0x58,
                   14001:   0x00,  0xF2,  0xF6,  0x0D,  0x00,  0xF2,  0x7E,  0x10,  0x00,  0xF2,  0xC6,  0x0F,  0x3C,  0x14,  0x1E,  0x1C,
                   14002:   0x00,  0xF0,  0x80,  0x01,  0x12,  0x1C,  0x22,  0x1C,  0xD2,  0x14,  0x00,  0xF0,  0x72,  0x01,  0x83,  0x59,
                   14003:   0x03,  0xDC,  0x73,  0x57,  0x80,  0x5D,  0x00,  0x16,  0x83,  0x59,  0x03,  0xDC,  0x38,  0x54,  0x70,  0x57,
                   14004:   0x33,  0x54,  0x3B,  0x54,  0x80,  0x5D,  0x00,  0x16,  0x03,  0x57,  0x83,  0x59,  0x38,  0x54,  0x00,  0xCC,
                   14005:   0x00,  0x16,  0x03,  0x57,  0x83,  0x59,  0x00,  0x4C,  0x00,  0x16,  0x02,  0x80,  0x48,  0xE4,  0x01,  0x00,
                   14006:   0x0E,  0x12,  0x48,  0xE4,  0x05,  0x00,  0x08,  0x12,  0x00,  0xF2,  0xBC,  0x11,  0x00,  0xF2,  0xC8,  0x11,
                   14007:   0xC1,  0x5A,  0x3A,  0x55,  0x02,  0xEC,  0xB5,  0x00,  0x45,  0x59,  0x00,  0xF2,  0xF6,  0x0D,  0x83,  0x58,
                   14008:   0x30,  0xE7,  0x00,  0x00,  0x10,  0x4D,  0x30,  0xE7,  0x40,  0x00,  0x10,  0x4F,  0x38,  0x90,  0xBA,  0x90,
                   14009:   0x10,  0x5C,  0x80,  0x5C,  0x83,  0x5A,  0x10,  0x4E,  0x04,  0xEA,  0xB5,  0x00,  0x43,  0x5B,  0x03,  0xF4,
                   14010:   0xE0,  0x00,  0x83,  0x59,  0x04,  0xCC,  0x01,  0x4A,  0x0A,  0x12,  0x45,  0x5A,  0x00,  0xF2,  0xF6,  0x0D,
                   14011:   0x00,  0xF2,  0x38,  0x10,  0x00,  0x16,  0x08,  0x1C,  0x00,  0xFC,  0xAC,  0x00,  0x06,  0x58,  0x67,  0x18,
                   14012:   0x18,  0xF4,  0x8F,  0xE1,  0x01,  0xFC,  0xAE,  0x00,  0x19,  0xF4,  0x70,  0x1E,  0xB0,  0x54,  0x07,  0x58,
                   14013:   0x00,  0xFC,  0xB0,  0x00,  0x08,  0x58,  0x00,  0xFC,  0xB2,  0x00,  0x09,  0x58,  0x0A,  0x1C,  0x00,  0xE6,
                   14014:   0x0F,  0x00,  0x00,  0xEA,  0xB9,  0x00,  0x38,  0x54,  0x00,  0xFA,  0x24,  0x01,  0x00,  0xFA,  0xB6,  0x00,
                   14015:   0x18,  0x1C,  0x14,  0x1C,  0x10,  0x1C,  0x32,  0x1C,  0x12,  0x1C,  0x00,  0x16,  0x3E,  0x57,  0x0C,  0x14,
                   14016:   0x0E,  0x47,  0x07,  0xE6,  0x10,  0x00,  0xCE,  0x47,  0xF5,  0x13,  0x00,  0x16,  0x00,  0xF2,  0xA2,  0x0D,
                   14017:   0x02,  0x4B,  0x03,  0xF6,  0xE0,  0x00,  0x00,  0xF2,  0x68,  0x0A,  0x01,  0x48,  0x20,  0x12,  0x44,  0x58,
                   14018:   0x45,  0x58,  0x9E,  0xE7,  0x15,  0x00,  0x9C,  0xE7,  0x04,  0x00,  0x00,  0xF2,  0xF6,  0x0D,  0x00,  0xF2,
                   14019:   0x7E,  0x10,  0x00,  0xF2,  0xC6,  0x0F,  0x00,  0xF2,  0x7A,  0x0A,  0x1E,  0x1C,  0xD5,  0x10,  0x00,  0x16,
                   14020:   0x69,  0x08,  0x48,  0xE4,  0x04,  0x00,  0x64,  0x12,  0x48,  0xE4,  0x02,  0x00,  0x20,  0x12,  0x48,  0xE4,
                   14021:   0x03,  0x00,  0x1A,  0x12,  0x48,  0xE4,  0x08,  0x00,  0x14,  0x12,  0x48,  0xE4,  0x01,  0x00,  0xF0,  0x12,
                   14022:   0x48,  0xE4,  0x07,  0x00,  0x12,  0x12,  0x01,  0xE6,  0x07,  0x00,  0x00,  0xF2,  0x4E,  0x0D,  0x00,  0xF2,
                   14023:   0x12,  0x11,  0x05,  0xF0,  0x60,  0x0B,  0x00,  0x16,  0x00,  0xE6,  0x01,  0x00,  0x00,  0xEA,  0x99,  0x00,
                   14024:   0x02,  0x80,  0x48,  0xE4,  0x03,  0x00,  0xE7,  0x12,  0x48,  0xE4,  0x06,  0x00,  0xE1,  0x12,  0x01,  0xE6,
                   14025:   0x06,  0x00,  0x00,  0xF2,  0x4E,  0x0D,  0x00,  0xF2,  0x12,  0x11,  0x04,  0xE6,  0x02,  0x00,  0x9E,  0xE7,
                   14026:   0x15,  0x00,  0x01,  0xF0,  0x1C,  0x0A,  0x00,  0xF0,  0x02,  0x0A,  0x00,  0x16,  0x02,  0x80,  0x48,  0xE4,
                   14027:   0x10,  0x00,  0x1C,  0x12,  0x82,  0xE7,  0x08,  0x00,  0x3C,  0x56,  0x03,  0x82,  0x00,  0xF2,  0xE2,  0x0D,
                   14028:   0x30,  0xE7,  0x08,  0x00,  0x04,  0xF7,  0x70,  0x01,  0x06,  0xF7,  0x02,  0x00,  0x00,  0xF0,  0x80,  0x01,
                   14029:   0x6C,  0x19,  0xED,  0x19,  0x5D,  0xF0,  0xD4,  0x0B,  0x44,  0x55,  0xE5,  0x55,  0x59,  0xF0,  0x52,  0x0C,
                   14030:   0x04,  0x55,  0xA5,  0x55,  0x1F,  0x80,  0x01,  0xEC,  0xB8,  0x00,  0x82,  0x48,  0x82,  0x80,  0x49,  0x44,
                   14031:   0x2E,  0x13,  0x01,  0xEC,  0xB8,  0x00,  0x41,  0xE4,  0x02,  0x00,  0x01,  0xEA,  0xB8,  0x00,  0x49,  0xE4,
                   14032:   0x11,  0x00,  0x59,  0xF0,  0x2E,  0x0C,  0x01,  0xE6,  0x17,  0x00,  0x01,  0xEA,  0xB8,  0x00,  0x02,  0x4B,
                   14033:   0x88,  0x90,  0xAC,  0x50,  0x8A,  0x90,  0xAE,  0x50,  0x01,  0xEC,  0xB8,  0x00,  0x82,  0x48,  0x82,  0x80,
                   14034:   0x10,  0x44,  0x02,  0x4B,  0x1F,  0x40,  0xC0,  0x44,  0x00,  0xF2,  0xB4,  0x0D,  0x04,  0x55,  0xA5,  0x55,
                   14035:   0x9F,  0x10,  0x0C,  0x51,  0x8E,  0x51,  0x30,  0x90,  0xB2,  0x90,  0x00,  0x56,  0xA1,  0x56,  0x30,  0x50,
                   14036:   0xB2,  0x50,  0x34,  0x90,  0xB6,  0x90,  0x40,  0x56,  0xE1,  0x56,  0x34,  0x50,  0xB6,  0x50,  0x65,  0x10,
                   14037:   0xB1,  0xF0,  0x70,  0x0C,  0x85,  0xF0,  0xCA,  0x0B,  0xE9,  0x09,  0x4B,  0xE4,  0x03,  0x00,  0x78,  0x12,
                   14038:   0x4B,  0xE4,  0x02,  0x00,  0x01,  0x13,  0xB1,  0xF0,  0x86,  0x0C,  0x85,  0xF0,  0xCA,  0x0B,  0x69,  0x08,
                   14039:   0x48,  0xE4,  0x03,  0x00,  0xD5,  0xF0,  0x86,  0x0B,  0x00,  0xF2,  0x12,  0x11,  0x85,  0xF0,  0xCA,  0x0B,
                   14040:   0xE8,  0x09,  0x3C,  0x56,  0x00,  0xFC,  0x20,  0x01,  0x98,  0x57,  0x02,  0x13,  0xBB,  0x45,  0x4B,  0xE4,
                   14041:   0x00,  0x00,  0x08,  0x12,  0x03,  0xE6,  0x01,  0x00,  0x04,  0xF6,  0x00,  0x80,  0xA8,  0x14,  0xD2,  0x14,
                   14042:   0x30,  0x1C,  0x02,  0x80,  0x48,  0xE4,  0x03,  0x00,  0x10,  0x13,  0x00,  0xFC,  0xB6,  0x00,  0x98,  0x57,
                   14043:   0x02,  0x13,  0x4C,  0x1C,  0x3E,  0x1C,  0x00,  0xF0,  0x8E,  0x0B,  0x00,  0xFC,  0x24,  0x01,  0xB0,  0x57,
                   14044:   0x00,  0xFA,  0x24,  0x01,  0x4C,  0x1C,  0x3E,  0x1C,  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0x8E,  0x0B,
                   14045:   0x00,  0xF2,  0x8C,  0x0E,  0x00,  0xF0,  0x8E,  0x0B,  0xB1,  0xF0,  0xF8,  0x0C,  0x85,  0xF0,  0x86,  0x0B,
                   14046:   0x69,  0x08,  0x48,  0xE4,  0x01,  0x00,  0xD5,  0xF0,  0x86,  0x0B,  0xFC,  0x14,  0x42,  0x58,  0x6C,  0x14,
                   14047:   0x80,  0x14,  0x30,  0x1C,  0x4A,  0xF4,  0x02,  0x00,  0x55,  0xF0,  0x86,  0x0B,  0x4A,  0xF4,  0x01,  0x00,
                   14048:   0x0E,  0x12,  0x02,  0x80,  0x48,  0xE4,  0x03,  0x00,  0x06,  0x13,  0x3E,  0x1C,  0x00,  0xF0,  0x8E,  0x0B,
                   14049:   0x00,  0xFC,  0xB6,  0x00,  0xB0,  0x57,  0x00,  0xFA,  0xB6,  0x00,  0x4C,  0x1C,  0x3E,  0x1C,  0x00,  0xF2,
                   14050:   0x12,  0x11,  0x86,  0xF0,  0x8E,  0x0B,  0x00,  0xF2,  0xBA,  0x0E,  0x00,  0xF0,  0x8E,  0x0B,  0x4C,  0x1C,
                   14051:   0xB1,  0xF0,  0x50,  0x0D,  0x85,  0xF0,  0x5C,  0x0D,  0x69,  0x08,  0xF3,  0x10,  0x86,  0xF0,  0x64,  0x0D,
                   14052:   0x4E,  0x1C,  0x89,  0x48,  0x00,  0x16,  0x00,  0xF6,  0x00,  0x01,  0x00,  0x57,  0x00,  0x57,  0x03,  0x58,
                   14053:   0x00,  0xDC,  0x18,  0xF4,  0xFF,  0x7F,  0x30,  0x56,  0x00,  0x5C,  0x00,  0x16,  0x00,  0xF6,  0x00,  0x01,
                   14054:   0x00,  0x57,  0x00,  0x57,  0x03,  0x58,  0x00,  0xDC,  0x18,  0xF4,  0x00,  0x80,  0x30,  0x56,  0x00,  0x5C,
                   14055:   0x00,  0x16,  0x00,  0xF6,  0x00,  0x01,  0x00,  0x57,  0x00,  0x57,  0x03,  0x58,  0x00,  0xDC,  0x0B,  0x58,
                   14056:   0x00,  0x16,  0x03,  0xF6,  0x24,  0x01,  0x00,  0xF2,  0x58,  0x0A,  0x03,  0xF6,  0xB6,  0x00,  0x00,  0xF2,
                   14057:   0x58,  0x0A,  0x00,  0x16,  0x02,  0xEC,  0xB8,  0x00,  0x02,  0x49,  0x18,  0xF4,  0xFF,  0x00,  0x00,  0x54,
                   14058:   0x00,  0x54,  0x00,  0x54,  0x00,  0xF4,  0x08,  0x00,  0xE1,  0x18,  0x80,  0x54,  0x03,  0x58,  0x00,  0xDD,
                   14059:   0x01,  0xDD,  0x02,  0xDD,  0x03,  0xDC,  0x02,  0x4B,  0x30,  0x50,  0xB2,  0x50,  0x34,  0x51,  0xB6,  0x51,
                   14060:   0x00,  0x16,  0x45,  0x5A,  0x1D,  0xF4,  0xFF,  0x00,  0x85,  0x56,  0x85,  0x56,  0x85,  0x56,  0x05,  0xF4,
                   14061:   0x02,  0x12,  0x83,  0x5A,  0x00,  0x16,  0x1D,  0xF4,  0xFF,  0x00,  0x85,  0x56,  0x85,  0x56,  0x85,  0x56,
                   14062:   0x05,  0xF4,  0x00,  0x12,  0x83,  0x5A,  0x00,  0x16,  0x38,  0x54,  0xBB,  0x55,  0x3C,  0x56,  0xBD,  0x56,
                   14063:   0x00,  0xF2,  0x12,  0x11,  0x85,  0xF0,  0x82,  0x0E,  0xE9,  0x09,  0xC1,  0x59,  0x00,  0xF2,  0x12,  0x11,
                   14064:   0x85,  0xF0,  0x82,  0x0E,  0xE8,  0x0A,  0x83,  0x55,  0x83,  0x55,  0x4B,  0xF4,  0x90,  0x01,  0x5C,  0xF0,
                   14065:   0x36,  0x0E,  0xBD,  0x56,  0x40,  0x10,  0x4B,  0xF4,  0x30,  0x00,  0x59,  0xF0,  0x48,  0x0E,  0x01,  0xF6,
                   14066:   0x0C,  0x00,  0x00,  0xF6,  0x01,  0x00,  0x2E,  0x10,  0x02,  0xFC,  0x9C,  0x00,  0x9A,  0x57,  0x14,  0x13,
                   14067:   0x4B,  0xF4,  0x64,  0x00,  0x59,  0xF0,  0x64,  0x0E,  0x03,  0xF6,  0x64,  0x00,  0x01,  0xF6,  0x19,  0x00,
                   14068:   0x00,  0xF6,  0x01,  0x00,  0x43,  0xF4,  0x33,  0x00,  0x56,  0xF0,  0x76,  0x0E,  0x04,  0xF4,  0x00,  0x01,
                   14069:   0x43,  0xF4,  0x19,  0x00,  0xF3,  0x10,  0xB4,  0x56,  0xC3,  0x58,  0x02,  0xFC,  0x9E,  0x00,  0x9A,  0x57,
                   14070:   0x08,  0x13,  0x3C,  0x56,  0x00,  0xF6,  0x02,  0x00,  0x00,  0x16,  0x00,  0x16,  0x09,  0xE7,  0x01,  0x00,
                   14071:   0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0xB8,  0x0E,  0x09,  0xE7,  0x02,  0x00,  0x00,  0xF2,  0x12,  0x11,
                   14072:   0x86,  0xF0,  0xB8,  0x0E,  0x09,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0xB8,  0x0E,
                   14073:   0x4E,  0x1C,  0x89,  0x49,  0x00,  0xF2,  0x12,  0x11,  0x00,  0x16,  0x09,  0xE7,  0x01,  0x00,  0x00,  0xF2,
                   14074:   0x12,  0x11,  0x86,  0xF0,  0xF2,  0x0E,  0x09,  0xE7,  0x03,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,
                   14075:   0xF2,  0x0E,  0x09,  0xE7,  0x01,  0x00,  0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0xF2,  0x0E,  0x89,  0x49,
                   14076:   0x00,  0xF2,  0x12,  0x11,  0x86,  0xF0,  0xF2,  0x0E,  0x4E,  0x1C,  0x89,  0x4A,  0x00,  0xF2,  0x12,  0x11,
                   14077:   0x00,  0x16,  0x3C,  0x56,  0x00,  0x16,  0x00,  0xEC,  0x26,  0x01,  0x48,  0xE4,  0x01,  0x00,  0x1E,  0x13,
                   14078:   0x38,  0x44,  0x00,  0xEA,  0x26,  0x01,  0x49,  0xF4,  0x00,  0x00,  0x04,  0x12,  0x4E,  0x1C,  0x02,  0x10,
                   14079:   0x4C,  0x1C,  0x01,  0xEC,  0x27,  0x01,  0x89,  0x48,  0x00,  0xF2,  0x12,  0x11,  0x02,  0x14,  0x00,  0x16,
                   14080:   0x85,  0xF0,  0x52,  0x0F,  0x38,  0x54,  0x00,  0xEA,  0x99,  0x00,  0x00,  0xF2,  0x60,  0x0B,  0x02,  0x80,
                   14081:   0x48,  0xE4,  0x06,  0x00,  0x1C,  0x13,  0x00,  0xEC,  0x99,  0x00,  0x48,  0xE4,  0x01,  0x00,  0x0A,  0x12,
                   14082:   0x04,  0x80,  0x30,  0xE4,  0x01,  0x00,  0x04,  0x40,  0x08,  0x10,  0x04,  0x80,  0x18,  0xE4,  0xFE,  0x00,
                   14083:   0x04,  0x40,  0x00,  0x16,  0x02,  0xF6,  0xE0,  0x00,  0x02,  0x57,  0x03,  0x59,  0x01,  0xCC,  0x81,  0x48,
                   14084:   0x22,  0x12,  0x00,  0x4E,  0x83,  0x5A,  0x90,  0x4C,  0x20,  0xE7,  0x00,  0x00,  0xC3,  0x58,  0x1B,  0xF4,
                   14085:   0xFF,  0x00,  0x83,  0x55,  0x83,  0x55,  0x83,  0x55,  0x03,  0xF4,  0x00,  0x12,  0x8B,  0x55,  0x83,  0x59,
                   14086:   0x00,  0x4E,  0x00,  0x16,  0x00,  0x4E,  0x02,  0xF6,  0xF0,  0x00,  0x02,  0x57,  0x03,  0x59,  0x00,  0x4E,
                   14087:   0x83,  0x5A,  0x30,  0xE7,  0x00,  0x00,  0x20,  0xE7,  0x00,  0x00,  0x00,  0x16,  0x02,  0xF6,  0xF0,  0x00,
                   14088:   0x02,  0x57,  0x03,  0x59,  0x01,  0xCC,  0x00,  0x4E,  0x83,  0x5A,  0x30,  0xE7,  0x00,  0x00,  0x80,  0x4C,
                   14089:   0xC3,  0x58,  0x1B,  0xF4,  0xFF,  0x00,  0x83,  0x55,  0x83,  0x55,  0x83,  0x55,  0x03,  0xF4,  0x00,  0x12,
                   14090:   0x83,  0x59,  0x00,  0x4E,  0x00,  0x16,  0x03,  0xF6,  0xE0,  0x00,  0x03,  0x57,  0x83,  0x59,  0x3A,  0x55,
                   14091:   0x02,  0xCC,  0x45,  0x5A,  0x00,  0xF2,  0xF6,  0x0D,  0xC0,  0x5A,  0x40,  0x5C,  0x38,  0x54,  0x00,  0xCD,
                   14092:   0x01,  0xCC,  0x4A,  0x46,  0x0A,  0x13,  0x83,  0x59,  0x00,  0x4C,  0x01,  0x48,  0x16,  0x13,  0x0C,  0x10,
                   14093:   0xC5,  0x58,  0x00,  0xF2,  0xF6,  0x0D,  0x00,  0x4C,  0x01,  0x48,  0x08,  0x13,  0x05,  0xF6,  0xF0,  0x00,
                   14094:   0x05,  0x57,  0x08,  0x10,  0x45,  0x58,  0x00,  0xF2,  0xF6,  0x0D,  0x8D,  0x56,  0x83,  0x5A,  0x80,  0x4C,
                   14095:   0x05,  0x17,  0x00,  0x16,  0x02,  0x4B,  0x06,  0xF7,  0x04,  0x00,  0x62,  0x0B,  0x03,  0x82,  0x00,  0xF2,
                   14096:   0xE2,  0x0D,  0x02,  0x80,  0x00,  0x4C,  0x45,  0xF4,  0x02,  0x00,  0x52,  0x14,  0x06,  0xF7,  0x02,  0x00,
                   14097:   0x06,  0x14,  0x00,  0xF2,  0x54,  0x0F,  0x00,  0x16,  0x02,  0x4B,  0x01,  0xF6,  0xFF,  0x00,  0x38,  0x1C,
                   14098:   0x05,  0xF4,  0x04,  0x00,  0x83,  0x5A,  0x18,  0xDF,  0x19,  0xDF,  0x1D,  0xF7,  0x3C,  0x00,  0xB8,  0xF0,
                   14099:   0x4E,  0x10,  0x9C,  0x14,  0x01,  0x48,  0x1C,  0x13,  0x0E,  0xF7,  0x3C,  0x00,  0x03,  0xF7,  0x04,  0x00,
                   14100:   0xAF,  0x19,  0x03,  0x42,  0x45,  0xF4,  0x02,  0x00,  0x83,  0x5A,  0x02,  0xCC,  0x02,  0x41,  0x45,  0xF4,
                   14101:   0x02,  0x00,  0x00,  0x16,  0x91,  0x44,  0xD5,  0xF0,  0x3E,  0x10,  0x00,  0xF0,  0x9E,  0x02,  0x01,  0xF6,
                   14102:   0xFF,  0x00,  0x38,  0x1C,  0x05,  0xF4,  0x04,  0x00,  0x83,  0x5A,  0x18,  0xDF,  0x19,  0xDF,  0x0E,  0xF7,
                   14103:   0x3C,  0x00,  0x03,  0xF7,  0x04,  0x00,  0x0F,  0x79,  0x1C,  0xF7,  0x3C,  0x00,  0xB8,  0xF0,  0x9C,  0x10,
                   14104:   0x4E,  0x14,  0x01,  0x48,  0x06,  0x13,  0x45,  0xF4,  0x04,  0x00,  0x00,  0x16,  0x91,  0x44,  0xD5,  0xF0,
                   14105:   0x82,  0x10,  0x00,  0xF0,  0x9E,  0x02,  0x02,  0xF6,  0xFF,  0x00,  0x38,  0x1C,  0x2C,  0xBC,  0xAE,  0xBC,
                   14106:   0xE2,  0x08,  0x00,  0xEC,  0xB8,  0x00,  0x02,  0x48,  0x1D,  0xF7,  0x80,  0x00,  0xB8,  0xF0,  0xCC,  0x10,
                   14107:   0x1E,  0x14,  0x01,  0x48,  0x0E,  0x13,  0x0E,  0xF7,  0x80,  0x00,  0x38,  0x54,  0x03,  0x58,  0xAF,  0x19,
                   14108:   0x82,  0x48,  0x00,  0x16,  0x82,  0x48,  0x12,  0x45,  0xD5,  0xF0,  0xBA,  0x10,  0x00,  0xF0,  0x9E,  0x02,
                   14109:   0x39,  0xF0,  0xF8,  0x10,  0x38,  0x44,  0x00,  0x16,  0x7E,  0x18,  0x18,  0xF4,  0x03,  0x00,  0x04,  0x13,
                   14110:   0x61,  0x18,  0x00,  0x16,  0x38,  0x1C,  0x00,  0xFC,  0x22,  0x01,  0x18,  0xF4,  0x01,  0x00,  0xF1,  0x12,
                   14111:   0xE3,  0x10,  0x30,  0x44,  0x30,  0x44,  0x30,  0x44,  0xB1,  0xF0,  0x18,  0x11,  0x00,  0x16,  0x3E,  0x57,
                   14112:   0x03,  0xF6,  0xE0,  0x00,  0x03,  0x57,  0x83,  0x59,  0x04,  0xCC,  0x01,  0x4A,  0x6A,  0x12,  0x45,  0x5A,
                   14113:   0x00,  0xF2,  0xF6,  0x0D,  0x02,  0x4B,  0x70,  0x14,  0x34,  0x13,  0x02,  0x80,  0x48,  0xE4,  0x08,  0x00,
                   14114:   0x18,  0x12,  0x9C,  0xE7,  0x02,  0x00,  0x9E,  0xE7,  0x15,  0x00,  0x00,  0xF2,  0xC6,  0x0F,  0x00,  0xF2,
                   14115:   0x7A,  0x0A,  0x1E,  0x1C,  0x01,  0xF6,  0x01,  0x00,  0x00,  0x16,  0x30,  0xE4,  0x10,  0x00,  0x04,  0x40,
                   14116:   0x00,  0xF2,  0xE2,  0x0D,  0x20,  0xE7,  0x01,  0x00,  0x01,  0xF6,  0x01,  0x00,  0x00,  0x16,  0x04,  0xDC,
                   14117:   0x01,  0x4A,  0x24,  0x12,  0x45,  0x5A,  0x00,  0xF2,  0xF6,  0x0D,  0x43,  0x5B,  0x06,  0xEC,  0x98,  0x00,
                   14118:   0x00,  0xF2,  0x38,  0x10,  0xC6,  0x59,  0x20,  0x14,  0x0A,  0x13,  0x00,  0xF2,  0xC6,  0x0F,  0x00,  0xF2,
                   14119:   0x14,  0x10,  0xA7,  0x10,  0x83,  0x5A,  0xD7,  0x10,  0x0E,  0x47,  0x07,  0xE6,  0x10,  0x00,  0xCE,  0x47,
                   14120:   0x5A,  0xF0,  0x20,  0x11,  0xB9,  0x54,  0x00,  0x16,  0x14,  0x90,  0x96,  0x90,  0x02,  0xFC,  0xA8,  0x00,
                   14121:   0x03,  0xFC,  0xAA,  0x00,  0x48,  0x55,  0x02,  0x13,  0xC9,  0x55,  0x00,  0x16,  0x00,  0xEC,  0xBA,  0x00,
                   14122:   0x10,  0x44,  0x00,  0xEA,  0xBA,  0x00,  0x00,  0x16,  0x03,  0xF6,  0xC0,  0x00,  0x00,  0xF2,  0x68,  0x0A,
                   14123:   0x10,  0x44,  0x00,  0x4C,  0x00,  0x16
                   14124: };
                   14125: 
                   14126: unsigned short _adv_mcode_size ASC_INITDATA =
                   14127:     sizeof(_adv_mcode_buf); /* 0x11D6 */
                   14128: unsigned long  _adv_mcode_chksum ASC_INITDATA = 0x03494981UL;
                   14129: 
                   14130: /* a_init.c */
                   14131: /*
                   14132:  * EEPROM Configuration.
                   14133:  *
                   14134:  * All drivers should use this structure to set the default EEPROM
                   14135:  * configuration. The BIOS now uses this structure when it is built.
                   14136:  * Additional structure information can be found in a_condor.h where
                   14137:  * the structure is defined.
                   14138:  */
                   14139: STATIC ADVEEP_CONFIG
                   14140: Default_EEPROM_Config ASC_INITDATA = {
                   14141:     ADV_EEPROM_BIOS_ENABLE,     /* cfg_msw */
                   14142:     0x0000,                     /* cfg_lsw */
                   14143:     0xFFFF,                     /* disc_enable */
                   14144:     0xFFFF,                     /* wdtr_able */
                   14145:     0xFFFF,                     /* sdtr_able */
                   14146:     0xFFFF,                     /* start_motor */
                   14147:     0xFFFF,                     /* tagqng_able */
                   14148:     0xFFFF,                     /* bios_scan */
                   14149:     0,                          /* scam_tolerant */
                   14150:     7,                          /* adapter_scsi_id */
                   14151:     0,                          /* bios_boot_delay */
                   14152:     3,                          /* scsi_reset_delay */
                   14153:     0,                          /* bios_id_lun */
                   14154:     0,                          /* termination */
                   14155:     0,                          /* reserved1 */
                   14156:     0xFFEF,                     /* bios_ctrl */
                   14157:     0xFFFF,                     /* ultra_able */
                   14158:     0,                          /* reserved2 */
                   14159:     ASC_DEF_MAX_HOST_QNG,       /* max_host_qng */
                   14160:     ASC_DEF_MAX_DVC_QNG,        /* max_dvc_qng */
                   14161:     0,                          /* dvc_cntl */
                   14162:     0,                          /* bug_fix */
                   14163:     0,                          /* serial_number_word1 */
                   14164:     0,                          /* serial_number_word2 */
                   14165:     0,                          /* serial_number_word3 */
                   14166:     0,                          /* check_sum */
                   14167:     { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* oem_name[16] */
                   14168:     0,                          /* dvc_err_code */
                   14169:     0,                          /* adv_err_code */
                   14170:     0,                          /* adv_err_addr */
                   14171:     0,                          /* saved_dvc_err_code */
                   14172:     0,                          /* saved_adv_err_code */
                   14173:     0,                          /* saved_adv_err_addr */
                   14174:     0                           /* num_of_err */
                   14175: };
                   14176: 
                   14177: /*
                   14178:  * Initialize the ADV_DVC_VAR structure.
                   14179:  *
                   14180:  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
                   14181:  *
                   14182:  * For a non-fatal error return a warning code. If there are no warnings
                   14183:  * then 0 is returned.
                   14184:  */
                   14185: ASC_INITFUNC(
                   14186: int
                   14187: AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
                   14188: )
                   14189: {
                   14190:     ushort      warn_code;
                   14191:     AdvPortAddr iop_base;
                   14192:     uchar       pci_cmd_reg;
                   14193:     int         status;
                   14194: 
                   14195:     warn_code = 0;
                   14196:     asc_dvc->err_code = 0;
                   14197:     iop_base = asc_dvc->iop_base;
                   14198: 
                   14199:     /*
                   14200:      * PCI Command Register
                   14201:      */
                   14202: 
                   14203:     if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc,
                   14204:                             AscPCIConfigCommandRegister))
                   14205:          & AscPCICmdRegBits_BusMastering)
                   14206:         != AscPCICmdRegBits_BusMastering)
                   14207:     {
                   14208:         pci_cmd_reg |= AscPCICmdRegBits_BusMastering;
                   14209: 
                   14210:         DvcAdvWritePCIConfigByte(asc_dvc,
                   14211:                 AscPCIConfigCommandRegister, pci_cmd_reg);
                   14212: 
                   14213:         if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister))
                   14214:              & AscPCICmdRegBits_BusMastering)
                   14215:             != AscPCICmdRegBits_BusMastering)
                   14216:         {
                   14217:             warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
                   14218:         }
                   14219:     }
                   14220: 
                   14221:     /*
                   14222:      * PCI Latency Timer
                   14223:      *
                   14224:      * If the "latency timer" register is 0x20 or above, then we don't need
                   14225:      * to change it.  Otherwise, set it to 0x20 (i.e. set it to 0x20 if it
                   14226:      * comes up less than 0x20).
                   14227:      */
                   14228:     if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) {
                   14229:         DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer, 0x20);
                   14230:         if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20)
                   14231:         {
                   14232:             warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
                   14233:         }
                   14234:     }
                   14235: 
                   14236:     /*
                   14237:      * Save the state of the PCI Configuration Command Register
                   14238:      * "Parity Error Response Control" Bit. If the bit is clear (0),
                   14239:      * in AdvInitAsc3550Driver() tell the microcode to ignore DMA
                   14240:      * parity errors.
                   14241:      */
                   14242:     asc_dvc->cfg->control_flag = 0;
                   14243:     if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister)
                   14244:          & AscPCICmdRegBits_ParErrRespCtrl)) == 0)
                   14245:     {
                   14246:         asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
                   14247:     }
                   14248: 
                   14249:     asc_dvc->cur_host_qng = 0;
                   14250: 
                   14251:     asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
                   14252:       ADV_LIB_VERSION_MINOR;
                   14253:     asc_dvc->cfg->chip_version =
                   14254:       AdvGetChipVersion(iop_base, asc_dvc->bus_type);
                   14255: 
                   14256:     /*
                   14257:      * Reset the chip to start and allow register writes.
                   14258:      */
                   14259:     if (AdvFindSignature(iop_base) == 0)
                   14260:     {
                   14261:         asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
                   14262:         return ADV_ERROR;
                   14263:     }
                   14264:     else {
                   14265: 
                   14266:         AdvResetChip(asc_dvc);
                   14267: 
                   14268:         if ((status = AdvInitFromEEP(asc_dvc)) == ADV_ERROR)
                   14269:         {
                   14270:             return ADV_ERROR;
                   14271:         }
                   14272:         warn_code |= status;
                   14273: 
                   14274:         /*
                   14275:          * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
                   14276:          * Resets should be performed.
                   14277:          */
                   14278:         if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
                   14279:         {
                   14280:             AdvResetSCSIBus(asc_dvc);
                   14281:         }
                   14282:     }
                   14283: 
                   14284:     return warn_code;
                   14285: }
                   14286: 
                   14287: /*
                   14288:  * Initialize the ASC3550.
                   14289:  *
                   14290:  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
                   14291:  *
                   14292:  * For a non-fatal error return a warning code. If there are no warnings
                   14293:  * then 0 is returned.
                   14294:  */
                   14295: ASC_INITFUNC(
                   14296: int
                   14297: AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
                   14298: )
                   14299: {
                   14300:     AdvPortAddr iop_base;
                   14301:     ushort      warn_code;
                   14302:     ulong       sum;
                   14303:     int         begin_addr;
                   14304:     int         end_addr;
                   14305:     int         code_sum;
                   14306:     int         word;
                   14307:     int         rql_addr;                   /* RISC Queue List address */
                   14308:     int         i;
                   14309:     ushort      scsi_cfg1;
                   14310:     uchar       biosmem[ASC_MC_BIOSLEN];    /* BIOS RISC Memory 0x40-0x8F. */
                   14311: 
                   14312:     /* If there is already an error, don't continue. */
                   14313:     if (asc_dvc->err_code != 0)
                   14314:     {
                   14315:         return ADV_ERROR;
                   14316:     }
                   14317: 
                   14318:     warn_code = 0;
                   14319:     iop_base = asc_dvc->iop_base;
                   14320: 
                   14321:     /*
                   14322:      * Save the RISC memory BIOS region before writing the microcode.
                   14323:      * The BIOS may already be loaded and using its RISC LRAM region
                   14324:      * so its region must be saved and restored.
                   14325:      *
                   14326:      * Note: This code makes the assumption, which is currently true,
                   14327:      * that a chip reset does not clear RISC LRAM.
                   14328:      */
                   14329:     for (i = 0; i < ASC_MC_BIOSLEN; i++)
                   14330:     {
                   14331:         AdvReadByteLram(iop_base, ASC_MC_BIOSMEM + i, biosmem[i]);
                   14332:     }
                   14333: 
                   14334:     /*
                   14335:      * Load the Microcode
                   14336:      *
                   14337:      * Write the microcode image to RISC memory starting at address 0.
                   14338:      */
                   14339:     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
                   14340:     for (word = 0; word < _adv_mcode_size; word += 2)
                   14341:     {
                   14342:         AdvWriteWordAutoIncLram(iop_base,
                   14343:             *((ushort *) (&_adv_mcode_buf[word])));
                   14344:     }
                   14345: 
                   14346:     /*
                   14347:      * Clear the rest of Condor's Internal RAM (8KB).
                   14348:      */
                   14349:     for (; word < ADV_CONDOR_MEMSIZE; word += 2)
                   14350:     {
                   14351:         AdvWriteWordAutoIncLram(iop_base, 0);
                   14352:     }
                   14353: 
                   14354:     /*
                   14355:      * Verify the microcode checksum.
                   14356:      */
                   14357:     sum = 0;
                   14358:     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
                   14359:     for (word = 0; word < _adv_mcode_size; word += 2)
                   14360:     {
                   14361:         sum += AdvReadWordAutoIncLram(iop_base);
                   14362:     }
                   14363: 
                   14364:     if (sum != _adv_mcode_chksum)
                   14365:     {
                   14366:         asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
                   14367:         return ADV_ERROR;
                   14368:     }
                   14369: 
                   14370:     /*
                   14371:      * Restore the RISC memory BIOS region.
                   14372:      */
                   14373:     for (i = 0; i < ASC_MC_BIOSLEN; i++)
                   14374:     {
                   14375:         AdvWriteByteLram(iop_base, ASC_MC_BIOSMEM + i, biosmem[i]);
                   14376:     }
                   14377: 
                   14378:     /*
                   14379:      * Calculate and write the microcode code checksum to the microcode
                   14380:      * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).  
                   14381:      */
                   14382:     AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
                   14383:     AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
                   14384:     code_sum = 0;
                   14385:     for (word = begin_addr; word < end_addr; word += 2)
                   14386:     {
                   14387:         code_sum += *((ushort *) (&_adv_mcode_buf[word]));
                   14388:     }
                   14389:     AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
                   14390: 
                   14391:     /*
                   14392:      * Read microcode version and date.
                   14393:      */
                   14394:     AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
                   14395:     AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
                   14396: 
                   14397:     /*
                   14398:      * Initialize microcode operating variables
                   14399:      */
                   14400:     AdvWriteWordLram(iop_base, ASC_MC_ADAPTER_SCSI_ID,
                   14401:                        asc_dvc->chip_scsi_id);
                   14402: 
                   14403:     /*
                   14404:      * If the PCI Configuration Command Register "Parity Error Response
                   14405:      * Control" Bit was clear (0), then set the microcode variable
                   14406:      * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
                   14407:      * to ignore DMA parity errors.
                   14408:      */
                   14409:     if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
                   14410:     {
                   14411:         /* 
                   14412:          * Note: Don't remove the use of a temporary variable in
                   14413:          * the following code, otherwise the Microsoft C compiler
                   14414:          * will turn the following lines into a no-op.
                   14415:          */
                   14416:         AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
                   14417:         word |= CONTROL_FLAG_IGNORE_PERR;
                   14418:         AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
                   14419:     }
                   14420: 
                   14421:     /*
                   14422:      * Set default microcode operating variables for WDTR, SDTR, and
                   14423:      * command tag queuing based on the EEPROM configuration values.
                   14424:      *
                   14425:      * These ADV_DVC_VAR fields and the microcode variables will be
                   14426:      * changed in AdvInquiryHandling() if it is found a device is
                   14427:      * incapable of a particular feature.
                   14428:      */
                   14429: 
                   14430:     /*
                   14431:      * Set the microcode ULTRA target mask from EEPROM value. The
                   14432:      * SDTR target mask overrides the ULTRA target mask in the
                   14433:      * microcode so it is safe to set this value without determining
                   14434:      * whether the device supports SDTR.
                   14435:      * 
                   14436:      * Note: There is no way to know whether a device supports ULTRA
                   14437:      * speed without attempting a SDTR ULTRA speed negotiation with
                   14438:      * the device. The device will reject the speed if it does not
                   14439:      * support it by responding with an SDTR message containing a
                   14440:      * slower speed.
                   14441:      */
                   14442:     AdvWriteWordLram(iop_base, ASC_MC_ULTRA_ABLE, asc_dvc->ultra_able);
                   14443:     AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
                   14444: 
                   14445: 
                   14446:     /*
                   14447:      * Set SCSI_CFG0 Microcode Default Value.
                   14448:      *
                   14449:      * The microcode will set the SCSI_CFG0 register using this value
                   14450:      * after it is started below.
                   14451:      */
                   14452:     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
                   14453:         PARITY_EN | SEL_TMO_LONG | OUR_ID_EN | asc_dvc->chip_scsi_id);
                   14454:   
                   14455:     /*
                   14456:      * Determine SCSI_CFG1 Microcode Default Value.
                   14457:      *
                   14458:      * The microcode will set the SCSI_CFG1 register using this value
                   14459:      * after it is started below.
                   14460:      */
                   14461: 
                   14462:     /* Read current SCSI_CFG1 Register value. */
                   14463:     scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
                   14464: 
                   14465:     /*
                   14466:      * If all three connectors are in use, return an error.
                   14467:      */
                   14468:     if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
                   14469:         (scsi_cfg1 & CABLE_ILLEGAL_B) == 0)
                   14470:     {
                   14471:         asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
                   14472:         return ADV_ERROR;
                   14473:     }
                   14474: 
                   14475:     /*
                   14476:      * If the internal narrow cable is reversed all of the SCSI_CTRL
                   14477:      * register signals will be set. Check for and return an error if
                   14478:      * this condition is found.
                   14479:      */
                   14480:     if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
                   14481:     {
                   14482:         asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
                   14483:         return ADV_ERROR;
                   14484:     }
                   14485: 
                   14486:     /*
                   14487:      * If this is a differential board and a single-ended device
                   14488:      * is attached to one of the connectors, return an error.
                   14489:      */
                   14490:     if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0)
                   14491:     {
                   14492:         asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
                   14493:         return ADV_ERROR;
                   14494:     }
                   14495: 
                   14496:     /*
                   14497:      * If automatic termination control is enabled, then set the
                   14498:      * termination value based on a table listed in a_condor.h.
                   14499:      *
                   14500:      * If manual termination was specified with an EEPROM setting
                   14501:      * then 'termination' was set-up in AdvInitFromEEP() and
                   14502:      * is ready to be 'ored' into SCSI_CFG1.
                   14503:      */
                   14504:     if (asc_dvc->cfg->termination == 0)
                   14505:     {
                   14506:         /*
                   14507:          * The software always controls termination by setting TERM_CTL_SEL.
                   14508:          * If TERM_CTL_SEL were set to 0, the hardware would set termination.
                   14509:          */
                   14510:         asc_dvc->cfg->termination |= TERM_CTL_SEL;
                   14511: 
                   14512:         switch(scsi_cfg1 & CABLE_DETECT)
                   14513:         {
                   14514:             /* TERM_CTL_H: on, TERM_CTL_L: on */
                   14515:             case 0x3: case 0x7: case 0xB: case 0xD: case 0xE: case 0xF:
                   14516:                 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
                   14517:                 break;
                   14518: 
                   14519:             /* TERM_CTL_H: on, TERM_CTL_L: off */
                   14520:             case 0x1: case 0x5: case 0x9: case 0xA: case 0xC:
                   14521:                 asc_dvc->cfg->termination |= TERM_CTL_H;
                   14522:                 break;
                   14523: 
                   14524:             /* TERM_CTL_H: off, TERM_CTL_L: off */
                   14525:             case 0x2: case 0x6:
                   14526:                 break;
                   14527:         }
                   14528:     }
                   14529: 
                   14530:     /*
                   14531:      * Clear any set TERM_CTL_H and TERM_CTL_L bits.
                   14532:      */
                   14533:     scsi_cfg1 &= ~TERM_CTL;
                   14534: 
                   14535:     /*
                   14536:      * Invert the TERM_CTL_H and TERM_CTL_L bits and then
                   14537:      * set 'scsi_cfg1'. The TERM_POL bit does not need to be
                   14538:      * referenced, because the hardware internally inverts
                   14539:      * the Termination High and Low bits if TERM_POL is set.
                   14540:      */
                   14541:     scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
                   14542: 
                   14543:     /*
                   14544:      * Set SCSI_CFG1 Microcode Default Value
                   14545:      *
                   14546:      * Set filter value and possibly modified termination control
                   14547:      * bits in the Microcode SCSI_CFG1 Register Value.
                   14548:      *
                   14549:      * The microcode will set the SCSI_CFG1 register using this value
                   14550:      * after it is started below.
                   14551:      */
                   14552:     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
                   14553:                        FLTR_11_TO_20NS | scsi_cfg1);
                   14554: 
                   14555:     /*
                   14556:      * Set SEL_MASK Microcode Default Value
                   14557:      *
                   14558:      * The microcode will set the SEL_MASK register using this value
                   14559:      * after it is started below.
                   14560:      */
                   14561:     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
                   14562:                         ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
                   14563: 
                   14564:     /*
                   14565:      * Link all the RISC Queue Lists together in a doubly-linked
                   14566:      * NULL terminated list.
                   14567:      *
                   14568:      * Skip the NULL (0) queue which is not used.
                   14569:      */
                   14570:     for (i = 1, rql_addr = ASC_MC_RISC_Q_LIST_BASE + ASC_MC_RISC_Q_LIST_SIZE;
                   14571:          i < ASC_MC_RISC_Q_TOTAL_CNT;
                   14572:          i++, rql_addr += ASC_MC_RISC_Q_LIST_SIZE)
                   14573:     {
                   14574:         /*
                   14575:          * Set the current RISC Queue List's RQL_FWD and RQL_BWD pointers
                   14576:          * in a one word write and set the state (RQL_STATE) to free.
                   14577:          */
                   14578:         AdvWriteWordLram(iop_base, rql_addr, ((i + 1) + ((i - 1) << 8)));
                   14579:         AdvWriteByteLram(iop_base, rql_addr + RQL_STATE, ASC_MC_QS_FREE);
                   14580:     }
                   14581: 
                   14582:     /*
                   14583:      * Set the Host and RISC Queue List pointers.
                   14584:      *
                   14585:      * Both sets of pointers are initialized with the same values:
                   14586:      * ASC_MC_RISC_Q_FIRST(0x01) and ASC_MC_RISC_Q_LAST (0xFF).
                   14587:      */
                   14588:     AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_READY, ASC_MC_RISC_Q_FIRST);
                   14589:     AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_DONE, ASC_MC_RISC_Q_LAST);
                   14590: 
                   14591:     AdvWriteByteLram(iop_base, ASC_MC_RISC_NEXT_READY, ASC_MC_RISC_Q_FIRST);
                   14592:     AdvWriteByteLram(iop_base, ASC_MC_RISC_NEXT_DONE, ASC_MC_RISC_Q_LAST);
                   14593: 
                   14594:     /*
                   14595:      * Finally, set up the last RISC Queue List (255) with
                   14596:      * a NULL forward pointer.
                   14597:      */
                   14598:     AdvWriteWordLram(iop_base, rql_addr, (ASC_MC_NULL_Q + ((i - 1) << 8)));
                   14599:     AdvWriteByteLram(iop_base, rql_addr + RQL_STATE, ASC_MC_QS_FREE);
                   14600: 
                   14601:     AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
                   14602:          (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
                   14603: 
                   14604:     /* 
                   14605:      * Note: Don't remove the use of a temporary variable in
                   14606:      * the following code, otherwise the Microsoft C compiler
                   14607:      * will turn the following lines into a no-op.
                   14608:      */
                   14609:     AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
                   14610:     AdvWriteWordRegister(iop_base, IOPW_PC, word);
                   14611: 
                   14612:     /* finally, finally, gentlemen, start your engine */
                   14613:     AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
                   14614:  
                   14615:     return warn_code;
                   14616: }
                   14617: 
                   14618: /*
                   14619:  * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
                   14620:  * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
                   14621:  * all of this is done.
                   14622:  *
                   14623:  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
                   14624:  *
                   14625:  * For a non-fatal error return a warning code. If there are no warnings
                   14626:  * then 0 is returned.
                   14627:  *
                   14628:  * Note: Chip is stopped on entry.
                   14629:  */
                   14630: ASC_INITFUNC(
                   14631: STATIC int
                   14632: AdvInitFromEEP(ADV_DVC_VAR *asc_dvc)
                   14633: )
                   14634: {
                   14635:     AdvPortAddr         iop_base;
                   14636:     ushort              warn_code;
                   14637:     ADVEEP_CONFIG       eep_config;
                   14638:     int                 i;
                   14639: 
                   14640:     iop_base = asc_dvc->iop_base;
                   14641: 
                   14642:     warn_code = 0;
                   14643: 
                   14644:     /*
                   14645:      * Read the board's EEPROM configuration.
                   14646:      *
                   14647:      * Set default values if a bad checksum is found.
                   14648:      */
                   14649:     if (AdvGetEEPConfig(iop_base, &eep_config) != eep_config.check_sum)
                   14650:     {
                   14651:         warn_code |= ASC_WARN_EEPROM_CHKSUM;
                   14652: 
                   14653:         /*
                   14654:          * Set EEPROM default values.
                   14655:          */
                   14656:         for (i = 0; i < sizeof(ADVEEP_CONFIG); i++)
                   14657:         {
                   14658:             *((uchar *) &eep_config + i) =
                   14659:                 *((uchar *) &Default_EEPROM_Config + i);
                   14660:         }
                   14661: 
                   14662:         /*
                   14663:          * Assume the 6 byte board serial number that was read
                   14664:          * from EEPROM is correct even if the EEPROM checksum
                   14665:          * failed.
                   14666:          */
                   14667:         eep_config.serial_number_word3 =
                   14668:             AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 1);
                   14669:         eep_config.serial_number_word2 =
                   14670:             AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 2);
                   14671:         eep_config.serial_number_word1 =
                   14672:             AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 3);
                   14673:         AdvSetEEPConfig(iop_base, &eep_config);
                   14674:     }
                   14675: 
                   14676:     /*
                   14677:      * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
                   14678:      * EEPROM configuration that was read.
                   14679:      *
                   14680:      * This is the mapping of EEPROM fields to Adv Library fields.
                   14681:      */
                   14682:     asc_dvc->wdtr_able = eep_config.wdtr_able;
                   14683:     asc_dvc->sdtr_able = eep_config.sdtr_able;
                   14684:     asc_dvc->ultra_able = eep_config.ultra_able;
                   14685:     asc_dvc->tagqng_able = eep_config.tagqng_able;
                   14686:     asc_dvc->cfg->disc_enable = eep_config.disc_enable;
                   14687:     asc_dvc->max_host_qng = eep_config.max_host_qng;
                   14688:     asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
                   14689:     asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
                   14690:     asc_dvc->start_motor = eep_config.start_motor;
                   14691:     asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
                   14692:     asc_dvc->cfg->bios_boot_wait = eep_config.bios_boot_delay;
                   14693:     asc_dvc->bios_ctrl = eep_config.bios_ctrl;
                   14694:     asc_dvc->no_scam = eep_config.scam_tolerant;
                   14695:     asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
                   14696:     asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
                   14697:     asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
                   14698: 
                   14699:     /*
                   14700:      * Set the host maximum queuing (max. 253, min. 16) and the per device
                   14701:      * maximum queuing (max. 63, min. 4).
                   14702:      */
                   14703:     if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
                   14704:     {
                   14705:         eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
                   14706:     } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
                   14707:     {
                   14708:         /* If the value is zero, assume it is uninitialized. */
                   14709:         if (eep_config.max_host_qng == 0)
                   14710:         {
                   14711:             eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
                   14712:         } else
                   14713:         {
                   14714:             eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
                   14715:         }
                   14716:     }
                   14717: 
                   14718:     if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
                   14719:     {
                   14720:         eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
                   14721:     } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
                   14722:     {
                   14723:         /* If the value is zero, assume it is uninitialized. */
                   14724:         if (eep_config.max_dvc_qng == 0)
                   14725:         {
                   14726:             eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
                   14727:         } else
                   14728:         {
                   14729:             eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
                   14730:         }
                   14731:     }
                   14732: 
                   14733:     /*
                   14734:      * If 'max_dvc_qng' is greater than 'max_host_qng', then
                   14735:      * set 'max_dvc_qng' to 'max_host_qng'.
                   14736:      */
                   14737:     if (eep_config.max_dvc_qng > eep_config.max_host_qng)
                   14738:     {
                   14739:         eep_config.max_dvc_qng = eep_config.max_host_qng;
                   14740:     }
                   14741: 
                   14742:     /*
                   14743:      * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_CFG 'max_dvc_qng'
                   14744:      * values based on possibly adjusted EEPROM values.
                   14745:      */
                   14746:     asc_dvc->max_host_qng = eep_config.max_host_qng;
                   14747:     asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
                   14748: 
                   14749: 
                   14750:     /*
                   14751:      * If the EEPROM 'termination' field is set to automatic (0), then set
                   14752:      * the ADV_DVC_CFG 'termination' field to automatic also.
                   14753:      *
                   14754:      * If the termination is specified with a non-zero 'termination'
                   14755:      * value check that a legal value is set and set the ADV_DVC_CFG
                   14756:      * 'termination' field appropriately.
                   14757:      */
                   14758:     if (eep_config.termination == 0)
                   14759:     {
                   14760:         asc_dvc->cfg->termination = 0;    /* auto termination */
                   14761:     } else
                   14762:     {
                   14763:         /* Enable manual control with low off / high off. */
                   14764:         if (eep_config.termination == 1)
                   14765:         {
                   14766:             asc_dvc->cfg->termination = TERM_CTL_SEL;
                   14767: 
                   14768:         /* Enable manual control with low off / high on. */
                   14769:         } else if (eep_config.termination == 2)
                   14770:         {
                   14771:             asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
                   14772: 
                   14773:         /* Enable manual control with low on / high on. */
                   14774:         } else if (eep_config.termination == 3)
                   14775:         {
                   14776:             asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
                   14777:         } else
                   14778:         {
                   14779:             /*
                   14780:              * The EEPROM 'termination' field contains a bad value. Use
                   14781:              * automatic termination instead.
                   14782:              */
                   14783:             asc_dvc->cfg->termination = 0;
                   14784:             warn_code |= ASC_WARN_EEPROM_TERMINATION;
                   14785:         }
                   14786:     }
                   14787: 
                   14788:     return warn_code;
                   14789: }
                   14790: 
                   14791: /*
                   14792:  * Read EEPROM configuration into the specified buffer.
                   14793:  *
                   14794:  * Return a checksum based on the EEPROM configuration read.
                   14795:  */
                   14796: ASC_INITFUNC(
                   14797: STATIC ushort
                   14798: AdvGetEEPConfig(AdvPortAddr iop_base, ADVEEP_CONFIG *cfg_buf)
                   14799: )
                   14800: {
                   14801:     ushort              wval, chksum;
                   14802:     ushort              *wbuf;
                   14803:     int                 eep_addr;
                   14804: 
                   14805:     wbuf = (ushort *) cfg_buf;
                   14806:     chksum = 0;
                   14807: 
                   14808:     for (eep_addr = ASC_EEP_DVC_CFG_BEGIN;
                   14809:          eep_addr < ASC_EEP_DVC_CFG_END;
                   14810:          eep_addr++, wbuf++)
                   14811:     {
                   14812:         wval = AdvReadEEPWord(iop_base, eep_addr);
                   14813:         chksum += wval;
                   14814:         *wbuf = wval;
                   14815:     }
                   14816:     *wbuf = AdvReadEEPWord(iop_base, eep_addr);
                   14817:     wbuf++;
                   14818:     for (eep_addr = ASC_EEP_DVC_CTL_BEGIN;
                   14819:          eep_addr < ASC_EEP_MAX_WORD_ADDR;
                   14820:          eep_addr++, wbuf++)
                   14821:     {
                   14822:         *wbuf = AdvReadEEPWord(iop_base, eep_addr);
                   14823:     }
                   14824:     return chksum;
                   14825: }
                   14826: 
                   14827: /*
                   14828:  * Read the EEPROM from specified location
                   14829:  */
                   14830: ASC_INITFUNC(
                   14831: STATIC ushort
                   14832: AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
                   14833: )
                   14834: {
                   14835:     AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
                   14836:         ASC_EEP_CMD_READ | eep_word_addr);
                   14837:     AdvWaitEEPCmd(iop_base);
                   14838:     return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
                   14839: }
                   14840: 
                   14841: /*
                   14842:  * Wait for EEPROM command to complete
                   14843:  */
                   14844: ASC_INITFUNC(
                   14845: STATIC void
                   14846: AdvWaitEEPCmd(AdvPortAddr iop_base)
                   14847: )
                   14848: {
                   14849:     int eep_delay_ms;
                   14850: 
                   14851:     for (eep_delay_ms = 0; eep_delay_ms < ASC_EEP_DELAY_MS; eep_delay_ms++)
                   14852:     {
                   14853:         if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE)
                   14854:         {
                   14855:             break;
                   14856:         }
                   14857:         DvcSleepMilliSecond(1);
                   14858:     }
                   14859:     if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) == 0)
                   14860:     {
                   14861:         ADV_ASSERT(0);
                   14862:     }
                   14863:     return;
                   14864: }
                   14865: 
                   14866: /*
                   14867:  * Write the EEPROM from 'cfg_buf'.
                   14868:  */
                   14869: ASC_INITFUNC(
                   14870: STATIC void
                   14871: AdvSetEEPConfig(AdvPortAddr iop_base, ADVEEP_CONFIG *cfg_buf)
                   14872: )
                   14873: {
                   14874:     ushort       *wbuf;
                   14875:     ushort       addr, chksum;
                   14876: 
                   14877:     wbuf = (ushort *) cfg_buf;
                   14878:     chksum = 0;
                   14879: 
                   14880:     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
                   14881:     AdvWaitEEPCmd(iop_base);
                   14882: 
                   14883:     /*
                   14884:      * Write EEPROM from word 0 to word 15
                   14885:      */
                   14886:     for (addr = ASC_EEP_DVC_CFG_BEGIN;
                   14887:          addr < ASC_EEP_DVC_CFG_END; addr++, wbuf++)
                   14888:     {
                   14889:         chksum += *wbuf;
                   14890:         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf);
                   14891:         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
                   14892:         AdvWaitEEPCmd(iop_base);
                   14893:         DvcSleepMilliSecond(ASC_EEP_DELAY_MS);
                   14894:     }
                   14895: 
                   14896:     /*
                   14897:      * Write EEPROM checksum at word 18
                   14898:      */
                   14899:     AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
                   14900:     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
                   14901:     AdvWaitEEPCmd(iop_base);
                   14902:     wbuf++;        /* skip over check_sum */
                   14903: 
                   14904:     /*
                   14905:      * Write EEPROM OEM name at words 19 to 26 
                   14906:      */
                   14907:     for (addr = ASC_EEP_DVC_CTL_BEGIN;
                   14908:          addr < ASC_EEP_MAX_WORD_ADDR; addr++, wbuf++)
                   14909:     {
                   14910:         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf);
                   14911:         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
                   14912:         AdvWaitEEPCmd(iop_base);
                   14913:     }
                   14914:     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
                   14915:     AdvWaitEEPCmd(iop_base);
                   14916:     return;
                   14917: }
                   14918: 
                   14919: /*
                   14920:  * This function resets the chip and SCSI bus
                   14921:  *
                   14922:  * It is up to the caller to add a delay to let the bus settle after
                   14923:  * calling this function.
                   14924:  *
                   14925:  * The SCSI_CFG0, SCSI_CFG1, and MEM_CFG registers are set-up in
                   14926:  * AdvInitAsc3550Driver(). Here when doing a write to one of these
                   14927:  * registers read first and then write.
                   14928:  *
                   14929:  * Note: A SCSI Bus Reset can not be done until after the EEPROM
                   14930:  * configuration is read to determine whether SCSI Bus Resets
                   14931:  * should be performed.
                   14932:  */
                   14933: ASC_INITFUNC(
                   14934: STATIC void
                   14935: AdvResetChip(ADV_DVC_VAR *asc_dvc)
                   14936: )
                   14937: {
                   14938:     AdvPortAddr    iop_base;
                   14939:     ushort         word;
                   14940:     uchar          byte;
                   14941: 
                   14942:     iop_base = asc_dvc->iop_base;
                   14943: 
                   14944:     /*
                   14945:      * Reset Chip.
                   14946:      */
                   14947:     AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
                   14948:     DvcSleepMilliSecond(100);
                   14949:     AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_WR_IO_REG);
                   14950: 
                   14951:     /*
                   14952:      * Initialize Chip registers.
                   14953:      * 
                   14954:      * Note: Don't remove the use of a temporary variable in the following
                   14955:      * code, otherwise the Microsoft C compiler will turn the following lines
                   14956:      * into a no-op.
                   14957:      */
                   14958:     byte = AdvReadByteRegister(iop_base, IOPB_MEM_CFG);
                   14959:     byte |= RAM_SZ_8KB;
                   14960:     AdvWriteByteRegister(iop_base, IOPB_MEM_CFG, byte);
                   14961: 
                   14962:     word = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
                   14963:     word &= ~BIG_ENDIAN;
                   14964:     AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, word);
                   14965: 
                   14966:     /*
                   14967:      * Setting the START_CTL_EMFU 3:2 bits sets a FIFO threshold
                   14968:      * of 128 bytes. This register is only accessible to the host.
                   14969:      */
                   14970:     AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
                   14971:         START_CTL_EMFU | READ_CMD_MRM);
                   14972: }
                   14973: 
                   14974: /* a_advlib.c */
                   14975: /*
                   14976:  * Description:
                   14977:  *      Send a SCSI request to the ASC3550 chip
                   14978:  *
                   14979:  * If there is no SG list for the request, set 'sg_entry_cnt' to 0.
                   14980:  *
                   14981:  * If 'sg_real_addr' is non-zero on entry, AscGetSGList() will not be
                   14982:  * called. It is assumed the caller has already initialized 'sg_real_addr'.
                   14983:  *
                   14984:  * Return:
                   14985:  *      ADV_SUCCESS(1) - the request is in the mailbox
                   14986:  *      ADV_BUSY(0) - total request count > 253, try later
                   14987:  *      ADV_ERROR(-1) - invalid scsi request Q
                   14988:  */
                   14989: STATIC int
                   14990: AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc,
                   14991:                 ADV_SCSI_REQ_Q *scsiq)
                   14992: {
                   14993:     if (scsiq == (ADV_SCSI_REQ_Q *) 0L)
                   14994:     {
                   14995:         /* 'scsiq' should never be NULL. */
                   14996:         ADV_ASSERT(0);
                   14997:         return ADV_ERROR;
                   14998:     }
                   14999: 
                   15000:     return AdvSendScsiCmd(asc_dvc, scsiq);
                   15001: }
                   15002: 
                   15003: /*
                   15004:  * Reset SCSI Bus and purge all outstanding requests.
                   15005:  *
                   15006:  * Return Value:
                   15007:  *      ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
                   15008:  *
                   15009:  * Note: Should always return ADV_TRUE.
                   15010:  */
                   15011: STATIC int
                   15012: AdvResetSB(ADV_DVC_VAR *asc_dvc)
                   15013: {
                   15014:     int         status;
                   15015: 
                   15016:     status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET, 0L, 0);
                   15017: 
                   15018:     AdvResetSCSIBus(asc_dvc);
                   15019: 
                   15020:     return status;
                   15021: }
                   15022: 
                   15023: /*
                   15024:  * Reset SCSI Bus and delay.
                   15025:  */
                   15026: STATIC void
                   15027: AdvResetSCSIBus(ADV_DVC_VAR *asc_dvc)
                   15028: {
                   15029:     AdvPortAddr    iop_base;
                   15030:     ushort         scsi_ctrl;
                   15031: 
                   15032:     iop_base = asc_dvc->iop_base;
                   15033: 
                   15034:     /*
                   15035:      * The microcode currently sets the SCSI Bus Reset signal while
                   15036:      * handling the AscSendIdleCmd() IDLE_CMD_SCSI_RESET command above.
                   15037:      * But the SCSI Bus Reset Hold Time in the microcode is not deterministic
                   15038:      * (it may in fact be for less than the SCSI Spec. minimum of 25 us).
                   15039:      * Therefore on return the Adv Library sets the SCSI Bus Reset signal
                   15040:      * for ASC_SCSI_RESET_HOLD_TIME_US, which is defined to be greater
                   15041:      * than 25 us.
                   15042:      */
                   15043:     scsi_ctrl = AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL);
                   15044:     AdvWriteWordRegister(iop_base, IOPW_SCSI_CTRL,
                   15045:         scsi_ctrl | ADV_SCSI_CTRL_RSTOUT);
                   15046:     DvcDelayMicroSecond(asc_dvc, (ushort) ASC_SCSI_RESET_HOLD_TIME_US);
                   15047:     AdvWriteWordRegister(iop_base, IOPW_SCSI_CTRL,
                   15048:         scsi_ctrl & ~ADV_SCSI_CTRL_RSTOUT);
                   15049: 
                   15050:     DvcSleepMilliSecond((ulong) asc_dvc->scsi_reset_wait * 1000);
                   15051: }
                   15052: 
                   15053: 
                   15054: /*
                   15055:  * Adv Library Interrupt Service Routine
                   15056:  *
                   15057:  *  This function is called by a driver's interrupt service routine.
                   15058:  *  The function disables and re-enables interrupts.
                   15059:  *
                   15060:  *  When a microcode idle command is completed, the ADV_DVC_VAR
                   15061:  *  'idle_cmd_done' field is set to ADV_TRUE.
                   15062:  *
                   15063:  *  Note: AdvISR() can be called when interrupts are disabled or even
                   15064:  *  when there is no hardware interrupt condition present. It will
                   15065:  *  always check for completed idle commands and microcode requests.
                   15066:  *  This is an important feature that shouldn't be changed because it
                   15067:  *  allows commands to be completed from polling mode loops.
                   15068:  *
                   15069:  * Return:
                   15070:  *   ADV_TRUE(1) - interrupt was pending
                   15071:  *   ADV_FALSE(0) - no interrupt was pending
                   15072:  */
                   15073: STATIC int
                   15074: AdvISR(ADV_DVC_VAR *asc_dvc)
                   15075: {
                   15076:     AdvPortAddr                 iop_base;
                   15077:     uchar                       int_stat;
                   15078:     ushort                      next_done_loc, target_bit;
                   15079:     int                         completed_q;
1.1.1.2   root     15080:     long                        flags;
1.1       root     15081:     ADV_SCSI_REQ_Q              *scsiq;
                   15082:     ASC_REQ_SENSE               *sense_data;
                   15083:     int                         ret;
                   15084: 
                   15085:     flags = DvcEnterCritical();
                   15086:     iop_base = asc_dvc->iop_base;
                   15087: 
                   15088:     if (AdvIsIntPending(iop_base))
                   15089:     {
                   15090:         ret = ADV_TRUE;
                   15091:     } else
                   15092:     {
                   15093:         ret = ADV_FALSE;
                   15094:     }
                   15095: 
                   15096:     /* Reading the register clears the interrupt. */
                   15097:     int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
                   15098: 
                   15099:     if (int_stat & ADV_INTR_STATUS_INTRB)
                   15100:     {
                   15101:         asc_dvc->idle_cmd_done = ADV_TRUE;
                   15102:     }
                   15103: 
                   15104:     /*
                   15105:      * Notify the driver of a hardware detected SCSI Bus Reset.
                   15106:      */
                   15107:     if (int_stat & ADV_INTR_STATUS_INTRC)
                   15108:     {
                   15109:         if (asc_dvc->sbreset_callback != 0)
                   15110:         {
                   15111:             (*(ADV_SBRESET_CALLBACK) asc_dvc->sbreset_callback)(asc_dvc);
                   15112:         }
                   15113:     }
                   15114: 
                   15115:     /*
                   15116:      * ASC_MC_HOST_NEXT_DONE (0x129) is actually the last completed RISC
                   15117:      * Queue List request. Its forward pointer (RQL_FWD) points to the
                   15118:      * current completed RISC Queue List request.
                   15119:      */
                   15120:     AdvReadByteLram(iop_base, ASC_MC_HOST_NEXT_DONE, next_done_loc);
                   15121:     next_done_loc = ASC_MC_RISC_Q_LIST_BASE +
                   15122:         (next_done_loc * ASC_MC_RISC_Q_LIST_SIZE) + RQL_FWD;
                   15123: 
                   15124:     AdvReadByteLram(iop_base, next_done_loc, completed_q);
                   15125: 
                   15126:     /* Loop until all completed Q's are processed. */
                   15127:     while (completed_q != ASC_MC_NULL_Q)
                   15128:     {
                   15129:         AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_DONE, completed_q);
                   15130: 
                   15131:         next_done_loc = ASC_MC_RISC_Q_LIST_BASE +
                   15132:           (completed_q * ASC_MC_RISC_Q_LIST_SIZE);
                   15133: 
                   15134:         /*
                   15135:          * Read the ADV_SCSI_REQ_Q virtual address pointer from
                   15136:          * the RISC list entry. The microcode has changed the
                   15137:          * ADV_SCSI_REQ_Q physical address to its virtual address.
                   15138:          *
                   15139:          * Refer to comments at the end of AdvSendScsiCmd() for
                   15140:          * more information on the RISC list structure.
                   15141:          */
                   15142:         {
                   15143:             ushort lsw, msw;
                   15144:             AdvReadWordLram(iop_base, next_done_loc + RQL_PHYADDR, lsw);
                   15145:             AdvReadWordLram(iop_base, next_done_loc + RQL_PHYADDR + 2, msw);
                   15146: 
                   15147:             scsiq = (ADV_SCSI_REQ_Q *) (((ulong) msw << 16) | lsw);
                   15148:         }
                   15149:         ADV_ASSERT(scsiq != NULL);
                   15150: 
                   15151:         target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
                   15152: 
                   15153:         /*
                   15154:          * Clear request microcode control flag.
                   15155:          */
                   15156:         scsiq->cntl = 0;
                   15157: 
                   15158:         /*
                   15159:          * Check Condition handling
                   15160:          */
                   15161:         if ((scsiq->done_status == QD_WITH_ERROR) &&
                   15162:             (scsiq->scsi_status == SS_CHK_CONDITION) &&
                   15163:             (sense_data = (ASC_REQ_SENSE *) scsiq->vsense_addr) != 0 &&
                   15164:             (scsiq->orig_sense_len - scsiq->sense_len) >= ASC_MIN_SENSE_LEN)
                   15165:         {
                   15166:             /*
                   15167:              * Command returned with a check condition and valid
                   15168:              * sense data.
                   15169:              */
                   15170:         }
                   15171:         /*
                   15172:          * If the command that completed was a SCSI INQUIRY and
                   15173:          * LUN 0 was sent the command, then process the INQUIRY
                   15174:          * command information for the device.
                   15175:          */
                   15176:         else if (scsiq->done_status == QD_NO_ERROR &&
                   15177:                    scsiq->cdb[0] == SCSICMD_Inquiry &&
                   15178:                    scsiq->target_lun == 0)
                   15179:         {
                   15180:             AdvInquiryHandling(asc_dvc, scsiq);
                   15181:         }
                   15182: 
                   15183:         
                   15184:         /* Change the RISC Queue List state to free. */
                   15185:         AdvWriteByteLram(iop_base, next_done_loc + RQL_STATE, ASC_MC_QS_FREE);
                   15186: 
                   15187:         /* Get the RISC Queue List forward pointer. */
                   15188:         AdvReadByteLram(iop_base, next_done_loc + RQL_FWD, completed_q);
                   15189: 
                   15190:         /*
                   15191:          * Notify the driver of the completed request by passing
                   15192:          * the ADV_SCSI_REQ_Q pointer to its callback function.
                   15193:          */
                   15194:         ADV_ASSERT(asc_dvc->cur_host_qng > 0);
                   15195:         asc_dvc->cur_host_qng--;
                   15196:         scsiq->a_flag |= ADV_SCSIQ_DONE;
                   15197:         (*(ADV_ISR_CALLBACK) asc_dvc->isr_callback)(asc_dvc, scsiq);
                   15198:         /*
                   15199:          * Note: After the driver callback function is called, 'scsiq'
                   15200:          * can no longer be referenced.
                   15201:          *
                   15202:          * Fall through and continue processing other completed
                   15203:          * requests...
                   15204:          */
                   15205: 
                   15206:         /*
                   15207:          * Disable interrupts again in case the driver inadvertently
                   15208:          * enabled interrupts in its callback function.
                   15209:          *
                   15210:          * The DvcEnterCritical() return value is ignored, because
                   15211:          * the 'flags' saved when AdvISR() was first entered will be
                   15212:          * used to restore the interrupt flag on exit.
                   15213:          */
                   15214:         (void) DvcEnterCritical();
                   15215:     }
                   15216:     DvcLeaveCritical(flags);
                   15217:     return ret;
                   15218: }
                   15219: 
                   15220: /*
                   15221:  * Send an idle command to the chip and wait for completion.
                   15222:  *
                   15223:  * Interrupts do not have to be enabled on entry.
                   15224:  *
                   15225:  * Return Values:
                   15226:  *   ADV_TRUE - command completed successfully
                   15227:  *   ADV_FALSE - command failed
                   15228:  */
                   15229: STATIC int
                   15230: AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
                   15231:                ushort idle_cmd,
                   15232:                ulong idle_cmd_parameter,
                   15233:                int flags)
                   15234: {
                   15235:     int         last_int_level;
                   15236:     ulong       i;
                   15237:     AdvPortAddr iop_base;
                   15238:     int         ret;
                   15239: 
                   15240:     asc_dvc->idle_cmd_done = 0;
                   15241: 
                   15242:     last_int_level = DvcEnterCritical();
                   15243:     iop_base = asc_dvc->iop_base;
                   15244: 
                   15245:     /*
                   15246:      * Write the idle command value after the idle command parameter
                   15247:      * has been written to avoid a race condition. If the order is not
                   15248:      * followed, the microcode may process the idle command before the
                   15249:      * parameters have been written to LRAM.
                   15250:      */
                   15251:     AdvWriteDWordLram(iop_base, ASC_MC_IDLE_PARA_STAT, idle_cmd_parameter);
                   15252:     AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
                   15253:     DvcLeaveCritical(last_int_level);
                   15254: 
                   15255:     /*
                   15256:      * If the 'flags' argument contains the ADV_NOWAIT flag, then
                   15257:      * return with success.
                   15258:      */
                   15259:     if (flags & ADV_NOWAIT)
                   15260:     {
                   15261:         return ADV_TRUE;
                   15262:     }
                   15263: 
                   15264:     for (i = 0; i < SCSI_WAIT_10_SEC * SCSI_MS_PER_SEC; i++)
                   15265:     {
                   15266:         /*
                   15267:          * 'idle_cmd_done' is set by AdvISR().
                   15268:          */
                   15269:         if (asc_dvc->idle_cmd_done)
                   15270:         {
                   15271:             break;
                   15272:         }
                   15273:         DvcSleepMilliSecond(1);
                   15274: 
                   15275:         /*
                   15276:          * If interrupts were disabled on entry to AdvSendIdleCmd(),
                   15277:          * then they will still be disabled here. Call AdvISR() to
                   15278:          * check for the idle command completion.
                   15279:          */
                   15280:         (void) AdvISR(asc_dvc);
                   15281:     }
                   15282: 
                   15283:     last_int_level = DvcEnterCritical();
                   15284: 
                   15285:     if (asc_dvc->idle_cmd_done == ADV_FALSE)
                   15286:     {
                   15287:         ADV_ASSERT(0); /* The idle command should never timeout. */
                   15288:         return ADV_FALSE;
                   15289:     } else
                   15290:     {
                   15291:         AdvReadWordLram(iop_base, ASC_MC_IDLE_PARA_STAT, ret);
                   15292:         return ret;
                   15293:     }
                   15294: }
                   15295: 
                   15296: /*
                   15297:  * Send the SCSI request block to the adapter
                   15298:  *
                   15299:  * Each of the 255 Adv Library/Microcode RISC Lists or mailboxes has the
                   15300:  * following structure:
                   15301:  *
                   15302:  * 0: RQL_FWD - RISC list forward pointer (1 byte)
                   15303:  * 1: RQL_BWD - RISC list backward pointer (1 byte)
                   15304:  * 2: RQL_STATE - RISC list state byte - free, ready, done, aborted (1 byte)
                   15305:  * 3: RQL_TID - request target id (1 byte)
                   15306:  * 4: RQL_PHYADDR - ADV_SCSI_REQ_Q physical pointer (4 bytes)
                   15307:  *
                   15308:  * Return:
                   15309:  *      ADV_SUCCESS(1) - the request is in the mailbox
                   15310:  *      ADV_BUSY(0) - total request count > 253, try later
                   15311:  */
                   15312: STATIC int
                   15313: AdvSendScsiCmd(
                   15314:     ADV_DVC_VAR *asc_dvc,
                   15315:     ADV_SCSI_REQ_Q  *scsiq)
                   15316: {
                   15317:     ushort                 next_ready_loc;
                   15318:     uchar                  next_ready_loc_fwd;
                   15319:     int                    last_int_level;
                   15320:     AdvPortAddr            iop_base;
                   15321:     long                   req_size;
                   15322:     ulong                  q_phy_addr;
                   15323: 
                   15324:     /*
                   15325:      * The ADV_SCSI_REQ_Q 'target_id' field should never be equal
                   15326:      * to the host adapter ID or exceed ADV_MAX_TID.
                   15327:      */
                   15328:     if (scsiq->target_id == asc_dvc->chip_scsi_id ||
                   15329:         scsiq->target_id > ADV_MAX_TID)
                   15330:     {
                   15331:         scsiq->host_status = QHSTA_M_INVALID_DEVICE;
                   15332:         scsiq->done_status = QD_WITH_ERROR;
                   15333:         return ADV_ERROR;
                   15334:     }
                   15335: 
                   15336:     iop_base = asc_dvc->iop_base;
                   15337: 
                   15338:     last_int_level = DvcEnterCritical();
                   15339: 
                   15340:     if (asc_dvc->cur_host_qng >= asc_dvc->max_host_qng)
                   15341:     {
                   15342:         DvcLeaveCritical(last_int_level);
                   15343:         return ADV_BUSY;
                   15344:     } else
                   15345:     {
                   15346:         ADV_ASSERT(asc_dvc->cur_host_qng < ASC_MC_RISC_Q_TOTAL_CNT);
                   15347:         asc_dvc->cur_host_qng++;
                   15348:     }
                   15349: 
                   15350:     /*
                   15351:      * Clear the ADV_SCSI_REQ_Q done flag.
                   15352:      */
                   15353:     scsiq->a_flag &= ~ADV_SCSIQ_DONE;
                   15354: 
                   15355:     /*
                   15356:      * Save the original sense buffer length.
                   15357:      *
                   15358:      * After the request completes 'sense_len' will be set to the residual
                   15359:      * byte count of the Auto-Request Sense if a command returns CHECK
                   15360:      * CONDITION and the Sense Data is valid indicated by 'host_status' not
                   15361:      * being set to QHSTA_M_AUTO_REQ_SENSE_FAIL. To determine the valid
                   15362:      * Sense Data Length subtract 'sense_len' from 'orig_sense_len'.
                   15363:      */
                   15364:     scsiq->orig_sense_len = scsiq->sense_len;
                   15365: 
                   15366:     AdvReadByteLram(iop_base, ASC_MC_HOST_NEXT_READY, next_ready_loc);
                   15367:     next_ready_loc = ASC_MC_RISC_Q_LIST_BASE +
                   15368:         (next_ready_loc * ASC_MC_RISC_Q_LIST_SIZE);
                   15369: 
                   15370:     /*
                   15371:      * Write the physical address of the Q to the mailbox.
                   15372:      * We need to skip the first four bytes, because the microcode
                   15373:      * uses them internally for linking Q's together.
                   15374:      */
                   15375:     req_size = sizeof(ADV_SCSI_REQ_Q);
                   15376:     q_phy_addr = DvcGetPhyAddr(asc_dvc, scsiq,
                   15377:                     (uchar *) scsiq, &req_size,
                   15378:                     ADV_IS_SCSIQ_FLAG);
                   15379:     ADV_ASSERT(ADV_DWALIGN(q_phy_addr) == q_phy_addr);
                   15380:     ADV_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
                   15381: 
                   15382:     scsiq->scsiq_ptr = (ADV_SCSI_REQ_Q *) scsiq;
                   15383: 
                   15384:     /*
                   15385:      * The RISC list structure, which 'next_ready_loc' is a pointer
                   15386:      * to in microcode LRAM, has the format detailed in the comment
                   15387:      * header for this function.
                   15388:      *
                   15389:      * Write the ADV_SCSI_REQ_Q physical pointer to 'next_ready_loc' request.
                   15390:      */
                   15391:     AdvWriteDWordLram(iop_base, next_ready_loc + RQL_PHYADDR, q_phy_addr);
                   15392: 
                   15393:     /* Write target_id to 'next_ready_loc' request. */
                   15394:     AdvWriteByteLram(iop_base, next_ready_loc + RQL_TID, scsiq->target_id);
                   15395: 
                   15396:     /*
                   15397:      * Set the ASC_MC_HOST_NEXT_READY (0x128) microcode variable to
                   15398:      * the 'next_ready_loc' request forward pointer.
                   15399:      *
                   15400:      * Do this *before* changing the 'next_ready_loc' queue to QS_READY.
                   15401:      * After the state is changed to QS_READY 'RQL_FWD' will be changed
                   15402:      * by the microcode.
                   15403:      *
                   15404:      * NOTE: The temporary variable 'next_ready_loc_fwd' is required to
                   15405:      * prevent some compilers from optimizing out 'AdvReadByteLram()' if
                   15406:      * it were used as the 3rd argument to 'AdvWriteByteLram()'.
                   15407:      */
                   15408:     AdvReadByteLram(iop_base, next_ready_loc + RQL_FWD, next_ready_loc_fwd);
                   15409:     AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_READY, next_ready_loc_fwd);
                   15410: 
                   15411:     /*
                   15412:      * Change the state of 'next_ready_loc' request from QS_FREE to
                   15413:      * QS_READY which will cause the microcode to pick it up and
                   15414:      * execute it.
                   15415:      *
                   15416:      * Can't reference 'next_ready_loc' after changing the request
                   15417:      * state to QS_READY. The microcode now owns the request.
                   15418:      */
                   15419:     AdvWriteByteLram(iop_base, next_ready_loc + RQL_STATE, ASC_MC_QS_READY);
                   15420: 
                   15421:     DvcLeaveCritical(last_int_level);
                   15422:     return ADV_SUCCESS;
                   15423: }
                   15424: 
                   15425: /*
                   15426:  * Inquiry Information Byte 7 Handling
                   15427:  *
                   15428:  * Handle SCSI Inquiry Command information for a device by setting
                   15429:  * microcode operating variables that affect WDTR, SDTR, and Tag 
                   15430:  * Queuing.
                   15431:  */
                   15432: STATIC void
                   15433: AdvInquiryHandling(
                   15434:     ADV_DVC_VAR          *asc_dvc,
                   15435:     ADV_SCSI_REQ_Q       *scsiq)
                   15436: {
                   15437:     AdvPortAddr          iop_base;
                   15438:     uchar                tid;
                   15439:     ASC_SCSI_INQUIRY     *inq;
                   15440:     ushort               tidmask;
                   15441:     ushort               cfg_word;
                   15442: 
                   15443:     /*
                   15444:      * AdvInquiryHandling() requires up to INQUIRY information Byte 7
                   15445:      * to be available.
                   15446:      *
                   15447:      * If less than 8 bytes of INQUIRY information were requested or less
                   15448:      * than 8 bytes were transferred, then return. cdb[4] is the request
                   15449:      * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the
                   15450:      * microcode to the transfer residual count.
                   15451:      */
                   15452:     if (scsiq->cdb[4] < 8 || (scsiq->cdb[4] - scsiq->data_cnt) < 8)
                   15453:     {
                   15454:         return;
                   15455:     }
                   15456: 
                   15457:     iop_base = asc_dvc->iop_base;
                   15458:     tid = scsiq->target_id;
                   15459:     inq = (ASC_SCSI_INQUIRY *) scsiq->vdata_addr;
                   15460: 
                   15461:     /*
                   15462:      * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
                   15463:      */
                   15464:     if (inq->byte3.rsp_data_fmt < 2 && inq->byte2.ansi_apr_ver < 2)
                   15465:     {
                   15466:         return;
                   15467:     } else
                   15468:     {
                   15469:         /*
                   15470:          * INQUIRY Byte 7 Handling
                   15471:          *
                   15472:          * Use a device's INQUIRY byte 7 to determine whether it
                   15473:          * supports WDTR, SDTR, and Tag Queuing. If the feature
                   15474:          * is enabled in the EEPROM and the device supports the
                   15475:          * feature, then enable it in the microcode.
                   15476:          */
                   15477: 
                   15478:         tidmask = ADV_TID_TO_TIDMASK(tid);
                   15479: 
                   15480:         /*
                   15481:          * Wide Transfers
                   15482:          *
                   15483:          * If the EEPROM enabled WDTR for the device and the device
                   15484:          * supports wide bus (16 bit) transfers, then turn on the
                   15485:          * device's 'wdtr_able' bit and write the new value to the
                   15486:          * microcode.
                   15487:          */
                   15488:         if ((asc_dvc->wdtr_able & tidmask) && inq->byte7.WBus16)
                   15489:         {
                   15490:             AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
                   15491:             if ((cfg_word & tidmask) == 0)
                   15492:             {
                   15493:                 cfg_word |= tidmask;
                   15494:                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
                   15495: 
                   15496:                 /*
                   15497:                  * Clear the microcode "WDTR negotiation" done indicator
                   15498:                  * for the target to cause it to negotiate with the new
                   15499:                  * setting set above.
                   15500:                  */
                   15501:                 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
                   15502:                 cfg_word &= ~tidmask;
                   15503:                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
                   15504:             }
                   15505:         }
                   15506: 
                   15507:         /*
                   15508:          * Synchronous Transfers
                   15509:          *
                   15510:          * If the EEPROM enabled SDTR for the device and the device
                   15511:          * supports synchronous transfers, then turn on the device's
                   15512:          * 'sdtr_able' bit. Write the new value to the microcode.
                   15513:          */
                   15514:         if ((asc_dvc->sdtr_able & tidmask) && inq->byte7.Sync)
                   15515:         {
                   15516:             AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
                   15517:             if ((cfg_word & tidmask) == 0)
                   15518:             {
                   15519:                 cfg_word |= tidmask;
                   15520:                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
                   15521: 
                   15522:                 /*
                   15523:                  * Clear the microcode "SDTR negotiation" done indicator
                   15524:                  * for the target to cause it to negotiate with the new
                   15525:                  * setting set above.
                   15526:                  */
                   15527:                 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
                   15528:                 cfg_word &= ~tidmask;
                   15529:                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
                   15530:             }
                   15531:         }
                   15532: 
                   15533:         /*
                   15534:          * If the EEPROM enabled Tag Queuing for device and the
                   15535:          * device supports Tag Queuing, then turn on the device's
                   15536:          * 'tagqng_enable' bit in the microcode and set the microcode
                   15537:          * maximum command count to the ADV_DVC_VAR 'max_dvc_qng'
                   15538:          * value.
                   15539:          *
                   15540:          * Tag Queuing is disabled for the BIOS which runs in polled
                   15541:          * mode and would see no benefit from Tag Queuing. Also by
                   15542:          * disabling Tag Queuing in the BIOS devices with Tag Queuing
                   15543:          * bugs will at least work with the BIOS.
                   15544:          */
                   15545:         if ((asc_dvc->tagqng_able & tidmask) && inq->byte7.CmdQue)
                   15546:         {
                   15547:             AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
                   15548:             cfg_word |= tidmask;
                   15549:             AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
                   15550:             AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
                   15551:                 asc_dvc->max_dvc_qng);
                   15552:         }
                   15553:     }
                   15554: }

unix.superglobalmegacorp.com

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