root/drivers/scsi/advansys.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. advansys_proc_info
  2. advansys_detect
  3. advansys_release
  4. advansys_info
  5. advansys_command
  6. advansys_queuecommand
  7. advansys_abort
  8. advansys_reset
  9. advansys_biosparam
  10. advansys_setup
  11. asc_proc_copy
  12. advansys_interrupt
  13. advansys_command_done
  14. asc_execute_scsi_cmnd
  15. asc_isr_callback
  16. asc_execute_pending
  17. asc_init_dev
  18. asc_srch_pci_dev
  19. asc_scan_method
  20. asc_pci_find_dev
  21. asc_get_pci_cfg
  22. asc_get_cfg_word
  23. asc_get_cfg_byte
  24. asc_enqueue
  25. asc_dequeue
  26. asc_rmqueue
  27. DvcSleepMilliSecond
  28. DvcDisplayString
  29. DvcEnterCritical
  30. DvcLeaveCritical
  31. DvcGetPhyAddr
  32. DvcGetSGList
  33. DvcPutScsiQ
  34. DvcGetQinfo
  35. DvcOutPortWords
  36. DvcInPortWords
  37. DvcOutPortDWords
  38. asc_prt_stats
  39. asc_prt_stats_line
  40. asc_prt_scsi_host
  41. asc_prt_dvc_var
  42. asc_prt_dvc_cfg
  43. asc_prt_scsi_q
  44. asc_prt_qdone_info
  45. asc_prt_hex
  46. interrupts_enabled
  47. AscGetEisaChipCfg
  48. AscSetChipScsiID
  49. AscGetChipBiosAddress
  50. AscGetChipVersion
  51. AscGetChipBusType
  52. AscEnableIsaDma
  53. AscLoadMicroCode
  54. AscSearchIOPortAddr
  55. AscSearchIOPortAddr11
  56. AscFindSignature
  57. AscToggleIRQAct
  58. AscSetISAPNPWaitForKey
  59. AscGetChipIRQ
  60. AscSetChipIRQ
  61. AscGetChipScsiCtrl
  62. AscIsrChipHalted
  63. _AscCopyLramScsiDoneQ
  64. AscIsrQDone
  65. AscISR
  66. AscScsiSetupCmdQ
  67. AscExeScsiQueue
  68. AscSendScsiQueue
  69. AscSgListToQueue
  70. AscGetNumOfFreeQueue
  71. AscPutReadyQueue
  72. AscPutReadySgListQueue
  73. AscAbortSRB
  74. AscResetDevice
  75. AscResetSB
  76. AscSetRunChipSynRegAtID
  77. AscSetChipSynRegAtID
  78. AscReInitLram
  79. AscInitLram
  80. AscInitQLinkVar
  81. AscSetLibErrorCode
  82. _AscWaitQDone
  83. AscMsgOutSDTR
  84. AscCalSDTRData
  85. AscSetChipSDTR
  86. AscGetSynPeriodIndex
  87. AscAllocFreeQueue
  88. AscAllocMultipleFreeQueue
  89. AscRiscHaltedAbortSRB
  90. AscRiscHaltedAbortTIX
  91. AscHostReqRiscHalt
  92. AscStopQueueExe
  93. AscStartQueueExe
  94. AscCleanUpBusyQueue
  95. AscCleanUpDiscQueue
  96. AscWaitTixISRDone
  97. AscWaitISRDone
  98. AscGetOnePhyAddr
  99. AscGetEisaProductID
  100. AscSearchIOPortAddrEISA
  101. AscStartChip
  102. AscStopChip
  103. AscIsChipHalted
  104. AscSetChipIH
  105. AscAckInterrupt
  106. AscDisableInterrupt
  107. AscEnableInterrupt
  108. AscSetBank
  109. AscResetChipAndScsiBus
  110. AscGetIsaDmaChannel
  111. AscSetIsaDmaChannel
  112. AscSetIsaDmaSpeed
  113. AscGetIsaDmaSpeed
  114. AscGetMaxDmaCount
  115. AscInitGetConfig
  116. AscInitSetConfig
  117. AscInitAsc1000Driver
  118. AscInitAscDvcVar
  119. AscInitFromAscDvcVar
  120. AscInitFromEEP
  121. AscInitMicroCodeVar
  122. AscInitPollIsrCallBack
  123. AscTestExternalLram
  124. AscWriteEEPCmdReg
  125. AscWriteEEPDataReg
  126. AscWaitEEPRead
  127. AscWaitEEPWrite
  128. AscReadEEPWord
  129. AscWriteEEPWord
  130. AscGetEEPConfig
  131. AscSetEEPConfigOnce
  132. AscSetEEPConfig
  133. AscInitPollBegin
  134. AscInitPollEnd
  135. AscInitPollTarget
  136. PollQueueDone
  137. PollScsiInquiry
  138. PollScsiReadCapacity
  139. swapfarbuf4
  140. PollScsiTestUnitReady
  141. PollScsiStartUnit
  142. InitTestUnitReady
  143. AscPollQDone
  144. AscReadLramByte
  145. AscReadLramWord
  146. AscReadLramDWord
  147. AscWriteLramWord
  148. AscWriteLramDWord
  149. AscWriteLramByte
  150. AscVerWriteLramWord
  151. AscMemWordCopyToLram
  152. AscMemDWordCopyToLram
  153. AscMemWordCopyFromLram
  154. AscMemSumLramWord
  155. AscMemWordSetLram
  156. AscScsiInquiry
  157. AscScsiReadCapacity
  158. AscScsiTestUnitReady
  159. AscScsiStartStopUnit

   1 /* $Id: advansys.c,v 1.11 1996/01/16 22:39:19 bobf Exp bobf $ */
   2 /*
   3  * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
   4  * 
   5  * Copyright (c) 1995-1996 Advanced System Products, Inc.
   6  * All Rights Reserved.
   7  *
   8  * This driver may be modified and freely distributed provided that
   9  * the above copyright message and this comment are included in the
  10  * distribution. The latest version of this driver is available at
  11  * the AdvanSys FTP and BBS sites listed below.
  12  *
  13  * Please send questions, comments, bug reports to:
  14  * bobf@advansys.com (Bob Frey)
  15  */
  16 
  17 /* The driver has been tested with Linux 1.2.1 and 1.3.57 kernels. */
  18 #define ASC_VERSION "1.2"       /* AdvanSys Driver Version */
  19 
  20 /*
  21 
  22   Documentation for the AdvanSys Driver
  23 
  24   A. Adapters Supported by this Driver
  25   B. Linux 1.2.X - Directions for Adding the AdvanSys Driver
  26   C. Linux 1.3.X - Directions for Adding the AdvanSys Driver
  27   D. Source Comments
  28   E. Driver Compile Time Options and Debugging
  29   F. Driver LILO Option
  30   G. Release History
  31   H. Known Problems or Issues
  32   I. Credits
  33   J. AdvanSys Contact Information
  34 
  35 
  36   A. Adapters Supported by this Driver
  37  
  38      AdvanSys (Advanced System Products, Inc.) manufactures the following
  39      Bus-Mastering SCSI-2 Host Adapters for the ISA, EISA, VL, and PCI
  40      buses. This Linux driver supports all of these adapters.
  41      
  42      The CDB counts below indicate the number of SCSI CDB (Command
  43      Descriptor Block) requests that can be stored in the RISC chip
  44      cache and board LRAM. The driver detect routine will display the
  45      number of CDBs available for each adapter detected. This value
  46      can be lowered in the BIOS by changing the 'Host Queue Size'
  47      adapter setting.
  48 
  49      Connectivity Products:
  50        ABP920 - Bus-Master PCI 16 CDB
  51        ABP930 - Bus-Master PCI 16 CDB
  52        ABP5140 - Bus-Master PnP ISA 16 CDB
  53    
  54      Single Channel Products:
  55        ABP542 - Bus-Master ISA 240 CDB
  56        ABP5150 - Bus-Master ISA 240 CDB *
  57        ABP742 - Bus-Master EISA 240 CDB
  58        ABP842 - Bus-Master VL 240 CDB
  59        ABP940 - Bus-Master PCI 240 CDB
  60    
  61      Dual Channel Products:
  62        ABP950 - Dual Channel Bus-Master PCI 240 CDB Per Channel
  63        ABP852 - Dual Channel Bus-Master VL 240 CDB Per Channel
  64        ABP752 - Dual Channel Bus-Master EISA 240 CDB Per Channel
  65 
  66      * This board is shipped by HP with the 4020i CD-R drive. It has
  67        no BIOS so it cannot control a boot device, but it can control
  68        any secondary devices.
  69  
  70   B. Linux 1.2.X - Directions for Adding the AdvanSys Driver
  71  
  72      There are two source files: advansys.h and advansys.c. Copy
  73      both of these files to the directory /usr/src/linux/drivers/scsi.
  74     
  75      1. Add the following line to /usr/src/linux/arch/i386/config.in
  76         after "comment 'SCSI low-level drivers'":
  77     
  78           bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y
  79     
  80      2. Add the following lines to /usr/src/linux/drivers/scsi/hosts.c
  81         after "#include "hosts.h"":
  82     
  83           #ifdef CONFIG_SCSI_ADVANSYS
  84           #include "advansys.h"
  85           #endif
  86     
  87         and after "static Scsi_Host_Template builtin_scsi_hosts[] =":
  88     
  89           #ifdef CONFIG_SCSI_ADVANSYS
  90           ADVANSYS,
  91           #endif
  92     
  93      3. Add the following lines to /usr/src/linux/drivers/scsi/Makefile:
  94     
  95           ifdef CONFIG_SCSI_ADVANSYS
  96           SCSI_SRCS := $(SCSI_SRCS) advansys.c
  97           SCSI_OBJS := $(SCSI_OBJS) advansys.o
  98           else
  99           SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o
 100           endif
 101 
 102      4. (Optional) If you would like to enable the LILO command line
 103         and /etc/lilo.conf 'advansys' option, make the following changes.
 104         This option can be used to disable I/O port scanning or to limit
 105         I/O port scanning to specific addresses. Refer to the 'Driver
 106         LILO Option' section below. Add the following lines to
 107         /usr/src/linux/init/main.c in the prototype section:
 108 
 109           extern void advansys_setup(char *str, int *ints);
 110 
 111         and add the following lines to the bootsetups[] array.
 112 
 113           #ifdef CONFIG_SCSI_ADVANSYS
 114              { "advansys=", advansys_setup },
 115           #endif
 116 
 117      5. If you have the HP 4020i CD-R driver and Linux 1.2.X you should
 118         add a fix to the CD-ROM target driver. This fix will allow
 119         you to mount CDs with the iso9660 file system. Linux 1.3.X
 120         already has this fix. In the file /usr/src/linux/drivers/scsi/sr.c
 121         and function get_sectorsize() after the line:
 122 
 123         if(scsi_CDs[i].sector_size == 0) scsi_CDs[i].sector_size = 2048;
 124 
 125         add the following line:
 126 
 127         if(scsi_CDs[i].sector_size == 2340) scsi_CDs[i].sector_size = 2048;
 128 
 129      6. In the directory /usr/src/linux run 'make config' to configure
 130         the AdvanSys driver, then run 'make vmlinux' or 'make zlilo' to
 131         make the kernel. If the AdvanSys driver is not configured, then
 132         a loadable module can be built by running 'make modules' and
 133         'make modules_install'. Use 'insmod' and 'rmmod' to install
 134         and remove advansys.o.
 135  
 136   C. Linux 1.3.X - Directions for Adding the AdvanSys Driver
 137 
 138      There are two source files: advansys.h and advansys.c. Copy
 139      both of these files to the directory /usr/src/linux/drivers/scsi.
 140    
 141      1. Add the following line to /usr/src/linux/drivers/scsi/Config.in
 142         after "comment 'SCSI low-level drivers'":
 143    
 144           dep_tristate 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS $CONFIG_SCSI
 145    
 146      2. Add the following lines to /usr/src/linux/drivers/scsi/hosts.c
 147         after "#include "hosts.h"":
 148    
 149           #ifdef CONFIG_SCSI_ADVANSYS
 150           #include "advansys.h"
 151           #endif
 152    
 153         and after "static Scsi_Host_Template builtin_scsi_hosts[] =":
 154    
 155           #ifdef CONFIG_SCSI_ADVANSYS
 156           ADVANSYS,
 157           #endif
 158    
 159      3. Add the following lines to /usr/src/linux/drivers/scsi/Makefile:
 160    
 161           ifeq ($(CONFIG_SCSI_ADVANSYS),y)
 162           L_OBJS += advansys.o
 163           else
 164             ifeq ($(CONFIG_SCSI_ADVANSYS),m)
 165             M_OBJS += advansys.o
 166             endif
 167           endif
 168    
 169      4. Add the following line to /usr/src/linux/include/linux/proc_fs.h
 170         in the enum scsi_directory_inos array:
 171    
 172           PROC_SCSI_ADVANSYS,
 173    
 174      5. (Optional) If you would like to enable the LILO command line
 175         and /etc/lilo.conf 'advansys' option, make the following changes.
 176         This option can be used to disable I/O port scanning or to limit
 177         I/O port scanning to specific addresses. Refer to the 'Driver
 178         LILO Option' section below. Add the following lines to
 179         /usr/src/linux/init/main.c in the prototype section:
 180    
 181           extern void advansys_setup(char *str, int *ints);
 182    
 183         and add the following lines to the bootsetups[] array.
 184    
 185           #ifdef CONFIG_SCSI_ADVANSYS
 186              { "advansys=", advansys_setup },
 187           #endif
 188    
 189      6. In the directory /usr/src/linux run 'make config' to configure
 190         the AdvanSys driver, then run 'make vmlinux' or 'make zlilo' to
 191         make the kernel. If the AdvanSys driver is not configured, then
 192         a loadable module can be built by running 'make modules' and
 193         'make modules_install'. Use 'insmod' and 'rmmod' to install
 194         and remove advansys.o.
 195 
 196   D. Source Comments
 197  
 198      1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'.
 199  
 200      2. This driver should be maintained in multiple files. But to make
 201         it easier to include with Linux and to follow Linux conventions,
 202         the whole driver is maintained in the source files advansys.h and
 203         advansys.c. In this file logical sections of the driver begin with
 204         a comment that contains '---'. The following are the logical sections
 205         of the driver below.
 206  
 207            --- Linux Version
 208            --- Linux Include Files 
 209            --- Driver Options
 210            --- Asc Library Constants and Macros
 211            --- Debugging Header
 212            --- Driver Constants
 213            --- Driver Macros
 214            --- Driver Structures
 215            --- Driver Data
 216            --- Driver Function Prototypes
 217            --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
 218            --- Loadable Driver Support
 219            --- Miscellaneous Driver Functions
 220            --- Functions Required by the Asc Library
 221            --- Tracing and Debugging Functions
 222            --- Asc Library Functions
 223  
 224      3. The string 'XXX' is used to flag code that needs to be re-written
 225         or that contains a problem that needs to be addressed.
 226  
 227      4. I have stripped comments from and reformatted the source for the
 228         Asc Library which is included in this file. I haven't done this
 229         to obfuscate the code. Actually I have done this to deobfuscate
 230         the code. The Asc Library source can be found under the following
 231         headings.
 232  
 233            --- Asc Library Constants and Macros
 234            --- Asc Library Functions
 235  
 236   E. Driver Compile Time Options and Debugging
 237  
 238      In this source file the following constants can be defined. They are
 239      defined in the source below. Both of these options are enabled by
 240      default.
 241  
 242      1. ADVANSYS_DEBUG - enable for debugging and assertions
 243  
 244         The amount of debugging output can be controlled with the global
 245         variable 'asc_dbglvl'. The higher the number the more output. By
 246         default the debug level is 0.
 247         
 248         If the driver is loaded at boot time and the LILO Driver Option
 249         is included in the system, the debug level can be changed by
 250         specifying a 5th (ASC_NUM_BOARD_SUPPORTED + 1) I/O Port. The
 251         first three hex digits of the pseudo I/O Port must be set to
 252         'deb' and the fourth hex digit specifies the debug level: 0 - F.
 253         The following command line will look for an adapter at 0x330
 254         and set the debug level to 2.
 255 
 256            linux advansys=0x330,0x0,0x0,0x0,0xdeb2
 257 
 258         If the driver is built as a loadable module this variable can be
 259         defined when the driver is loaded. The following insmod command
 260         will set the debug level to one.
 261   
 262            insmod advansys.o asc_dbglvl=1
 263  
 264  
 265         Debugging Message Levels:
 266            0: Errors Only
 267            1: High-Level Tracing
 268            2-N: Verbose Tracing
 269  
 270         I don't know the approved way for turning on printk()s to the
 271         console. Here's a program I use to do this. Debug output is
 272         logged in /var/adm/messages.
 273  
 274           main()
 275           {
 276                   syscall(103, 7, 0, 0);
 277           }
 278  
 279         I found that increasing LOG_BUF_LEN to 40960 in kernel/printk.c
 280         prevents most level 1 debug messages from being lost.
 281  
 282      2. ADVANSYS_STATS - enable statistics and tracing
 283  
 284         For Linux 1.2.X if ADVANSYS_STATS_1_2_PRINT is defined every
 285         10,000 I/O operations the driver will print statistics to the
 286         console. This value can be changed by modifying the constant
 287         used in advansys_queuecommand(). ADVANSYS_STATS_1_2_PRINT is
 288         off by default.
 289 
 290         For Linux 1.3.X statistics can be accessed by reading the
 291         /proc/scsi/advansys/[0-9] files.
 292 
 293         Note: these statistics are currently maintained on a global driver
 294         basis and not per board.
 295 
 296   F. Driver LILO Option
 297  
 298      If init/main.c is modified as described in the 'Directions for Adding
 299      the AdvanSys Driver to Linux' section (B.4.) above, the driver will
 300      recognize the 'advansys' LILO command line and /etc/lilo.conf option.
 301      This option can be used to either disable I/O port scanning or to limit
 302      scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and
 303      PCI boards will still be searched for and detected. This option only
 304      affects searching for ISA and VL boards.
 305 
 306      Examples:
 307        1. Eliminate I/O port scanning:
 308             boot: linux advansys=
 309               or
 310             boot: linux advansys=0x0
 311        2. Limit I/O port scanning to one I/O port:
 312             boot: linux advansys=0x110
 313        3. Limit I/O port scanning to four I/O ports:
 314             boot: linux advansys=0x110,0x210,0x230,0x330
 315 
 316      For a loadable module the same effect can be achieved by setting
 317      the 'asc_iopflag' variable and 'asc_ioport' array when loading
 318      the driver, e.g.
 319 
 320            insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330
 321 
 322      If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_BOARD_SUPPORTED + 1)
 323      I/O Port may be added to specify the driver debug level. Refer to
 324      the 'Driver Compile Time Options and Debugging' section above for
 325      more information.
 326 
 327   G. Release History
 328 
 329      12/23/95 BETA-1.0:
 330          First Release
 331 
 332      12/28/95 BETA-1.1:
 333          1. Prevent advansys_detect() from being called twice.
 334          2. Add LILO 0xdeb[0-f] option to set 'asc_dbglvl'.
 335 
 336      1/12/96 1.2:
 337          1. Prevent re-entrancy in the interrupt handler which
 338             resulted in the driver hanging Linux.
 339          2. Fix problem that prevented ABP-940 cards from being
 340             recognized on some PCI motherboards.
 341          3. Add support for the ABP-5140 PnP ISA card.
 342          4. Fix check condition return status.
 343          5. Add conditionally compiled code for Linux 1.3.X.
 344         
 345   H. Known Problems or Issues
 346 
 347      1. The setting for 'cmd_per_lun' needs to be changed. It is currently
 348         less then what the AdvanSys boards can queue. Because the target and
 349         mid-level Linux drivers base memory allocation on 'cmd_per_lun' (as
 350         well as 'sg_tablesize') memory use gets out of hand with a large
 351         'cmd_per_lun'. 'cmd_per_lun' should be per device instead of per
 352         adapter. When the driver is compiled as a loadable module both
 353         'cmd_per_lun' and 'sg_tablesize' are tuned down to try to prevent
 354         memory allocation errors.
 355 
 356      2. For the first scsi command sent to a device the driver increases
 357         the timeout value. This gives the driver more time to perform
 358         its own initialization for the board and each device. The timeout
 359         value is only changed on the first scsi command for each device
 360         and never thereafter.
 361 
 362   I. Credits
 363 
 364      Nathan Hartwell (mage@cdc3.cdc.net) provided the directions and
 365      and basis for the Linux 1.3.X changes which were included in the
 366      1.2 release.
 367 
 368   J. AdvanSys Contact Information
 369  
 370      Mail:                   Advanced System Products, Inc.
 371                              1150 Ringwood Court
 372                              San Jose, CA 95131 USA
 373      Operator:               1-408-383-9400
 374      FAX:                    1-408-383-9612
 375      Tech Support:           1-800-525-7440
 376      BBS:                    1-408-383-9540 (9600,N,8,1)
 377      Interactive FAX:        1-408-383-9753
 378      Customer Direct Sales:  1-800-883-1099
 379      Tech Support E-Mail:    support@advansys.com
 380      Linux Support E-Mail:   bobf@advansys.com
 381      FTP Site:               ftp.advansys.com (login: anonymous)
 382      Web Site:               http://www.advansys.com
 383 
 384 */
 385 
 386 
 387 /*
 388  * --- Linux Version
 389  */
 390 
 391 /*
 392  * The driver can be used in Linux 1.2.X or 1.3.X.
 393  */
 394 #if !defined(LINUX_1_2) && !defined(LINUX_1_3)
 395 #ifndef LINUX_VERSION_CODE
 396 #include <linux/version.h>
 397 #endif /* LINUX_VERSION_CODE */
 398 #if LINUX_VERSION_CODE > 65536 + 3 * 256
 399 #define LINUX_1_3
 400 #else /* LINUX_VERSION_CODE */
 401 #define LINUX_1_2
 402 #endif /* LINUX_VERSION_CODE */
 403 #endif /* !defined(LINUX_1_2) && !defined(LINUX_1_3) */
 404 
 405 
 406 /*
 407  * --- Linux Include Files 
 408  */
 409 
 410 #ifdef MODULE
 411 #ifdef LINUX_1_3
 412 #include <linux/autoconf.h>
 413 #endif /* LINUX_1_3 */ 
 414 #include <linux/module.h>
 415 #endif /* MODULE */
 416 #include <linux/string.h>
 417 #include <linux/sched.h>
 418 #include <linux/kernel.h>
 419 #include <linux/head.h>
 420 #include <linux/types.h>
 421 #include <linux/ioport.h>
 422 #include <linux/delay.h>
 423 #include <linux/malloc.h>
 424 #include <linux/config.h>
 425 #ifdef LINUX_1_3
 426 #include <linux/proc_fs.h>
 427 #endif /* LINUX_1_3 */ 
 428 #include <asm/io.h>
 429 #include <asm/system.h>
 430 #include <asm/dma.h>
 431 #ifdef LINUX_1_2
 432 #include "../block/blk.h"
 433 #else /* LINUX_1_3 */ 
 434 #include <linux/blk.h>
 435 #include <linux/stat.h>
 436 #endif /* LINUX_1_3 */ 
 437 #include "scsi.h"
 438 #include "hosts.h"
 439 #include "sd.h"
 440 #include "advansys.h"
 441 
 442 
 443 /*
 444  * --- Driver Options
 445  */
 446 #define ADVANSYS_DEBUG /* Enable for debugging and assertions. */
 447 #define ADVANSYS_STATS /* Enable for statistics and tracing. */
 448 #ifdef LINUX_1_2
 449 #undef ADVANSYS_STATS_1_2_PRINT /* Enable to print statistics to console. */
 450 #endif /* LINUX_1_2 */
 451 
 452 
 453 /*
 454  * --- Asc Library Constants and Macros
 455  */
 456 
 457 #define ASC_LIB_VERSION_MAJOR  1
 458 #define ASC_LIB_VERSION_MINOR  16
 459 #define ASC_LIB_SERIAL_NUMBER  53
 460 
 461 typedef unsigned char uchar;
 462 typedef unsigned char BYTE;
 463 typedef unsigned short WORD;
 464 typedef unsigned long DWORD;
 465 
 466 typedef int         BOOL;
 467 
 468 #ifndef NULL
 469 #define NULL     (0)
 470 #endif
 471 
 472 #ifndef TRUE
 473 #define TRUE     (1)
 474 #endif
 475 
 476 #ifndef FALSE
 477 #define FALSE    (0)
 478 #endif
 479 
 480 #define  REG     register
 481 
 482 #define rchar    REG char
 483 #define rshort   REG short
 484 #define rint     REG int
 485 #define rlong    REG long
 486 
 487 #define ruchar   REG uchar
 488 #define rushort  REG ushort
 489 #define ruint    REG uint
 490 #define rulong   REG ulong
 491 
 492 #define NULLPTR   ( void *)0
 493 #define FNULLPTR  ( void dosfar *)0UL
 494 #define EOF      (-1)
 495 #define EOS      '\0'
 496 #define ERR      (-1)
 497 #define UB_ERR   (uchar)(0xFF)
 498 #define UW_ERR   (uint)(0xFFFF)
 499 #define UL_ERR   (ulong)(0xFFFFFFFFUL)
 500 
 501 #define iseven_word( val )  ( ( ( ( uint )val) & ( uint )0x0001 ) == 0 )
 502 #define isodd_word( val )   ( ( ( ( uint )val) & ( uint )0x0001 ) != 0 )
 503 #define toeven_word( val )  ( ( ( uint )val ) & ( uint )0xFFFE )
 504 
 505 #define biton( val, bits )   ((( uint )( val >> bits ) & (uint)0x0001 ) != 0 )
 506 #define bitoff( val, bits )  ((( uint )( val >> bits ) & (uint)0x0001 ) == 0 )
 507 #define lbiton( val, bits )  ((( ulong )( val >> bits ) & (ulong)0x00000001UL ) != 0 )
 508 #define lbitoff( val, bits ) ((( ulong )( val >> bits ) & (ulong)0x00000001UL ) == 0 )
 509 
 510 #define  absh( val )    ( ( val ) < 0 ? -( val ) : ( val ) )
 511 
 512 #define  swapbyte( ch )  ( ( ( (ch) << 4 ) | ( (ch) >> 4 ) ) )
 513 
 514 #ifndef GBYTE
 515 #define GBYTE       (0x40000000UL)
 516 #endif
 517 
 518 #ifndef MBYTE
 519 #define MBYTE       (0x100000UL)
 520 #endif
 521 
 522 #ifndef KBYTE
 523 #define KBYTE       (0x400)
 524 #endif
 525 
 526 #define HI_BYTE(x) ( *( ( BYTE *)(&x)+1 ) )
 527 #define LO_BYTE(x) ( *( ( BYTE *)&x ) )
 528 
 529 #define HI_WORD(x) ( *( ( WORD *)(&x)+1 ) )
 530 #define LO_WORD(x) ( *( ( WORD *)&x ) )
 531 
 532 #ifndef MAKEWORD
 533 #define MAKEWORD(lo, hi)    ((WORD) (((WORD) lo) | ((WORD) hi << 8)))
 534 #endif
 535 
 536 #ifndef MAKELONG
 537 #define MAKELONG(lo, hi)    ((DWORD) (((DWORD) lo) | ((DWORD) hi << 16)))
 538 #endif
 539 
 540 #define SwapWords(dWord)        ((DWORD) ((dWord >> 16) | (dWord << 16)))
 541 #define SwapBytes(word)         ((WORD) ((word >> 8) | (word << 8)))
 542 
 543 #define BigToLittle(dWord) \
 544     ((DWORD) (SwapWords(MAKELONG(SwapBytes(LO_WORD(dWord)), SwapBytes(HI_WORD(dWord))))))
 545 #define LittleToBig(dWord)      BigToLittle(dWord)
 546 
 547 #define Lptr
 548 #define dosfar
 549 #define far
 550 #define PortAddr                        unsigned short
 551 #define Ptr2Func                ulong
 552 
 553 #define inp(port)               inb(port)
 554 #define inpw(port)              inw(port)
 555 #define outp(port, byte)    outb((byte), (port))
 556 #define outpw(port, word)   outw((word), (port))
 557 
 558 #define ASC_MAX_SG_QUEUE        5
 559 #define ASC_MAX_SG_LIST         (1 + ((ASC_SG_LIST_PER_Q) * (ASC_MAX_SG_QUEUE)))
 560 
 561 #define CC_INIT_INQ_DISPLAY     FALSE
 562 
 563 #define CC_CLEAR_LRAM_SRB_PTR   FALSE
 564 #define CC_VERIFY_LRAM_COPY     FALSE
 565 
 566 #define CC_DEBUG_SG_LIST        FALSE
 567 #define CC_FAST_STRING_IO       FALSE
 568 
 569 #define CC_WRITE_IO_COUNT       FALSE
 570 #define CC_CLEAR_DMA_REMAIN     FALSE
 571 
 572 #define CC_DISABLE_PCI_PARITY_INT TRUE
 573 
 574 #define CC_LINK_BUSY_Q         FALSE
 575 
 576 #define CC_TARGET_MODE         FALSE
 577 
 578 #define CC_SCAM                FALSE
 579 
 580 #define CC_LITTLE_ENDIAN_HOST  TRUE
 581 
 582 #ifndef CC_TEST_LRAM_ENDIAN
 583 
 584 #if CC_LITTLE_ENDIAN_HOST
 585 #define CC_TEST_LRAM_ENDIAN     FALSE
 586 #else
 587 #define CC_TEST_LRAM_ENDIAN     TRUE
 588 #endif
 589 
 590 #endif
 591 
 592 #define CC_STRUCT_ALIGNED      TRUE
 593 
 594 #define CC_MEMORY_MAPPED_IO    FALSE
 595 
 596 #ifndef CC_TARGET_MODE
 597 #define CC_TARGET_MODE         FALSE
 598 #endif
 599 
 600 #ifndef CC_STRUCT_ALIGNED
 601 #define CC_STRUCT_ALIGNED      FALSE
 602 #endif
 603 
 604 #ifndef CC_LITTLE_ENDIAN_HOST
 605 #define CC_LITTLE_ENDIAN_HOST  TRUE
 606 #endif
 607 
 608 #if !CC_LITTLE_ENDIAN_HOST
 609 
 610 #ifndef CC_TEST_LRAM_ENDIAN
 611 #define CC_TEST_LRAM_ENDIAN    TRUE
 612 #endif
 613 
 614 #endif
 615 
 616 #ifndef CC_MEMORY_MAPPED_IO
 617 #define CC_MEMORY_MAPPED_IO    FALSE
 618 #endif
 619 
 620 #ifndef CC_WRITE_IO_COUNT
 621 #define CC_WRITE_IO_COUNT      FALSE
 622 #endif
 623 
 624 #ifndef CC_CLEAR_DMA_REMAIN
 625 #define CC_CLEAR_DMA_REMAIN    FALSE
 626 #endif
 627 
 628 #define ASC_CS_TYPE  unsigned short
 629 
 630 #ifndef asc_ptr_type
 631 #define asc_ptr_type
 632 #endif
 633 
 634 #ifndef CC_SCAM
 635 #define CC_SCAM  FALSE
 636 #endif
 637 
 638 #ifndef ASC_GET_PTR2FUNC
 639 #define ASC_GET_PTR2FUNC( fun )  ( Ptr2Func )( fun )
 640 #endif
 641 
 642 #define FLIP_BYTE_NIBBLE( x )    ( ((x<<4)& 0xFF) | (x>>4) )
 643 
 644 #define ASC_IS_ISA          (0x0001)
 645 #define ASC_IS_ISAPNP       (0x0081)
 646 #define ASC_IS_EISA         (0x0002)
 647 #define ASC_IS_PCI          (0x0004)
 648 #define ASC_IS_PCMCIA       (0x0008)
 649 #define ASC_IS_PNP          (0x0010)
 650 #define ASC_IS_MCA          (0x0020)
 651 #define ASC_IS_VL           (0x0040)
 652 
 653 #define ASC_ISA_PNP_PORT_ADDR  (0x279)
 654 #define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
 655 
 656 #define ASC_IS_WIDESCSI_16  (0x0100)
 657 #define ASC_IS_WIDESCSI_32  (0x0200)
 658 
 659 #define ASC_IS_BIG_ENDIAN   (0x8000)
 660 
 661 #define ASC_CHIP_MIN_VER_VL      (0x01)
 662 #define ASC_CHIP_MAX_VER_VL      (0x07)
 663 
 664 #define ASC_CHIP_MIN_VER_PCI     (0x09)
 665 #define ASC_CHIP_MAX_VER_PCI     (0x0F)
 666 #define ASC_CHIP_VER_PCI_BIT     (0x08)
 667 
 668 #define ASC_CHIP_MIN_VER_ISA     (0x11)
 669 #define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
 670 #define ASC_CHIP_MAX_VER_ISA     (0x27)
 671 #define ASC_CHIP_VER_ISA_BIT     (0x30)
 672 #define ASC_CHIP_VER_ISAPNP_BIT  (0x20)
 673 
 674 #define ASC_CHIP_VER_ASYN_BUG    (0x21)
 675 
 676 #define ASC_CHIP_MIN_VER_EISA (0x41)
 677 #define ASC_CHIP_MAX_VER_EISA (0x47)
 678 #define ASC_CHIP_VER_EISA_BIT (0x40)
 679 
 680 #define ASC_MAX_VL_DMA_ADDR     (0x07FFFFFFL)
 681 #define ASC_MAX_VL_DMA_COUNT    (0x07FFFFFFL)
 682 
 683 #define ASC_MAX_PCI_DMA_ADDR    (0xFFFFFFFFL)
 684 #define ASC_MAX_PCI_DMA_COUNT   (0xFFFFFFFFL)
 685 
 686 #define ASC_MAX_ISA_DMA_ADDR    (0x00FFFFFFL)
 687 #define ASC_MAX_ISA_DMA_COUNT   (0x00FFFFFFL)
 688 
 689 #define ASC_MAX_EISA_DMA_ADDR   (0x07FFFFFFL)
 690 #define ASC_MAX_EISA_DMA_COUNT  (0x07FFFFFFL)
 691 
 692 #if !CC_STRUCT_ALIGNED
 693 
 694 #define DvcGetQinfo( iop_base, s_addr, outbuf, words)  \
 695         AscMemWordCopyFromLram( iop_base, s_addr, outbuf, words)
 696 
 697 #define DvcPutScsiQ( iop_base, s_addr, outbuf, words) \
 698         AscMemWordCopyToLram( iop_base, s_addr, outbuf, words)
 699 
 700 #endif
 701 
 702 #define ASC_SCSI_ID_BITS  3
 703 #define ASC_SCSI_TIX_TYPE     uchar
 704 #define ASC_ALL_DEVICE_BIT_SET  0xFF
 705 
 706 #ifdef ASC_WIDESCSI_16
 707 
 708 #undef  ASC_SCSI_ID_BITS
 709 #define ASC_SCSI_ID_BITS  4
 710 #define ASC_ALL_DEVICE_BIT_SET  0xFFFF
 711 
 712 #endif
 713 
 714 #ifdef ASC_WIDESCSI_32
 715 
 716 #undef  ASC_SCSI_ID_BITS
 717 #define ASC_SCSI_ID_BITS  5
 718 #define ASC_ALL_DEVICE_BIT_SET  0xFFFFFFFFL
 719 
 720 #endif
 721 
 722 #if ASC_SCSI_ID_BITS == 3
 723 
 724 #define ASC_SCSI_BIT_ID_TYPE  uchar
 725 #define ASC_MAX_TID       7
 726 #define ASC_MAX_LUN       7
 727 #define ASC_SCSI_WIDTH_BIT_SET  0xFF
 728 
 729 #elif ASC_SCSI_ID_BITS == 4
 730 
 731 #define ASC_SCSI_BIT_ID_TYPE   ushort
 732 #define ASC_MAX_TID         15
 733 #define ASC_MAX_LUN         7
 734 #define ASC_SCSI_WIDTH_BIT_SET  0xFFFF
 735 
 736 #elif ASC_SCSI_ID_BITS == 5
 737 
 738 #define ASC_SCSI_BIT_ID_TYPE    ulong
 739 #define ASC_MAX_TID         31
 740 #define ASC_MAX_LUN         7
 741 #define ASC_SCSI_WIDTH_BIT_SET  0xFFFFFFFF
 742 
 743 #else
 744 
 745 #error  ASC_SCSI_ID_BITS definition is wrong
 746 
 747 #endif
 748 
 749 #define ASC_MAX_SENSE_LEN   32
 750 #define ASC_MIN_SENSE_LEN   14
 751 
 752 #define ASC_MAX_CDB_LEN     12
 753 
 754 #define SCSICMD_TestUnitReady     0x00
 755 #define SCSICMD_Rewind            0x01
 756 #define SCSICMD_Rezero            0x01
 757 #define SCSICMD_RequestSense      0x03
 758 #define SCSICMD_Format            0x04
 759 #define SCSICMD_FormatUnit        0x04
 760 #define SCSICMD_Read6             0x08
 761 #define SCSICMD_Write6            0x0A
 762 #define SCSICMD_Seek6             0x0B
 763 #define SCSICMD_Inquiry           0x12
 764 #define SCSICMD_Verify6           0x13
 765 #define SCSICMD_ModeSelect6       0x15
 766 #define SCSICMD_ModeSense6        0x1A
 767 
 768 #define SCSICMD_StartStopUnit     0x1B
 769 #define SCSICMD_LoadUnloadTape    0x1B
 770 #define SCSICMD_ReadCapacity      0x25
 771 #define SCSICMD_Read10            0x28
 772 #define SCSICMD_Write10           0x2A
 773 #define SCSICMD_Seek10            0x2B
 774 #define SCSICMD_Erase10           0x2C
 775 #define SCSICMD_WriteAndVerify10  0x2E
 776 #define SCSICMD_Verify10          0x2F
 777 
 778 #define SCSICMD_ModeSelect10      0x55
 779 #define SCSICMD_ModeSense10       0x5A
 780 
 781 #define SCSI_TYPE_DASD     0x00
 782 #define SCSI_TYPE_SASD     0x01
 783 #define SCSI_TYPE_PRN      0x02
 784 #define SCSI_TYPE_PROC     0x03
 785 
 786 #define SCSI_TYPE_WORM     0x04
 787 #define SCSI_TYPE_CDROM    0x05
 788 #define SCSI_TYPE_SCANNER  0x06
 789 #define SCSI_TYPE_OPTMEM   0x07
 790 #define SCSI_TYPE_MED_CHG  0x08
 791 #define SCSI_TYPE_COMM     0x09
 792 #define SCSI_TYPE_UNKNOWN  0x1F
 793 #define SCSI_TYPE_NO_DVC   0xFF
 794 
 795 #define ASC_SCSIDIR_NOCHK    0x00
 796 
 797 #define ASC_SCSIDIR_T2H      0x08
 798 
 799 #define ASC_SCSIDIR_H2T      0x10
 800 
 801 #define ASC_SCSIDIR_NODATA   0x18
 802 
 803 #define SCSI_SENKEY_NO_SENSE      0x00
 804 #define SCSI_SENKEY_UNDEFINED     0x01
 805 #define SCSI_SENKEY_NOT_READY     0x02
 806 #define SCSI_SENKEY_MEDIUM_ERR    0x03
 807 #define SCSI_SENKEY_HW_ERR        0x04
 808 #define SCSI_SENKEY_ILLEGAL       0x05
 809 #define SCSI_SENKEY_ATTENSION     0x06
 810 #define SCSI_SENKEY_PROTECTED     0x07
 811 #define SCSI_SENKEY_BLANK         0x08
 812 #define SCSI_SENKEY_V_UNIQUE      0x09
 813 #define SCSI_SENKEY_CPY_ABORT     0x0A
 814 #define SCSI_SENKEY_ABORT         0x0B
 815 #define SCSI_SENKEY_EQUAL         0x0C
 816 #define SCSI_SENKEY_VOL_OVERFLOW  0x0D
 817 #define SCSI_SENKEY_MISCOMP       0x0E
 818 #define SCSI_SENKEY_RESERVED      0x0F
 819 
 820 #define ASC_SRB_HOST( x )  ( ( uchar )( ( uchar )( x ) >> 4 ) )
 821 #define ASC_SRB_TID( x )   ( ( uchar )( ( uchar )( x ) & ( uchar )0x0F ) )
 822 
 823 #define ASC_SRB_LUN( x )   ( ( uchar )( ( uint )( x ) >> 13 ) )
 824 
 825 #define PUT_CDB1( x )   ( ( uchar )( ( uint )( x ) >> 8 ) )
 826 
 827 #define SS_GOOD              0x00
 828 #define SS_CHK_CONDITION     0x02
 829 #define SS_CONDITION_MET     0x04
 830 #define SS_TARGET_BUSY       0x08
 831 #define SS_INTERMID          0x10
 832 #define SS_INTERMID_COND_MET 0x14
 833 
 834 #define SS_RSERV_CONFLICT    0x18
 835 #define SS_CMD_TERMINATED    0x22
 836 
 837 #define SS_QUEUE_FULL        0x28
 838 
 839 #define MS_CMD_DONE    0x00
 840 #define MS_EXTEND      0x01
 841 #define MS_SDTR_LEN    0x03
 842 #define MS_SDTR_CODE   0x01
 843 
 844 #define M1_SAVE_DATA_PTR        0x02
 845 #define M1_RESTORE_PTRS         0x03
 846 #define M1_DISCONNECT           0x04
 847 #define M1_INIT_DETECTED_ERR    0x05
 848 #define M1_ABORT                0x06
 849 #define M1_MSG_REJECT           0x07
 850 #define M1_NO_OP                0x08
 851 #define M1_MSG_PARITY_ERR       0x09
 852 #define M1_LINK_CMD_DONE        0x0A
 853 #define M1_LINK_CMD_DONE_WFLAG  0x0B
 854 #define M1_BUS_DVC_RESET        0x0C
 855 #define M1_ABORT_TAG            0x0D
 856 #define M1_CLR_QUEUE            0x0E
 857 #define M1_INIT_RECOVERY        0x0F
 858 #define M1_RELEASE_RECOVERY     0x10
 859 #define M1_KILL_IO_PROC         0x11
 860 
 861 #define M2_QTAG_MSG_SIMPLE      0x20
 862 #define M2_QTAG_MSG_HEAD        0x21
 863 #define M2_QTAG_MSG_ORDERED     0x22
 864 #define M2_IGNORE_WIDE_RESIDUE  0x23
 865 
 866 typedef struct {
 867         uchar               peri_dvc_type:5;
 868         uchar               peri_qualifier:3;
 869 } ASC_SCSI_INQ0;
 870 
 871 typedef struct {
 872         uchar               dvc_type_modifier:7;
 873         uchar               rmb:1;
 874 } ASC_SCSI_INQ1;
 875 
 876 typedef struct {
 877         uchar               ansi_apr_ver:3;
 878         uchar               ecma_ver:3;
 879         uchar               iso_ver:2;
 880 } ASC_SCSI_INQ2;
 881 
 882 typedef struct {
 883         uchar               rsp_data_fmt:4;
 884 
 885         uchar               res:2;
 886         uchar               TemIOP:1;
 887         uchar               aenc:1;
 888 } ASC_SCSI_INQ3;
 889 
 890 typedef struct {
 891         uchar               StfRe:1;
 892         uchar               CmdQue:1;
 893         uchar               Reserved:1;
 894         uchar               Linked:1;
 895         uchar               Sync:1;
 896         uchar               WBus16:1;
 897         uchar               WBus32:1;
 898         uchar               RelAdr:1;
 899 } ASC_SCSI_INQ7;
 900 
 901 typedef struct {
 902         ASC_SCSI_INQ0       byte0;
 903         ASC_SCSI_INQ1       byte1;
 904         ASC_SCSI_INQ2       byte2;
 905         ASC_SCSI_INQ3       byte3;
 906         uchar               add_len;
 907         uchar               res1;
 908         uchar               res2;
 909         ASC_SCSI_INQ7       byte7;
 910         uchar               vendor_id[8];
 911         uchar               product_id[16];
 912         uchar               product_rev_level[4];
 913 } ASC_SCSI_INQUIRY;
 914 
 915 typedef struct asc_req_sense {
 916         uchar               err_code:7;
 917         uchar               info_valid:1;
 918         uchar               segment_no;
 919         uchar               sense_key:4;
 920         uchar               reserved_bit:1;
 921         uchar               sense_ILI:1;
 922         uchar               sense_EOM:1;
 923         uchar               file_mark:1;
 924         uchar               info1[4];
 925         uchar               add_sense_len;
 926         uchar               cmd_sp_info[4];
 927         uchar               asc;
 928         uchar               ascq;
 929 
 930         uchar               fruc;
 931         uchar               sks_byte0:7;
 932         uchar               sks_valid:1;
 933         uchar               sks_bytes[2];
 934         uchar               notused[2];
 935         uchar               ex_sense_code;
 936         uchar               info2[4];
 937 } ASC_REQ_SENSE;
 938 
 939 #define ASC_SG_LIST_PER_Q   7
 940 
 941 #define QS_FREE        0x00
 942 #define QS_READY       0x01
 943 #define QS_DISC1       0x02
 944 #define QS_DISC2       0x04
 945 #define QS_BUSY        0x08
 946 
 947 #define QS_ABORTED     0x40
 948 #define QS_DONE        0x80
 949 
 950 #define QC_NO_CALLBACK   0x01
 951 
 952 #define QC_SG_SWAP_QUEUE 0x02
 953 #define QC_SG_HEAD       0x04
 954 #define QC_DATA_IN       0x08
 955 #define QC_DATA_OUT      0x10
 956 
 957 #define QC_URGENT        0x20
 958 #define QC_MSG_OUT       0x40
 959 #define QC_REQ_SENSE     0x80
 960 
 961 #define QCSG_SG_XFER_LIST  0x02
 962 #define QCSG_SG_XFER_MORE  0x04
 963 #define QCSG_SG_XFER_END   0x08
 964 
 965 #define QD_IN_PROGRESS       0x00
 966 #define QD_NO_ERROR          0x01
 967 #define QD_ABORTED_BY_HOST   0x02
 968 #define QD_WITH_ERROR        0x04
 969 #define QD_INVALID_REQUEST   0x80
 970 #define QD_INVALID_HOST_NUM  0x81
 971 #define QD_INVALID_DEVICE    0x82
 972 #define QD_ERR_INTERNAL      0xFF
 973 
 974 #define QHSTA_NO_ERROR               0x00
 975 #define QHSTA_M_SEL_TIMEOUT          0x11
 976 #define QHSTA_M_DATA_OVER_RUN        0x12
 977 #define QHSTA_M_DATA_UNDER_RUN       0x12
 978 #define QHSTA_M_UNEXPECTED_BUS_FREE  0x13
 979 #define QHSTA_M_BAD_BUS_PHASE_SEQ    0x14
 980 
 981 #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
 982 #define QHSTA_D_ASC_DVC_ERROR_CODE_SET  0x22
 983 #define QHSTA_D_HOST_ABORT_FAILED       0x23
 984 #define QHSTA_D_EXE_SCSI_Q_FAILED       0x24
 985 #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
 986 
 987 #define QHSTA_D_ASPI_NO_BUF_POOL        0x26
 988 
 989 #define QHSTA_M_WTM_TIMEOUT         0x41
 990 #define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
 991 #define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
 992 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
 993 #define QHSTA_M_TARGET_STATUS_BUSY  0x45
 994 #define QHSTA_M_BAD_TAG_CODE        0x46
 995 
 996 #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY  0x47
 997 
 998 #define QHSTA_D_LRAM_CMP_ERROR        0x81
 999 #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
1000 
1001 #define ASC_FLAG_SCSIQ_REQ        0x01
1002 #define ASC_FLAG_BIOS_SCSIQ_REQ   0x02
1003 #define ASC_FLAG_BIOS_ASYNC_IO    0x04
1004 #define ASC_FLAG_SRB_LINEAR_ADDR  0x08
1005 
1006 #define ASC_FLAG_WIN16            0x10
1007 #define ASC_FLAG_WIN32            0x20
1008 
1009 #define ASC_FLAG_DOS_VM_CALLBACK  0x80
1010 
1011 #define ASC_TAG_FLAG_ADD_ONE_BYTE     0x10
1012 #define ASC_TAG_FLAG_ISAPNP_ADD_BYTES 0x40
1013 
1014 #define ASC_SCSIQ_CPY_BEG              4
1015 #define ASC_SCSIQ_SGHD_CPY_BEG         2
1016 
1017 #define ASC_SCSIQ_B_FWD                0
1018 #define ASC_SCSIQ_B_BWD                1
1019 
1020 #define ASC_SCSIQ_B_STATUS             2
1021 #define ASC_SCSIQ_B_QNO                3
1022 
1023 #define ASC_SCSIQ_B_CNTL               4
1024 #define ASC_SCSIQ_B_SG_QUEUE_CNT       5
1025 
1026 #define ASC_SCSIQ_D_DATA_ADDR          8
1027 #define ASC_SCSIQ_D_DATA_CNT          12
1028 #define ASC_SCSIQ_B_SENSE_LEN         20
1029 #define ASC_SCSIQ_DONE_INFO_BEG       22
1030 #define ASC_SCSIQ_D_SRBPTR            22
1031 #define ASC_SCSIQ_B_TARGET_IX         26
1032 #define ASC_SCSIQ_B_CDB_LEN           28
1033 #define ASC_SCSIQ_B_TAG_CODE          29
1034 #define ASC_SCSIQ_W_VM_ID             30
1035 #define ASC_SCSIQ_DONE_STATUS         32
1036 #define ASC_SCSIQ_HOST_STATUS         33
1037 #define ASC_SCSIQ_SCSI_STATUS         34
1038 #define ASC_SCSIQ_CDB_BEG             36
1039 #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
1040 #define ASC_SCSIQ_DW_REMAIN_XFER_CNT  60
1041 #define ASC_SCSIQ_B_SG_WK_QP          49
1042 #define ASC_SCSIQ_B_SG_WK_IX          50
1043 #define ASC_SCSIQ_W_REQ_COUNT         52
1044 #define ASC_SCSIQ_B_LIST_CNT          6
1045 #define ASC_SCSIQ_B_CUR_LIST_CNT      7
1046 
1047 #define ASC_SGQ_B_SG_CNTL             4
1048 #define ASC_SGQ_B_SG_HEAD_QP          5
1049 #define ASC_SGQ_B_SG_LIST_CNT         6
1050 #define ASC_SGQ_B_SG_CUR_LIST_CNT     7
1051 #define ASC_SGQ_LIST_BEG              8
1052 
1053 #define ASC_DEF_SCSI1_QNG    2
1054 #define ASC_MAX_SCSI1_QNG    2
1055 #define ASC_DEF_SCSI2_QNG    16
1056 #define ASC_MAX_SCSI2_QNG    32
1057 
1058 #define ASC_TAG_CODE_MASK    0x23
1059 
1060 #define ASC_STOP_REQ_RISC_STOP      0x01
1061 
1062 #define ASC_STOP_ACK_RISC_STOP      0x03
1063 
1064 #define ASC_STOP_CLEAN_UP_BUSY_Q    0x10
1065 #define ASC_STOP_CLEAN_UP_DISC_Q    0x20
1066 #define ASC_STOP_HOST_REQ_RISC_HALT 0x40
1067 #define ASC_STOP_SEND_INT_TO_HOST   0x80
1068 
1069 #define ASC_TIDLUN_TO_IX( tid, lun )  ( ASC_SCSI_TIX_TYPE )( (tid) + ((lun)<<ASC_SCSI_ID_BITS) )
1070 
1071 #define ASC_TID_TO_TARGET_ID( tid )   ( ASC_SCSI_BIT_ID_TYPE )( 0x01 << (tid) )
1072 #define ASC_TIX_TO_TARGET_ID( tix )   ( 0x01 << ( (tix) & ASC_MAX_TID ) )
1073 #define ASC_TIX_TO_TID( tix )  ( (tix) & ASC_MAX_TID )
1074 #define ASC_TID_TO_TIX( tid )  ( (tid) & ASC_MAX_TID )
1075 #define ASC_TIX_TO_LUN( tix )  ( ( (tix) >> ASC_SCSI_ID_BITS ) & ASC_MAX_LUN )
1076 
1077 #define ASC_QNO_TO_QADDR( q_no )      ( (ASC_QADR_BEG)+( ( int )(q_no) << 6 ) )
1078 
1079 typedef struct asc_scisq_1 {
1080         uchar               status;
1081         uchar               q_no;
1082         uchar               cntl;
1083         uchar               sg_queue_cnt;
1084 
1085         uchar               target_id;
1086         uchar               target_lun;
1087 
1088         ulong               data_addr;
1089         ulong               data_cnt;
1090         ulong               sense_addr;
1091         uchar               sense_len;
1092         uchar               user_def;
1093 } ASC_SCSIQ_1;
1094 
1095 typedef struct asc_scisq_2 {
1096         ulong               srb_ptr;
1097         uchar               target_ix;
1098 
1099         uchar               flag;
1100         uchar               cdb_len;
1101         uchar               tag_code;
1102 
1103         ushort              vm_id;
1104 } ASC_SCSIQ_2;
1105 
1106 typedef struct asc_scsiq_3 {
1107         uchar               done_stat;
1108         uchar               host_stat;
1109         uchar               scsi_stat;
1110         uchar               scsi_msg;
1111 } ASC_SCSIQ_3;
1112 
1113 typedef struct asc_scsiq_4 {
1114         uchar               cdb[ASC_MAX_CDB_LEN];
1115         uchar               y_first_sg_list_qp;
1116         uchar               y_working_sg_qp;
1117         uchar               y_working_sg_ix;
1118         uchar               y_cntl;
1119         ushort              x_req_count;
1120         ushort              x_reconnect_rtn;
1121         ulong               x_saved_data_addr;
1122         ulong               x_saved_data_cnt;
1123 } ASC_SCSIQ_4;
1124 
1125 typedef struct asc_q_done_info {
1126         ASC_SCSIQ_2         d2;
1127         ASC_SCSIQ_3         d3;
1128         uchar               q_status;
1129         uchar               q_no;
1130         uchar               cntl;
1131         uchar               sense_len;
1132         uchar               user_def;
1133         uchar               res;
1134         ulong               remain_bytes;
1135 } ASC_QDONE_INFO;
1136 
1137 typedef struct asc_sg_list {
1138         ulong               addr;
1139         ulong               bytes;
1140 } ASC_SG_LIST;
1141 
1142 typedef struct asc_sg_head {
1143         uchar               entry_cnt;
1144 
1145         uchar               queue_cnt;
1146 
1147         uchar               entry_to_copy;
1148         uchar               res;
1149         ASC_SG_LIST         sg_list[ASC_MAX_SG_LIST];
1150 } ASC_SG_HEAD;
1151 
1152 #define ASC_MIN_SG_LIST   2
1153 
1154 typedef struct asc_min_sg_head {
1155         uchar               entry_cnt;
1156 
1157         uchar               queue_cnt;
1158 
1159         uchar               entry_to_copy;
1160         uchar               res;
1161         ASC_SG_LIST         sg_list[ASC_MIN_SG_LIST];
1162 } ASC_MIN_SG_HEAD;
1163 
1164 #define QCX_SORT        (0x0001)
1165 #define QCX_COALEASE    (0x0002)
1166 
1167 #if CC_LINK_BUSY_Q
1168 typedef struct asc_ext_scsi_q {
1169         ulong               lba;
1170         ushort              lba_len;
1171         struct asc_scsi_q dosfar *next;
1172         struct asc_scsi_q dosfar *join;
1173         ushort              cntl;
1174         ushort              buffer_id;
1175         uchar               q_required;
1176         uchar               res;
1177 } ASC_EXT_SCSI_Q;
1178 
1179 #endif
1180 
1181 typedef struct asc_scsi_q {
1182         ASC_SCSIQ_1         q1;
1183         ASC_SCSIQ_2         q2;
1184         uchar dosfar       *cdbptr;
1185 
1186         ASC_SG_HEAD dosfar *sg_head;
1187 
1188 #if CC_LINK_BUSY_Q
1189         ASC_EXT_SCSI_Q      ext;
1190 #endif
1191 
1192 } ASC_SCSI_Q;
1193 
1194 typedef struct asc_scsi_req_q {
1195         ASC_SCSIQ_1         r1;
1196         ASC_SCSIQ_2         r2;
1197         uchar dosfar       *cdbptr;
1198         ASC_SG_HEAD dosfar *sg_head;
1199 
1200 #if CC_LINK_BUSY_Q
1201         ASC_EXT_SCSI_Q      ext;
1202 #endif
1203 
1204         uchar dosfar       *sense_ptr;
1205 
1206         ASC_SCSIQ_3         r3;
1207         uchar               cdb[ASC_MAX_CDB_LEN];
1208         uchar               sense[ASC_MIN_SENSE_LEN];
1209 } ASC_SCSI_REQ_Q;
1210 
1211 typedef struct asc_risc_q {
1212         uchar               fwd;
1213         uchar               bwd;
1214         ASC_SCSIQ_1         i1;
1215         ASC_SCSIQ_2         i2;
1216         ASC_SCSIQ_3         i3;
1217         ASC_SCSIQ_4         i4;
1218 } ASC_RISC_Q;
1219 
1220 typedef struct asc_sg_list_q {
1221 
1222         uchar               seq_no;
1223         uchar               q_no;
1224         uchar               cntl;
1225         uchar               sg_head_qp;
1226         uchar               sg_list_cnt;
1227         uchar               sg_cur_list_cnt;
1228 
1229 } ASC_SG_LIST_Q;
1230 
1231 typedef struct asc_risc_sg_list_q {
1232         uchar               fwd;
1233         uchar               bwd;
1234         ASC_SG_LIST_Q       sg;
1235         ASC_SG_LIST         sg_list[7];
1236 } ASC_RISC_SG_LIST_Q;
1237 
1238 #define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP  0x1000000UL
1239 #define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP  1024
1240 
1241 #define ASCQ_ERR_NO_ERROR             0
1242 #define ASCQ_ERR_IO_NOT_FOUND         1
1243 #define ASCQ_ERR_LOCAL_MEM            2
1244 #define ASCQ_ERR_CHKSUM               3
1245 #define ASCQ_ERR_START_CHIP           4
1246 #define ASCQ_ERR_INT_TARGET_ID        5
1247 #define ASCQ_ERR_INT_LOCAL_MEM        6
1248 #define ASCQ_ERR_HALT_RISC            7
1249 #define ASCQ_ERR_GET_ASPI_ENTRY       8
1250 #define ASCQ_ERR_CLOSE_ASPI           9
1251 #define ASCQ_ERR_HOST_INQUIRY         0x0A
1252 #define ASCQ_ERR_SAVED_SRB_BAD        0x0B
1253 #define ASCQ_ERR_QCNTL_SG_LIST        0x0C
1254 #define ASCQ_ERR_Q_STATUS             0x0D
1255 #define ASCQ_ERR_WR_SCSIQ             0x0E
1256 #define ASCQ_ERR_PC_ADDR              0x0F
1257 #define ASCQ_ERR_SYN_OFFSET           0x10
1258 #define ASCQ_ERR_SYN_XFER_TIME        0x11
1259 #define ASCQ_ERR_LOCK_DMA             0x12
1260 #define ASCQ_ERR_UNLOCK_DMA           0x13
1261 #define ASCQ_ERR_VDS_CHK_INSTALL      0x14
1262 #define ASCQ_ERR_MICRO_CODE_HALT      0x15
1263 #define ASCQ_ERR_SET_LRAM_ADDR        0x16
1264 #define ASCQ_ERR_CUR_QNG              0x17
1265 #define ASCQ_ERR_SG_Q_LINKS           0x18
1266 #define ASCQ_ERR_SCSIQ_PTR            0x19
1267 #define ASCQ_ERR_ISR_RE_ENTRY         0x1A
1268 #define ASCQ_ERR_CRITICAL_RE_ENTRY    0x1B
1269 #define ASCQ_ERR_ISR_ON_CRITICAL      0x1C
1270 #define ASCQ_ERR_SG_LIST_ODD_ADDRESS  0x1D
1271 #define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
1272 #define ASCQ_ERR_SCSIQ_NULL_PTR       0x1F
1273 #define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR   0x20
1274 #define ASCQ_ERR_GET_NUM_OF_FREE_Q    0x21
1275 #define ASCQ_ERR_SEND_SCSI_Q          0x22
1276 #define ASCQ_ERR_HOST_REQ_RISC_HALT   0x23
1277 #define ASCQ_ERR_RESET_SDTR           0x24
1278 
1279 #define ASC_WARN_NO_ERROR             0x0000
1280 #define ASC_WARN_IO_PORT_ROTATE       0x0001
1281 #define ASC_WARN_EEPROM_CHKSUM        0x0002
1282 #define ASC_WARN_IRQ_MODIFIED         0x0004
1283 #define ASC_WARN_AUTO_CONFIG          0x0008
1284 #define ASC_WARN_CMD_QNG_CONFLICT     0x0010
1285 
1286 #define ASC_WARN_EEPROM_RECOVER       0x0020
1287 #define ASC_WARN_CFG_MSW_RECOVER      0x0040
1288 
1289 #define ASC_IERR_WRITE_EEPROM         0x0001
1290 #define ASC_IERR_MCODE_CHKSUM         0x0002
1291 #define ASC_IERR_SET_PC_ADDR          0x0004
1292 #define ASC_IERR_START_STOP_CHIP      0x0008
1293 
1294 #define ASC_IERR_IRQ_NO               0x0010
1295 
1296 #define ASC_IERR_SET_IRQ_NO           0x0020
1297 #define ASC_IERR_CHIP_VERSION         0x0040
1298 #define ASC_IERR_SET_SCSI_ID          0x0080
1299 #define ASC_IERR_GET_PHY_ADDR         0x0100
1300 #define ASC_IERR_BAD_SIGNATURE        0x0200
1301 #define ASC_IERR_NO_BUS_TYPE          0x0400
1302 #define ASC_IERR_SCAM                 0x0800
1303 #define ASC_IERR_SET_SDTR             0x1000
1304 #define ASC_IERR_RW_LRAM              0x8000
1305 
1306 #define ASC_DEF_IRQ_NO  10
1307 #define ASC_MAX_IRQ_NO  15
1308 #define ASC_MIN_IRQ_NO  10
1309 
1310 #define ASC_MIN_REMAIN_Q        (0x02)
1311 #define ASC_DEF_MAX_TOTAL_QNG   (0x40)
1312 
1313 #define ASC_MIN_TAG_Q_PER_DVC   (0x04)
1314 #define ASC_DEF_TAG_Q_PER_DVC   (0x04)
1315 
1316 #define ASC_MIN_FREE_Q        ASC_MIN_REMAIN_Q
1317 
1318 #define ASC_MIN_TOTAL_QNG     (( ASC_MAX_SG_QUEUE )+( ASC_MIN_FREE_Q ))
1319 
1320 #define ASC_MAX_TOTAL_QNG 240
1321 #define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
1322 
1323 #define ASC_MAX_INRAM_TAG_QNG   16
1324 
1325 typedef struct asc_dvc_cfg {
1326         ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
1327 
1328         ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
1329         ASC_SCSI_BIT_ID_TYPE disc_enable;
1330         uchar               res;
1331         uchar               chip_scsi_id:4;
1332 
1333         uchar               isa_dma_speed:4;
1334 
1335         uchar               isa_dma_channel;
1336         uchar               chip_version;
1337         ushort              pci_device_id;
1338         ushort              lib_serial_no;
1339         ushort              lib_version;
1340         ushort              mcode_date;
1341         ushort              mcode_version;
1342         uchar               sdtr_data[ASC_MAX_TID + 1];
1343         uchar               max_tag_qng[ASC_MAX_TID + 1];
1344         uchar dosfar       *overrun_buf;
1345 
1346 } ASC_DVC_CFG;
1347 
1348 #define ASC_DEF_DVC_CNTL       0xFFFF
1349 #define ASC_DEF_CHIP_SCSI_ID   7
1350 #define ASC_DEF_ISA_DMA_SPEED  4
1351 
1352 #define ASC_INIT_STATE_NULL          0x0000
1353 #define ASC_INIT_STATE_BEG_GET_CFG   0x0001
1354 #define ASC_INIT_STATE_END_GET_CFG   0x0002
1355 #define ASC_INIT_STATE_BEG_SET_CFG   0x0004
1356 #define ASC_INIT_STATE_END_SET_CFG   0x0008
1357 #define ASC_INIT_STATE_BEG_LOAD_MC   0x0010
1358 #define ASC_INIT_STATE_END_LOAD_MC   0x0020
1359 #define ASC_INIT_STATE_BEG_INQUIRY   0x0040
1360 #define ASC_INIT_STATE_END_INQUIRY   0x0080
1361 #define ASC_INIT_RESET_SCSI_DONE     0x0100
1362 
1363 #define ASC_PCI_DEVICE_ID_REV_A      0x1100
1364 #define ASC_PCI_DEVICE_ID_REV_B      0x1200
1365 
1366 #define ASC_BUG_FIX_ADD_ONE_BYTE     0x0001
1367 
1368 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
1369 
1370 #define ASC_MIN_TAGGED_CMD  7
1371 
1372 typedef struct asc_dvc_var {
1373         PortAddr            iop_base;
1374         ushort              err_code;
1375         ushort              dvc_cntl;
1376         ushort              bug_fix_cntl;
1377         ushort              bus_type;
1378         Ptr2Func            isr_callback;
1379         Ptr2Func            exe_callback;
1380 
1381         ASC_SCSI_BIT_ID_TYPE init_sdtr;
1382 
1383         ASC_SCSI_BIT_ID_TYPE sdtr_done;
1384 
1385         ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
1386 
1387         ASC_SCSI_BIT_ID_TYPE unit_not_ready;
1388 
1389         ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
1390 
1391         ASC_SCSI_BIT_ID_TYPE start_motor;
1392         uchar               scsi_reset_wait;
1393         uchar               chip_no;
1394 
1395         char                is_in_int;
1396         uchar               max_total_qng;
1397 
1398         uchar               cur_total_qng;
1399 
1400         uchar               in_critical_cnt;
1401 
1402         uchar               irq_no;
1403         uchar               last_q_shortage;
1404 
1405         ushort              init_state;
1406         uchar               cur_dvc_qng[ASC_MAX_TID + 1];
1407         uchar               max_dvc_qng[ASC_MAX_TID + 1];
1408 
1409         ASC_SCSI_Q dosfar  *scsiq_busy_head[ASC_MAX_TID + 1];
1410         ASC_SCSI_Q dosfar  *scsiq_busy_tail[ASC_MAX_TID + 1];
1411 
1412         ulong               int_count;
1413         ulong               req_count;
1414         ulong               busy_count;
1415 
1416         ASC_DVC_CFG dosfar *cfg;
1417         Ptr2Func            saved_ptr2func;
1418         ulong               reserved2;
1419         ulong               reserved3;
1420         ulong               max_dma_count;
1421         ASC_SCSI_BIT_ID_TYPE no_scam;
1422         ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
1423 } ASC_DVC_VAR;
1424 
1425 typedef int         (dosfar * ASC_ISR_CALLBACK) (ASC_DVC_VAR asc_ptr_type *, ASC_QDONE_INFO dosfar *);
1426 typedef int         (dosfar * ASC_EXE_CALLBACK) (ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q dosfar *);
1427 
1428 typedef struct asc_dvc_inq_info {
1429         uchar               type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1430 } ASC_DVC_INQ_INFO;
1431 
1432 typedef struct asc_cap_info {
1433         ulong               lba;
1434         ulong               blk_size;
1435 } ASC_CAP_INFO;
1436 
1437 typedef struct asc_cap_info_array {
1438         ASC_CAP_INFO        cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1439 } ASC_CAP_INFO_ARRAY;
1440 
1441 #define ASC_IOADR_TABLE_MAX_IX  11
1442 #define ASC_IOADR_GAP   0x10
1443 #define ASC_SEARCH_IOP_GAP 0x10
1444 #define ASC_MIN_IOP_ADDR   ( PortAddr )0x0100
1445 #define ASC_MAX_IOP_ADDR   ( PortAddr )0x3F0
1446 
1447 #define ASC_IOADR_1     ( PortAddr )0x0110
1448 #define ASC_IOADR_2     ( PortAddr )0x0130
1449 #define ASC_IOADR_3     ( PortAddr )0x0150
1450 #define ASC_IOADR_4     ( PortAddr )0x0190
1451 #define ASC_IOADR_5     ( PortAddr )0x0210
1452 #define ASC_IOADR_6     ( PortAddr )0x0230
1453 #define ASC_IOADR_7     ( PortAddr )0x0250
1454 #define ASC_IOADR_8     ( PortAddr )0x0330
1455 #define ASC_IOADR_DEF   ASC_IOADR_8
1456 
1457 #define ASC_SYN_XFER_NO   8
1458 #define ASC_MAX_SDTR_PERIOD_INDEX  7
1459 #define ASC_SYN_MAX_OFFSET   0x0F
1460 #define ASC_DEF_SDTR_OFFSET  0x0F
1461 #define ASC_DEF_SDTR_INDEX   0x00
1462 
1463 #define SYN_XFER_NS_0  25
1464 #define SYN_XFER_NS_1  30
1465 #define SYN_XFER_NS_2  35
1466 #define SYN_XFER_NS_3  40
1467 #define SYN_XFER_NS_4  50
1468 #define SYN_XFER_NS_5  60
1469 #define SYN_XFER_NS_6  70
1470 #define SYN_XFER_NS_7  85
1471 
1472 #define ASC_SDTR_PERIOD_IX_MIN  7
1473 
1474 #define SYN_XMSG_WLEN  3
1475 
1476 typedef struct sdtr_xmsg {
1477         uchar               msg_type;
1478         uchar               msg_len;
1479         uchar               msg_req;
1480         uchar               xfer_period;
1481         uchar               req_ack_offset;
1482         uchar               res;
1483 } SDTR_XMSG;
1484 
1485 #define ASC_MCNTL_NO_SEL_TIMEOUT  ( ushort )0x0001
1486 #define ASC_MCNTL_NULL_TARGET     ( ushort )0x0002
1487 
1488 #define ASC_CNTL_INITIATOR         ( ushort )0x0001
1489 #define ASC_CNTL_BIOS_GT_1GB       ( ushort )0x0002
1490 #define ASC_CNTL_BIOS_GT_2_DISK    ( ushort )0x0004
1491 #define ASC_CNTL_BIOS_REMOVABLE    ( ushort )0x0008
1492 #define ASC_CNTL_NO_SCAM           ( ushort )0x0010
1493 #define ASC_CNTL_NO_PCI_FIX_ASYN_XFER ( ushort )0x0020
1494 
1495 #define ASC_CNTL_INT_MULTI_Q       ( ushort )0x0080
1496 
1497 #define ASC_CNTL_NO_LUN_SUPPORT    ( ushort )0x0040
1498 
1499 #define ASC_CNTL_NO_VERIFY_COPY    ( ushort )0x0100
1500 #define ASC_CNTL_RESET_SCSI        ( ushort )0x0200
1501 #define ASC_CNTL_INIT_INQUIRY      ( ushort )0x0400
1502 #define ASC_CNTL_INIT_VERBOSE      ( ushort )0x0800
1503 
1504 #define ASC_CNTL_SCSI_PARITY       ( ushort )0x1000
1505 #define ASC_CNTL_BURST_MODE        ( ushort )0x2000
1506 
1507 #define ASC_CNTL_USE_8_IOP_BASE    ( ushort )0x4000
1508 
1509 #define ASC_EEP_DVC_CFG_BEG_VL    2
1510 #define ASC_EEP_MAX_DVC_ADDR_VL   15
1511 
1512 #define ASC_EEP_DVC_CFG_BEG      32
1513 #define ASC_EEP_MAX_DVC_ADDR     45
1514 
1515 #define ASC_EEP_DEFINED_WORDS    10
1516 #define ASC_EEP_MAX_ADDR         63
1517 #define ASC_EEP_RES_WORDS         0
1518 #define ASC_EEP_MAX_RETRY        20
1519 #define ASC_MAX_INIT_BUSY_RETRY   8
1520 
1521 #define ASC_EEP_ISA_PNP_WSIZE    16
1522 
1523 typedef struct asceep_config {
1524         ushort              cfg_lsw;
1525         ushort              cfg_msw;
1526 
1527         uchar               init_sdtr;
1528         uchar               disc_enable;
1529 
1530         uchar               use_cmd_qng;
1531 
1532         uchar               start_motor;
1533         uchar               max_total_qng;
1534         uchar               max_tag_qng;
1535         uchar               bios_scan;
1536 
1537         uchar               power_up_wait;
1538 
1539         uchar               no_scam;
1540         uchar               chip_scsi_id:4;
1541 
1542         uchar               isa_dma_speed:4;
1543 
1544         uchar               sdtr_data[ASC_MAX_TID + 1];
1545 
1546         uchar               adapter_info[6];
1547 
1548         ushort              cntl;
1549 
1550         ushort              chksum;
1551 } ASCEEP_CONFIG;
1552 
1553 #define ASC_EEP_CMD_READ          0x80
1554 #define ASC_EEP_CMD_WRITE         0x40
1555 #define ASC_EEP_CMD_WRITE_ABLE    0x30
1556 #define ASC_EEP_CMD_WRITE_DISABLE 0x00
1557 
1558 #define ASC_OVERRUN_BSIZE  0x00000048UL
1559 
1560 #define ASCV_MSGOUT_BEG         0x0000
1561 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
1562 #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
1563 
1564 #define ASCV_MSGIN_BEG          (ASCV_MSGOUT_BEG+8)
1565 #define ASCV_MSGIN_SDTR_PERIOD  (ASCV_MSGIN_BEG+3)
1566 #define ASCV_MSGIN_SDTR_OFFSET  (ASCV_MSGIN_BEG+4)
1567 
1568 #define ASCV_SDTR_DATA_BEG      (ASCV_MSGIN_BEG+8)
1569 #define ASCV_SDTR_DONE_BEG      (ASCV_SDTR_DATA_BEG+8)
1570 #define ASCV_MAX_DVC_QNG_BEG    ( ushort )0x0020
1571 
1572 #define ASCV_ASCDVC_ERR_CODE_W  ( ushort )0x0030
1573 #define ASCV_MCODE_CHKSUM_W   ( ushort )0x0032
1574 #define ASCV_MCODE_SIZE_W     ( ushort )0x0034
1575 #define ASCV_STOP_CODE_B      ( ushort )0x0036
1576 #define ASCV_DVC_ERR_CODE_B   ( ushort )0x0037
1577 
1578 #define ASCV_OVERRUN_PADDR_D  ( ushort )0x0038
1579 #define ASCV_OVERRUN_BSIZE_D  ( ushort )0x003C
1580 
1581 #define ASCV_HALTCODE_W       ( ushort )0x0040
1582 #define ASCV_CHKSUM_W         ( ushort )0x0042
1583 #define ASCV_MC_DATE_W        ( ushort )0x0044
1584 #define ASCV_MC_VER_W         ( ushort )0x0046
1585 #define ASCV_NEXTRDY_B        ( ushort )0x0048
1586 #define ASCV_DONENEXT_B       ( ushort )0x0049
1587 #define ASCV_USE_TAGGED_QNG_B ( ushort )0x004A
1588 #define ASCV_SCSIBUSY_B       ( ushort )0x004B
1589 #define ASCV_CDBCNT_B         ( ushort )0x004C
1590 #define ASCV_CURCDB_B         ( ushort )0x004D
1591 #define ASCV_RCLUN_B          ( ushort )0x004E
1592 #define ASCV_BUSY_QHEAD_B     ( ushort )0x004F
1593 #define ASCV_DISC1_QHEAD_B    ( ushort )0x0050
1594 
1595 #define ASCV_DISC_ENABLE_B    ( ushort )0x0052
1596 #define ASCV_CAN_TAGGED_QNG_B ( ushort )0x0053
1597 #define ASCV_HOSTSCSI_ID_B    ( ushort )0x0055
1598 #define ASCV_MCODE_CNTL_B     ( ushort )0x0056
1599 #define ASCV_NULL_TARGET_B    ( ushort )0x0057
1600 
1601 #define ASCV_FREE_Q_HEAD_W    ( ushort )0x0058
1602 #define ASCV_DONE_Q_TAIL_W    ( ushort )0x005A
1603 #define ASCV_FREE_Q_HEAD_B    ( ushort )(ASCV_FREE_Q_HEAD_W+1)
1604 #define ASCV_DONE_Q_TAIL_B    ( ushort )(ASCV_DONE_Q_TAIL_W+1)
1605 
1606 #define ASCV_HOST_FLAG_B      ( ushort )0x005D
1607 
1608 #define ASCV_TOTAL_READY_Q_B  ( ushort )0x0064
1609 #define ASCV_VER_SERIAL_B     ( ushort )0x0065
1610 #define ASCV_HALTCODE_SAVED_W ( ushort )0x0066
1611 #define ASCV_WTM_FLAG_B       ( ushort )0x0068
1612 #define ASCV_RISC_FLAG_B      ( ushort )0x006A
1613 #define ASCV_REQ_SG_LIST_QP   ( ushort )0x006B
1614 
1615 #define ASC_HOST_FLAG_IN_ISR        0x01
1616 #define ASC_HOST_FLAG_ACK_INT       0x02
1617 
1618 #define ASC_RISC_FLAG_GEN_INT      0x01
1619 #define ASC_RISC_FLAG_REQ_SG_LIST  0x02
1620 
1621 #define IOP_CTRL         (0x0F)
1622 #define IOP_STATUS       (0x0E)
1623 #define IOP_INT_ACK      IOP_STATUS
1624 
1625 #define IOP_REG_IFC      (0x0D)
1626 
1627 #define IOP_SYN_OFFSET   (0x0B)
1628 #define IOP_REG_PC       (0x0C)
1629 #define IOP_RAM_ADDR     (0x0A)
1630 #define IOP_RAM_DATA     (0x08)
1631 #define IOP_EEP_DATA     (0x06)
1632 #define IOP_EEP_CMD      (0x07)
1633 
1634 #define IOP_VERSION      (0x03)
1635 #define IOP_CONFIG_HIGH  (0x04)
1636 #define IOP_CONFIG_LOW   (0x02)
1637 #define IOP_ASPI_ID_LOW  (0x01)
1638 #define IOP_ASPI_ID_HIGH (0x00)
1639 
1640 #define IOP_REG_DC1      (0x0E)
1641 #define IOP_REG_DC0      (0x0C)
1642 #define IOP_REG_SB       (0x0B)
1643 #define IOP_REG_DA1      (0x0A)
1644 #define IOP_REG_DA0      (0x08)
1645 #define IOP_REG_SC       (0x09)
1646 #define IOP_DMA_SPEED    (0x07)
1647 #define IOP_REG_FLAG     (0x07)
1648 #define IOP_FIFO_H       (0x06)
1649 #define IOP_FIFO_L       (0x04)
1650 #define IOP_REG_ID       (0x05)
1651 #define IOP_REG_QP       (0x03)
1652 #define IOP_REG_IH       (0x02)
1653 #define IOP_REG_IX       (0x01)
1654 #define IOP_REG_AX       (0x00)
1655 
1656 #define IFC_REG_LOCK      (0x00)
1657 #define IFC_REG_UNLOCK    (0x09)
1658 
1659 #define IFC_WR_EN_FILTER  (0x10)
1660 #define IFC_RD_NO_EEPROM  (0x10)
1661 #define IFC_SLEW_RATE     (0x20)
1662 #define IFC_ACT_NEG       (0x40)
1663 #define IFC_INP_FILTER    (0x80)
1664 
1665 #define IFC_INIT_DEFAULT  ( IFC_ACT_NEG | IFC_REG_UNLOCK )
1666 
1667 #define SC_SEL   (0x80)
1668 #define SC_BSY   (0x40)
1669 #define SC_ACK   (0x20)
1670 #define SC_REQ   (0x10)
1671 #define SC_ATN   (0x08)
1672 #define SC_IO    (0x04)
1673 #define SC_CD    (0x02)
1674 #define SC_MSG   (0x01)
1675 
1676 #define AscGetVarFreeQHead( port )       AscReadLramWord( port, ASCV_FREE_Q_HEAD_W )
1677 #define AscGetVarDoneQTail( port )       AscReadLramWord( port, ASCV_DONE_Q_TAIL_W )
1678 #define AscPutVarFreeQHead( port, val )  AscWriteLramWord( port, ASCV_FREE_Q_HEAD_W, val )
1679 #define AscPutVarDoneQTail( port, val )  AscWriteLramWord( port, ASCV_DONE_Q_TAIL_W, val )
1680 
1681 #define AscGetRiscVarFreeQHead( port )        AscReadLramByte( port, ASCV_NEXTRDY_B )
1682 #define AscGetRiscVarDoneQTail( port )        AscReadLramByte( port, ASCV_DONENEXT_B )
1683 #define AscPutRiscVarFreeQHead( port, val )   AscWriteLramByte( port, ASCV_NEXTRDY_B, val )
1684 #define AscPutRiscVarDoneQTail( port, val )   AscWriteLramByte( port, ASCV_DONENEXT_B, val )
1685 
1686 #define AscGetChipIFC( port )               inp( (port)+IOP_REG_IFC )
1687 #define AscPutChipIFC( port, data )         outp( (port)+IOP_REG_IFC, data )
1688 
1689 #define AscGetChipLramAddr( port )          ( ushort )inpw( ( PortAddr )((port)+IOP_RAM_ADDR) )
1690 #define AscSetChipLramAddr( port, addr )    outpw( ( PortAddr )( (port)+IOP_RAM_ADDR ), addr )
1691 #define AscPutChipLramData( port, data )    outpw( (port)+IOP_RAM_DATA, data )
1692 #define AscGetChipLramData( port )          inpw( (port)+IOP_RAM_DATA )
1693 
1694 #define AscWriteChipSyn( port, data )       outp( (port)+IOP_SYN_OFFSET, data )
1695 #define AscReadChipSyn( port )              inp( (port)+IOP_SYN_OFFSET )
1696 
1697 #define AscWriteChipIH( port, data )        outpw( (port)+IOP_REG_IH, data )
1698 #define AscReadChipIH( port )               inpw( (port)+IOP_REG_IH )
1699 
1700 #define AscWriteChipScsiID( port, data )    outp( (port)+IOP_REG_ID, data )
1701 #define AscReadChipScsiID( port )           inp( (port)+IOP_REG_ID )
1702 
1703 #define AscGetChipDmaSpeed( port )         ( uchar )inp( (port)+IOP_DMA_SPEED )
1704 #define AscSetChipDmaSpeed( port, data )   outp( (port)+IOP_DMA_SPEED, data )
1705 #define AscGetChipQP( port )               ( uchar )inp( (port)+IOP_REG_QP )
1706 #define AscSetPCAddr( port, data )         outpw( (port)+IOP_REG_PC, data )
1707 #define AscGetPCAddr( port )               inpw( (port)+IOP_REG_PC )
1708 #define AscGetChipVerNo( port )            ( uchar )inp( (port)+IOP_VERSION )
1709 
1710 #define AscGetChipEEPCmd( port )           ( uchar )inp( (port)+IOP_EEP_CMD )
1711 #define AscSetChipEEPCmd( port, data )     outp( (port)+IOP_EEP_CMD, data )
1712 #define AscGetChipEEPData( port )          inpw( (port)+IOP_EEP_DATA )
1713 #define AscSetChipEEPData( port, data )    outpw( (port)+IOP_EEP_DATA, data )
1714 
1715 #define AscGetChipControl( port )          ( uchar )inp( (port)+IOP_CTRL )
1716 #define AscSetChipControl( port, cc_val )  outp( (port)+IOP_CTRL, cc_val )
1717 
1718 #define AscGetChipStatus( port )           ( ASC_CS_TYPE )inpw( (port)+IOP_STATUS )
1719 #define AscSetChipStatus( port, cs_val )   outpw( (port)+IOP_STATUS, cs_val )
1720 
1721 #define AscGetChipCfgLsw( port )           ( ushort )inpw( (port)+IOP_CONFIG_LOW )
1722 #define AscGetChipCfgMsw( port )           ( ushort )inpw( (port)+IOP_CONFIG_HIGH )
1723 #define AscSetChipCfgLsw( port, data )     outpw( (port)+IOP_CONFIG_LOW, data )
1724 #define AscSetChipCfgMsw( port, data )     outpw( (port)+IOP_CONFIG_HIGH, data )
1725 
1726 #define AscIsIntPending( port )           ( AscGetChipStatus( port ) & CSW_INT_PENDING )
1727 #define AscGetChipScsiID( port )          ( ( AscGetChipCfgLsw( port ) >> 8 ) & ASC_MAX_TID )
1728 
1729 #define ASC_HALT_EXTMSG_IN     ( ushort )0x8000
1730 #define ASC_HALT_CHK_CONDITION ( ushort )0x8100
1731 #define ASC_HALT_SS_QUEUE_FULL ( ushort )0x8200
1732 #define ASC_HALT_SDTR_REJECTED ( ushort )0x4000
1733 
1734 #define ASC_MAX_QNO        0xF8
1735 #define ASC_DATA_SEC_BEG   ( ushort )0x0080
1736 #define ASC_DATA_SEC_END   ( ushort )0x0080
1737 #define ASC_CODE_SEC_BEG   ( ushort )0x0080
1738 #define ASC_CODE_SEC_END   ( ushort )0x0080
1739 #define ASC_QADR_BEG       (0x4000)
1740 #define ASC_QADR_USED      ( ushort )( ASC_MAX_QNO * 64 )
1741 #define ASC_QADR_END       ( ushort )0x7FFF
1742 #define ASC_QLAST_ADR      ( ushort )0x7FC0
1743 #define ASC_QBLK_SIZE      0x40
1744 #define ASC_BIOS_DATA_QBEG 0xF8
1745 
1746 #define ASC_MIN_ACTIVE_QNO 0x01
1747 
1748 #define ASC_QLINK_END      0xFF
1749 #define ASC_EEPROM_WORDS   0x10
1750 #define ASC_MAX_MGS_LEN    0x10
1751 
1752 #define ASC_BIOS_ADDR_DEF  0xDC00
1753 #define ASC_BIOS_SIZE      0x3800
1754 #define ASC_BIOS_RAM_OFF   0x3800
1755 #define ASC_BIOS_RAM_SIZE  0x800
1756 #define ASC_BIOS_MIN_ADDR  0xC000
1757 #define ASC_BIOS_MAX_ADDR  0xEC00
1758 #define ASC_BIOS_BANK_SIZE 0x0400
1759 
1760 #define ASC_MCODE_START_ADDR  0x0080
1761 
1762 #define ASC_CFG0_HOST_INT_ON    0x0020
1763 #define ASC_CFG0_BIOS_ON        0x0040
1764 #define ASC_CFG0_VERA_BURST_ON  0x0080
1765 #define ASC_CFG0_SCSI_PARITY_ON 0x0800
1766 
1767 #define ASC_CFG1_SCSI_TARGET_ON 0x0080
1768 #define ASC_CFG1_LRAM_8BITS_ON  0x0800
1769 
1770 #define ASC_CFG_MSW_CLR_MASK    0xF0C0
1771 
1772 #define CSW_TEST1             ( ASC_CS_TYPE )0x8000
1773 #define CSW_AUTO_CONFIG       ( ASC_CS_TYPE )0x4000
1774 #define CSW_RESERVED1         ( ASC_CS_TYPE )0x2000
1775 #define CSW_IRQ_WRITTEN       ( ASC_CS_TYPE )0x1000
1776 #define CSW_33MHZ_SELECTED    ( ASC_CS_TYPE )0x0800
1777 #define CSW_TEST2             ( ASC_CS_TYPE )0x0400
1778 #define CSW_TEST3             ( ASC_CS_TYPE )0x0200
1779 #define CSW_RESERVED2         ( ASC_CS_TYPE )0x0100
1780 #define CSW_DMA_DONE          ( ASC_CS_TYPE )0x0080
1781 #define CSW_FIFO_RDY          ( ASC_CS_TYPE )0x0040
1782 
1783 #define CSW_EEP_READ_DONE     ( ASC_CS_TYPE )0x0020
1784 
1785 #define CSW_HALTED            ( ASC_CS_TYPE )0x0010
1786 #define CSW_SCSI_RESET_ACTIVE ( ASC_CS_TYPE )0x0008
1787 
1788 #define CSW_PARITY_ERR        ( ASC_CS_TYPE )0x0004
1789 #define CSW_SCSI_RESET_LATCH  ( ASC_CS_TYPE )0x0002
1790 
1791 #define CSW_INT_PENDING       ( ASC_CS_TYPE )0x0001
1792 
1793 #define CIW_INT_ACK      ( ASC_CS_TYPE )0x0100
1794 #define CIW_TEST1        ( ASC_CS_TYPE )0x0200
1795 #define CIW_TEST2        ( ASC_CS_TYPE )0x0400
1796 #define CIW_SEL_33MHZ    ( ASC_CS_TYPE )0x0800
1797 
1798 #define CIW_IRQ_ACT      ( ASC_CS_TYPE )0x1000
1799 
1800 #define CC_CHIP_RESET   ( uchar )0x80
1801 #define CC_SCSI_RESET   ( uchar )0x40
1802 #define CC_HALT         ( uchar )0x20
1803 #define CC_SINGLE_STEP  ( uchar )0x10
1804 #define CC_DMA_ABLE     ( uchar )0x08
1805 #define CC_TEST         ( uchar )0x04
1806 #define CC_BANK_ONE     ( uchar )0x02
1807 #define CC_DIAG         ( uchar )0x01
1808 
1809 #define ASC_1000_ID0W      0x04C1
1810 #define ASC_1000_ID0W_FIX  0x00C1
1811 #define ASC_1000_ID1B      0x25
1812 
1813 #define ASC_EISA_BIG_IOP_GAP   (0x1C30-0x0C50)
1814 #define ASC_EISA_SMALL_IOP_GAP (0x0020)
1815 #define ASC_EISA_MIN_IOP_ADDR  (0x0C30)
1816 #define ASC_EISA_MAX_IOP_ADDR  (0xFC50)
1817 #define ASC_EISA_REV_IOP_MASK  (0x0C83)
1818 #define ASC_EISA_PID_IOP_MASK  (0x0C80)
1819 #define ASC_EISA_CFG_IOP_MASK  (0x0C86)
1820 
1821 #define ASC_GET_EISA_SLOT( iop )  ( PortAddr )( (iop) & 0xF000 )
1822 
1823 #define ASC_EISA_ID_740    0x01745004UL
1824 #define ASC_EISA_ID_750    0x01755004UL
1825 
1826 #define INS_HALTINT        ( ushort )0x6281
1827 #define INS_HALT           ( ushort )0x6280
1828 #define INS_SINT           ( ushort )0x6200
1829 #define INS_RFLAG_WTM      ( ushort )0x7380
1830 
1831 #define ASC_MC_SAVE_CODE_WSIZE  0x500
1832 #define ASC_MC_SAVE_DATA_WSIZE  0x40
1833 
1834 typedef struct asc_mc_saved {
1835         ushort              data[ASC_MC_SAVE_DATA_WSIZE];
1836         ushort              code[ASC_MC_SAVE_CODE_WSIZE];
1837 } ASC_MC_SAVED;
1838 
1839 int                 AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
1840 int                 AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
1841 void                AscWaitEEPRead(void);
1842 void                AscWaitEEPWrite(void);
1843 ushort              AscReadEEPWord(PortAddr, uchar);
1844 ushort              AscWriteEEPWord(PortAddr, uchar, ushort);
1845 ushort              AscGetEEPConfig(PortAddr, ASCEEP_CONFIG dosfar *, ushort);
1846 int                 AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG dosfar *, ushort);
1847 int                 AscSetEEPConfig(PortAddr, ASCEEP_CONFIG dosfar *, ushort);
1848 ushort              AscEEPSum(PortAddr, uchar, uchar);
1849 
1850 int                 AscStartChip(PortAddr);
1851 int                 AscStopChip(PortAddr);
1852 void                AscSetChipIH(PortAddr, ushort);
1853 int                 AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
1854 
1855 int                 AscIsChipHalted(PortAddr);
1856 
1857 void                AscSetChipCfgDword(PortAddr, ulong);
1858 ulong               AscGetChipCfgDword(PortAddr);
1859 
1860 void                AscAckInterrupt(PortAddr);
1861 void                AscDisableInterrupt(PortAddr);
1862 void                AscEnableInterrupt(PortAddr);
1863 void                AscSetBank(PortAddr, uchar);
1864 uchar               AscGetBank(PortAddr);
1865 int                 AscResetChipAndScsiBus(PortAddr);
1866 ushort              AscGetIsaDmaChannel(PortAddr);
1867 ushort              AscSetIsaDmaChannel(PortAddr, ushort);
1868 uchar               AscSetIsaDmaSpeed(PortAddr, uchar);
1869 uchar               AscGetIsaDmaSpeed(PortAddr);
1870 
1871 uchar               AscReadLramByte(PortAddr, ushort);
1872 ushort              AscReadLramWord(PortAddr, ushort);
1873 ulong               AscReadLramDWord(PortAddr, ushort);
1874 void                AscWriteLramWord(PortAddr, ushort, ushort);
1875 void                AscWriteLramDWord(PortAddr, ushort, ulong);
1876 void                AscWriteLramByte(PortAddr, ushort, uchar);
1877 int                 AscVerWriteLramDWord(PortAddr, ushort, ulong);
1878 int                 AscVerWriteLramWord(PortAddr, ushort, ushort);
1879 int                 AscVerWriteLramByte(PortAddr, ushort, uchar);
1880 
1881 ulong               AscMemSumLramWord(PortAddr, ushort, int);
1882 void                AscMemWordSetLram(PortAddr, ushort, ushort, int);
1883 void                AscMemWordCopyToLram(PortAddr, ushort, ushort dosfar *, int);
1884 void                AscMemDWordCopyToLram(PortAddr, ushort, ulong dosfar *, int);
1885 void                AscMemWordCopyFromLram(PortAddr, ushort, ushort dosfar *, int);
1886 int                 AscMemWordCmpToLram(PortAddr, ushort, ushort dosfar *, int);
1887 
1888 ushort              AscInitAscDvcVar(ASC_DVC_VAR asc_ptr_type *);
1889 ulong               AscLoadMicroCode(PortAddr, ushort,
1890                                                                          ushort dosfar *, ushort);
1891 ushort              AscInitFromEEP(ASC_DVC_VAR asc_ptr_type *);
1892 ushort              AscInitFromAscDvcVar(ASC_DVC_VAR asc_ptr_type *);
1893 ushort              AscInitMicroCodeVar(ASC_DVC_VAR asc_ptr_type * asc_dvc);
1894 
1895 void dosfar         AscInitPollIsrCallBack(ASC_DVC_VAR asc_ptr_type *,
1896                                                                                    ASC_QDONE_INFO dosfar *);
1897 int                 AscTestExternalLram(ASC_DVC_VAR asc_ptr_type *);
1898 ushort              AscTestLramEndian(PortAddr);
1899 
1900 uchar               AscMsgOutSDTR(PortAddr, uchar, uchar);
1901 
1902 uchar               AscCalSDTRData(uchar, uchar);
1903 void                AscSetChipSDTR(PortAddr, uchar, uchar);
1904 int                 AscInitChipAllSynReg(ASC_DVC_VAR asc_ptr_type *, uchar);
1905 uchar               AscGetSynPeriodIndex(uchar);
1906 uchar               AscSynIndexToPeriod(uchar);
1907 uchar               AscAllocFreeQueue(PortAddr, uchar);
1908 uchar               AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
1909 int                 AscRiscHaltedAbortSRB(ASC_DVC_VAR asc_ptr_type *, ulong);
1910 int                 AscRiscHaltedAbortTIX(ASC_DVC_VAR asc_ptr_type *, uchar);
1911 int                 AscRiscHaltedAbortALL(ASC_DVC_VAR asc_ptr_type *);
1912 int                 AscHostReqRiscHalt(PortAddr);
1913 int                 AscStopQueueExe(PortAddr);
1914 int                 AscStartQueueExe(PortAddr);
1915 int                 AscCleanUpDiscQueue(PortAddr);
1916 int                 AscCleanUpBusyQueue(PortAddr);
1917 int                 _AscAbortTidBusyQueue(ASC_DVC_VAR asc_ptr_type *,
1918                                                                                   ASC_QDONE_INFO dosfar *, uchar);
1919 int                 _AscAbortSrbBusyQueue(ASC_DVC_VAR asc_ptr_type *,
1920                                                                                   ASC_QDONE_INFO dosfar *, ulong);
1921 int                 AscWaitTixISRDone(ASC_DVC_VAR asc_ptr_type *, uchar);
1922 int                 AscWaitISRDone(ASC_DVC_VAR asc_ptr_type *);
1923 ulong               AscGetOnePhyAddr(ASC_DVC_VAR asc_ptr_type *, uchar dosfar *, ulong);
1924 
1925 int                 AscSendScsiQueue(ASC_DVC_VAR asc_ptr_type * asc_dvc,
1926                                                                          ASC_SCSI_Q dosfar * scsiq,
1927                                                                          uchar n_q_required);
1928 int                 AscPutReadyQueue(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q dosfar *, uchar);
1929 int                 AscPutReadySgListQueue(ASC_DVC_VAR asc_ptr_type *,
1930                                                                                    ASC_SCSI_Q dosfar *, uchar);
1931 int                 AscAbortScsiIO(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q dosfar *);
1932 void                AscExeScsiIO(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q dosfar *);
1933 int                 AscSetChipSynRegAtID(PortAddr, uchar, uchar);
1934 int                 AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
1935 ushort              AscInitLram(ASC_DVC_VAR asc_ptr_type *);
1936 int                 AscReInitLram(ASC_DVC_VAR asc_ptr_type *);
1937 ushort              AscInitQLinkVar(ASC_DVC_VAR asc_ptr_type *);
1938 int                 AscSetLibErrorCode(ASC_DVC_VAR asc_ptr_type *, ushort);
1939 int                 _AscWaitQDone(PortAddr, ASC_SCSI_Q dosfar *);
1940 
1941 int                 AscEnterCritical(void);
1942 void                AscLeaveCritical(int);
1943 
1944 int                 AscIsrChipHalted(ASC_DVC_VAR asc_ptr_type *);
1945 uchar               _AscCopyLramScsiDoneQ(PortAddr, ushort,
1946                                                                                   ASC_QDONE_INFO dosfar *, ulong);
1947 int                 AscIsrQDone(ASC_DVC_VAR asc_ptr_type *);
1948 ushort              AscIsrExeBusyQueue(ASC_DVC_VAR asc_ptr_type *, uchar);
1949 int                 AscScsiSetupCmdQ(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_REQ_Q dosfar *,
1950                                                                          uchar dosfar *, ulong);
1951 
1952 int                 AscScsiInquiry(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_REQ_Q dosfar *,
1953                                                                    uchar dosfar *, int);
1954 int                 AscScsiTestUnitReady(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_REQ_Q dosfar *);
1955 int                 AscScsiStartStopUnit(ASC_DVC_VAR asc_ptr_type *,
1956                                                                                  ASC_SCSI_REQ_Q dosfar *, uchar);
1957 int                 AscScsiReadCapacity(ASC_DVC_VAR asc_ptr_type *,
1958                                                                                 ASC_SCSI_REQ_Q dosfar *,
1959                                                                                 uchar dosfar *);
1960 
1961 ulong dosfar       *swapfarbuf4(uchar dosfar *);
1962 int                 PollQueueDone(ASC_DVC_VAR asc_ptr_type *,
1963                                                                   ASC_SCSI_REQ_Q dosfar *,
1964                                                                   int);
1965 int                 PollScsiReadCapacity(ASC_DVC_VAR asc_ptr_type *,
1966                                                                                  ASC_SCSI_REQ_Q dosfar *,
1967                                                                                  ASC_CAP_INFO dosfar *);
1968 int                 PollScsiInquiry(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_REQ_Q dosfar *,
1969                                                                         uchar dosfar *, int);
1970 int                 PollScsiTestUnitReady(ASC_DVC_VAR asc_ptr_type *,
1971                                                                                   ASC_SCSI_REQ_Q dosfar *);
1972 int                 PollScsiStartUnit(ASC_DVC_VAR asc_ptr_type *,
1973                                                                           ASC_SCSI_REQ_Q dosfar *);
1974 int                 InitTestUnitReady(ASC_DVC_VAR asc_ptr_type *,
1975                                                                           ASC_SCSI_REQ_Q dosfar *);
1976 void                AscDispInquiry(uchar, uchar, ASC_SCSI_INQUIRY dosfar *);
1977 int                 AscPollQDone(ASC_DVC_VAR asc_ptr_type *,
1978                                                                  ASC_SCSI_REQ_Q dosfar *, int);
1979 
1980 int                 AscSetBIOSBank(PortAddr, int, ushort);
1981 int                 AscSetVlBIOSBank(PortAddr, int);
1982 int                 AscSetEisaBIOSBank(PortAddr, int);
1983 int                 AscSetIsaBIOSBank(PortAddr, int);
1984 
1985 int                 AscIsBiosEnabled(PortAddr, ushort);
1986 void                AscResetScsiBus(PortAddr);
1987 void                AscClrResetScsiBus(PortAddr);
1988 
1989 void                AscSingleStepChip(PortAddr);
1990 uchar               AscSetChipScsiID(PortAddr, uchar);
1991 ushort              AscGetChipBiosAddress(PortAddr, ushort);
1992 ushort              AscSetChipBiosAddress(PortAddr, ushort, ushort);
1993 uchar               AscGetChipVersion(PortAddr, ushort);
1994 ushort              AscGetChipBusType(PortAddr);
1995 
1996 PortAddr            AscSearchIOPortAddr11(PortAddr);
1997 PortAddr            AscSearchIOPortAddr100(PortAddr);
1998 int                 AscFindSignature(PortAddr);
1999 void                AscToggleIRQAct(PortAddr);
2000 int                 AscResetChip(PortAddr);
2001 void                AscClrResetChip(PortAddr);
2002 
2003 short               itos(ushort, uchar dosfar *, short, short);
2004 int                 insnchar(uchar dosfar *, short, short, ruchar, short);
2005 void                itoh(ushort, ruchar dosfar *);
2006 void                btoh(uchar, ruchar dosfar *);
2007 void                ltoh(ulong, ruchar dosfar *);
2008 uchar dosfar       *todstr(ushort, uchar dosfar *);
2009 uchar dosfar       *tohstr(ushort, uchar dosfar *);
2010 uchar dosfar       *tobhstr(uchar, uchar dosfar *);
2011 uchar dosfar       *tolhstr(ulong, uchar dosfar *);
2012 
2013 void                AscSetISAPNPWaitForKey(void);
2014 uchar               AscGetChipIRQ(PortAddr, ushort);
2015 uchar               AscSetChipIRQ(PortAddr, uchar, ushort);
2016 uchar               AscGetChipScsiCtrl(PortAddr);
2017 
2018 ushort              AscGetEisaChipCfg(PortAddr);
2019 ushort              AscGetEisaChipGpReg(PortAddr);
2020 ushort              AscSetEisaChipCfg(PortAddr, ushort);
2021 ushort              AscSetEisaChipGpReg(PortAddr, ushort);
2022 
2023 ulong               AscGetEisaProductID(PortAddr);
2024 PortAddr            AscSearchIOPortAddrEISA(PortAddr);
2025 
2026 int                 AscPollQTailSync(PortAddr);
2027 int                 AscPollQHeadSync(PortAddr);
2028 int                 AscWaitQTailSync(PortAddr);
2029 
2030 int                 _AscRestoreMicroCode(PortAddr, ASC_MC_SAVED dosfar *);
2031 
2032 int                 AscSCAM(ASC_DVC_VAR asc_ptr_type *);
2033 
2034 ushort              SwapByteOfWord(ushort word_val);
2035 ulong               SwapWordOfDWord(ulong dword_val);
2036 ulong               AdjEndianDword(ulong dword_val);
2037 
2038 int                 AscAdjEndianScsiQ(ASC_SCSI_Q dosfar *);
2039 int                 AscAdjEndianQDoneInfo(ASC_QDONE_INFO dosfar *);
2040 
2041 extern int          DvcEnterCritical(void);
2042 extern void         DvcLeaveCritical(int);
2043 
2044 extern void         DvcInPortWords(PortAddr, ushort dosfar *, int);
2045 extern void         DvcOutPortWords(PortAddr, ushort dosfar *, int);
2046 extern void         DvcOutPortDWords(PortAddr, ulong dosfar *, int);
2047 
2048 extern void         DvcSleepMilliSecond(ulong);
2049 extern void         DvcDisplayString(uchar dosfar *);
2050 extern ulong        DvcGetPhyAddr(uchar dosfar * buf_addr, ulong buf_len);
2051 extern ulong        DvcGetSGList(ASC_DVC_VAR asc_ptr_type *, uchar dosfar *, ulong,
2052                                                                  ASC_SG_HEAD dosfar *);
2053 
2054 extern void         DvcSCAMDelayMS(ulong);
2055 extern int          DvcDisableCPUInterrupt(void);
2056 extern void         DvcRestoreCPUInterrupt(int);
2057 
2058 void                DvcPutScsiQ(PortAddr, ushort, ushort dosfar *, int);
2059 void                DvcGetQinfo(PortAddr, ushort, ushort dosfar *, int);
2060 
2061 PortAddr            AscSearchIOPortAddr(PortAddr, ushort);
2062 ushort              AscInitGetConfig(ASC_DVC_VAR asc_ptr_type *);
2063 ushort              AscInitSetConfig(ASC_DVC_VAR asc_ptr_type *);
2064 ushort              AscInitAsc1000Driver(ASC_DVC_VAR asc_ptr_type *);
2065 int                 AscInitScsiTarget(ASC_DVC_VAR asc_ptr_type *,
2066                                                                           ASC_DVC_INQ_INFO dosfar *,
2067                                                                           uchar dosfar *,
2068                                                                           ASC_CAP_INFO_ARRAY dosfar *,
2069                                                                           ushort);
2070 int                 AscInitPollBegin(ASC_DVC_VAR asc_ptr_type *);
2071 int                 AscInitPollEnd(ASC_DVC_VAR asc_ptr_type *);
2072 int                 AscInitPollTarget(ASC_DVC_VAR asc_ptr_type *,
2073                                                                           ASC_SCSI_REQ_Q dosfar *,
2074                                                                           ASC_SCSI_INQUIRY dosfar *,
2075                                                                           ASC_CAP_INFO dosfar *);
2076 int                 AscExeScsiQueue(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q dosfar *);
2077 
2078 int                 AscISR(ASC_DVC_VAR asc_ptr_type *);
2079 void                AscISR_AckInterrupt(ASC_DVC_VAR asc_ptr_type *);
2080 int                 AscISR_CheckQDone(ASC_DVC_VAR asc_ptr_type *,
2081                                                                           ASC_QDONE_INFO dosfar *,
2082                                                                           uchar dosfar *);
2083 
2084 int                 AscStartUnit(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_TIX_TYPE);
2085 int                 AscStopUnit(
2086                                                                    ASC_DVC_VAR asc_ptr_type * asc_dvc,
2087                                                                    ASC_SCSI_TIX_TYPE target_ix
2088 );
2089 
2090 uint                AscGetNumOfFreeQueue(ASC_DVC_VAR asc_ptr_type *, uchar, uchar);
2091 int                 AscSgListToQueue(int);
2092 int                 AscQueueToSgList(int);
2093 int                 AscSetDvcErrorCode(ASC_DVC_VAR asc_ptr_type *, uchar);
2094 
2095 int                 AscAbortSRB(ASC_DVC_VAR asc_ptr_type *, ulong);
2096 int                 AscResetDevice(ASC_DVC_VAR asc_ptr_type *, uchar);
2097 int                 AscResetSB(ASC_DVC_VAR asc_ptr_type *);
2098 
2099 void                AscEnableIsaDma(uchar);
2100 void                AscDisableIsaDma(uchar);
2101 
2102 ulong               AscGetMaxDmaAddress(ushort);
2103 ulong               AscGetMaxDmaCount(ushort);
2104 
2105 int                 AscSaveMicroCode(ASC_DVC_VAR asc_ptr_type *, ASC_MC_SAVED dosfar *);
2106 int                 AscRestoreOldMicroCode(ASC_DVC_VAR asc_ptr_type *, ASC_MC_SAVED dosfar *);
2107 int                 AscRestoreNewMicroCode(ASC_DVC_VAR asc_ptr_type *, ASC_MC_SAVED dosfar *);
2108 
2109 /*
2110  * --- Debugging Header
2111  */
2112 
2113 #ifdef ADVANSYS_DEBUG
2114 #define STATIC
2115 #else /* ADVANSYS_DEBUG */
2116 #define STATIC static
2117 #endif /* ADVANSYS_DEBUG */
2118 
2119 
2120 /*
2121  * --- Driver Constants and Macros
2122  */
2123 
2124 #define ASC_NUM_BOARD_SUPPORTED 4
2125 #define ASC_NUM_BUS                             4
2126 
2127 /* Reference Scsi_Host hostdata */
2128 #define ASC_BOARD(host) ((struct asc_board *) &(host)->hostdata)
2129 
2130 #define NO_ISA_DMA      0xff            /* No ISA DMA Channel Used */
2131 
2132 #ifndef min
2133 #define min(a, b) (((a) < (b)) ? (a) : (b))
2134 #endif /* min */
2135 
2136 /* Asc Library return codes */
2137 #define ASC_TRUE                1
2138 #define ASC_FALSE               0
2139 #define ASC_NOERROR             1
2140 #define ASC_BUSY                0
2141 #define ASC_ERROR               (-1)
2142 
2143 /* Scsi_Cmnd function return codes */
2144 #define STATUS_BYTE(byte)       (byte)
2145 #define MSG_BYTE(byte)          ((byte) << 8)
2146 #define HOST_BYTE(byte)         ((byte) << 16)
2147 #define DRIVER_BYTE(byte)       ((byte) << 24)
2148 
2149 /* asc_enqueue() flags */
2150 #define ASC_FRONT               1
2151 #define ASC_BACK                2
2152 
2153 /* PCI configuration declarations */
2154 
2155 #define ASC_PCI_REV_A_INIT              0x01
2156 #define ASC_PCI_REV_A_DONE              0x02
2157 #define ASC_PCI_REV_B_INIT              0x04
2158 #define ASC_PCI_REV_B_DONE              0x08
2159 
2160 #define PCI_BASE_CLASS_PREDEFINED                       0x00
2161 #define PCI_BASE_CLASS_MASS_STORAGE                     0x01
2162 #define PCI_BASE_CLASS_NETWORK                          0x02
2163 #define PCI_BASE_CLASS_DISPLAY                          0x03
2164 #define PCI_BASE_CLASS_MULTIMEDIA                       0x04
2165 #define PCI_BASE_CLASS_MEMORY_CONTROLLER        0x05
2166 #define PCI_BASE_CLASS_BRIDGE_DEVICE            0x06
2167 
2168 /* MASS STORAGE */
2169 #define PCI_SUB_CLASS_SCSI_CONTROLLER                   0x00
2170 #define PCI_SUB_CLASS_IDE_CONTROLLER                    0x01
2171 #define PCI_SUB_CLASS_FLOPPY_DISK_CONTROLLER    0x02
2172 #define PCI_SUB_CLASS_IPI_BUS_CONTROLLER                0x03
2173 #define PCI_SUB_CLASS_OTHER_MASS_CONTROLLER             0x80
2174 
2175 /* NETWORK CONTROLLER */
2176 #define PCI_SUB_CLASS_ETHERNET_CONTROLLER               0x00
2177 #define PCI_SUB_CLASS_TOKEN_RING_CONTROLLER             0x01
2178 #define PCI_SUB_CLASS_FDDI_CONTROLLER                   0x02
2179 #define PCI_SUB_CLASS_OTHER_NETWORK_CONTROLLER  0x80
2180 
2181 /* DISPLAY CONTROLLER */
2182 #define PCI_SUB_CLASS_VGA_CONTROLLER                    0x00
2183 #define PCI_SUB_CLASS_XGA_CONTROLLER                    0x01
2184 #define PCI_SUB_CLASS_OTHER_DISPLAY_CONTROLLER  0x80
2185 
2186 /* MULTIMEDIA CONTROLLER */
2187 #define PCI_SUB_CLASS_VIDEO_DEVICE                              0x00
2188 #define PCI_SUB_CLASS_AUDIO_DEVICE                              0x01
2189 #define PCI_SUB_CLASS_OTHER_MULTIMEDIA_DEVICE   0x80
2190 
2191 /* MEMORY CONTROLLER */
2192 #define PCI_SUB_CLASS_RAM_CONTROLLER                    0x00
2193 #define PCI_SUB_CLASS_FLASH_CONTROLLER                  0x01
2194 #define PCI_SUB_CLASS_OTHER_MEMORY_CONTROLLER   0x80
2195 
2196 /* BRIDGE CONTROLLER */
2197 #define PCI_SUB_CLASS_HOST_BRIDGE_CONTROLLER            0x00
2198 #define PCI_SUB_CLASS_ISA_BRIDGE_CONTROLLER                     0x01
2199 #define PCI_SUB_CLASS_EISA_BRIDGE_CONTROLLER            0x02
2200 #define PCI_SUB_CLASS_MC_BRIDGE_CONTROLLER                      0x03
2201 #define PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER      0x04
2202 #define PCI_SUB_CLASS_PCMCIA_BRIDGE_CONTROLLER          0x05
2203 #define PCI_SUB_CLASS_OTHER_BRIDGE_CONTROLLER           0x80
2204 
2205 #define PCI_MAX_SLOT                    0x1F
2206 #define PCI_MAX_BUS                             0xFF
2207 #define ASC_PCI_VENDORID                0x10CD
2208 #define PCI_IOADDRESS_MASK              0xFFFE
2209 
2210 /* PCI IO Port Addresses to generate special cycle */
2211 
2212 #define PCI_CONFIG_ADDRESS_MECH1                0x0CF8
2213 #define PCI_CONFIG_DATA_MECH1                   0x0CFC
2214 
2215 #define PCI_CONFIG_FORWARD_REGISTER             0x0CFA  /* 0=type 0; 1=type 1; */
2216 
2217 #define PCI_CONFIG_BUS_NUMBER_MASK              0x00FF0000
2218 #define PCI_CONFIG_DEVICE_FUNCTION_MASK 0x0000FF00
2219 #define PCI_CONFIG_REGISTER_NUMBER_MASK 0x000000F8
2220 
2221 #define PCI_DEVICE_FOUND                                0x0000
2222 #define PCI_DEVICE_NOT_FOUND                    0xffff
2223 
2224 #define SUBCLASS_OFFSET         0x0A
2225 #define CLASSCODE_OFFSET        0x0B
2226 #define VENDORID_OFFSET         0x00
2227 #define DEVICEID_OFFSET         0x02
2228 
2229 /*
2230  * --- Driver Macros
2231  */
2232 
2233 #ifndef ADVANSYS_STATS
2234 #define ASC_STATS(counter)
2235 #define ASC_STATS_ADD(counter, count)
2236 #else /* ADVANSYS_STATS */
2237 #define ASC_STATS(counter)                              asc_stats.counter++
2238 #define ASC_STATS_ADD(counter, count)   asc_stats.counter += (count)
2239 #endif /* ADVANSYS_STATS */
2240 
2241 #ifndef ADVANSYS_DEBUG
2242 
2243 #define ASC_DBG(lvl, s)
2244 #define ASC_DBG1(lvl, s, a1)
2245 #define ASC_DBG2(lvl, s, a1, a2)
2246 #define ASC_DBG3(lvl, s, a1, a2, a3)
2247 #define ASC_DBG4(lvl, s, a1, a2, a3, a4)
2248 #define ASC_DBG_PRT_SCSI_HOST(lvl, s)
2249 #define ASC_DBG_PRT_DVC_VAR(lvl, v)
2250 #define ASC_DBG_PRT_DVC_CFG(lvl, c)
2251 #define ASC_DBG_PRT_SCSI_Q(lvl, scsiqp)
2252 #define ASC_DBG_PRT_QDONE_INFO(lvl, qdone)
2253 #define ASC_DBG_PRT_HEX(lvl, name, start, length)
2254 #define ASC_DBG_PRT_CDB(lvl, cdb, len)
2255 #define ASC_DBG_PRT_SENSE(lvl, sense, len)
2256 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
2257 #define ASC_ASSERT(a)
2258 
2259 #else /* ADVANSYS_DEBUG */
2260 
2261 /*
2262  * Debugging Message Levels:
2263  * 0: Errors Only
2264  * 1: High-Level Tracing
2265  * 2-N: Verbose Tracing
2266  */
2267 
2268 #define ASC_DBG(lvl, s) \
2269         { \
2270                 if (asc_dbglvl >= (lvl)) { \
2271                         printk(s); \
2272                 } \
2273         }
2274 
2275 #define ASC_DBG1(lvl, s, a1) \
2276         { \
2277                 if (asc_dbglvl >= (lvl)) { \
2278                         printk((s), (a1)); \
2279                 } \
2280         }
2281 
2282 #define ASC_DBG2(lvl, s, a1, a2) \
2283         { \
2284                 if (asc_dbglvl >= (lvl)) { \
2285                         printk((s), (a1), (a2)); \
2286                 } \
2287         }
2288 
2289 #define ASC_DBG3(lvl, s, a1, a2, a3) \
2290         { \
2291                 if (asc_dbglvl >= (lvl)) { \
2292                         printk((s), (a1), (a2), (a3)); \
2293                 } \
2294         }
2295 
2296 #define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
2297         { \
2298                 if (asc_dbglvl >= (lvl)) { \
2299                         printk((s), (a1), (a2), (a3), (a4)); \
2300                 } \
2301         }
2302 
2303 #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
2304         { \
2305                 if (asc_dbglvl >= (lvl)) { \
2306                         asc_prt_scsi_host(s); \
2307                 } \
2308         }
2309 
2310 #define ASC_DBG_PRT_DVC_VAR(lvl, v) \
2311         { \
2312                 if (asc_dbglvl >= (lvl)) { \
2313                         asc_prt_dvc_var(v); \
2314                 } \
2315         }
2316 
2317 #define ASC_DBG_PRT_DVC_CFG(lvl, c) \
2318         { \
2319                 if (asc_dbglvl >= (lvl)) { \
2320                         asc_prt_dvc_cfg(c); \
2321                 } \
2322         }
2323 
2324 #define ASC_DBG_PRT_SCSI_Q(lvl, scsiqp) \
2325         { \
2326                 if (asc_dbglvl >= (lvl)) { \
2327                         asc_prt_scsi_q(scsiqp); \
2328                 } \
2329         }
2330 
2331 #define ASC_DBG_PRT_QDONE_INFO(lvl, qdone) \
2332         { \
2333                 if (asc_dbglvl >= (lvl)) { \
2334                         asc_prt_qdone_info(qdone); \
2335                 } \
2336         }
2337 
2338 #define ASC_DBG_PRT_HEX(lvl, name, start, length) \
2339         { \
2340                 if (asc_dbglvl >= (lvl)) { \
2341                         asc_prt_hex((name), (start), (length)); \
2342                 } \
2343         }
2344 
2345 #define ASC_DBG_PRT_CDB(lvl, cdb, len) \
2346                 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
2347 
2348 #define ASC_DBG_PRT_SENSE(lvl, sense, len) \
2349                 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
2350 
2351 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
2352                 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
2353 
2354 #define ASC_ASSERT(a) \
2355         { \
2356                 if (!(a)) { \
2357                         printk("ASC_ASSERT() Failure: file %s, line %d\n", \
2358                                 __FILE__, __LINE__); \
2359                 } \
2360         }
2361 #endif /* ADVANSYS_DEBUG */
2362 
2363 
2364 /*
2365  * --- Driver Structures
2366  */
2367 
2368 /*
2369  * Structure allocated for each board.
2370  *
2371  * This structure is allocated by scsi_register() at the end
2372  * of the 'Scsi_Host' structure starting at the 'hostdata'
2373  * field. It is guaranteed to be allocated from DMA-able memory.
2374  */
2375 struct asc_board {
2376         /* Asc Library */
2377         ASC_DVC_VAR                      board;                                 /* Board configuration */
2378         ASC_DVC_CFG                      cfg;                                   /* Device configuration */
2379         uchar                            overrun_buf[ASC_OVERRUN_BSIZE];
2380         /* Queued Commands */
2381         ASC_SCSI_BIT_ID_TYPE pending_tidmask;           /* Pending command mask */
2382         Scsi_Cmnd                        *pending[ASC_MAX_TID];
2383         /* Target Initialization */
2384         ASC_SCSI_BIT_ID_TYPE init_tidmask;                      /* Target initialized mask */
2385         ASC_SCSI_REQ_Q           scsireqq;
2386         ASC_CAP_INFO             cap_info;
2387         ASC_SCSI_INQUIRY         inquiry;
2388 };
2389 
2390 /*
2391  * PCI configuration structures
2392  */
2393 typedef struct _PCI_DATA_
2394 {
2395         uchar   type;
2396         uchar   bus;
2397         uchar   slot;
2398         uchar   func;
2399         uchar   offset;
2400 } PCI_DATA;
2401 
2402 typedef struct _PCI_DEVICE_
2403 {
2404         ushort  vendorID;
2405         ushort  deviceID;
2406         ushort  slotNumber;
2407         ushort  slotFound;
2408         uchar   busNumber;
2409         uchar   maxBusNumber;
2410         uchar   devFunc;
2411         ushort  startSlot;
2412         ushort  endSlot;
2413         uchar   bridge;
2414         uchar   type;
2415 } PCI_DEVICE;
2416 
2417 typedef struct _PCI_CONFIG_SPACE_
2418 {
2419         ushort  vendorID;
2420         ushort  deviceID;
2421         ushort  command;
2422         ushort  status;
2423         uchar   revision;
2424         uchar   classCode[3];
2425         uchar   cacheSize;
2426         uchar   latencyTimer;
2427         uchar   headerType;
2428         uchar   bist;
2429         ulong   baseAddress[6];
2430         ushort  reserved[4];
2431         ulong   optionRomAddr;
2432         ushort  reserved2[4];
2433         uchar   irqLine;
2434         uchar   irqPin;
2435         uchar   minGnt;
2436         uchar   maxLatency;
2437 } PCI_CONFIG_SPACE;
2438 
2439 #ifdef ADVANSYS_STATS
2440 struct asc_stats {
2441         ulong   command;                /* # calls to advansys_command() */
2442         ulong   queuecommand;   /* # calls to advansys_queuecommand() */
2443         ulong   abort;                  /* # calls to advansys_abort() */
2444         ulong   reset;                  /* # calls to advansys_reset() */
2445         ulong   biosparam;              /* # calls to advansys_biosparam() */
2446         ulong   interrupt;              /* # calls to advansys_interrupt() */
2447         ulong   callback;               /* # calls asc_isr_callback() */
2448         ulong   cont_cnt;               /* # non-scatter-gather I/O requests received */
2449         ulong   cont_xfer;              /* contiguous transfer total (512 byte units) */
2450         ulong   sg_cnt;                 /* # scatter-gather I/O requests received */
2451         ulong   sg_elem;                /* scatter-gather element total */
2452         ulong   sg_xfer;                /* scatter-gather tranfer total (512 byte units) */
2453         ulong   error;                  /* # AscExeScsiQueue() ASC_ERROR returns. */
2454         /*
2455          * Number of times interrupts disabled in advansys_queuecommand() and
2456          * asc_isr_callback(), respectively. For the former indicates how many
2457          * times commands were pending when a new command was received.
2458          */
2459         ulong   cmd_disable;
2460         ulong   intr_disable;
2461         /*
2462          * Number of times asc_enqueue() called. Indicates how many ASC_BUSY
2463          * returns have occurred.
2464          */
2465         ulong   enqueue;
2466         ulong   dequeue;                /* # calls to asc_dequeue(). */
2467         /*
2468          * Number of times asc_rmqueue() called and the specified command
2469          * was found and removed.
2470          */
2471         ulong   rmqueue;
2472 } asc_stats;
2473 #endif /* ADVANSYS_STATS */
2474 
2475 
2476 /*
2477  * --- Driver Data
2478  */
2479 
2480 #ifdef LINUX_1_3
2481 struct proc_dir_entry proc_scsi_advansys =
2482 {
2483         PROC_SCSI_ADVANSYS,                             /* unsigned short low_ino */
2484         8,                                                              /* unsigned short namelen */
2485         "advansys",                                             /* const char *name */
2486         S_IFDIR | S_IRUGO | S_IXUGO,    /* mode_t mode */
2487         2                                                               /* nlink_t nlink */
2488 };
2489 #endif /* LINUX_1_3 */
2490 
2491 STATIC int asc_board_count; /* Number of boards detected in system. */
2492 STATIC struct Scsi_Host *asc_host[ASC_NUM_BOARD_SUPPORTED];
2493 STATIC Scsi_Cmnd *asc_scsi_done; /* Commands needing done function call. */
2494 
2495 STATIC ushort asc_bus[ASC_NUM_BUS] = {
2496         ASC_IS_ISA,
2497         ASC_IS_VL,
2498         ASC_IS_EISA,
2499         ASC_IS_PCI,
2500 };
2501 
2502 /*
2503  * Used with the LILO 'advansys' option to eliminate or
2504  * limit I/O port probing at boot time, cf. advansys_setup().
2505  */
2506 int asc_iopflag = ASC_FALSE;
2507 int asc_ioport[ASC_NUM_BOARD_SUPPORTED] = { 0, 0, 0, 0 };
2508 
2509 #ifdef ADVANSYS_DEBUG
2510 char *
2511 asc_bus_name[ASC_NUM_BUS] = {
2512         "ASC_IS_ISA",
2513         "ASC_IS_VL",
2514         "ASC_IS_EISA",
2515         "ASC_IS_PCI",
2516 };
2517 
2518 int             asc_dbglvl = 0;
2519 #endif /* ADVANSYS_DEBUG */
2520 
2521 
2522 /*
2523  * --- Driver Function Prototypes
2524  *
2525  * advansys.h contains function prototypes for functions global to Linux.
2526  */
2527 
2528 #ifdef LINUX_1_3
2529 STATIC int                      asc_proc_copy(off_t, off_t, char *, int , char *, int);
2530 #endif /* LINUX_1_3 */
2531 STATIC void             advansys_interrupt(int, struct pt_regs *);
2532 STATIC void             advansys_command_done(Scsi_Cmnd *);
2533 STATIC int                      asc_execute_scsi_cmnd(Scsi_Cmnd *);
2534 STATIC void             asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
2535 STATIC void                     asc_execute_pending(struct Scsi_Host *);
2536 STATIC int                      asc_init_dev(ASC_DVC_VAR *, Scsi_Cmnd *);
2537 STATIC int                      asc_srch_pci_dev(PCI_DEVICE *);
2538 STATIC uchar            asc_scan_method(PCI_DEVICE *);
2539 STATIC int                      asc_pci_find_dev(PCI_DEVICE *);
2540 STATIC void             asc_get_pci_cfg(PCI_DEVICE *, PCI_CONFIG_SPACE *);
2541 STATIC ushort           asc_get_cfg_word(PCI_DATA *);
2542 STATIC uchar            asc_get_cfg_byte(PCI_DATA *);
2543 STATIC void                     asc_enqueue(struct Scsi_Host *, Scsi_Cmnd *, int, int);
2544 STATIC Scsi_Cmnd        *asc_dequeue(struct Scsi_Host *, int);
2545 STATIC int                      asc_rmqueue(struct Scsi_Host *, Scsi_Cmnd *, int);
2546 
2547 /* XXX - Asc Library Routines not supposed to be used directly */
2548 ushort                  AscGetChipBiosAddress(PortAddr, ushort);
2549 int             AscFindSignature(PortAddr);
2550 
2551 #ifdef ADVANSYS_STATS
2552 STATIC int              asc_prt_stats(char *, int);
2553 STATIC int              asc_prt_stats_line(char *, int, char *fmt, ...);
2554 #endif /* ADVANSYS_STATS */
2555 #ifdef ADVANSYS_DEBUG
2556 STATIC void     asc_prt_scsi_host(struct Scsi_Host *);
2557 STATIC void     asc_prt_dvc_cfg(ASC_DVC_CFG *);
2558 STATIC void     asc_prt_dvc_var(ASC_DVC_VAR *);
2559 STATIC void     asc_prt_scsi_q(ASC_SCSI_Q *);
2560 STATIC void     asc_prt_qdone_info(ASC_QDONE_INFO *);
2561 STATIC void     asc_prt_hex(char *f, uchar *, int);
2562 STATIC int              interrupts_enabled(void);
2563 #endif /* ADVANSYS_DEBUG */
2564 
2565 
2566 /*
2567  * --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
2568  */
2569 
2570 #ifdef LINUX_1_3
2571 /*
2572  * advansys_proc_info() - /proc/scsi/advansys/[0-ASC_NUM_BOARD_SUPPORTED]
2573  *
2574  * *buffer: I/O buffer
2575  * **start: if inout == FALSE pointer into buffer where user read should start
2576  * offset: current offset into /proc/scsi/advansys file
2577  * length: length of buffer
2578  * hostno: Scsi_Host host_no
2579  * inout: TRUE - user is writing; FALSE - user is reading
2580  *
2581  * Return the number of bytes read from or written to
2582  * /proc/scsi/advansys file.
2583  */
2584 int
2585 advansys_proc_info(char *buffer, char **start, off_t offset, int length, 
     /* [previous][next][first][last][top][bottom][index][help] */
2586                                    int hostno, int inout)
2587 {
2588         struct Scsi_Host        *shp;
2589         int                                     i;
2590         char                            *cp;
2591         int                                     cplen;
2592         int                                     cnt;
2593         int                                     totcnt;
2594         int                                     leftlen;
2595         char                            *curbuf;
2596         off_t                           advoffset;
2597     Scsi_Device                 *scd;
2598         char                            prtbuf[480];    /* 6 lines */
2599 
2600         ASC_DBG(1, "advansys_proc_info: begin\n");
2601 
2602         /*
2603          * User write not supported.
2604          */
2605         if (inout == TRUE) {
2606                 return(-ENOSYS);
2607         }
2608 
2609         /*
2610          * User read of /proc/scsi/advansys file.
2611          */
2612 
2613         /* Find the specified board. */
2614         for (i = 0; i < asc_board_count; i++) {
2615                 if (asc_host[i]->host_no == hostno) {
2616                         break;
2617                 }
2618         }
2619         if (i == asc_board_count) {
2620                 return(-ENOENT);
2621         }
2622         shp = asc_host[i];
2623 
2624         /* Always copy read data to the beginning of the buffer. */
2625         *start = buffer;
2626 
2627         curbuf = buffer;
2628         advoffset = 0;
2629         totcnt = 0;
2630         leftlen = length;
2631 
2632         /* Get board information. */
2633         cp = (char *) advansys_info(shp);
2634         strcat(cp, "\n");
2635         cplen = strlen(cp);
2636 
2637         /* Copy board information. */
2638         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
2639         totcnt += cnt;
2640         leftlen -= cnt;
2641         if (leftlen == 0) {
2642                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2643                 return totcnt;
2644         }
2645         advoffset += cplen;
2646         curbuf += cnt;
2647 
2648         /*
2649          * Get and copy information for each device attached to the board.
2650          */
2651         cp = &prtbuf[0];
2652         sprintf(cp, "\nDevices attached to SCSI Host %d:\n", shp->host_no);
2653         cplen = strlen(cp);
2654         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
2655         totcnt += cnt;
2656         leftlen -= cnt;
2657         if (leftlen == 0) {
2658                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2659                 return totcnt;
2660         }
2661         advoffset += cplen;
2662         curbuf += cnt;
2663 
2664         cp = &prtbuf[0];
2665     for (scd = scsi_devices; scd; scd = scd->next) {
2666                 if (scd->host == shp) {
2667                 proc_print_scsidevice(scd, cp, &cplen, 0);
2668                         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
2669                         totcnt += cnt;
2670                         leftlen -= cnt;
2671                         if (leftlen == 0) {
2672                                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2673                                 return totcnt;
2674                         }
2675                         advoffset += cplen;
2676                         curbuf += cnt;
2677                 }
2678     }
2679     
2680 #ifdef ADVANSYS_STATS
2681         /*
2682          * prtbuf[] has about 6 lines worth of space. If the statistics ever
2683          * get longer than 6 lines, prtbuf[] should be increased in size. If
2684          * prtbuf[] is too small it will not be overwritten. Instead the user
2685          * just won't get all of the available statistics.
2686          */
2687         cp = &prtbuf[0];
2688         cplen = asc_prt_stats(cp, sizeof(prtbuf));
2689         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
2690         totcnt += cnt;
2691         leftlen -= cnt;
2692         if (leftlen == 0) {
2693                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2694                 return totcnt;
2695         }
2696         advoffset += cplen;
2697         curbuf += cnt;
2698 #endif /* ADVANSYS_STATS */
2699 
2700         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2701 
2702         return totcnt;
2703 }
2704 #endif /* LINUX_1_3 */
2705 
2706 
2707 /*
2708  * advansys_detect()
2709  *
2710  * Detect function for AdvanSys adapters.
2711  *
2712  * Argument is a pointer to the host driver's scsi_hosts entry.
2713  *
2714  * Return number of adapters found.
2715  *
2716  * Note: Because this function is called during system initialization
2717  * it must not call SCSI mid-level functions including scsi_malloc()
2718  * and scsi_free().
2719  */
2720 int
2721 advansys_detect(Scsi_Host_Template *tpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
2722 {
2723         static int                      detect_called = ASC_FALSE;
2724         int                                     iop;
2725         int                                     bus;
2726         struct Scsi_Host        *shp;
2727         ASC_DVC_VAR                     *boardp;
2728         int                                     ioport = 0;
2729         PCI_DEVICE                      pciDevice;
2730         PCI_CONFIG_SPACE        pciConfig;
2731         int                                     ret;
2732         extern PortAddr         _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX];
2733 
2734 
2735         if (detect_called == ASC_FALSE) {
2736                 detect_called = ASC_TRUE;
2737         } else {
2738                 printk("AdvanSys SCSI: advansys_detect() mulitple calls ignored\n");
2739                 return 0;
2740         }
2741 
2742         ASC_DBG(1, "advansys_detect: begin\n");
2743 
2744 #ifdef LINUX_1_3
2745         tpnt->proc_dir = &proc_scsi_advansys;
2746 #endif /* LINUX_1_3 */
2747 
2748 #ifdef ADVANSYS_STATS
2749         memset(&asc_stats, 0, sizeof(asc_stats));
2750 #endif /* ADVANSYS_STATS */
2751 
2752         asc_board_count = 0;
2753 
2754         /*
2755          * If I/O port probing has been modified, then verify and
2756          * clean-up the 'asc_ioport' list.
2757          */
2758         if (asc_iopflag == ASC_TRUE) {
2759                 for (ioport = 0; ioport < ASC_NUM_BOARD_SUPPORTED; ioport++) {
2760                         ASC_DBG2(1, "asdvansys_detect: asc_ioport[%d] %x\n",
2761                                 ioport, asc_ioport[ioport]);
2762                         if (asc_ioport[ioport] != 0) {
2763                                 for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX; iop++) {
2764                                         if (_asc_def_iop_base[iop] == asc_ioport[ioport]) {
2765                                                 break;
2766                                         }
2767                                 }
2768                                 if (iop == ASC_IOADR_TABLE_MAX_IX) {
2769                                         printk("AdvanSys SCSI: specified I/O Port 0x%X is invalid\n",
2770                                                 asc_ioport[ioport]);
2771                                         asc_ioport[ioport] = 0;
2772                                 }
2773                         }
2774                 }
2775                 ioport = 0;
2776         }
2777 
2778         memset(&pciDevice, 0, sizeof(PCI_DEVICE));
2779         memset(&pciConfig, 0, sizeof(PCI_CONFIG_SPACE));
2780         pciDevice.maxBusNumber = PCI_MAX_BUS;
2781         pciDevice.endSlot = PCI_MAX_SLOT;
2782 
2783         for (bus = 0; bus < ASC_NUM_BUS; bus++) {
2784 
2785                 ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n",
2786                         bus, asc_bus_name[bus]);
2787                 iop = 0;
2788 
2789                 while (asc_board_count < ASC_NUM_BOARD_SUPPORTED) {
2790 
2791                         ASC_DBG1(2, "advansys_detect: asc_board_count %d\n",
2792                                 asc_board_count);
2793 
2794                         switch (asc_bus[bus]) {
2795                         case ASC_IS_ISA:
2796                         case ASC_IS_VL:
2797                                 if (asc_iopflag == ASC_FALSE) {
2798                                         iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
2799                                 } else {
2800                                         /*
2801                                          * ISA and VL I/O port scanning has either been
2802                                          * eliminated or limited to selected ports on
2803                                          * the LILO command line, /etc/lilo.conf, or
2804                                          * by setting variables when the module was loaded.
2805                                          */
2806                                         ASC_DBG(1, "advansys_detect: I/O port scanning modified\n");
2807                                 ioport_try_again:
2808                                         iop = 0;
2809                                         for (; ioport < ASC_NUM_BOARD_SUPPORTED; ioport++) {
2810                                                 if ((iop = asc_ioport[ioport]) != 0) {
2811                                                         break;
2812                                                 }
2813                                         }
2814                                         if (iop) {
2815                                                 ASC_DBG1(1, "advansys_detect: probing I/O port %x...\n",
2816                                                         iop);
2817                                                 if (check_region(iop, ASC_IOADR_GAP) != 0) {
2818                                                         printk("AdvanSys SCSI: specified I/O Port 0x%X is busy\n", iop);
2819                                                         /* Don't try this I/O port twice. */
2820                                                         asc_ioport[ioport] = 0;
2821                                                         goto ioport_try_again;
2822                                                 } else if (AscFindSignature(iop) == ASC_FALSE) {
2823                                                         printk("AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n", iop);
2824                                                         /* Don't try this I/O port twice. */
2825                                                         asc_ioport[ioport] = 0;
2826                                                         goto ioport_try_again;
2827                                                 } else {
2828                                                         /*
2829                                                          * If this isn't an ISA board, then it must be
2830                                                          * a VL board. If currently looking an ISA
2831                                                          * board is being looked for then try for
2832                                                          * another ISA board in 'asc_ioport'.
2833                                                          */
2834                                                         if (asc_bus[bus] == ASC_IS_ISA &&
2835                                                             (AscGetChipVersion(iop, ASC_IS_ISA) &
2836                                                                  ASC_CHIP_VER_ISA_BIT) == 0) {
2837                                                                 /*
2838                                                                  * Don't clear 'asc_ioport[ioport]'. Try
2839                                                                  * this board again for VL. Increment
2840                                                                  * 'ioport' past this board.
2841                                                                  */
2842                                                                  ioport++;
2843                                                                  goto ioport_try_again;
2844                                                         }
2845                                                 }
2846                                                 /*
2847                                                  * This board appears good, don't try the I/O port
2848                                                  * again by clearing its value. Increment 'ioport'
2849                                                  * for the next iteration.
2850                                                  */
2851                                                 asc_ioport[ioport++] = 0;
2852                                         }
2853                                 }
2854                                 break;
2855 
2856                         case ASC_IS_EISA:
2857                                 iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
2858                                 break;
2859 
2860                         case ASC_IS_PCI:
2861                                         if (asc_srch_pci_dev(&pciDevice) != PCI_DEVICE_FOUND) {
2862                                                 iop = 0;
2863                                         } else {
2864                                                 ASC_DBG2(2,
2865                                                         "advansys_detect: slotFound %d, busNumber %d\n",
2866                                                         pciDevice.slotFound, pciDevice.busNumber);
2867                                                 asc_get_pci_cfg(&pciDevice, &pciConfig);
2868                                                 iop = pciConfig.baseAddress[0] & PCI_IOADDRESS_MASK;
2869                                                 ASC_DBG2(2, "advansys_detect: iop %x, irqLine %d\n",
2870                                                         iop, pciConfig.irqLine);
2871                                         }
2872                                 break;
2873 
2874                         default:
2875                                 ASC_DBG(0, "advansys_detect: unknown bus type\n");
2876                                 break;
2877                         }
2878                         ASC_DBG1(1, "advansys_detect: iop %x\n", iop);
2879 
2880                         /*
2881                          * Adapter not found, try next bus type.
2882                          */
2883                         if (iop == 0) {
2884                                 break;
2885                         }
2886 
2887                         /*
2888                          * Adapter found.
2889                          *
2890                          * Register the adapter, get its configuration, and
2891                          * initialize it.
2892                          */
2893                         ASC_DBG(2, "advansys_detect: scsi_register()\n");
2894                         shp = scsi_register(tpnt, sizeof(struct asc_board));
2895 
2896                         /* Save a pointer to the Scsi_host of each found board. */
2897                         asc_host[asc_board_count++] = shp;
2898 
2899                         /* Initialize private per board data */
2900                         memset(ASC_BOARD(shp), 0, sizeof(struct asc_board));
2901                         boardp = &ASC_BOARD(shp)->board;
2902                         boardp->cfg = &ASC_BOARD(shp)->cfg;
2903                         boardp->cfg->overrun_buf = &ASC_BOARD(shp)->overrun_buf[0];
2904                         boardp->iop_base = iop;
2905 
2906                         /*
2907                          * Set the board bus type and PCI IRQ for AscInitGetConfig().
2908                          */
2909                         boardp->bus_type = asc_bus[bus];
2910                         switch (boardp->bus_type) {
2911                         case ASC_IS_ISA:
2912                                 shp->unchecked_isa_dma = TRUE;
2913                                 break;
2914                         case ASC_IS_EISA:
2915                                 shp->unchecked_isa_dma = FALSE;
2916                                 break;
2917                         case ASC_IS_VL:
2918                                 shp->unchecked_isa_dma = FALSE;
2919                                 break;
2920                         case ASC_IS_PCI:
2921                                 shp->irq = boardp->irq_no = pciConfig.irqLine;
2922                                 boardp->cfg->pci_device_id = pciConfig.deviceID;
2923                                 shp->unchecked_isa_dma = FALSE;
2924                                 break;
2925                         default:
2926                                 ASC_DBG(0, "advansys_detect: unknown adapter type");
2927                                 shp->unchecked_isa_dma = TRUE;
2928                                 break;
2929                         }
2930 
2931                         /*
2932                          * Get the board configuration.  AscInitGetConfig() may change
2933                          * the board's bus_type value. The asc_bus[bus] value should no
2934                          * longer be used.
2935                          */
2936                         ASC_DBG(2, "advansys_detect: AscInitGetConfig()\n");
2937                         switch(ret = AscInitGetConfig(boardp)) {
2938                         case 0: /* No error */
2939                                 break;
2940                         case ASC_WARN_IO_PORT_ROTATE:
2941                                 ASC_DBG(0, "AscInitGetConfig: I/O port address modified\n");
2942                                 break;
2943                         case ASC_WARN_EEPROM_CHKSUM:
2944                                 ASC_DBG(0, "AscInitGetConfig: EEPROM checksum error\n");
2945                                 break;
2946                         case ASC_WARN_IRQ_MODIFIED:
2947                                 ASC_DBG(0, "AscInitGetConfig: IRQ modified\n");
2948                                 break;
2949                         case ASC_WARN_CMD_QNG_CONFLICT:
2950                                 ASC_DBG(0,
2951                                         "AscInitGetConfig: Tag queuing enabled w/o disconnects\n");
2952                                 break;
2953                         default:
2954                                 ASC_DBG1(0, "AscInitGetConfig: Unknown warning: %x\n", ret);
2955                                 break;
2956                         }
2957                         if (boardp->err_code != 0) {
2958                                 ASC_DBG2(0,
2959                                         "AscInitGetConfig: error: init_state %x, err_code %x\n",
2960                                         boardp->init_state, boardp->err_code);
2961                                 scsi_unregister(shp);
2962                                 asc_board_count--;
2963                                 continue;
2964                         }
2965 
2966                         /*
2967                          * Modify board configuration.
2968                          */
2969                         boardp->isr_callback = (Ptr2Func) asc_isr_callback;
2970                         boardp->exe_callback = (Ptr2Func) NULL;
2971 
2972                         ASC_DBG(2, "advansys_detect: AscInitSetConfig()\n");
2973                         switch (ret = AscInitSetConfig(boardp)) {
2974                         case 0: /* No error. */
2975                                 break;
2976                         case ASC_WARN_IO_PORT_ROTATE:
2977                                 ASC_DBG(0, "AscInitSetConfig: I/O port address modified\n");
2978                                 break;
2979                         case ASC_WARN_EEPROM_CHKSUM:
2980                                 ASC_DBG(0, "AscInitSetConfig: EEPROM checksum error\n");
2981                                 break;
2982                         case ASC_WARN_IRQ_MODIFIED:
2983                                 ASC_DBG(0, "AscInitSetConfig: IRQ modified\n");
2984                                 break;
2985                         case ASC_WARN_CMD_QNG_CONFLICT:
2986                                 ASC_DBG(0, "AscInitSetConfig: Tag queuing w/o disconnects\n");
2987                                 break;
2988                         default:
2989                                 ASC_DBG1(0, "AscInitSetConfig: Unknown warning: %x\n", ret);
2990                                 break;
2991                         }
2992                         if (boardp->err_code != 0) {
2993                                 ASC_DBG2(0,
2994                                         "AscInitSetConfig: error: init_state %x, err_code %x\n",
2995                                         boardp->init_state, boardp->err_code);
2996                                 scsi_unregister(shp);
2997                                 asc_board_count--;
2998                                 continue;
2999                         }
3000 
3001                         /*
3002                          * Finish initializing the 'Scsi_Host' structure.
3003                          */
3004 
3005                         /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
3006                         if (boardp->bus_type != ASC_IS_PCI) {
3007                                 shp->irq = boardp->irq_no;
3008                         }
3009 
3010                         shp->io_port = boardp->iop_base;
3011                         shp->n_io_port = ASC_IOADR_GAP;
3012                         shp->this_id = boardp->cfg->chip_scsi_id;
3013 
3014                         /* Maximum number of queues this adapter can handle. */
3015                         shp->can_queue = boardp->max_total_qng;
3016 
3017                         /*
3018                          * XXX - Command queuing limits are maintained per target
3019                          * by AdvanSys adapters. Set 'cmd_per_lun' to the minimum
3020                          * value of the all the target settings for the adapter.
3021                          *
3022                          * For now set 'cmd_per_lun' to 'max_total_qng'. This
3023                          * value should be adjusted every time a new device is
3024                          * found in asc_init_dev().
3025                          *
3026                          * XXX - memory allocation is done by the mid-level scsi
3027                          * driver based on 'cmd_per_lun'. If 'sg_tablesize' is too large
3028                          * allocation failures can occur in scsi_register_host().
3029                          * A 'Scsi_Cmnd' structure is pre-allocated for each command
3030                          * also DMA memory is reserved. Set it artificially low for now.
3031                          *
3032                          * shp->cmd_per_lun = boardp->max_total_qng;
3033                          */
3034 #ifdef MODULE
3035                         shp->cmd_per_lun = 1;
3036 #else /* MODULE */
3037                         shp->cmd_per_lun = 4;
3038 #endif /* MODULE */
3039                         ASC_DBG1(1, "advansys_detect: cmd_per_lun: %d\n", shp->cmd_per_lun);
3040                         
3041                         /* Maximum number of scatter-gather elements adapter can handle. */
3042                         /*
3043                          * XXX - memory allocation is done by the mid-level scsi
3044                          * driver based on sg_tablesize. If 'sg_tablesize' is too large
3045                          * allocation failures can occur in scsi_register_host().
3046                          */
3047 #ifdef MODULE
3048                         shp->sg_tablesize = 8;
3049 #else /* MODULE */
3050                         shp->sg_tablesize = ASC_MAX_SG_LIST;
3051 #endif /* MODULE */
3052                         ASC_DBG1(1, "advansys_detect: sg_tablesize: %d\n",
3053                                 shp->sg_tablesize);
3054 
3055                         /* BIOS start address. */
3056                         shp->base = (char *) ((ulong) AscGetChipBiosAddress(
3057                                                                                                 boardp->iop_base,
3058                                                                                                 boardp->bus_type));
3059 
3060                         /*
3061                          * Register Board Resources - I/O Port, DMA, IRQ
3062                          */
3063 
3064                         /* Register I/O port range */
3065                         ASC_DBG(2, "advansys_detect: request_region()\n");
3066                         request_region(shp->io_port, shp->n_io_port, "advansys");
3067 
3068                         /* Register DMA channel for ISA bus. */
3069                         if ((boardp->bus_type & ASC_IS_ISA) == 0) {
3070                                 shp->dma_channel = NO_ISA_DMA;
3071                         } else {
3072                                 shp->dma_channel = boardp->cfg->isa_dma_channel;
3073                                 if ((ret = request_dma(shp->dma_channel, "advansys")) != 0) {
3074                                         ASC_DBG2(0, "advansys_detect: request_dma() %d failed %d\n",
3075                                                 shp->dma_channel, ret);
3076                                         release_region(shp->io_port, shp->n_io_port);
3077                                         scsi_unregister(shp);
3078                                         asc_board_count--;
3079                                         continue;
3080                                 }
3081                                 AscEnableIsaDma(shp->dma_channel);
3082                         }
3083 
3084                         /* Register IRQ Number. */
3085                         ASC_DBG1(2, "advansys_detect: request_irq() %d\n", shp->irq);
3086                         if ((ret = request_irq(shp->irq, advansys_interrupt,
3087                                                                 SA_INTERRUPT, "advansys")) != 0) {
3088                                 ASC_DBG1(0, "advansys_detect: request_irq() failed %d\n", ret);
3089                                 release_region(shp->io_port, shp->n_io_port);
3090                                 if (shp->dma_channel != NO_ISA_DMA) {
3091                                         free_dma(shp->dma_channel);
3092                                 }
3093                                 scsi_unregister(shp);
3094                                 asc_board_count--;
3095                                 continue;
3096                         }
3097 
3098                         /*
3099                          * Initialize board RISC chip and enable interrupts.
3100                          */
3101                         ASC_DBG(2, "advansys_detect: AscInitAsc1000Driver()\n");
3102                         if (AscInitAsc1000Driver(boardp)) {
3103                                 ASC_DBG2(0,
3104                                         "AscInitAsc1000Driver: error: init_state %x, err_code %x\n",
3105                                         boardp->init_state, boardp->err_code);
3106                                 release_region(shp->io_port, shp->n_io_port);
3107                                 if (shp->dma_channel != NO_ISA_DMA) {
3108                                         free_dma(shp->dma_channel);
3109                                 }
3110                                 free_irq(shp->irq);
3111                                 scsi_unregister(shp);
3112                                 asc_board_count--;
3113                                 continue;
3114                         }
3115                         ASC_DBG_PRT_SCSI_HOST(2, shp);
3116                 }
3117         }
3118 
3119         ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n", asc_board_count);
3120         return asc_board_count;
3121 }
3122 
3123 /*
3124  * advansys_release()
3125  *
3126  * Release resources allocated for a single AdvanSys adapter.
3127  */
3128 int
3129 advansys_release(struct Scsi_Host *shp)
     /* [previous][next][first][last][top][bottom][index][help] */
3130 {
3131         ASC_DBG(1, "advansys_release: begin\n");
3132         free_irq(shp->irq);
3133         if (shp->dma_channel != NO_ISA_DMA) {
3134                 ASC_DBG(1, "advansys_release: free_dma()\n");
3135                 free_dma(shp->dma_channel);
3136         }
3137         release_region(shp->io_port, shp->n_io_port);
3138         scsi_unregister(shp);
3139         ASC_DBG(1, "advansys_release: end\n");
3140         return 0;
3141 }
3142 
3143 /*
3144  * advansys_info()
3145  *
3146  * Return suitable for printing on the console with the argument
3147  * adapter's configuration information.
3148  */
3149 const char *
3150 advansys_info(struct Scsi_Host *shp)
     /* [previous][next][first][last][top][bottom][index][help] */
3151 {
3152         static char     info[128];
3153         ASC_DVC_VAR             *boardp;
3154         char                    *busname;
3155 
3156         boardp = &ASC_BOARD(shp)->board;
3157         ASC_DBG(1, "advansys_info: begin\n");
3158         if (boardp->bus_type & ASC_IS_ISA) {
3159                 sprintf(info,
3160                         "AdvanSys SCSI %s: ISA (%u CDB): BIOS %X, IO %X-%X, IRQ %u, DMA %u",
3161                         ASC_VERSION, ASC_BOARD(shp)->board.max_total_qng,
3162                         (unsigned) shp->base, shp->io_port,
3163                         shp->io_port + (shp->n_io_port - 1), shp->irq, shp->dma_channel);
3164         } else {
3165                 switch (boardp->bus_type) {
3166                 case ASC_IS_EISA:
3167                         busname = "EISA";
3168                         break;
3169                 case ASC_IS_VL:
3170                         busname = "VL";
3171                         break;
3172                 case ASC_IS_PCI:
3173                         busname = "PCI";
3174                         break;
3175                 default:
3176                         busname = "?";
3177                         ASC_DBG1(0, "advansys_info: unknown bus type %d\n",
3178                                 boardp->bus_type);
3179                         break;
3180                 }
3181                 /* No DMA channel for non-ISA busses. */
3182                 sprintf(info,
3183                         "AdvanSys SCSI %s: %s (%u CDB): BIOS %X, IO %X-%X, IRQ %u",
3184                         ASC_VERSION, busname, ASC_BOARD(shp)->board.max_total_qng,
3185                         (unsigned) shp->base, shp->io_port,
3186                         shp->io_port + (shp->n_io_port - 1), shp->irq);
3187         }
3188         ASC_DBG(1, "advansys_info: end\n");
3189         return info;
3190 }
3191 
3192 /*
3193  * advansys_command()
3194  *
3195  * Polled-I/O. Apparently host driver shouldn't return until
3196  * command is finished.
3197  *
3198  * XXX - Can host driver block here instead of spinning on command status?
3199  */
3200 int
3201 advansys_command(Scsi_Cmnd *scp)
     /* [previous][next][first][last][top][bottom][index][help] */
3202 {
3203         ASC_DBG1(1, "advansys_command: scp %x\n", (unsigned) scp);
3204         ASC_STATS(command);
3205         scp->SCp.Status = 0; /* Set to a known state */
3206         advansys_queuecommand(scp, advansys_command_done);
3207         while (scp->SCp.Status == 0) {
3208                 continue;
3209         }
3210         ASC_DBG1(1, "advansys_command: result %x\n", scp->result);
3211         return scp->result;
3212 }
3213 
3214 /*
3215  * advansys_queuecommand()
3216  *
3217  * This function always returns 0. Command return status is saved
3218  * in the 'scp' result field.
3219  */
3220 int
3221 advansys_queuecommand(Scsi_Cmnd *scp, void (*done)(Scsi_Cmnd *))
     /* [previous][next][first][last][top][bottom][index][help] */
3222 {
3223         struct Scsi_Host                *shp;
3224         int                                             flags = 0;
3225         int                                             interrupts_disabled;
3226 
3227         ASC_STATS(queuecommand);
3228         shp = scp->host;
3229 
3230 #ifdef LINUX_1_2
3231         /*
3232          * For LINUX_1_3, if statistics are enabled they can be accessed
3233          * by reading /proc/scsi/advansys/[0-9].
3234          */
3235 #ifdef ADVANSYS_STATS_1_2_PRINT
3236         /* Display statistics every 10000 commands. */
3237         if ((asc_stats.queuecommand % 10000) == 0) {
3238                 printk("\n");
3239                 (void) asc_prt_stats(NULL, 0);
3240                 printk("\n");
3241         }
3242 #endif /* ADVANSYS_STATS_1_2_PRINT */
3243 #endif /* LINUX_1_2 */
3244 
3245         /*
3246          * If there are any pending commands for this board before trying
3247          * to execute them, disable interrupts to preserve request ordering.
3248          *
3249          * The typical case will be no pending commands and interrupts
3250          * not disabled.
3251          */
3252         if (ASC_BOARD(shp)->pending_tidmask == 0) {
3253                 interrupts_disabled = ASC_FALSE;
3254         } else {
3255                 ASC_STATS(cmd_disable);
3256                 /* Disable interrupts */
3257                 interrupts_disabled = ASC_TRUE;
3258                 save_flags(flags);
3259                 cli();
3260                 ASC_DBG1(1, "advansys_queuecommand: asc_execute_pending() %x\n",
3261                         ASC_BOARD(shp)->pending_tidmask);
3262                 asc_execute_pending(shp);
3263         }
3264 
3265         /*
3266          * Save the function pointer to Linux mid-level 'done' function and
3267          * execute the command.
3268          */
3269         scp->scsi_done = done;
3270         if (asc_execute_scsi_cmnd(scp) == ASC_BUSY) {
3271                 if (interrupts_disabled == ASC_FALSE) {
3272                         save_flags(flags);
3273                         cli();
3274                         interrupts_disabled = ASC_TRUE;
3275                 }
3276                 asc_enqueue(shp, scp, scp->target, ASC_BACK);
3277         }
3278 
3279         if (interrupts_disabled == ASC_TRUE) {
3280                 restore_flags(flags);
3281         }
3282 
3283         return 0;
3284 }
3285 
3286 /*
3287  * advansys_abort()
3288  *
3289  * Abort the specified command and reset the device
3290  * associated with the command 'scp'.
3291  */
3292 int
3293 advansys_abort(Scsi_Cmnd *scp)
     /* [previous][next][first][last][top][bottom][index][help] */
3294 {
3295         ASC_DVC_VAR             *boardp;
3296         int                             flags;
3297         int                             ret;
3298 
3299         ASC_DBG1(1, "advansys_abort: scp %x\n", (unsigned) scp);
3300         save_flags(flags);
3301         cli();
3302         ASC_STATS(abort);
3303         if (scp->host == NULL) {
3304                 scp->result = HOST_BYTE(DID_ERROR);
3305                 ret = SCSI_ABORT_ERROR;
3306         } else if (asc_rmqueue(scp->host, scp, scp->target) == ASC_TRUE) {
3307                 scp->result = HOST_BYTE(DID_ABORT);
3308                 ret = SCSI_ABORT_SUCCESS;
3309                 (void) AscResetDevice(&ASC_BOARD(scp->host)->board, scp->target);
3310         } else {
3311                 /* Must enable interrupts for AscAbortSRB() */
3312                 sti();
3313                 boardp = &ASC_BOARD(scp->host)->board;
3314                 scp->result = HOST_BYTE(DID_ABORT);
3315                 switch (AscAbortSRB(boardp, (ulong) scp)) {
3316                 case ASC_TRUE:
3317                         /* asc_isr_callback() will be called */
3318                         ASC_DBG(1, "advansys_abort: AscAbortSRB() TRUE\n");
3319                         ret = SCSI_ABORT_PENDING;
3320                         break;
3321                 case ASC_FALSE:
3322                         /* Request has apparently already completed. */
3323                         ASC_DBG(1, "advansys_abort: AscAbortSRB() FALSE\n");
3324                         ret = SCSI_ABORT_NOT_RUNNING;
3325                         break;
3326                 case ASC_ERROR:
3327                 default:
3328                         ASC_DBG(1, "advansys_abort: AscAbortSRB() ERROR\n");
3329                         ret = SCSI_ABORT_ERROR;
3330                         break;
3331                 }
3332                 (void) AscResetDevice(boardp, scp->target);
3333         }
3334         restore_flags(flags);
3335         ASC_DBG1(1, "advansys_abort: ret %d\n", ret);
3336         return ret;
3337 }
3338 
3339 /*
3340  * advansys_reset()
3341  *
3342  * Reset all devices and the SCSI bus for the board
3343  * associated with 'scp'.
3344  */
3345 int
3346 advansys_reset(Scsi_Cmnd *scp)
     /* [previous][next][first][last][top][bottom][index][help] */
3347 {
3348         ASC_DVC_VAR             *boardp;
3349         int                             flags;
3350         Scsi_Cmnd               *tscp;
3351         int                             i;
3352         int                             ret;
3353 
3354         ASC_DBG1(1, "advansys_reset: %x\n", (unsigned) scp);
3355         save_flags(flags);
3356         cli();
3357         ASC_STATS(reset);
3358         if (scp->host == NULL) {
3359                 scp->result = HOST_BYTE(DID_ERROR);
3360                 ret = SCSI_RESET_ERROR;
3361         } else {
3362                 /* Remove any pending commands, set DID_RESET, and done them.  */
3363                 for (i = 0; i < ASC_MAX_TID; i++) {
3364                         while ((tscp = asc_dequeue(scp->host, i)) != NULL) {
3365                                 tscp->result = HOST_BYTE(DID_RESET);
3366                                 tscp->scsi_done(tscp);
3367                         }
3368                 }
3369                 /* Must enable interrupts for AscResetSB() */
3370                 sti();
3371                 boardp = &ASC_BOARD(scp->host)->board;
3372                 scp->result = HOST_BYTE(DID_RESET);
3373                 switch (AscResetSB(boardp)) {
3374                 case ASC_TRUE:
3375                         ASC_DBG(1, "advansys_abort: AscResetSB() TRUE\n");
3376                         ret = SCSI_RESET_SUCCESS;
3377                         break;
3378                 case ASC_ERROR:
3379                 default:
3380                         ASC_DBG(1, "advansys_abort: AscResetSB() ERROR\n");
3381                         ret = SCSI_RESET_ERROR;
3382                         break;
3383                 }
3384         }
3385         restore_flags(flags);
3386         ASC_DBG1(1, "advansys_reset: ret %d", ret);
3387         return ret;
3388 }
3389 
3390 /*
3391  * advansys_biosparam()
3392  *
3393  * Translate disk drive geometry if the "BIOS greater than 1 GB"
3394  * support is enabled for a drive.
3395  *
3396  * ip (information pointer) is an int array with the following definition:
3397  * ip[0]: heads
3398  * ip[1]: sectors
3399  * ip[2]: cylinders
3400  */
3401 int
3402 #ifdef LINUX_1_2
3403 advansys_biosparam(Disk *dp, int dep, int ip[])
     /* [previous][next][first][last][top][bottom][index][help] */
3404 #else /* LINUX_1_3 */
3405 advansys_biosparam(Disk *dp, kdev_t dep, int ip[])
3406 #endif /* LINUX_1_3 */
3407 {
3408         ASC_DBG(1, "advansys_biosparam: begin\n");
3409         ASC_STATS(biosparam);
3410         if ((ASC_BOARD(dp->device->host)->board.dvc_cntl & ASC_CNTL_BIOS_GT_1GB) &&
3411                 dp->capacity > 0x200000) {
3412                         ip[0] = 255;
3413                         ip[1] = 64;
3414         } else {
3415                         ip[0] = 64;
3416                         ip[1] = 32;
3417         }
3418         ip[2] = dp->capacity / (ip[0] * ip[1]);
3419         ASC_DBG(1, "advansys_biosparam: end\n");
3420         return 0;
3421 }
3422 
3423 /*
3424  * advansys_setup()
3425  *
3426  * This function is called from init/main.c at boot time.
3427  * It it passed LILO parameters that can be set from the
3428  * LILO command line or in /etc/lilo.conf.
3429  *
3430  * It is used by the AdvanSys driver to either disable I/O
3431  * port scanning or to limit scanning to 1 - 4 I/O ports.
3432  * Regardless of the option setting EISA and PCI boards
3433  * will still be searched for and detected. This option
3434  * only affects searching for ISA and VL boards.
3435  *
3436  * If ADVANSYS_DEBUG is defined the driver debug level may
3437  * be set using the 5th (ASC_NUM_BOARD_SUPPORTED + 1) I/O Port.
3438  *
3439  * Examples:
3440  * 1. Eliminate I/O port scanning:
3441  *              boot: linux advansys=
3442  *       or
3443  *              boot: linux advansys=0x0
3444  * 2. Limit I/O port scanning to one I/O port:
3445  *              boot: linux advansys=0x110
3446  * 3. Limit I/O port scanning to four I/O ports:
3447  *              boot: linux advansys=0x110,0x210,0x230,0x330
3448  * 4. If ADVANSYS_DEBUG, limit I/O port scanning to four I/O ports and
3449  *    set the driver debug level to 2.
3450  *              boot: linux advansys=0x110,0x210,0x230,0x330,0xdeb2
3451  *
3452  * ints[0] - number of arguments
3453  * ints[1] - first argument
3454  * ints[2] - second argument
3455  * ...
3456  */
3457 void
3458 advansys_setup(char *str, int *ints)
     /* [previous][next][first][last][top][bottom][index][help] */
3459 {
3460         int     i;
3461 
3462         if (asc_iopflag == ASC_TRUE) {
3463                 printk("AdvanSys SCSI: 'advansys' LILO option may appear only once\n");
3464                 return;
3465         }
3466 
3467         asc_iopflag = ASC_TRUE;
3468 
3469         if (ints[0] > ASC_NUM_BOARD_SUPPORTED) {
3470 #ifdef ADVANSYS_DEBUG
3471                 if ((ints[0] == ASC_NUM_BOARD_SUPPORTED + 1) &&
3472                     (ints[ASC_NUM_BOARD_SUPPORTED + 1] >> 4 == 0xdeb)) {
3473                         asc_dbglvl = ints[ASC_NUM_BOARD_SUPPORTED + 1] & 0xf;
3474                 } else {
3475 #endif /* ADVANSYS_DEBUG */
3476                         printk("AdvanSys SCSI: only %d I/O ports accepted\n",
3477                                 ASC_NUM_BOARD_SUPPORTED);
3478 #ifdef ADVANSYS_DEBUG
3479                 }
3480 #endif /* ADVANSYS_DEBUG */
3481         }
3482 
3483 #ifdef ADVANSYS_DEBUG
3484         ASC_DBG1(1, "advansys_setup: ints[0] %d\n", ints[0]);
3485         for (i = 1; i < ints[0]; i++) {
3486                 ASC_DBG2(1, " ints[%d] %x", i, ints[i]);
3487         }
3488         ASC_DBG(1, "\n");
3489 #endif /* ADVANSYS_DEBUG */
3490 
3491         for (i = 1; i <= ints[0] && i <= ASC_NUM_BOARD_SUPPORTED; i++) {
3492                 asc_ioport[i-1] = ints[i];
3493                 ASC_DBG2(1, "advansys_setup: asc_ioport[%d] %x\n",
3494                         i - 1, asc_ioport[i-1]);
3495         }
3496 }
3497 
3498 
3499 /*
3500  * --- Loadable Driver Support
3501  */
3502 
3503 #ifdef MODULE
3504 Scsi_Host_Template driver_template = ADVANSYS;
3505 # include "scsi_module.c"
3506 #endif /* MODULE */
3507 
3508 
3509 /*
3510  * --- Miscellaneous Driver Functions
3511  */
3512 
3513 #ifdef LINUX_1_3
3514 /*
3515  * asc_proc_copy() 
3516  *
3517  * Copy proc information to a read buffer considering the current read
3518  * offset in the file and the remaining space in the read buffer.
3519  */
3520 STATIC int
3521 asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
     /* [previous][next][first][last][top][bottom][index][help] */
3522                           char *cp, int cplen)
3523 {
3524         int cnt = 0;
3525         
3526         ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
3527                         (unsigned) offset, (unsigned) advoffset, cplen);
3528         if (offset <= advoffset) {
3529                 /* Read offset below current offset, copy everything. */
3530                 cnt = min(cplen, leftlen);
3531                 ASC_DBG3(2, "asc_proc_copy: curbuf %x, cp %x, cnt %d\n",
3532                                 (unsigned) curbuf, (unsigned) cp, cnt);
3533                 memcpy(curbuf, cp, cnt);
3534         } else if (offset < advoffset + cplen) {
3535                 /* Read offset within current range, partial copy. */
3536                 cnt = (advoffset + cplen) - offset;
3537                 cp = (cp + cplen) - cnt;
3538                 cnt = min(cnt, leftlen);
3539                 ASC_DBG3(2, "asc_proc_copy: curbuf %x, cp %x, cnt %d\n",
3540                                 (unsigned) curbuf, (unsigned) cp, cnt);
3541                 memcpy(curbuf, cp, cnt);
3542         }
3543         return cnt;
3544 }
3545 #endif /* LINUX_1_3 */
3546 
3547 /*
3548  * First-level interrupt handler.
3549  */
3550 STATIC void
3551 advansys_interrupt(int irq, struct pt_regs *regs)
     /* [previous][next][first][last][top][bottom][index][help] */
3552 {
3553         int                     i;
3554         int                     flags;
3555         Scsi_Cmnd       *scp;
3556         Scsi_Cmnd       *tscp;
3557 
3558         /* Disable interrupts, if the aren't already disabled. */
3559         save_flags(flags);
3560         cli();
3561 
3562         ASC_DBG(1, "advansys_interrupt: begin\n");
3563         ASC_STATS(interrupt);
3564         /*
3565          * Check for interrupts on all boards.
3566          * AscISR() will call asc_isr_callback().
3567          */
3568         for (i = 0; i < asc_board_count; i++) {
3569                 while (AscIsIntPending(asc_host[i]->io_port)) {
3570                         ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
3571                         AscISR(&ASC_BOARD(asc_host[i])->board);
3572                 }
3573         }
3574         ASC_DBG(1, "advansys_interrupt: end\n");
3575 
3576         /*
3577          * While interrupts are still disabled save the list of requests that
3578          * need their done function called. After re-enabling interrupts call
3579          * the done function which may re-enable interrupts anyway.
3580          */
3581         if ((scp = asc_scsi_done) != NULL) {
3582                 asc_scsi_done = NULL;
3583         }
3584 
3585         /* Re-enable interrupts, if they were enabled on entry. */
3586         restore_flags(flags);
3587 
3588         while (scp) {
3589                 tscp = (Scsi_Cmnd *) scp->host_scribble;
3590                 scp->scsi_done(scp);
3591                 scp = tscp;
3592         }
3593 
3594         return;
3595 }
3596 
3597 /*
3598  * Function used only with polled I/O requests that are initiated by
3599  * advansys_command().
3600  */
3601 STATIC void
3602 advansys_command_done(Scsi_Cmnd *scp)
     /* [previous][next][first][last][top][bottom][index][help] */
3603 {
3604         ASC_DBG1(1, "advansys_command_done: scp %x\n", (unsigned) scp);
3605         scp->SCp.Status = 1;
3606 }
3607 
3608 /*
3609  * Execute a single 'Scsi_Cmnd'.
3610  *
3611  * The function 'done' is called when the request has been completed.
3612  *
3613  * Scsi_Cmnd:
3614  *
3615  *  host - board controlling device
3616  *  device - device to send command
3617  *  target - target of device
3618  *  lun - lun of device
3619  *  cmd_len - length of SCSI CDB
3620  *      cmnd - buffer for SCSI 8, 10, or 12 byte CDB
3621  *  use_sg - if non-zero indicates scatter-gather request with use_sg elements
3622  *
3623  *  if (use_sg == 0)
3624  *              request_buffer - buffer address for request
3625  *              request_bufflen - length of request buffer
3626  *  else
3627  *              request_buffer - pointer to scatterlist structure
3628  *
3629  *  sense_buffer - sense command buffer
3630  *
3631  *  result (4 bytes of an int):
3632  *   Byte Meaning
3633  *   0    SCSI Status Byte Code
3634  *   1    SCSI One Byte Message Code
3635  *   2    Host Error Code
3636  *   3    Mid-Level Error Code
3637  *
3638  *  host driver fields:
3639  *  SCp - Scsi_Pointer used for command processing status
3640  *  scsi_done - used to save caller's done function
3641  *      host_scribble - used for pointer to another Scsi_Cmnd
3642  *
3643  * If this function returns ASC_NOERROR or ASC_ERROR the done
3644  * function has been called. If ASC_BUSY is returned the request
3645  * must be enqueued by the caller and re-tried later.
3646  */
3647 STATIC int
3648 asc_execute_scsi_cmnd(Scsi_Cmnd *scp)
     /* [previous][next][first][last][top][bottom][index][help] */
3649 {
3650         ASC_DVC_VAR             *boardp;
3651         ASC_SCSI_Q              scsiq;
3652         ASC_SG_HEAD             sghead;
3653         int                             ret;
3654 
3655         ASC_DBG2(1, "asc_execute_scsi_cmnd: scp %x, done %x\n",
3656                 (unsigned) scp, (unsigned) scp->scsi_done);
3657 
3658         boardp = &ASC_BOARD(scp->host)->board;
3659 
3660         /*
3661          * If this is the first command, then initialize the device. If
3662          * no device is found set 'DID_BAD_TARGET' and return.
3663          */
3664         if ((ASC_BOARD(scp->host)->init_tidmask &
3665                  ASC_TIX_TO_TARGET_ID(scp->target)) == 0) {
3666                 if (asc_init_dev(boardp, scp) == ASC_FALSE) {
3667                         scp->result = HOST_BYTE(DID_BAD_TARGET);
3668                         scp->scsi_done(scp);
3669                         return ASC_ERROR;
3670                 }
3671                 ASC_BOARD(scp->host)->init_tidmask |= ASC_TIX_TO_TARGET_ID(scp->target);
3672         }
3673 
3674         memset(&scsiq, 0, sizeof(ASC_SCSI_Q));
3675 
3676         /*
3677          * Point the ASC_SCSI_Q to the 'Scsi_Cmnd'.
3678          */
3679         scsiq.q2.srb_ptr = (ulong) scp;
3680 
3681         /*
3682          * Build the ASC_SCSI_Q request.
3683          */
3684         scsiq.cdbptr = &scp->cmnd[0];
3685         scsiq.q2.cdb_len = scp->cmd_len;
3686         scsiq.q1.target_id = ASC_TID_TO_TARGET_ID(scp->target);
3687         scsiq.q1.target_lun = scp->lun;
3688         scsiq.q2.target_ix = ASC_TIDLUN_TO_IX(scp->target, scp->lun);
3689         scsiq.q1.sense_addr = (ulong) &scp->sense_buffer[0];
3690         scsiq.q1.sense_len = sizeof(scp->sense_buffer);
3691         scsiq.q2.tag_code = M2_QTAG_MSG_SIMPLE;
3692 
3693         /*
3694          * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
3695          * buffer command.
3696          */
3697         if (scp->use_sg == 0) {
3698                 /*
3699                  * CDB request of single contiguous buffer.
3700                  */
3701                 ASC_STATS(cont_cnt);
3702                 /* request_buffer is already a real address. */
3703                 scsiq.q1.data_addr = (ulong) scp->request_buffer;
3704                 scsiq.q1.data_cnt = scp->request_bufflen;
3705                 ASC_STATS_ADD(cont_xfer, (scp->request_bufflen + 511) >> 9);
3706                 scsiq.q1.sg_queue_cnt = 0;
3707                 scsiq.sg_head = NULL;
3708         } else {
3709                 /*
3710                  * CDB scatter-gather request list.
3711                  */
3712                 int                                     sgcnt;
3713                 struct scatterlist      *slp;
3714 
3715                 if (scp->use_sg > ASC_MAX_SG_LIST) {
3716                         ASC_DBG2(0, "asc_execute_scsi_cmnd: use_sg %d > %d\n",
3717                                 scp->use_sg, ASC_MAX_SG_LIST);
3718                         scp->result = HOST_BYTE(DID_ERROR);
3719                         scp->scsi_done(scp);
3720                         return ASC_ERROR;
3721                 }
3722 
3723                 ASC_STATS(sg_cnt);
3724 
3725                 /*
3726                  * Allocate a ASC_SG_HEAD structure and set the ASC_SCSI_Q
3727                  * to point to it.
3728                  */
3729                 memset(&sghead, 0, sizeof(ASC_SG_HEAD));
3730 
3731                 scsiq.q1.cntl |= QC_SG_HEAD;
3732                 scsiq.sg_head = &sghead;
3733                 scsiq.q1.data_cnt = 0;
3734                 scsiq.q1.data_addr = 0;
3735                 sghead.entry_cnt = scsiq.q1.sg_queue_cnt = scp->use_sg;
3736                 ASC_STATS_ADD(sg_elem, sghead.entry_cnt);
3737 
3738                 /*
3739                  * Convert scatter-gather list into ASC_SG_HEAD list.
3740                  */
3741                 slp = (struct scatterlist *) scp->request_buffer;
3742                 for (sgcnt = 0; sgcnt < scp->use_sg; sgcnt++, slp++) {
3743                         sghead.sg_list[sgcnt].addr = (ulong) slp->address;
3744                         sghead.sg_list[sgcnt].bytes = slp->length;
3745                         ASC_STATS_ADD(sg_xfer, (slp->length + 511) >> 9);
3746                 }
3747         }
3748 
3749         ASC_DBG_PRT_SCSI_Q(2, &scsiq);
3750         ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
3751 
3752         switch (ret = AscExeScsiQueue(boardp, &scsiq)) {
3753         case ASC_NOERROR:
3754                 ASC_DBG(1, "asc_execute_scsi_cmnd: AscExeScsiQueue() ASC_NOERROR\n");
3755                 break;
3756         case ASC_BUSY:
3757                 /* Caller must enqueue request and retry later. */
3758                 break;
3759         case ASC_ERROR:
3760                 ASC_DBG1(0,
3761                         "asc_execute_scsi_cmnd: AscExeScsiQueue() ASC_ERROR err_code %x\n",
3762                         boardp->err_code);
3763                 ASC_STATS(error);
3764                 scp->result = HOST_BYTE(DID_ERROR);
3765                 scp->scsi_done(scp);
3766                 break;
3767         }
3768 
3769         ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
3770         return ret;
3771 }
3772 
3773 /*
3774  * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
3775  */
3776 void
3777 asc_isr_callback(ASC_DVC_VAR *boardp, ASC_QDONE_INFO *qdonep)
     /* [previous][next][first][last][top][bottom][index][help] */
3778 {
3779         Scsi_Cmnd                       *scp;
3780         struct Scsi_Host        *shp;
3781         int                                     flags;
3782         Scsi_Cmnd                       **scpp;
3783 
3784         ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
3785         ASC_DBG2(1, "asc_isr_callback: boardp %x, qdonep %x\n",
3786                 (unsigned) boardp, (unsigned) qdonep);
3787         ASC_STATS(callback);
3788         ASC_DBG_PRT_QDONE_INFO(2, qdonep);
3789 
3790         /*
3791          * Get the Scsi_Cmnd structure and Scsi_Host structure for the
3792          * command that has been completed.
3793          */
3794         scp = (Scsi_Cmnd *) qdonep->d2.srb_ptr;
3795         ASC_DBG1(1, "asc_isr_callback: scp %x\n", (unsigned) scp);
3796         ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
3797 
3798         shp = scp->host;
3799         ASC_ASSERT(shp);
3800         ASC_DBG1(1, "asc_isr_callback: shp %x\n", (unsigned) shp);
3801 
3802         /*
3803          * 'qdonep' contains the command's ending status.
3804          */
3805         switch (qdonep->d3.done_stat) {
3806         case QD_NO_ERROR:
3807                 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
3808                 switch (qdonep->d3.host_stat) {
3809                 case QHSTA_NO_ERROR:
3810                         scp->result = 0;
3811                         break;
3812                 default:
3813                         /* QHSTA error occurred */
3814                         scp->result = HOST_BYTE(DID_ERROR);
3815                         break;
3816                 }
3817                 break;
3818 
3819         case QD_WITH_ERROR:
3820                 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
3821                 switch (qdonep->d3.host_stat) {
3822                 case QHSTA_NO_ERROR:
3823                         if (qdonep->d3.scsi_stat == SS_CHK_CONDITION) {
3824                                 ASC_DBG(2, "asc_isr_callback: SS_CHK_CONDITION\n");
3825                                 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
3826                                         sizeof(scp->sense_buffer));
3827                                 /*
3828                                  * Note: The status_byte() macro used by target drivers
3829                                  * defined in scsi.h shifts the status byte returned by
3830                                  * host drivers right by 1 bit. This is why target drivers
3831                                  * also use left shifted status byte definitions. For instance
3832                                  * target drivers use CHECK_CONDITION, defined to 0x1, instead
3833                                  * of the SCSI defined check condition value of 0x2.
3834                                  */
3835                                 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
3836                                         STATUS_BYTE(qdonep->d3.scsi_stat); 
3837                         } else {
3838                                 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat); 
3839                         }
3840                         break;
3841 
3842                 default:
3843                         /* QHSTA error occurred */
3844                         ASC_DBG1(2, "asc_isr_callback: host_stat %x\n",
3845                                 qdonep->d3.host_stat);
3846                         scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.scsi_msg) |
3847                                 STATUS_BYTE(qdonep->d3.scsi_stat);
3848                         break;
3849                 }
3850                 break;
3851 
3852         case QD_ABORTED_BY_HOST:
3853                 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
3854                 scp->result = HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.scsi_msg) |
3855                                 STATUS_BYTE(qdonep->d3.scsi_stat);
3856                 break;
3857 
3858         default:
3859                 ASC_DBG1(0, "asc_isr_callback: done_stat %x\n", qdonep->d3.done_stat );
3860                 scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.scsi_msg) |
3861                                 STATUS_BYTE(qdonep->d3.scsi_stat);
3862                 break;
3863         }
3864 
3865         /*
3866          * Before calling 'scsi_done' for the current 'Scsi_Cmnd' and possibly
3867          * triggering more commands to be issued, try to start any pending
3868          * commands.
3869          */
3870         if (ASC_BOARD(shp)->pending_tidmask != 0) {
3871                 /*
3872                  * If there are any pending commands for this board before trying
3873                  * to execute them, disable interrupts to preserve request ordering.
3874                  */
3875                 ASC_STATS(intr_disable);
3876                 save_flags(flags);
3877                 cli();
3878                 ASC_DBG1(1, "asc_isr_callback: asc_execute_pending() %x\n",
3879                         ASC_BOARD(shp)->pending_tidmask);
3880                 asc_execute_pending(shp);
3881                 restore_flags(flags);
3882         }
3883 
3884         /* 
3885          * Because interrupts may be enabled by the 'Scsi_Cmnd' done function,
3886          * add the command to the end of the global done list. The done function
3887          * for the command will be called in advansys_interrupt().
3888          */
3889         for (scpp = &asc_scsi_done; *scpp;
3890              scpp = (Scsi_Cmnd **) &(*scpp)->host_scribble) {
3891                 ;
3892         }
3893         *scpp = scp;
3894         scp->host_scribble = NULL;
3895         return;
3896 }
3897 
3898 /*
3899  * Execute as many pending requests as possible for the
3900  * board specified by 'Scsi_Host'.
3901  */
3902 STATIC void
3903 asc_execute_pending(struct Scsi_Host *shp)
     /* [previous][next][first][last][top][bottom][index][help] */
3904 {
3905         ASC_SCSI_BIT_ID_TYPE    scan_tidmask;
3906         Scsi_Cmnd                               *scp;
3907         int                                             i;
3908 
3909         ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
3910         /*
3911          * Execute pending commands for devices attached to
3912          * the current board in round-robin fashion.
3913          */
3914         scan_tidmask = ASC_BOARD(shp)->pending_tidmask;
3915         do {
3916                 for (i = 0; i < ASC_MAX_TID; i++) {
3917                         if (scan_tidmask & ASC_TIX_TO_TARGET_ID(i)) {
3918                                 if ((scp = asc_dequeue(shp, i)) == NULL) {
3919                                         scan_tidmask &= ~ASC_TIX_TO_TARGET_ID(i);
3920                                 } else if (asc_execute_scsi_cmnd(scp) == ASC_BUSY) {
3921                                         scan_tidmask &= ~ASC_TIX_TO_TARGET_ID(i);
3922                                         /* Put the request back at front of the list. */
3923                                         asc_enqueue(shp, scp, i, ASC_FRONT);
3924                                 }
3925                         }
3926                 }
3927         } while (scan_tidmask);
3928         return;
3929 }
3930 
3931 /*
3932  * asc_init_dev()
3933  *
3934  * Perform one-time initialization of a device.
3935  */
3936 STATIC int
3937 asc_init_dev(ASC_DVC_VAR *boardp, Scsi_Cmnd *scp)
     /* [previous][next][first][last][top][bottom][index][help] */
3938 {
3939         ASC_SCSI_REQ_Q                  *scsireqq;
3940         ASC_CAP_INFO                    *cap_info;
3941         ASC_SCSI_INQUIRY                *inquiry;
3942         int                                             found;
3943         ASC_SCSI_BIT_ID_TYPE    save_use_tagged_qng;
3944         ASC_SCSI_BIT_ID_TYPE    save_can_tagged_qng;
3945         int                                             ret;
3946 #ifdef ADVANSYS_DEBUG
3947         ASC_SCSI_BIT_ID_TYPE    tidmask; /* target id bit mask: 1 - 128 */
3948 #endif /* ADVANSYS_DEBUG */
3949 
3950         ASC_DBG1(1, "asc_init_dev: target %d\n", (unsigned) scp->target);
3951 
3952         /* Return true for the board's target id. */
3953         if (boardp->cfg->chip_scsi_id == scp->target) {
3954                 return ASC_TRUE;
3955         }
3956 
3957         /*
3958          * XXX - Host drivers should not modify the timeout field.
3959          * But on the first command only add some extra time to
3960          * allow the driver to complete its initialization for the
3961          * device.
3962          */
3963         scp->timeout += 2000;   /* Add 5 seconds to the request timeout. */
3964 
3965         /* Set-up AscInitPollTarget() arguments. */
3966         scsireqq = &ASC_BOARD(scp->host)->scsireqq;
3967         memset(scsireqq, 0, sizeof(ASC_SCSI_REQ_Q));
3968         cap_info = &ASC_BOARD(scp->host)->cap_info;
3969         memset(cap_info, 0, sizeof(ASC_CAP_INFO));
3970         inquiry = &ASC_BOARD(scp->host)->inquiry;
3971         memset(inquiry, 0, sizeof(ASC_SCSI_INQUIRY));
3972 
3973         /*
3974          * XXX - AscInitPollBegin() re-initializes these fields to
3975          * zero. 'Or' in the new values and restore them before calling 
3976          * AscInitPollEnd(). Normally all targets are initialized within
3977          * a call to AscInitPollBegin() and AscInitPollEnd().
3978          */
3979         save_use_tagged_qng = boardp->use_tagged_qng;
3980     save_can_tagged_qng = boardp->cfg->can_tagged_qng;
3981 
3982         ASC_DBG(2, "asc_init_dev: AscInitPollBegin()\n");
3983         if (AscInitPollBegin(boardp)) {
3984                 ASC_DBG(0, "asc_init_dev: AscInitPollBegin() failed\n");
3985                 return ASC_FALSE;
3986         }
3987 
3988         scsireqq->sense_ptr = &scsireqq->sense[0];
3989         scsireqq->r1.sense_len = ASC_MIN_SENSE_LEN;
3990         scsireqq->r1.target_id = ASC_TID_TO_TARGET_ID(scp->target);
3991         scsireqq->r1.target_lun = 0;
3992         scsireqq->r2.target_ix = ASC_TIDLUN_TO_IX(scp->target, 0);
3993 
3994         found = ASC_FALSE;
3995         ASC_DBG(2, "asc_init_dev: AscInitPollTarget()\n");
3996         switch (ret = AscInitPollTarget(boardp, scsireqq, inquiry, cap_info)) {
3997         case ASC_TRUE:
3998                 found = ASC_TRUE;
3999 #ifdef ADVANSYS_DEBUG
4000                 tidmask = ASC_TIX_TO_TARGET_ID(scp->target);
4001                 ASC_DBG2(1, "asc_init_dev: lba %lu, blk_size %lu\n",
4002                         cap_info->lba, cap_info->blk_size);
4003                 ASC_DBG1(1, "asc_init_dev: peri_dvc_type %x\n",
4004                         inquiry->byte0.peri_dvc_type);
4005                 if (boardp->use_tagged_qng & tidmask) {
4006                         ASC_DBG1(1, "asc_init_dev: command queuing enabled: %d\n",
4007                                 boardp->max_dvc_qng[scp->target]);
4008                 } else {
4009                         ASC_DBG(1, "asc_init_dev: command queuing disabled\n");
4010                 }
4011                 if (boardp->init_sdtr & tidmask) {
4012                         ASC_DBG(1, "asc_init_dev: synchronous transfers enabled\n");
4013                 } else {
4014                         ASC_DBG(1, "asc_init_dev: synchronous transfers disabled\n");
4015                 }
4016                 /* Set bit means fix disabled. */
4017                 if (boardp->pci_fix_asyn_xfer & tidmask) {
4018                         ASC_DBG(1, "asc_init_dev: synchronous transfer fix disabled\n");
4019                 } else {
4020                         ASC_DBG(1, "asc_init_dev: synchronous transfer fix enabled\n");
4021                 }
4022 #endif /* ADVANSYS_DEBUG */
4023                 break;
4024         case ASC_FALSE:
4025                 ASC_DBG(1, "asc_init_dev: no device found\n");
4026                 break;
4027         case ASC_ERROR:
4028                 ASC_DBG(0, "asc_init_dev: AscInitPollTarget() ASC_ERROR\n");
4029                 break;
4030         default:
4031                 ASC_DBG1(0, "asc_init_dev: AscInitPollTarget() unknown ret %d\n", ret);
4032                 break;
4033         }
4034 
4035         /* XXX - 'Or' in original tag bits. */
4036         boardp->use_tagged_qng |= save_use_tagged_qng;
4037         boardp->cfg->can_tagged_qng |= save_can_tagged_qng;
4038 
4039         ASC_DBG(2, "asc_init_dev: AscInitPollEnd()\n");
4040         AscInitPollEnd(boardp);
4041 
4042 #ifdef ASC_SET_CMD_PER_LUN
4043         /*
4044          * XXX - Refer to the comment in advansys_detect()
4045          * regarding cmd_per_lun.
4046          */
4047         for (i = 0; i <= ASC_MAX_TID; i++) {
4048                 if (boardp->max_dvc_qng[i] < scp->host->cmd_per_lun) {
4049                         scp->host->cmd_per_lun = boardp->max_dvc_qng[i];
4050                 }
4051         }
4052 #endif /* ASC_SET_CMD_PER_LUN */
4053 
4054         return found;
4055 }
4056 
4057 /*
4058  * Search for an AdvanSys PCI device in the PCI configuration space.
4059  */
4060 STATIC int
4061 asc_srch_pci_dev(PCI_DEVICE *pciDevice)
     /* [previous][next][first][last][top][bottom][index][help] */
4062 {
4063         int ret;
4064         static int scan = 1;
4065 
4066         ASC_DBG(2, "asc_srch_pci_dev: begin\n");
4067 
4068         if (scan) {
4069                 pciDevice->type = asc_scan_method(pciDevice);
4070                 scan = 0;
4071                 ASC_DBG1(2, "asc_srch_pci_dev: type %d\n", pciDevice->type);
4072         }
4073         ret = asc_pci_find_dev(pciDevice);
4074         ASC_DBG1(2, "asc_srch_pci_dev: asc_pci_find_dev() return %d\n", ret);
4075         if (ret == PCI_DEVICE_FOUND) {
4076                 pciDevice->slotNumber = pciDevice->slotFound + 1;
4077                 pciDevice->startSlot = pciDevice->slotFound + 1;
4078         } else {
4079                 if (pciDevice->bridge > pciDevice->busNumber) {
4080                         ASC_DBG2(2, "asc_srch_pci_dev: bridge %x, busNumber %x\n",
4081                                 pciDevice->bridge, pciDevice->busNumber);
4082                         pciDevice->busNumber++;
4083                         pciDevice->slotNumber = 0;
4084                         pciDevice->startSlot = 0;
4085                         pciDevice->endSlot = 0x0f;
4086                         ret = asc_srch_pci_dev(pciDevice);
4087                         ASC_DBG1(2, "asc_srch_pci_dev recursive call return %d\n", ret);
4088                 }
4089         }
4090         ASC_DBG1(2, "asc_srch_pci_dev: return %d\n", ret);
4091         return ret;
4092 }
4093 
4094 /*
4095  * Determine the access method to be used for 'pciDevice'.
4096  */
4097 STATIC uchar
4098 asc_scan_method(PCI_DEVICE *pciDevice)
     /* [previous][next][first][last][top][bottom][index][help] */
4099 {
4100         ushort data;
4101         PCI_DATA pciData;
4102         uchar type;
4103         uchar slot;
4104 
4105         ASC_DBG(2, "asc_scan_method: begin\n");
4106         memset(&pciData, 0, sizeof(pciData));
4107         for (type = 1; type < 3; type++) {
4108                 pciData.type = type;
4109                 for (slot = 0; slot < PCI_MAX_SLOT; slot++) {
4110                         pciData.slot = slot;
4111                         data = asc_get_cfg_word(&pciData);
4112                         if ((data != 0xFFFF) && (data != 0x0000)) {
4113                                 ASC_DBG2(4, "asc_scan_method: data %x, type %d\n", data, type);
4114                                 return (type);
4115                         }
4116                 }
4117         }
4118         ASC_DBG1(4, "asc_scan_method: type %d\n", type);
4119         return (type);
4120 }
4121 
4122 /*
4123  * Check for an AdvanSys PCI device in 'pciDevice'.
4124  *
4125  * Return PCI_DEVICE_FOUND if found, otherwise return PCI_DEVICE_NOT_FOUND.
4126  */
4127 STATIC int
4128 asc_pci_find_dev(PCI_DEVICE *pciDevice)
     /* [previous][next][first][last][top][bottom][index][help] */
4129 {
4130         PCI_DATA pciData;
4131         ushort vendorid, deviceid;
4132         uchar classcode, subclass;
4133         uchar lslot;
4134 
4135         ASC_DBG(3, "asc_pci_find_dev: begin\n");
4136         pciData.type = pciDevice->type;
4137         pciData.bus = pciDevice->busNumber;
4138         pciData.func = pciDevice->devFunc;
4139         lslot = pciDevice->startSlot;
4140         for (; lslot < pciDevice->endSlot; lslot++) {
4141                 pciData.slot = lslot;
4142                 pciData.offset = VENDORID_OFFSET;
4143                 vendorid = asc_get_cfg_word(&pciData);
4144                 ASC_DBG1(3, "asc_pci_find_dev: vendorid %x\n", vendorid);
4145                 if (vendorid != 0xffff) {
4146                         pciData.offset = DEVICEID_OFFSET;
4147                         deviceid = asc_get_cfg_word(&pciData);
4148                         ASC_DBG1(3, "asc_pci_find_dev: deviceid %x\n", deviceid);
4149                         if ((vendorid == ASC_PCI_VENDORID) &&
4150                                 ((deviceid == ASC_PCI_DEVICE_ID_REV_A) ||
4151                                 (deviceid == ASC_PCI_DEVICE_ID_REV_B))) {
4152                                 pciDevice->slotFound = lslot;
4153                                 ASC_DBG(3, "asc_pci_find_dev: PCI_DEVICE_FOUND\n");
4154                                 return PCI_DEVICE_FOUND;
4155                         } else {
4156                                 pciData.offset = SUBCLASS_OFFSET;
4157                                 subclass = asc_get_cfg_byte(&pciData);
4158                                 pciData.offset = CLASSCODE_OFFSET;
4159                                 classcode = asc_get_cfg_byte(&pciData);
4160                                 if ((classcode & PCI_BASE_CLASS_BRIDGE_DEVICE) &&
4161                                         (subclass & PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER)) {
4162                                         pciDevice->bridge++;
4163                                 }
4164                                 ASC_DBG2(3, "asc_pci_find_dev: subclass %x, classcode %x\n",
4165                                         subclass, classcode);
4166                         }
4167                 }
4168         }
4169         return PCI_DEVICE_NOT_FOUND;
4170 }
4171 
4172 /*
4173  * Read PCI configuration data into 'pciConfig'.
4174  */
4175 STATIC void
4176 asc_get_pci_cfg(PCI_DEVICE *pciDevice, PCI_CONFIG_SPACE *pciConfig)
     /* [previous][next][first][last][top][bottom][index][help] */
4177 {
4178         PCI_DATA pciData;
4179         uchar counter;
4180         uchar *localConfig;
4181 
4182         ASC_DBG1(4, "asc_get_pci_cfg: slot found - %d\n ",
4183                 pciDevice->slotFound);
4184 
4185         pciData.type = pciDevice->type;
4186         pciData.bus = pciDevice->busNumber;
4187         pciData.slot = pciDevice->slotFound;
4188         pciData.func = pciDevice->devFunc;
4189         localConfig = (uchar *) pciConfig;
4190 
4191         for (counter = 0; counter < sizeof(PCI_CONFIG_SPACE); counter++) {
4192                 pciData.offset = counter;
4193                 *localConfig = asc_get_cfg_byte(&pciData);
4194                 ASC_DBG1(4, "asc_get_pci_cfg: byte %x\n", *localConfig);
4195                 localConfig++;
4196         }
4197         ASC_DBG1(4, "asc_get_pci_cfg: counter %d\n", counter);
4198 }
4199 
4200 /*
4201  * Read a word (16 bits) from the PCI configuration space.
4202  *
4203  * The configuration mechanism is checked for the correct access method.
4204  */
4205 STATIC ushort
4206 asc_get_cfg_word(PCI_DATA *pciData)
     /* [previous][next][first][last][top][bottom][index][help] */
4207 {
4208         ushort tmp;
4209         ulong address;
4210         ulong lbus = pciData->bus;
4211         ulong lslot = pciData->slot;
4212         ulong lfunc = pciData->func;
4213         uchar t2CFA, t2CF8;
4214         ushort t1CF8, t1CFA, t1CFC, t1CFE;
4215 
4216         ASC_DBG4(4, "asc_get_cfg_word: type %d, bus %lu, slot %lu, func %lu\n",
4217                 pciData->type, lbus, lslot, lfunc);
4218 
4219         /*
4220          * check type of configuration mechanism
4221          */
4222         if (pciData->type == 2) {
4223                 /*
4224                  * save these registers so we can restore them after we are done
4225                  */
4226                 t2CFA = inp(0xCFA);     /* save PCI bus register */
4227                 t2CF8 = inp(0xCF8);     /* save config space enable register */
4228 
4229                 /*
4230                  * go out and write the bus and enable registers
4231                  */
4232                 /* set for type 1 cycle, if needed */
4233                 outp(0xCFA, pciData->bus);
4234                 /* set the function number */
4235                 outp(0xCF8, 0x10 | (pciData->func << 1)) ;
4236 
4237                 /*
4238                  * read the configuration space type 2 locations
4239                  */
4240                 tmp = (ushort) inpw(0xC000 | ((pciData->slot << 8) + pciData->offset));
4241         } else {
4242                 /*
4243                  * type 1 configuration mechanism
4244                  *
4245                  * save the CONFIG_ADDRESS and CONFIG_DATA register values
4246                  */
4247                 t1CFC = inpw(0xCFC);
4248                 t1CFE = inpw(0xCFE);
4249                 t1CF8 = inpw(0xCF8);
4250                 t1CFA = inpw(0xCFA);
4251 
4252                 /*
4253                  * enable <31>, bus = <23:16>, slot = <15:11>,
4254                  * func = <10:8>, reg = <7:2>
4255                  */
4256                 address = (ulong) ((lbus << 16) | (lslot << 11) |
4257                         (lfunc << 8) | (pciData->offset & 0xFC) | 0x80000000L);
4258 
4259                 /*
4260                  * write out the address to CONFIG_ADDRESS
4261                  */
4262                 outl(address, 0xCF8);
4263 
4264                 /*
4265                  * read in the word from CONFIG_DATA
4266                  */
4267                 tmp = (ushort) ((inl(0xCFC) >>
4268                                  ((pciData->offset & 2) * 8)) & 0xFFFF);
4269         }
4270         ASC_DBG1(4, "asc_get_cfg_word: config data: %x\n", tmp);
4271         return tmp;
4272 }
4273 
4274 /*
4275  * Reads a byte from the PCI configuration space.
4276  *
4277  * The configuration mechanism is checked for the correct access method.
4278  */
4279 STATIC uchar
4280 asc_get_cfg_byte(PCI_DATA *pciData)
     /* [previous][next][first][last][top][bottom][index][help] */
4281 {
4282         uchar tmp;
4283         ulong address;
4284         ulong lbus = pciData->bus, lslot = pciData->slot, lfunc = pciData->func;
4285         uchar t2CFA, t2CF8;
4286         ushort t1CF8, t1CFA, t1CFC, t1CFE;
4287 
4288         ASC_DBG1(4, "asc_get_cfg_byte: type: %d\n", pciData->type);
4289 
4290         /*
4291          * check type of configuration mechanism
4292          */
4293         if (pciData->type == 2) {
4294                 /*
4295                  * save these registers so we can restore them after we are done
4296                  */
4297                 t2CFA = inp(0xCFA);     /* save PCI bus register */
4298                 t2CF8 = inp(0xCF8);     /* save config space enable register */
4299 
4300                 /*
4301                  * go out and write the bus and enable registers
4302                  */
4303                 /* set for type 1 cycle, if needed */
4304                 outp(0xCFA, pciData->bus);
4305                 /* set the function number */
4306                 outp(0xCF8, 0x10 | (pciData->func << 1));
4307 
4308                 /*
4309                  * read the configuration space type 2 locations
4310                  */
4311                 tmp = inp(0xC000 | ((pciData->slot << 8) + pciData->offset));
4312 
4313                 /*
4314                  * restore the registers used for our transaction
4315                  */
4316                 outp(0xCF8, t2CF8);     /* restore the enable register */
4317                 outp(0xCFA, t2CFA);     /* restore PCI bus register */
4318         } else {
4319                 /*
4320                  * type 1 configuration mechanism
4321                  *
4322                  * save the CONFIG_ADDRESS and CONFIG_DATA register values
4323                  */
4324                 t1CFC = inpw(0xCFC);
4325                 t1CFE = inpw(0xCFE);
4326                 t1CF8 = inpw(0xCF8);
4327                 t1CFA = inpw(0xCFA);
4328 
4329                 /*
4330                  * enable <31>, bus = <23:16>, slot = <15:11>, func = <10:8>,
4331                  * reg = <7:2>
4332                  */
4333                 address = (ulong) ((lbus << 16) | (lslot << 11) |
4334                         (lfunc << 8) | (pciData->offset & 0xFC) | 0x80000000L);
4335 
4336                 /*
4337                  * write out the address to CONFIG_ADDRESS
4338                  */
4339                 outl(address, 0xCF8);
4340 
4341                 /*
4342                  * read in the word from CONFIG_DATA
4343                  */
4344                 tmp = (uchar) ((inl(0xCFC) >> ((pciData->offset & 3) * 8)) & 0xFF);
4345         }
4346         ASC_DBG1(4, "asc_get_cfg_byte: config data: %x\n", tmp);
4347         return tmp;
4348 }
4349 
4350 /*
4351  * Add a 'Scsi_Cmnd' to the end of specified 'Scsi_Host' 
4352  * target device pending command list. Set 'pending_tidmask'
4353  * to indicate a command is queued for the device.
4354  *
4355  * 'flag' may be either ASC_FRONT or ASC_BACK.
4356  *
4357  * The 'Scsi_Cmnd' host_scribble field is used as a next pointer.
4358  */
4359 STATIC void
4360 asc_enqueue(struct Scsi_Host *shp, Scsi_Cmnd *scp, int tid, int flag)
     /* [previous][next][first][last][top][bottom][index][help] */
4361 {
4362         Scsi_Cmnd       **scpp;
4363 
4364         ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
4365         ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
4366         ASC_STATS(enqueue);
4367         if (flag == ASC_FRONT) {
4368                 scp->host_scribble = (unsigned char *) ASC_BOARD(shp)->pending[tid];
4369                 ASC_BOARD(shp)->pending[tid] = (Scsi_Cmnd *) scp;
4370         } else { /* ASC_BACK */
4371                 for (scpp = &ASC_BOARD(shp)->pending[tid]; *scpp;
4372                          scpp = (Scsi_Cmnd **) &(*scpp)->host_scribble) {
4373                         ;
4374                 }
4375                 *scpp = scp;
4376                 scp->host_scribble = NULL;
4377         }
4378         ASC_BOARD(shp)->pending_tidmask |= ASC_TIX_TO_TARGET_ID(tid);
4379 }
4380 
4381 /*
4382  * Return first pending 'Scsi_Cmnd' on the specified 'Scsi_Host'
4383  * for the specified target device. Clear the 'pending_tidmask'
4384  * bit for the device if no more commands are left queued for it.
4385  *
4386  * The 'Scsi_Cmnd' host_scribble field is used as a next pointer.
4387  */
4388 STATIC Scsi_Cmnd *
4389 asc_dequeue(struct Scsi_Host *shp, int tid)
     /* [previous][next][first][last][top][bottom][index][help] */
4390 {
4391         Scsi_Cmnd       *scp;
4392 
4393         ASC_STATS(dequeue);
4394         ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
4395         if ((scp = ASC_BOARD(shp)->pending[tid]) != NULL) {
4396                 ASC_BOARD(shp)->pending[tid] = (Scsi_Cmnd *) scp->host_scribble;
4397         }
4398         if (ASC_BOARD(shp)->pending[tid] == NULL) {
4399                 ASC_BOARD(shp)->pending_tidmask &= ~ASC_TIX_TO_TARGET_ID(tid);
4400         }
4401         return scp;
4402 }
4403 
4404 /*
4405  * Remove the specified 'Scsi_Cmnd' from the specified 'Scsi_Host'
4406  * for the specified target device. Clear the 'pending_tidmask'
4407  * bit for the device if no more commands are left queued for it.
4408  *
4409  * The 'Scsi_Cmnd' host_scribble field is used as a next pointer.
4410  *
4411  * Return ASC_TRUE if the command was found and removed, otherwise
4412  * return ASC_FALSE if the command was not found.
4413  */
4414 STATIC int
4415 asc_rmqueue(struct Scsi_Host *shp, Scsi_Cmnd *scp, int tid)
     /* [previous][next][first][last][top][bottom][index][help] */
4416 {
4417         Scsi_Cmnd       **scpp;
4418         int                     ret;
4419 
4420         ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
4421         ret = ASC_FALSE;
4422         for (scpp = &ASC_BOARD(shp)->pending[tid];
4423              *scpp; scpp = (Scsi_Cmnd **) &(*scpp)->host_scribble) {
4424                 if (*scpp == scp) {
4425                         *scpp = (Scsi_Cmnd *) scp->host_scribble;       
4426                         scp->host_scribble = NULL;
4427                         ASC_STATS(rmqueue);
4428                         ret = ASC_TRUE;
4429                 }
4430         }
4431         if (ASC_BOARD(shp)->pending[tid] == NULL) {
4432                 ASC_BOARD(shp)->pending_tidmask &= ~ASC_TIX_TO_TARGET_ID(tid);
4433         }
4434         return ret;
4435 }
4436 
4437 
4438 /*
4439  * --- Functions Required by the Asc Library
4440  */
4441 
4442 /*
4443  * Delay for 'n' milliseconds. Don't use the 'jiffies'
4444  * global variable which is incremented once every 5 ms
4445  * from a timer interrupt, because this function may be
4446  * called when interrupts are disabled.
4447  */
4448 void
4449 DvcSleepMilliSecond(ulong n)
     /* [previous][next][first][last][top][bottom][index][help] */
4450 {
4451         ulong i;
4452 
4453         ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", n);
4454         for (i = 0; i < n; i++) {
4455                 udelay(1000);
4456         }
4457 }
4458 
4459 void
4460 DvcDisplayString(uchar *s)
     /* [previous][next][first][last][top][bottom][index][help] */
4461 {
4462         printk(s);
4463 }
4464 
4465 int
4466 DvcEnterCritical(void)
     /* [previous][next][first][last][top][bottom][index][help] */
4467 {
4468         int     flags;
4469 
4470         save_flags(flags);
4471         cli();
4472         return flags;
4473 }
4474 
4475 void
4476 DvcLeaveCritical(int flags)
     /* [previous][next][first][last][top][bottom][index][help] */
4477 {
4478         restore_flags(flags);
4479 }
4480 
4481 /*
4482  * Convert a virtual address to a virtual address.
4483  *
4484  * Apparently Linux is loaded V=R (virtual equals real). Just return
4485  * the virtual address.
4486  */
4487 ulong
4488 DvcGetPhyAddr(uchar *buf_addr, ulong buf_len)
     /* [previous][next][first][last][top][bottom][index][help] */
4489 {
4490         ulong phys_addr;
4491 
4492         phys_addr = (ulong) buf_addr;
4493         return phys_addr;
4494 }
4495 
4496 ulong
4497 DvcGetSGList(ASC_DVC_VAR *asc_dvc_sg, uchar *buf_addr, ulong buf_len,
     /* [previous][next][first][last][top][bottom][index][help] */
4498                          ASC_SG_HEAD *asc_sg_head_ptr)
4499 {
4500         ulong buf_size;
4501 
4502         buf_size = buf_len;
4503         asc_sg_head_ptr->entry_cnt = 1;
4504         asc_sg_head_ptr->sg_list[0].addr = (ulong) buf_addr;
4505         asc_sg_head_ptr->sg_list[0].bytes = buf_size;
4506         return buf_size;
4507 }
4508 
4509 /*
4510  * void
4511  * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, ushort *outbuf, int words)
4512  *
4513  * Calling/Exit State:
4514  *      none
4515  *
4516  * Description:
4517  *      Output an ASC_SCSI_Q structure to the chip
4518  */
4519 void
4520 DvcPutScsiQ(PortAddr iop_base, ushort s_addr, ushort *outbuf, int words)
     /* [previous][next][first][last][top][bottom][index][help] */
4521 {
4522         int     i;
4523 
4524         ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", (uchar *) outbuf, 2 * words);
4525         AscSetChipLramAddr(iop_base, s_addr);
4526         for (i = 0; i < words; i++, outbuf++) {
4527                 if (i == 2 || i == 10) {
4528                         continue;
4529                 }
4530                 AscPutChipLramData(iop_base, *outbuf);
4531         }
4532 }
4533 
4534 /*
4535  * void
4536  * DvcGetQinfo(PortAddr iop_base, ushort s_addr, ushort *inbuf, int words)
4537  *
4538  * Calling/Exit State:
4539  *      none
4540  *
4541  * Description:
4542  *      Input an ASC_QDONE_INFO structure from the chip
4543  */
4544 void
4545 DvcGetQinfo(PortAddr iop_base, ushort s_addr, ushort *inbuf, int words)
     /* [previous][next][first][last][top][bottom][index][help] */
4546 {
4547         int     i;
4548 
4549         AscSetChipLramAddr(iop_base, s_addr);
4550         for (i = 0; i < words; i++, inbuf++) {
4551                 if (i == 5) {
4552                         continue;
4553                 }
4554                 *inbuf = AscGetChipLramData(iop_base);
4555         }
4556         ASC_DBG_PRT_HEX(2, "DvcGetQinfo", (uchar *) inbuf, 2 * words);
4557 }
4558 
4559 /*
4560  * void DvcOutPortWords(ushort iop_base, ushort &outbuf, int words)
4561  *
4562  * Calling/Exit State:
4563  *      none
4564  *
4565  * Description:
4566  *      output a buffer to an i/o port address
4567  */
4568 void
4569 DvcOutPortWords(ushort iop_base, ushort *outbuf, int words)
     /* [previous][next][first][last][top][bottom][index][help] */
4570 {
4571         int     i;
4572 
4573         for (i = 0; i < words; i++, outbuf++)
4574                 outpw(iop_base, *outbuf);
4575 }
4576 
4577 /*
4578  * void DvcInPortWords(ushort iop_base, ushort &outbuf, int words)
4579  *
4580  * Calling/Exit State:
4581  *      none
4582  *
4583  * Description:
4584  *      input a buffer from an i/o port address
4585  */
4586 void
4587 DvcInPortWords(ushort iop_base, ushort *inbuf, int words)
     /* [previous][next][first][last][top][bottom][index][help] */
4588 {
4589         int     i;
4590 
4591         for (i = 0; i < words; i++, inbuf++)
4592                 *inbuf = inpw(iop_base);
4593 }
4594 
4595 
4596 /*
4597  * void DvcOutPortDWords(PortAddr port, ulong *pdw, int dwords)
4598  *
4599  * Calling/Exit State:
4600  *      none
4601  *
4602  * Description:
4603  *      output a buffer of 32-bit integers to an i/o port address in
4604  *  16 bit integer units
4605  */
4606 void  
4607 DvcOutPortDWords(PortAddr port, ulong *pdw, int dwords)
     /* [previous][next][first][last][top][bottom][index][help] */
4608 {
4609         int             i;
4610         int             words;
4611         ushort  *pw;
4612 
4613         pw = (ushort *) pdw;
4614         words = dwords << 1;
4615         for(i = 0; i < words; i++, pw++) {
4616                 outpw(port, *pw);
4617         }
4618         return;
4619 }
4620 
4621 
4622 /*
4623  * --- Tracing and Debugging Functions
4624  */
4625 
4626 #ifdef ADVANSYS_STATS
4627 
4628 #define ASC_PRT_STATS_NEXT() \
4629         if (cp) { \
4630                 totlen += len; \
4631                 leftlen -= len; \
4632                 if (leftlen == 0) { \
4633                         return totlen; \
4634                 } \
4635                 cp += len; \
4636         }
4637 
4638 /*
4639  * asc_prt_stats()
4640  *
4641  * Note: no single line should be greater than 160 characters, cf.
4642  * asc_prt_stats_line().
4643  *
4644  * Return the number of characters copied into 'cp'. No more than
4645  * 'cplen' characters will be copied to 'cp'.
4646  */
4647 STATIC int
4648 asc_prt_stats(char *cp, int cplen)
     /* [previous][next][first][last][top][bottom][index][help] */
4649 {
4650         struct asc_stats        *s;
4651         int                                     leftlen;
4652         int                                     totlen;
4653         int                                     len;
4654 
4655         s = &asc_stats;
4656         leftlen = cplen;
4657         totlen = len = 0;
4658 
4659         len = asc_prt_stats_line(cp, leftlen,
4660 "\nAdvanSys SCSI Host Driver Statistics:\n");
4661         ASC_PRT_STATS_NEXT();
4662         
4663         len = asc_prt_stats_line(cp, leftlen,
4664 " command %lu, queuecommand %lu, abort %lu, reset %lu, biosparam %lu,\n",
4665                 s->command, s->queuecommand, s->abort, s->reset, s->biosparam);
4666         ASC_PRT_STATS_NEXT();
4667 
4668         len = asc_prt_stats_line(cp, leftlen,
4669 " interrupt %lu, callback %lu, cmd_disable %lu, intr_disable %lu,\n",
4670                 s->interrupt, s->callback, s->cmd_disable, s->intr_disable);
4671         ASC_PRT_STATS_NEXT();
4672 
4673         len = asc_prt_stats_line(cp, leftlen,
4674 " error %lu, enqueue %lu, dequeue %lu, rmqueue %lu,\n",
4675                 s->error, s->enqueue, s->dequeue, s->rmqueue);
4676         ASC_PRT_STATS_NEXT();
4677 
4678         if (s->cont_cnt > 0) {
4679                 len = asc_prt_stats_line(cp, leftlen,
4680 " cont_cnt %lu, cont_xfer %lu: avg_xfer=%lu kb\n",
4681                         s->cont_cnt, s->cont_xfer, (s->cont_xfer/2)/s->cont_cnt);
4682                 ASC_PRT_STATS_NEXT();
4683         }
4684 
4685         if (s->sg_cnt > 0) {
4686                 len = asc_prt_stats_line(cp, leftlen,
4687 " sg_cnt %lu, sg_elem %lu, sg_xfer %lu: avg_elem=%lu, avg_size=%lu kb\n",
4688                         s->sg_cnt, s->sg_elem, s->sg_xfer,
4689                         s->sg_elem/s->sg_cnt, (s->sg_xfer/2)/s->sg_cnt);
4690                 ASC_PRT_STATS_NEXT();
4691         }
4692 
4693         return totlen;
4694 }
4695 
4696 /*
4697  * asc_prt_stats_line()
4698  *
4699  * If 'cp' is NULL print to the console, otherwise print to a buffer.
4700  *
4701  * Return 0 if printing to the console, otherwise return the number of
4702  * bytes written to the buffer.
4703  *
4704  * Note: If any single line is greater than 160 bytes the stack
4705  * will be corrupted. 's[]' is defined to be 160 bytes.
4706  */
4707 int
4708 asc_prt_stats_line(char *buf, int buflen, char *fmt, ...)
     /* [previous][next][first][last][top][bottom][index][help] */
4709 {
4710         va_list         args;
4711         int                     ret;
4712         char            s[160];         /* 2 lines */
4713 
4714         va_start(args, fmt);
4715         ret = vsprintf(s, fmt, args);
4716         if (buf == NULL) {
4717                 (void) printk(s);
4718                 ret = 0;
4719         } else {
4720                 ret = min(buflen, ret);
4721                 memcpy(buf, s, ret);
4722         }
4723         va_end(args);
4724         return ret;
4725 }
4726 #endif /* ADVANSYS_STATS */
4727 
4728 #ifdef ADVANSYS_DEBUG
4729 /*
4730  * asc_prt_scsi_host()
4731  */
4732 STATIC void 
4733 asc_prt_scsi_host(struct Scsi_Host *s)
     /* [previous][next][first][last][top][bottom][index][help] */
4734 {
4735         printk("Scsi_Host at addr %x\n", (unsigned) s);
4736         printk(
4737 " next %x, extra_bytes %u, host_busy %u, host_no %d, last_reset %d,\n",
4738                 (unsigned) s->next, s->extra_bytes, s->host_busy, s->host_no,
4739                 s->last_reset);
4740 
4741         printk(
4742 " host_wait %x, host_queue %x, hostt %x, block %x,\n",
4743                 (unsigned) s->host_wait, (unsigned) s->host_queue,
4744                 (unsigned) s->hostt, (unsigned) s->block);
4745 
4746         printk(
4747 " wish_block %d, base %x, io_port %d, n_io_port %d, irq %d, dma_channel %d,\n",
4748                 s->wish_block, (unsigned) s->base, s->io_port, s->n_io_port,
4749                 s->irq, s->dma_channel);
4750 
4751         printk(
4752 " this_id %d, can_queue %d,\n", s->this_id, s->can_queue);
4753 
4754         printk(
4755 " cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d, loaded_as_module %d\n",
4756                 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma,
4757                 s->loaded_as_module);
4758 
4759         printk("hostdata (struct asc_board)\n");
4760         asc_prt_dvc_var(&ASC_BOARD(s)->board);
4761         asc_prt_dvc_cfg(&ASC_BOARD(s)->cfg);
4762         printk(" overrun_buf %x\n", (unsigned) &ASC_BOARD(s)->overrun_buf[0]);
4763 }
4764 
4765 /*
4766  * asc_prt_dvc_var()
4767  */
4768 STATIC void 
4769 asc_prt_dvc_var(ASC_DVC_VAR *h)
     /* [previous][next][first][last][top][bottom][index][help] */
4770 {
4771         printk("ASC_DVC_VAR at addr %x\n", (unsigned) h);
4772 
4773         printk(
4774 " iop_base %x, err_code %x, dvc_cntl %x, bug_fix_cntl %d,\n",
4775                 h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
4776 
4777         printk(
4778 " bus_type %d, isr_callback %x, exe_callback %x, init_sdtr %x,\n",
4779                 h->bus_type, (unsigned) h->isr_callback, (unsigned) h->exe_callback,
4780                 (unsigned) h->init_sdtr);
4781 
4782         printk(
4783 " sdtr_done %x, use_tagged_qng %x, unit_not_ready %x, chip_no %x,\n",
4784                 (unsigned) h->sdtr_done, (unsigned) h->use_tagged_qng,
4785                 (unsigned) h->unit_not_ready, (unsigned) h->chip_no);
4786                 
4787         printk(
4788 " queue_full_or_busy %x, start_motor %x, scsi_reset_wait %x, irq_no %x,\n",
4789                 (unsigned) h->queue_full_or_busy, (unsigned) h->start_motor,
4790                 (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
4791 
4792         printk(
4793 " is_in_int %x, max_total_qng %x, cur_total_qng %x, in_critical_cnt %x,\n",
4794                 (unsigned) h->is_in_int, (unsigned) h->max_total_qng,
4795                 (unsigned) h->cur_total_qng, (unsigned) h->in_critical_cnt);
4796 
4797         printk(
4798 " last_q_shortage %x, init_state %x, no_scam %x, pci_fix_asyn_xfer %x,\n",
4799                 (unsigned) h->last_q_shortage, (unsigned) h->init_state,
4800                 (unsigned) h->no_scam, (unsigned) h->pci_fix_asyn_xfer);
4801 
4802         printk(
4803 " int_count %ld, req_count %ld, busy_count %ld, cfg %x, saved_ptr2func %x\n",
4804                 h->int_count, h->req_count, h->busy_count, (unsigned) h->cfg,
4805                 (unsigned) h->saved_ptr2func);
4806 }
4807 
4808 /*
4809  * asc_prt_dvc_cfg()
4810  */
4811 STATIC void 
4812 asc_prt_dvc_cfg(ASC_DVC_CFG *h)
     /* [previous][next][first][last][top][bottom][index][help] */
4813 {
4814         printk("ASC_DVC_CFG at addr %x\n", (unsigned) h);
4815 
4816         printk(
4817 " can_tagged_qng %x, cmd_qng_enabled %x, disc_enable %x, res %x,\n",
4818                         h->can_tagged_qng, h->cmd_qng_enabled, h->disc_enable, h->res);
4819 
4820         printk(
4821 " chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
4822                          h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
4823                          h->chip_version);
4824 
4825         printk(
4826 " pci_device_id %d, lib_serial_no %d, lib_version %d, mcode_date %d,\n",
4827                   h->pci_device_id, h->lib_serial_no, h->lib_version, h->mcode_date);
4828 
4829         printk(
4830 " mcode_version %d, overrun_buf %x\n",
4831                         h->mcode_version, (unsigned) h->overrun_buf);
4832 }
4833 
4834 /*
4835  * asc_prt_scsi_q()
4836  */
4837 STATIC void 
4838 asc_prt_scsi_q(ASC_SCSI_Q *q)
     /* [previous][next][first][last][top][bottom][index][help] */
4839 {
4840         ASC_SG_HEAD     *sgp;
4841         int i;
4842 
4843         printk("ASC_SCSI_Q at addr %x\n", (unsigned) q);
4844 
4845         printk(
4846 " target_ix %u, target_lun %u, srb_ptr %x, tag_code %u,\n",
4847                         q->q2.target_ix, q->q1.target_lun,
4848                         (unsigned) q->q2.srb_ptr, q->q2.tag_code);
4849 
4850         printk(
4851 " data_addr %x, data_cnt %lu, sense_addr %x, sense_len %u,\n",
4852                         (unsigned) q->q1.data_addr, q->q1.data_cnt,
4853                         (unsigned) q->q1.sense_addr, q->q1.sense_len);
4854 
4855         printk(
4856 " cdbptr %x, cdb_len %u, sg_head %x, sg_queue_cnt %u\n",
4857                         (unsigned) q->cdbptr, q->q2.cdb_len,
4858                         (unsigned) q->sg_head, q->q1.sg_queue_cnt);
4859 
4860         if (q->sg_head) {
4861                 sgp = q->sg_head;
4862                 printk("ASC_SG_HEAD at addr %x\n", (unsigned) sgp);
4863                 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, sgp->queue_cnt);
4864                 for (i = 0; i < sgp->entry_cnt; i++) {
4865                         printk(" [%u]: addr %x, bytes %lu\n",
4866                                 i, (unsigned) sgp->sg_list[i].addr, sgp->sg_list[i].bytes);
4867                 }
4868 
4869         }
4870 }
4871 
4872 /*
4873  * asc_prt_qdone_info()
4874  */
4875 STATIC void 
4876 asc_prt_qdone_info(ASC_QDONE_INFO *q)
     /* [previous][next][first][last][top][bottom][index][help] */
4877 {
4878         printk("ASC_QDONE_INFO at addr %x\n", (unsigned) q);
4879         printk(
4880 " srb_ptr %x, target_ix %u, cdb_len %u, tag_code %u, done_stat %x\n",
4881                         (unsigned) q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
4882                         q->d2.tag_code, q->d3.done_stat);
4883         printk(
4884 " host_stat %x, scsi_stat %x, scsi_msg %x\n",
4885                         q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
4886 }
4887 
4888 /*
4889  * asc_prt_hex()
4890  *
4891  * Print hexadecimal output in 4 byte groupings 32 bytes 
4892  * or 8 double-words per line.
4893  */
4894 STATIC void 
4895 asc_prt_hex(char *f, uchar *s, int l)
     /* [previous][next][first][last][top][bottom][index][help] */
4896 {
4897         int                     i;
4898         int                     j;
4899         int                     k;
4900         int                     m;
4901 
4902         printk("%s: (%d bytes)\n", f, l);
4903 
4904         for (i = 0; i < l; i += 32) {
4905                 
4906                 /* Display a maximum of 8 double-words per line. */
4907                 if ((k = (l - i) / 4) >= 8) {
4908                         k = 8;
4909                         m = 0;
4910                 } else {
4911                         m = (l - i) % 4 ;
4912                 }
4913 
4914                 for (j = 0; j < k; j++) {
4915                         printk(" %2.2X%2.2X%2.2X%2.2X",
4916                                 (unsigned) s[i+(j*4)], (unsigned) s[i+(j*4)+1],
4917                                 (unsigned) s[i+(j*4)+2], (unsigned) s[i+(j*4)+3]);
4918                 }
4919 
4920                 switch (m) {
4921                 case 0:
4922                 default:
4923                         break;
4924                 case 1:
4925                         printk(" %2.2X",
4926                                 (unsigned) s[i+(j*4)+4]);
4927                         break;
4928                 case 2:
4929                         printk(" %2.2X%2.2X",
4930                                 (unsigned) s[i+(j*4)+4],
4931                                 (unsigned) s[i+(j*4)+5]);
4932                         break;
4933                 case 3:
4934                         printk(" %2.2X%2.2X%2.2X",
4935                                 (unsigned) s[i+(j*4)+4],
4936                                 (unsigned) s[i+(j*4)+5],
4937                                 (unsigned) s[i+(j*4)+6]);
4938                         break;
4939                 }
4940 
4941                 printk("\n");
4942         }
4943 }
4944 
4945 /*
4946  * interrupts_enabled()
4947  *
4948  * Return 1 if interrupts are enabled, otherwise return 0.
4949  */
4950 STATIC int
4951 interrupts_enabled(void)
     /* [previous][next][first][last][top][bottom][index][help] */
4952 {
4953         int flags;
4954 
4955         save_flags(flags);
4956         if (flags & 0x0200) {
4957                 return ASC_TRUE;
4958         } else {
4959                 return ASC_FALSE;
4960         }
4961 }
4962 
4963 #endif /* ADVANSYS_DEBUG */
4964 
4965 
4966 /*
4967  * --- Asc Library Functions
4968  */
4969 
4970 ushort
4971 AscGetEisaChipCfg(
     /* [previous][next][first][last][top][bottom][index][help] */
4972                                          PortAddr iop_base
4973 )
4974 {
4975         PortAddr            eisa_cfg_iop;
4976 
4977         eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
4978           (PortAddr) (ASC_EISA_CFG_IOP_MASK);
4979         return (inpw(eisa_cfg_iop));
4980 }
4981 
4982 uchar
4983 AscSetChipScsiID(
     /* [previous][next][first][last][top][bottom][index][help] */
4984                                         PortAddr iop_base,
4985                                         uchar new_host_id
4986 )
4987 {
4988         ushort              cfg_lsw;
4989 
4990         if (AscGetChipScsiID(iop_base) == new_host_id) {
4991                 return (new_host_id);
4992         }
4993         cfg_lsw = AscGetChipCfgLsw(iop_base);
4994         cfg_lsw &= 0xF8FF;
4995         cfg_lsw |= (ushort) ((new_host_id & ASC_MAX_TID) << 8);
4996         AscSetChipCfgLsw(iop_base, cfg_lsw);
4997         return (AscGetChipScsiID(iop_base));
4998 }
4999 
5000 ushort
5001 AscGetChipBiosAddress(
     /* [previous][next][first][last][top][bottom][index][help] */
5002                                                  PortAddr iop_base,
5003                                                  ushort bus_type
5004 )
5005 {
5006         ushort              cfg_lsw;
5007         ushort              bios_addr;
5008 
5009         if ((bus_type & ASC_IS_EISA) != 0) {
5010                 cfg_lsw = AscGetEisaChipCfg(iop_base);
5011                 cfg_lsw &= 0x000F;
5012                 bios_addr = (ushort) (ASC_BIOS_MIN_ADDR +
5013                                                           (cfg_lsw * ASC_BIOS_BANK_SIZE));
5014                 return (bios_addr);
5015         }
5016         cfg_lsw = AscGetChipCfgLsw(iop_base);
5017         bios_addr = (ushort) (((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) + ASC_BIOS_MIN_ADDR);
5018         return (bios_addr);
5019 }
5020 
5021 uchar
5022 AscGetChipVersion(
     /* [previous][next][first][last][top][bottom][index][help] */
5023                                          PortAddr iop_base,
5024                                          ushort bus_type
5025 )
5026 {
5027         if ((bus_type & ASC_IS_EISA) != 0) {
5028 
5029                 PortAddr            eisa_iop;
5030                 uchar               revision;
5031 
5032                 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
5033                   (PortAddr) ASC_EISA_REV_IOP_MASK;
5034                 revision = inp(eisa_iop);
5035                 return ((uchar) ((ASC_CHIP_MIN_VER_EISA - 1) + revision));
5036         }
5037         return (AscGetChipVerNo(iop_base));
5038 }
5039 
5040 ushort
5041 AscGetChipBusType(
     /* [previous][next][first][last][top][bottom][index][help] */
5042                                          PortAddr iop_base
5043 )
5044 {
5045         ushort              chip_ver;
5046 
5047         chip_ver = AscGetChipVerNo(iop_base);
5048         if ((chip_ver >= ASC_CHIP_MIN_VER_VL) &&
5049                 (chip_ver <= ASC_CHIP_MAX_VER_VL)) {
5050                 if (((iop_base & 0x0C30) == 0x0C30) ||
5051                         ((iop_base & 0x0C50) == 0x0C50)) {
5052                         return (ASC_IS_EISA);
5053                 }
5054                 return (ASC_IS_VL);
5055         } else if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
5056                            (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
5057                 if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
5058                         return (ASC_IS_ISAPNP);
5059                 }
5060                 return (ASC_IS_ISA);
5061         } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
5062                            (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
5063                 return (ASC_IS_PCI);
5064         } else {
5065                 return (0);
5066         }
5067 }
5068 
5069 void
5070 AscEnableIsaDma(
     /* [previous][next][first][last][top][bottom][index][help] */
5071                                    uchar dma_channel
5072 )
5073 {
5074         if (dma_channel < 4) {
5075                 outp(0x000B, (ushort) (0xC0 | dma_channel));
5076                 outp(0x000A, dma_channel);
5077         } else if (dma_channel < 8) {
5078 
5079                 outp(0x00D6, (ushort) (0xC0 | (dma_channel - 4)));
5080                 outp(0x00D4, (ushort) (dma_channel - 4));
5081         }
5082         return;
5083 }
5084 
5085 ulong
5086 AscLoadMicroCode(
     /* [previous][next][first][last][top][bottom][index][help] */
5087                                         PortAddr iop_base,
5088                                         ushort s_addr,
5089                                         ushort dosfar * mcode_buf,
5090                                         ushort mcode_size
5091 )
5092 {
5093         ulong               chksum;
5094         ushort              mcode_word_size;
5095         ushort              mcode_chksum;
5096 
5097         mcode_word_size = (ushort) (mcode_size >> 1);
5098         AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
5099         AscMemWordCopyToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
5100 
5101         chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
5102         mcode_chksum = (ushort) AscMemSumLramWord(iop_base,
5103                                                                                           (ushort) ASC_CODE_SEC_BEG,
5104                   (ushort) ((mcode_size - s_addr - (ushort) ASC_CODE_SEC_BEG) / 2));
5105         AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
5106         AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
5107         return (chksum);
5108 }
5109 
5110 uchar               _hextbl_[16] =
5111 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
5112  'A', 'B', 'C', 'D', 'E', 'F'};
5113 
5114 uchar               _isa_pnp_inited = 0;
5115 
5116 PortAddr            _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] =
5117 {
5118         0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
5119         ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
5120 };
5121 
5122 PortAddr
5123 AscSearchIOPortAddr(
     /* [previous][next][first][last][top][bottom][index][help] */
5124                                            PortAddr iop_beg,
5125                                            ushort bus_type
5126 )
5127 {
5128         if (bus_type & ASC_IS_VL) {
5129                 while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
5130                         if (AscGetChipVersion(iop_beg, bus_type) <= ASC_CHIP_MAX_VER_VL) {
5131                                 return (iop_beg);
5132                         }
5133                 }
5134                 return (0);
5135         }
5136         if (bus_type & ASC_IS_ISA) {
5137                 if (_isa_pnp_inited == 0) {
5138                         AscSetISAPNPWaitForKey();
5139                         _isa_pnp_inited++;
5140                 }
5141                 while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
5142                         if ((AscGetChipVersion(iop_beg, bus_type) & ASC_CHIP_VER_ISA_BIT) != 0) {
5143                                 return (iop_beg);
5144                         }
5145                 }
5146                 return (0);
5147         }
5148         if (bus_type & ASC_IS_EISA) {
5149                 if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) {
5150                         return (iop_beg);
5151                 }
5152                 return (0);
5153         }
5154         return (0);
5155 }
5156 
5157 PortAddr
5158 AscSearchIOPortAddr11(
     /* [previous][next][first][last][top][bottom][index][help] */
5159                                                  PortAddr s_addr
5160 )
5161 {
5162 
5163         int                 i;
5164         PortAddr            iop_base;
5165 
5166         for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) {
5167                 if (_asc_def_iop_base[i] > s_addr) {
5168                         break;
5169                 }
5170         }
5171         for (; i < ASC_IOADR_TABLE_MAX_IX; i++) {
5172                 iop_base = _asc_def_iop_base[i];
5173                 if (AscFindSignature(iop_base)) {
5174                         return (iop_base);
5175                 }
5176         }
5177         return (0);
5178 }
5179 
5180 int
5181 AscFindSignature(
     /* [previous][next][first][last][top][bottom][index][help] */
5182                                         PortAddr iop_base
5183 )
5184 {
5185         ushort              sig_word;
5186 
5187         if ((inp((PortAddr) (iop_base + 1)) & 0xFF) == (uchar) ASC_1000_ID1B) {
5188                 sig_word = inpw(iop_base);
5189                 if ((sig_word == (ushort) ASC_1000_ID0W) ||
5190                         (sig_word == (ushort) ASC_1000_ID0W_FIX)) {
5191                         return (1);
5192                 }
5193         }
5194         return (0);
5195 }
5196 
5197 void
5198 AscToggleIRQAct(
     /* [previous][next][first][last][top][bottom][index][help] */
5199                                    PortAddr iop_base
5200 )
5201 {
5202         AscSetChipStatus(iop_base, CIW_IRQ_ACT);
5203         AscSetChipStatus(iop_base, 0);
5204         return;
5205 }
5206 
5207 #if CC_INIT_INQ_DISPLAY
5208 
5209 #endif
5210 
5211 void
5212 AscSetISAPNPWaitForKey(
     /* [previous][next][first][last][top][bottom][index][help] */
5213                                                   void)
5214 {
5215 
5216         outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
5217         outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
5218         return;
5219 }
5220 
5221 uchar
5222 AscGetChipIRQ(
     /* [previous][next][first][last][top][bottom][index][help] */
5223                                  PortAddr iop_base,
5224                                  ushort bus_type
5225 )
5226 {
5227         ushort              cfg_lsw;
5228         uchar               chip_irq;
5229 
5230         if ((bus_type & ASC_IS_EISA) != 0) {
5231 
5232                 cfg_lsw = AscGetEisaChipCfg(iop_base);
5233                 chip_irq = (uchar) (((cfg_lsw >> 8) & 0x07) + 10);
5234                 if ((chip_irq == 13) || (chip_irq > 15)) {
5235 
5236                         return (0);
5237                 }
5238                 return (chip_irq);
5239         } else {
5240 
5241                 cfg_lsw = AscGetChipCfgLsw(iop_base);
5242 
5243                 if ((bus_type & ASC_IS_VL) != 0) {
5244 
5245                         chip_irq = (uchar) (((cfg_lsw >> 2) & 0x07));
5246                         if ((chip_irq == 0) ||
5247                                 (chip_irq == 4) ||
5248                                 (chip_irq == 7)) {
5249                                 return (0);
5250                         }
5251                         return ((uchar) (chip_irq + (ASC_MIN_IRQ_NO - 1)));
5252                 }
5253                 chip_irq = (uchar) (((cfg_lsw >> 2) & 0x03));
5254                 if (chip_irq == 3)
5255                         chip_irq += (uchar) 2;
5256                 return ((uchar) (chip_irq + ASC_MIN_IRQ_NO));
5257         }
5258 }
5259 
5260 uchar
5261 AscSetChipIRQ(
     /* [previous][next][first][last][top][bottom][index][help] */
5262                                  PortAddr iop_base,
5263                                  uchar irq_no,
5264                                  ushort bus_type
5265 )
5266 {
5267         ushort              cfg_lsw;
5268 
5269         if ((bus_type & ASC_IS_VL) != 0) {
5270 
5271                 if (irq_no != 0) {
5272                         if ((irq_no < ASC_MIN_IRQ_NO) || (irq_no > ASC_MAX_IRQ_NO)) {
5273                                 irq_no = 0;
5274                         } else {
5275                                 irq_no -= (uchar) ((ASC_MIN_IRQ_NO - 1));
5276                         }
5277                 }
5278                 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE3);
5279                 cfg_lsw |= (ushort) 0x0010;
5280                 AscSetChipCfgLsw(iop_base, cfg_lsw);
5281                 AscToggleIRQAct(iop_base);
5282 
5283                 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE0);
5284                 cfg_lsw |= (ushort) ((irq_no & 0x07) << 2);
5285                 AscSetChipCfgLsw(iop_base, cfg_lsw);
5286                 AscToggleIRQAct(iop_base);
5287 
5288                 return (AscGetChipIRQ(iop_base, bus_type));
5289 
5290         } else if ((bus_type & (ASC_IS_ISA)) != 0) {
5291 
5292                 if (irq_no == 15)
5293                         irq_no -= (uchar) 2;
5294                 irq_no -= (uchar) ASC_MIN_IRQ_NO;
5295                 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFF3);
5296                 cfg_lsw |= (ushort) ((irq_no & 0x03) << 2);
5297                 AscSetChipCfgLsw(iop_base, cfg_lsw);
5298                 return (AscGetChipIRQ(iop_base, bus_type));
5299         } else {
5300 
5301                 return (0);
5302         }
5303 }
5304 
5305 uchar
5306 AscGetChipScsiCtrl(
     /* [previous][next][first][last][top][bottom][index][help] */
5307                                           PortAddr iop_base
5308 )
5309 {
5310         uchar               sc;
5311 
5312         AscSetBank(iop_base, 1);
5313         sc = inp(iop_base + IOP_REG_SC);
5314         AscSetBank(iop_base, 0);
5315         return (sc);
5316 }
5317 
5318 extern uchar        _sdtr_period_tbl_[];
5319 
5320 int
5321 AscIsrChipHalted(
     /* [previous][next][first][last][top][bottom][index][help] */
5322                                         ASC_DVC_VAR asc_ptr_type * asc_dvc
5323 )
5324 {
5325         SDTR_XMSG           sdtr_xmsg;
5326         SDTR_XMSG           out_msg;
5327         ushort              halt_q_addr;
5328         int                 sdtr_accept;
5329         ushort              int_halt_code;
5330         ASC_SCSI_BIT_ID_TYPE scsi_busy;
5331         ASC_SCSI_BIT_ID_TYPE target_id;
5332         PortAddr            iop_base;
5333         uchar               tag_code;
5334         uchar               q_status;
5335         uchar               halt_qp;
5336         uchar               sdtr_data;
5337         uchar               target_ix;
5338         uchar               q_cntl, tid_no;
5339         uchar               cur_dvc_qng;
5340         uchar               asyn_sdtr;
5341         uchar               scsi_status;
5342 
5343         iop_base = asc_dvc->iop_base;
5344         int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
5345 
5346         halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
5347         halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
5348         target_ix = AscReadLramByte(iop_base,
5349                                    (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TARGET_IX));
5350         q_cntl = AscReadLramByte(iop_base,
5351                                                 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL));
5352         tid_no = ASC_TIX_TO_TID(target_ix);
5353         target_id = (uchar) ASC_TID_TO_TARGET_ID(tid_no);
5354         if (asc_dvc->pci_fix_asyn_xfer & target_id) {
5355 
5356                 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
5357         } else {
5358                 asyn_sdtr = 0;
5359         }
5360         if (int_halt_code == ASC_HALT_EXTMSG_IN) {
5361 
5362                 AscMemWordCopyFromLram(iop_base,
5363                                                            ASCV_MSGIN_BEG,
5364                                                            (ushort dosfar *) & sdtr_xmsg,
5365                                                            (ushort) (sizeof (SDTR_XMSG) >> 1));
5366                 if ((sdtr_xmsg.msg_type == MS_EXTEND) &&
5367                         (sdtr_xmsg.msg_len == MS_SDTR_LEN)) {
5368                         sdtr_accept = TRUE;
5369                         if (sdtr_xmsg.msg_req == MS_SDTR_CODE) {
5370                                 if (sdtr_xmsg.req_ack_offset > ASC_SYN_MAX_OFFSET) {
5371 
5372                                         sdtr_accept = FALSE;
5373                                         sdtr_xmsg.req_ack_offset = ASC_SYN_MAX_OFFSET;
5374                                 }
5375                                 sdtr_data = AscCalSDTRData(sdtr_xmsg.xfer_period,
5376                                                                                    sdtr_xmsg.req_ack_offset);
5377                                 if (sdtr_xmsg.req_ack_offset == 0) {
5378 
5379                                         q_cntl &= ~QC_MSG_OUT;
5380                                         asc_dvc->init_sdtr &= ~target_id;
5381                                         asc_dvc->sdtr_done &= ~target_id;
5382                                         AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
5383                                 } else if ((sdtr_data == 0xFF)) {
5384 
5385                                         q_cntl |= QC_MSG_OUT;
5386                                         asc_dvc->init_sdtr &= ~target_id;
5387                                         asc_dvc->sdtr_done &= ~target_id;
5388                                         AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
5389                                 } else {
5390                                         if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
5391 
5392                                                 q_cntl &= ~QC_MSG_OUT;
5393                                                 asc_dvc->sdtr_done |= target_id;
5394                                                 asc_dvc->init_sdtr |= target_id;
5395                                                 asc_dvc->pci_fix_asyn_xfer &= ~target_id;
5396                                                 AscSetChipSDTR(iop_base, sdtr_data, tid_no);
5397                                         } else {
5398 
5399                                                 q_cntl |= QC_MSG_OUT;
5400 
5401                                                 AscMsgOutSDTR(iop_base,
5402                                                                           sdtr_xmsg.xfer_period,
5403                                                                           sdtr_xmsg.req_ack_offset);
5404                                                 asc_dvc->pci_fix_asyn_xfer &= ~target_id;
5405                                                 AscSetChipSDTR(iop_base, sdtr_data, tid_no);
5406                                                 asc_dvc->sdtr_done |= target_id;
5407                                                 asc_dvc->init_sdtr |= target_id;
5408                                         }
5409                                 }
5410 
5411                                 AscWriteLramByte(iop_base,
5412                                                  (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
5413                                                                  q_cntl);
5414                                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
5415                                 return (0);
5416                         }
5417                 }
5418         } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
5419 
5420                 q_cntl |= QC_REQ_SENSE;
5421                 if (((asc_dvc->init_sdtr & target_id) != 0) &&
5422                         ((asc_dvc->sdtr_done & target_id) != 0)) {
5423 
5424                         sdtr_data = AscReadLramByte(iop_base,
5425                                   (ushort) ((ushort) ASCV_SDTR_DATA_BEG + (ushort) tid_no));
5426                         AscMsgOutSDTR(iop_base,
5427                                                   _sdtr_period_tbl_[(sdtr_data >> 4) & (uchar) (ASC_SYN_XFER_NO - 1)],
5428                                                   (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
5429                         q_cntl |= QC_MSG_OUT;
5430                 }
5431                 AscWriteLramByte(iop_base,
5432                                                  (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
5433                                                  q_cntl);
5434 
5435                 tag_code = AscReadLramByte(iop_base,
5436                                         (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE));
5437                 tag_code &= 0xDC;
5438                 AscWriteLramByte(iop_base,
5439                                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE),
5440                                                  tag_code);
5441 
5442                 q_status = AscReadLramByte(iop_base,
5443                                           (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS));
5444                 q_status |= (QS_READY | QS_BUSY);
5445                 AscWriteLramByte(iop_base,
5446                                            (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
5447                                                  q_status);
5448 
5449                 scsi_busy = AscReadLramByte(iop_base,
5450                                                                         (ushort) ASCV_SCSIBUSY_B);
5451                 scsi_busy &= ~target_id;
5452                 AscWriteLramByte(iop_base, (ushort) ASCV_SCSIBUSY_B, scsi_busy);
5453 
5454                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
5455                 return (0);
5456         } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
5457 
5458                 AscMemWordCopyFromLram(iop_base,
5459                                                            ASCV_MSGOUT_BEG,
5460                                                            (ushort dosfar *) & out_msg,
5461                                                            (ushort) (sizeof (SDTR_XMSG) >> 1));
5462 
5463                 if ((out_msg.msg_type == MS_EXTEND) &&
5464                         (out_msg.msg_len == MS_SDTR_LEN) &&
5465                         (out_msg.msg_req == MS_SDTR_CODE)) {
5466 
5467                         asc_dvc->init_sdtr &= ~target_id;
5468                         asc_dvc->sdtr_done &= ~target_id;
5469                         AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
5470 
5471                 } else {
5472 
5473                 }
5474 
5475                 q_cntl &= ~QC_MSG_OUT;
5476                 AscWriteLramByte(iop_base,
5477                                                  (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
5478                                                  q_cntl);
5479                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
5480                 return (0);
5481         } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
5482 
5483                 scsi_status = AscReadLramByte(iop_base,
5484                   (ushort) ((ushort) halt_q_addr + (ushort) ASC_SCSIQ_SCSI_STATUS));
5485                 cur_dvc_qng = AscReadLramByte(iop_base,
5486                                          (ushort) ((ushort) ASC_QADR_BEG + (ushort) target_ix));
5487                 if ((cur_dvc_qng > 0) &&
5488                         (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
5489 
5490                         scsi_busy = AscReadLramByte(iop_base,
5491                                                                                 (ushort) ASCV_SCSIBUSY_B);
5492                         scsi_busy |= target_id;
5493                         AscWriteLramByte(iop_base,
5494                                                          (ushort) ASCV_SCSIBUSY_B, scsi_busy);
5495                         asc_dvc->queue_full_or_busy |= target_id;
5496 
5497                         if (scsi_status == SS_QUEUE_FULL) {
5498                                 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
5499                                         cur_dvc_qng -= 1;
5500                                         asc_dvc->max_dvc_qng[tid_no] = cur_dvc_qng;
5501 
5502                                         AscWriteLramByte(iop_base,
5503                                                                          (ushort) ((ushort) ASCV_MAX_DVC_QNG_BEG + (ushort) tid_no),
5504                                                                          cur_dvc_qng);
5505                                 }
5506                         }
5507                 }
5508                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
5509                 return (0);
5510         }
5511         return (0);
5512 }
5513 
5514 uchar
5515 _AscCopyLramScsiDoneQ(
     /* [previous][next][first][last][top][bottom][index][help] */
5516                                                  PortAddr iop_base,
5517                                                  ushort q_addr,
5518                                                  ASC_QDONE_INFO dosfar * scsiq,
5519                                                  ulong max_dma_count
5520 )
5521 {
5522         ushort              _val;
5523         uchar               sg_queue_cnt;
5524 
5525         DvcGetQinfo(iop_base,
5526                                 (ushort) (q_addr + (ushort) ASC_SCSIQ_DONE_INFO_BEG),
5527                                 (ushort dosfar *) scsiq,
5528                           (ushort) ((sizeof (ASC_SCSIQ_2) + sizeof (ASC_SCSIQ_3)) / 2));
5529 
5530 #if !CC_LITTLE_ENDIAN_HOST
5531         AscAdjEndianQDoneInfo(scsiq);
5532 #endif
5533 
5534         _val = AscReadLramWord(iop_base,
5535                                                    (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS));
5536         scsiq->q_status = (uchar) _val;
5537         scsiq->q_no = (uchar) (_val >> 8);
5538 
5539         _val = AscReadLramWord(iop_base,
5540                                                    (ushort) (q_addr + (ushort) ASC_SCSIQ_B_CNTL));
5541         scsiq->cntl = (uchar) _val;
5542         sg_queue_cnt = (uchar) (_val >> 8);
5543 
5544         _val = AscReadLramWord(iop_base,
5545                                                 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SENSE_LEN));
5546         scsiq->sense_len = (uchar) _val;
5547         scsiq->user_def = (uchar) (_val >> 8);
5548 
5549         scsiq->remain_bytes = AscReadLramDWord(iop_base,
5550                                  (ushort) (q_addr + (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT));
5551         scsiq->remain_bytes &= max_dma_count;
5552 
5553         return (sg_queue_cnt);
5554 }
5555 
5556 int
5557 AscIsrQDone(
     /* [previous][next][first][last][top][bottom][index][help] */
5558                            ASC_DVC_VAR asc_ptr_type * asc_dvc
5559 )
5560 {
5561         uchar               next_qp;
5562         uchar               i;
5563         uchar               n_q_used;
5564         uchar               sg_list_qp;
5565         uchar               sg_queue_cnt;
5566         uchar               done_q_tail;
5567 
5568         uchar               tid_no;
5569         ASC_SCSI_BIT_ID_TYPE scsi_busy;
5570         ASC_SCSI_BIT_ID_TYPE target_id;
5571         PortAddr            iop_base;
5572         ushort              q_addr;
5573         ushort              sg_q_addr;
5574         uchar               cur_target_qng;
5575         ASC_QDONE_INFO      scsiq_buf;
5576         ASC_QDONE_INFO dosfar *scsiq;
5577         int                 false_overrun;
5578         ASC_ISR_CALLBACK    asc_isr_callback;
5579 
5580         uchar               tag_code;
5581 
5582 #if CC_LINK_BUSY_Q
5583         ushort              n_busy_q_done;
5584 
5585 #endif
5586 
5587         iop_base = asc_dvc->iop_base;
5588         asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
5589 
5590         n_q_used = 1;
5591         scsiq = (ASC_QDONE_INFO dosfar *) & scsiq_buf;
5592         done_q_tail = (uchar) AscGetVarDoneQTail(iop_base);
5593         q_addr = ASC_QNO_TO_QADDR(done_q_tail);
5594         next_qp = AscReadLramByte(iop_base,
5595                                                           (ushort) (q_addr + (ushort) ASC_SCSIQ_B_FWD));
5596         if (next_qp != ASC_QLINK_END) {
5597 
5598                 AscPutVarDoneQTail(iop_base, next_qp);
5599                 q_addr = ASC_QNO_TO_QADDR(next_qp);
5600 
5601                 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count);
5602 
5603                 AscWriteLramByte(iop_base,
5604                                                  (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
5605                          (uchar) (scsiq->q_status & (uchar) ~ (QS_READY | QS_ABORTED)));
5606                 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
5607                 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
5608                 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
5609                         sg_q_addr = q_addr;
5610                         sg_list_qp = next_qp;
5611                         for (i = 0; i < sg_queue_cnt; i++) {
5612                                 sg_list_qp = AscReadLramByte(