|
|
1.1.1.2 ! root 1: /* $Id: advansys.c,v 1.1.4.1 2005/06/02 18:52:38 ams Exp $ */ 1.1 root 2: #define ASC_VERSION "3.1E" /* AdvanSys Driver Version */ 3: 4: /* 5: * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters 6: * 7: * Copyright (c) 1995-1998 Advanced System Products, Inc. 8: * All Rights Reserved. 9: * 10: * Redistribution and use in source and binary forms, with or without 11: * modification, are permitted provided that redistributions of source 12: * code retain the above copyright notice and this comment without 13: * modification. 14: * 15: * There is an AdvanSys Linux WWW page at: 16: * http://www.advansys.com/linux.html 17: * 18: * The latest version of the AdvanSys driver is available at: 19: * ftp://ftp.advansys.com/pub/linux/linux.tgz 20: * 21: * Please send questions, comments, bug reports to: 22: * [email protected] (Bob Frey) 23: */ 24: 25: /* 26: 27: Documentation for the AdvanSys Driver 28: 29: A. Linux Kernel Testing 30: B. Adapters Supported by this Driver 31: C. Linux v1.2.X - Directions for Adding the AdvanSys Driver 32: D. Linux v1.3.1 - v1.3.57 - Directions for Adding the AdvanSys Driver 33: E. Linux v1.3.58 and Newer - Upgrading the AdvanSys Driver 34: F. Source Comments 35: G. Driver Compile Time Options and Debugging 36: H. Driver LILO Option 37: I. Release History 38: J. Known Problems or Issues 39: K. Credits 40: L. AdvanSys Contact Information 41: 42: A. Linux Kernel Testing 43: 44: This driver has been tested in the following Linux kernels: v1.2.13, 45: v1.3.57, v2.0.33, v2.1.77. These kernel versions are major releases 46: of Linux or the latest Linux kernel versions available when this version 47: of the driver was released. The driver should also work in earlier 48: versions of the Linux kernel. Beginning with v1.3.58 the AdvanSys driver 49: is included with all Linux kernels. Please refer to sections C, D, and 50: E for instructions on adding or upgrading the AdvanSys driver. 51: 52: B. Adapters Supported by this Driver 53: 54: AdvanSys (Advanced System Products, Inc.) manufactures the following 55: RISC-based, Bus-Mastering, Fast (10 Mhz) and Ultra (20 Mhz) Narrow 56: (8-bit transfer) SCSI Host Adapters for the ISA, EISA, VL, and PCI 57: buses and RISC-based, Bus-Mastering, Ultra (20 Mhz) Wide (16-bit 58: transfer) SCSI Host Adapters for the PCI bus. 59: 60: The CDB counts below indicate the number of SCSI CDB (Command 61: Descriptor Block) requests that can be stored in the RISC chip 62: cache and board LRAM. A CDB is a single SCSI command. The driver 63: detect routine will display the number of CDBs available for each 64: adapter detected. The number of CDBs used by the driver can be 65: lowered in the BIOS by changing the 'Host Queue Size' adapter setting. 66: 67: Connectivity Products: 68: ABP510/5150 - Bus-Master ISA (240 CDB) (Footnote 1) 69: ABP5140 - Bus-Master ISA PnP (16 CDB) (Footnote 1, 3) 70: ABP5142 - Bus-Master ISA PnP with floppy (16 CDB) (Footnote 4) 71: ABP920 - Bus-Master PCI (16 CDB) 72: ABP930 - Bus-Master PCI (16 CDB) (Footnote 5) 73: ABP930U - Bus-Master PCI Ultra (16 CDB) 74: ABP930UA - Bus-Master PCI Ultra (16 CDB) 75: ABP960 - Bus-Master PCI MAC/PC (16 CDB) (Footnote 2) 76: ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB) (Footnote 2) 77: 78: Single Channel Products: 79: ABP542 - Bus-Master ISA with floppy (240 CDB) 80: ABP742 - Bus-Master EISA (240 CDB) 81: ABP842 - Bus-Master VL (240 CDB) 82: ABP940 - Bus-Master PCI (240 CDB) 83: ABP940U - Bus-Master PCI Ultra (240 CDB) 84: ABP970 - Bus-Master PCI MAC/PC (240 CDB) 85: ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB) 86: ABP940UW - Bus-Master PCI Ultra-Wide (240 CDB) 87: 88: Multi Channel Products: 89: ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel) 90: ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel) 91: ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel) 92: ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel) 93: ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel) 94: 95: Footnotes: 96: 1. This board has been shipped by HP with the 4020i CD-R drive. 97: The board has no BIOS so it cannot control a boot device, but 98: it can control any secondary SCSI device. 99: 2. This board has been sold by Iomega as a Jaz Jet PCI adapter. 100: 3. This board has been sold by SIIG as the i540 SpeedMaster. 101: 4. This board has been sold by SIIG as the i542 SpeedMaster. 102: 5. This board has been sold by SIIG as the Fast SCSI Pro PCI. 103: 104: C. Linux v1.2.X - Directions for Adding the AdvanSys Driver 105: 106: These directions apply to v1.2.13. For versions that follow v1.2.13. 107: but precede v1.3.57 some of the changes for Linux v1.3.X listed 108: below may need to be modified or included. A patch is available 109: for v1.2.13 from the AdvanSys WWW and FTP sites. 110: 111: There are two source files: advansys.h and advansys.c. Copy 112: both of these files to the directory /usr/src/linux/drivers/scsi. 113: 114: 1. Add the following line to /usr/src/linux/arch/i386/config.in 115: after "comment 'SCSI low-level drivers'": 116: 117: bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y 118: 119: 2. Add the following lines to /usr/src/linux/drivers/scsi/hosts.c 120: after "#include "hosts.h"": 121: 122: #ifdef CONFIG_SCSI_ADVANSYS 123: #include "advansys.h" 124: #endif 125: 126: and after "static Scsi_Host_Template builtin_scsi_hosts[] =": 127: 128: #ifdef CONFIG_SCSI_ADVANSYS 129: ADVANSYS, 130: #endif 131: 132: 3. Add the following lines to /usr/src/linux/drivers/scsi/Makefile: 133: 134: ifdef CONFIG_SCSI_ADVANSYS 135: SCSI_SRCS := $(SCSI_SRCS) advansys.c 136: SCSI_OBJS := $(SCSI_OBJS) advansys.o 137: else 138: SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o 139: endif 140: 141: 4. (Optional) If you would like to enable the LILO command line 142: and /etc/lilo.conf 'advansys' option, make the following changes. 143: This option can be used to disable I/O port scanning or to limit 144: I/O port scanning to specific addresses. Refer to the 'Driver 145: LILO Option' section below. Add the following lines to 146: /usr/src/linux/init/main.c in the prototype section: 147: 148: extern void advansys_setup(char *str, int *ints); 149: 150: and add the following lines to the bootsetups[] array. 151: 152: #ifdef CONFIG_SCSI_ADVANSYS 153: { "advansys=", advansys_setup }, 154: #endif 155: 156: 5. If you have the HP 4020i CD-R driver and Linux v1.2.X you should 157: add a fix to the CD-ROM target driver. This fix will allow 158: you to mount CDs with the iso9660 file system. Linux v1.3.X 159: already has this fix. In the file /usr/src/linux/drivers/scsi/sr.c 160: and function get_sectorsize() after the line: 161: 162: if(scsi_CDs[i].sector_size == 0) scsi_CDs[i].sector_size = 2048; 163: 164: add the following line: 165: 166: if(scsi_CDs[i].sector_size == 2340) scsi_CDs[i].sector_size = 2048; 167: 168: 6. In the directory /usr/src/linux run 'make config' to configure 169: the AdvanSys driver, then run 'make vmlinux' or 'make zlilo' to 170: make the kernel. If the AdvanSys driver is not configured, then 171: a loadable module can be built by running 'make modules' and 172: 'make modules_install'. Use 'insmod' and 'rmmod' to install 173: and remove advansys.o. 174: 175: D. Linux v1.3.1 - v1.3.57 - Directions for Adding the AdvanSys Driver 176: 177: These directions apply to v1.3.57. For versions that precede v1.3.57 178: some of these changes may need to be modified or eliminated. A patch 179: is available for v1.3.57 from the AdvanSys WWW and FTP sites. 180: Beginning with v1.3.58 this driver is included with the Linux 181: distribution eliminating the need for making any changes. 182: 183: There are two source files: advansys.h and advansys.c. Copy 184: both of these files to the directory /usr/src/linux/drivers/scsi. 185: 186: 1. Add the following line to /usr/src/linux/drivers/scsi/Config.in 187: after "comment 'SCSI low-level drivers'": 188: 189: dep_tristate 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS $CONFIG_SCSI 190: 191: 2. Add the following lines to /usr/src/linux/drivers/scsi/hosts.c 192: after "#include "hosts.h"": 193: 194: #ifdef CONFIG_SCSI_ADVANSYS 195: #include "advansys.h" 196: #endif 197: 198: and after "static Scsi_Host_Template builtin_scsi_hosts[] =": 199: 200: #ifdef CONFIG_SCSI_ADVANSYS 201: ADVANSYS, 202: #endif 203: 204: 3. Add the following lines to /usr/src/linux/drivers/scsi/Makefile: 205: 206: ifeq ($(CONFIG_SCSI_ADVANSYS),y) 207: L_OBJS += advansys.o 208: else 209: ifeq ($(CONFIG_SCSI_ADVANSYS),m) 210: M_OBJS += advansys.o 211: endif 212: endif 213: 214: 4. Add the following line to /usr/src/linux/include/linux/proc_fs.h 215: in the enum scsi_directory_inos array: 216: 217: PROC_SCSI_ADVANSYS, 218: 219: 5. (Optional) If you would like to enable the LILO command line 220: and /etc/lilo.conf 'advansys' option, make the following changes. 221: This option can be used to disable I/O port scanning or to limit 222: I/O port scanning to specific addresses. Refer to the 'Driver 223: LILO Option' section below. Add the following lines to 224: /usr/src/linux/init/main.c in the prototype section: 225: 226: extern void advansys_setup(char *str, int *ints); 227: 228: and add the following lines to the bootsetups[] array. 229: 230: #ifdef CONFIG_SCSI_ADVANSYS 231: { "advansys=", advansys_setup }, 232: #endif 233: 234: 6. In the directory /usr/src/linux run 'make config' to configure 235: the AdvanSys driver, then run 'make vmlinux' or 'make zlilo' to 236: make the kernel. If the AdvanSys driver is not configured, then 237: a loadable module can be built by running 'make modules' and 238: 'make modules_install'. Use 'insmod' and 'rmmod' to install 239: and remove advansys.o. 240: 241: E. Linux v1.3.58 and Newer - Upgrading the AdvanSys Driver 242: 243: To upgrade the AdvanSys driver in a Linux v1.3.58 and newer 244: kernel, first check the version of the current driver. The 245: version is defined by the manifest constant ASC_VERSION at 246: the beginning of advansys.c. The new driver should have a 247: ASC_VERSION value greater than the current version. To install 248: the new driver rename advansys.c and advansys.h in the Linux 249: kernel source tree drivers/scsi directory to different names 250: or save them to a different directory in case you want to revert 251: to the old version of the driver. After the old driver is saved 252: copy the new advansys.c and advansys.h to drivers/scsi, rebuild 253: the kernel, and install the new kernel. No other changes are needed. 254: 255: F. Source Comments 256: 257: 1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'. 258: 259: 2. This driver should be maintained in multiple files. But to make 260: it easier to include with Linux and to follow Linux conventions, 261: the whole driver is maintained in the source files advansys.h and 262: advansys.c. In this file logical sections of the driver begin with 263: a comment that contains '---'. The following are the logical sections 264: of the driver below. 265: 266: --- Linux Version 267: --- Linux Include Files 268: --- Driver Options 269: --- Debugging Header 270: --- Asc Library Constants and Macros 271: --- Adv Library Constants and Macros 272: --- Driver Constants and Macros 273: --- Driver Structures 274: --- Driver Data 275: --- Driver Function Prototypes 276: --- Linux 'Scsi_Host_Template' and advansys_setup() Functions 277: --- Loadable Driver Support 278: --- Miscellaneous Driver Functions 279: --- Functions Required by the Asc Library 280: --- Functions Required by the Adv Library 281: --- Tracing and Debugging Functions 282: --- Asc Library Functions 283: --- Adv Library Functions 284: 285: 3. The string 'XXX' is used to flag code that needs to be re-written 286: or that contains a problem that needs to be addressed. 287: 288: 4. I have stripped comments from and reformatted the source for the 289: Asc Library and Adv Library to reduce the size of this file. This 290: source can be found under the following headings. The Asc Library 291: is used to support Narrow Boards. The Adv Library is used to 292: support Wide Boards. 293: 294: --- Asc Library Constants and Macros 295: --- Adv Library Constants and Macros 296: --- Asc Library Functions 297: --- Adv Library Functions 298: 299: G. Driver Compile Time Options and Debugging 300: 301: In this source file the following constants can be defined. They are 302: defined in the source below. Both of these options are enabled by 303: default. 304: 305: 1. ADVANSYS_ASSERT - Enable driver assertions (Def: Enabled) 306: 307: Enabling this option adds assertion logic statements to the 308: driver. If an assertion fails a message will be displayed to 309: the console, but the system will continue to operate. Any 310: assertions encountered should be reported to the person 311: responsible for the driver. Assertion statements may proactively 312: detect problems with the driver and facilitate fixing these 313: problems. Enabling assertions will add a small overhead to the 314: execution of the driver. 315: 316: 2. ADVANSYS_DEBUG - Enable driver debugging (Def: Disabled) 317: 318: Enabling this option adds tracing functions to the driver and 319: the ability to set a driver tracing level at boot time. This 320: option will also export symbols not required outside the driver to 321: the kernel name space. This option is very useful for debugging 322: the driver, but it will add to the size of the driver execution 323: image and add overhead to the execution of the driver. 324: 325: The amount of debugging output can be controlled with the global 326: variable 'asc_dbglvl'. The higher the number the more output. By 327: default the debug level is 0. 328: 329: If the driver is loaded at boot time and the LILO Driver Option 330: is included in the system, the debug level can be changed by 331: specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The 332: first three hex digits of the pseudo I/O Port must be set to 333: 'deb' and the fourth hex digit specifies the debug level: 0 - F. 334: The following command line will look for an adapter at 0x330 335: and set the debug level to 2. 336: 337: linux advansys=0x330,0,0,0,0xdeb2 338: 339: If the driver is built as a loadable module this variable can be 340: defined when the driver is loaded. The following insmod command 341: will set the debug level to one. 342: 343: insmod advansys.o asc_dbglvl=1 344: 345: Debugging Message Levels: 346: 0: Errors Only 347: 1: High-Level Tracing 348: 2-N: Verbose Tracing 349: 350: I don't know the approved way for turning on printk()s to the 351: console. Here's a program I use to do this. Debug output is 352: logged in /var/adm/messages. 353: 354: main() 355: { 356: syscall(103, 7, 0, 0); 357: } 358: 359: I found that increasing LOG_BUF_LEN to 40960 in kernel/printk.c 360: prevents most level 1 debug messages from being lost. 361: 362: 3. ADVANSYS_STATS - Enable statistics (Def: Enabled >= v1.3.0) 363: 364: Enabling this option adds statistics collection and display 365: through /proc to the driver. The information is useful for 366: monitoring driver and device performance. It will add to the 367: size of the driver execution image and add minor overhead to 368: the execution of the driver. 369: 370: Statistics are maintained on a per adapter basis. Driver entry 371: point call counts and transfer size counts are maintained. 372: Statistics are only available for kernels greater than or equal 373: to v1.3.0 with the CONFIG_PROC_FS (/proc) file system configured. 374: 375: AdvanSys SCSI adapter files have the following path name format: 376: 377: /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)] 378: 379: This information can be displayed with cat. For example: 380: 381: cat /proc/scsi/advansys/0 382: 383: When ADVANSYS_STATS is not defined the AdvanSys /proc files only 384: contain adapter and device configuration information. 385: 386: H. Driver LILO Option 387: 388: If init/main.c is modified as described in the 'Directions for Adding 389: the AdvanSys Driver to Linux' section (B.4.) above, the driver will 390: recognize the 'advansys' LILO command line and /etc/lilo.conf option. 391: This option can be used to either disable I/O port scanning or to limit 392: scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and 393: PCI boards will still be searched for and detected. This option only 394: affects searching for ISA and VL boards. 395: 396: Examples: 397: 1. Eliminate I/O port scanning: 398: boot: linux advansys= 399: or 400: boot: linux advansys=0x0 401: 2. Limit I/O port scanning to one I/O port: 402: boot: linux advansys=0x110 403: 3. Limit I/O port scanning to four I/O ports: 404: boot: linux advansys=0x110,0x210,0x230,0x330 405: 406: For a loadable module the same effect can be achieved by setting 407: the 'asc_iopflag' variable and 'asc_ioport' array when loading 408: the driver, e.g. 409: 410: insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330 411: 412: If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_IOPORT_PROBE + 1) 413: I/O Port may be added to specify the driver debug level. Refer to 414: the 'Driver Compile Time Options and Debugging' section above for 415: more information. 416: 417: I. Release History 418: 419: BETA-1.0 (12/23/95): 420: First Release 421: 422: BETA-1.1 (12/28/95): 423: 1. Prevent advansys_detect() from being called twice. 424: 2. Add LILO 0xdeb[0-f] option to set 'asc_dbglvl'. 425: 426: 1.2 (1/12/96): 427: 1. Prevent re-entrancy in the interrupt handler which 428: resulted in the driver hanging Linux. 429: 2. Fix problem that prevented ABP-940 cards from being 430: recognized on some PCI motherboards. 431: 3. Add support for the ABP-5140 PnP ISA card. 432: 4. Fix check condition return status. 433: 5. Add conditionally compiled code for Linux v1.3.X. 434: 435: 1.3 (2/23/96): 436: 1. Fix problem in advansys_biosparam() that resulted in the 437: wrong drive geometry being returned for drives > 1GB with 438: extended translation enabled. 439: 2. Add additional tracing during device initialization. 440: 3. Change code that only applies to ISA PnP adapter. 441: 4. Eliminate 'make dep' warning. 442: 5. Try to fix problem with handling resets by increasing their 443: timeout value. 444: 445: 1.4 (5/8/96): 446: 1. Change definitions to eliminate conflicts with other subsystems. 447: 2. Add versioning code for the shared interrupt changes. 448: 3. Eliminate problem in asc_rmqueue() with iterating after removing 449: a request. 450: 4. Remove reset request loop problem from the "Known Problems or 451: Issues" section. This problem was isolated and fixed in the 452: mid-level SCSI driver. 453: 454: 1.5 (8/8/96): 455: 1. Add support for ABP-940U (PCI Ultra) adapter. 456: 2. Add support for IRQ sharing by setting the SA_SHIRQ flag for 457: request_irq and supplying a dev_id pointer to both request_irq() 458: and free_irq(). 459: 3. In AscSearchIOPortAddr11() restore a call to check_region() which 460: should be used before I/O port probing. 461: 4. Fix bug in asc_prt_hex() which resulted in the displaying 462: the wrong data. 463: 5. Incorporate miscellaneous Asc Library bug fixes and new microcode. 464: 6. Change driver versioning to be specific to each Linux sub-level. 465: 7. Change statistics gathering to be per adapter instead of global 466: to the driver. 467: 8. Add more information and statistics to the adapter /proc file: 468: /proc/scsi/advansys[0...]. 469: 9. Remove 'cmd_per_lun' from the "Known Problems or Issues" list. 470: This problem has been addressed with the SCSI mid-level changes 471: made in v1.3.89. The advansys_select_queue_depths() function 472: was added for the v1.3.89 changes. 473: 474: 1.6 (9/10/96): 475: 1. Incorporate miscellaneous Asc Library bug fixes and new microcode. 476: 477: 1.7 (9/25/96): 478: 1. Enable clustering and optimize the setting of the maximum number 479: of scatter gather elements for any particular board. Clustering 480: increases CPU utilization, but results in a relatively larger 481: increase in I/O throughput. 482: 2. Improve the performance of the request queuing functions by 483: adding a last pointer to the queue structure. 484: 3. Correct problems with reset and abort request handling that 485: could have hung or crashed Linux. 486: 4. Add more information to the adapter /proc file: 487: /proc/scsi/advansys[0...]. 488: 5. Remove the request timeout issue form the driver issues list. 489: 6. Miscellaneous documentation additions and changes. 490: 491: 1.8 (10/4/96): 492: 1. Make changes to handle the new v2.1.0 kernel memory mapping 493: in which a kernel virtual address may not be equivalent to its 494: bus or DMA memory address. 495: 2. Change abort and reset request handling to make it yet even 496: more robust. 497: 3. Try to mitigate request starvation by sending ordered requests 498: to heavily loaded, tag queuing enabled devices. 499: 4. Maintain statistics on request response time. 500: 5. Add request response time statistics and other information to 501: the adapter /proc file: /proc/scsi/advansys[0...]. 502: 503: 1.9 (10/21/96): 504: 1. Add conditionally compiled code (ASC_QUEUE_FLOW_CONTROL) to 505: make use of mid-level SCSI driver device queue depth flow 506: control mechanism. This will eliminate aborts caused by a 507: device being unable to keep up with requests and eliminate 508: repeat busy or QUEUE FULL status returned by a device. 509: 2. Incorporate miscellaneous Asc Library bug fixes. 510: 3. To allow the driver to work in kernels with broken module 511: support set 'cmd_per_lun' if the driver is compiled as a 512: module. This change affects kernels v1.3.89 to present. 513: 4. Remove PCI BIOS address from the driver banner. The PCI BIOS 514: is relocated by the motherboard BIOS and its new address can 515: not be determined by the driver. 516: 5. Add mid-level SCSI queue depth information to the adapter 517: /proc file: /proc/scsi/advansys[0...]. 518: 519: 2.0 (11/14/96): 520: 1. Change allocation of global structures used for device 521: initialization to guarantee they are in DMA-able memory. 522: Previously when the driver was loaded as a module these 523: structures might not have been in DMA-able memory, causing 524: device initialization to fail. 525: 526: 2.1 (12/30/96): 527: 1. In advansys_reset(), if the request is a synchronous reset 528: request, even if the request serial number has changed, then 529: complete the request. 530: 2. Add Asc Library bug fixes including new microcode. 531: 3. Clear inquiry buffer before using it. 532: 4. Correct ifdef typo. 533: 534: 2.2 (1/15/97): 535: 1. Add Asc Library bug fixes including new microcode. 536: 2. Add synchronous data transfer rate information to the 537: adapter /proc file: /proc/scsi/advansys[0...]. 538: 3. Change ADVANSYS_DEBUG to be disabled by default. This 539: will reduce the size of the driver image, eliminate execution 540: overhead, and remove unneeded symbols from the kernel symbol 541: space that were previously added by the driver. 542: 4. Add new compile-time option ADVANSYS_ASSERT for assertion 543: code that used to be defined within ADVANSYS_DEBUG. This 544: option is enabled by default. 545: 546: 2.8 (5/26/97): 547: 1. Change version number to 2.8 to synchronize the Linux driver 548: version numbering with other AdvanSys drivers. 549: 2. Reformat source files without tabs to present the same view 550: of the file to everyone regardless of the editor tab setting 551: being used. 552: 3. Add Asc Library bug fixes. 553: 554: 3.1A (1/8/98): 555: 1. Change version number to 3.1 to indicate that support for 556: Ultra-Wide adapters (ABP-940UW) is included in this release. 557: 2. Add Asc Library (Narrow Board) bug fixes. 558: 3. Report an underrun condition with the host status byte set 559: to DID_UNDERRUN. Currently DID_UNDERRUN is defined to 0 which 560: causes the underrun condition to be ignored. When Linux defines 561: its own DID_UNDERRUN the constant defined in this file can be 562: removed. 563: 4. Add patch to AscWaitTixISRDone(). 564: 5. Add support for up to 16 different AdvanSys host adapter SCSI 565: channels in one system. This allows four cards with four channels 566: to be used in one system. 567: 568: 3.1B (1/9/98): 569: 1. Handle that PCI register base addresses are not always page 570: aligned even though ioremap() requires that the address argument 571: be page aligned. 572: 573: 3.1C (1/10/98): 574: 1. Update latest BIOS version checked for from the /proc file. 575: 2. Don't set microcode SDTR variable at initialization. Instead 576: wait until device capabilities have been detected from an Inquiry 577: command. 578: 579: 3.1D (1/21/98): 580: 1. Improve performance when the driver is compiled as module by 581: allowing up to 64 scatter-gather elements instead of 8. 582: 583: 3.1E (5/1/98): 584: 1. Set time delay in AscWaitTixISRDone() to 1000 ms. 585: 2. Include SMP locking changes. 586: 3. For v2.1.93 and newer kernels use CONFIG_PCI and new PCI BIOS 587: access functions. 588: 4. Update board serial number printing. 589: 5. Try allocating an IRQ both with and without the SA_INTERRUPT 590: flag set to allow IRQ sharing with drivers that do not set 591: the SA_INTERRUPT flag. Also display a more descriptive error 592: message if request_irq() fails. 593: 5. Update to latest Asc and Adv Libraries. 594: 595: J. Known Problems or Issues 596: 597: 1. Remove conditional constants (ASC_QUEUE_FLOW_CONTROL) around 598: the queue depth flow control code when mid-level SCSI changes 599: are included in Linux. 600: 601: K. Credits 602: 603: Nathan Hartwell <[email protected]> provided the directions and 604: basis for the Linux v1.3.X changes which were included in the 605: 1.2 release. 606: 607: Thomas E Zerucha <[email protected]> pointed out a bug 608: in advansys_biosparam() which was fixed in the 1.3 release. 609: 610: Erik Ratcliffe <[email protected]> has done testing of the 611: AdvanSys driver in the Caldera releases. 612: 613: Rik van Riel <[email protected]> provided a patch to 614: AscWaitTixISRDone() which he found necessary to make the 615: driver work with a SCSI-1 disk. 616: 617: Mark Moran <[email protected]> has helped test Ultra-Wide 618: support in the 3.1A driver. 619: 620: L. AdvanSys Contact Information 621: 622: Mail: Advanced System Products, Inc. 623: 1150 Ringwood Court 624: San Jose, CA 95131 625: Operator: 1-408-383-9400 626: FAX: 1-408-383-9612 627: Tech Support: 1-800-525-7440/1-408-467-2930 628: BBS: 1-408-383-9540 (14400,N,8,1) 629: Interactive FAX: 1-408-383-9753 630: Customer Direct Sales: 1-800-525-7443/1-408-383-5777 631: Tech Support E-Mail: [email protected] 632: FTP Site: ftp.advansys.com (login: anonymous) 633: Web Site: http://www.advansys.com 634: 635: */ 636: 637: 638: /* 639: * --- Linux Version 640: */ 641: 642: /* Convert Linux Version, Patch-level, Sub-level to LINUX_VERSION_CODE. */ 643: #define ASC_LINUX_VERSION(V, P, S) (((V) * 65536) + ((P) * 256) + (S)) 644: 645: #ifndef LINUX_VERSION_CODE 646: #include <linux/version.h> 647: #endif /* LINUX_VERSION_CODE */ 648: 649: 650: /* 651: * --- Linux Include Files 652: */ 653: 654: #include <linux/config.h> 655: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0) 656: #ifdef MODULE 657: #include <linux/module.h> 658: #endif /* MODULE */ 659: #endif /* version >= v1.3.0 */ 660: #include <linux/string.h> 661: #include <linux/sched.h> 662: #include <linux/kernel.h> 663: #include <linux/head.h> 664: #include <linux/types.h> 665: #include <linux/ioport.h> 666: #include <linux/delay.h> 667: #include <linux/malloc.h> 668: #include <linux/mm.h> 669: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0) 670: #include <linux/proc_fs.h> 671: #endif /* version >= v1.3.0 */ 672: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,23) 673: #include <linux/init.h> 674: #endif /* version >= v2.1.23 */ 675: #include <asm/io.h> 676: #include <asm/system.h> 677: #include <asm/dma.h> 678: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0) 679: #include "../block/blk.h" 680: #else /* version >= v1.3.0 */ 681: #include <linux/blk.h> 682: #include <linux/stat.h> 683: #endif /* version >= v1.3.0 */ 684: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,95) 685: #include <asm/spinlock.h> 686: #endif /* version >= 2.1.95 */ 687: #include "scsi.h" 688: #include "hosts.h" 689: #include "sd.h" 690: #include "advansys.h" 691: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,93) 692: #ifdef CONFIG_PCI 693: #include <linux/pci.h> 694: #endif /* CONFIG_PCI */ 695: #else /* version < v2.1.93 */ 696: /* 697: * For earlier than v2.1.93 the driver has its own PCI configuration. 698: * If PCI is not needed in a kernel before v2.1.93 this define can be 699: * turned-off to make the driver object smaller. 700: */ 701: #define ASC_CONFIG_PCI 702: #endif /* version < v2.1.93 */ 703: 704: /* 705: * If Linux eventually defines a DID_UNDERRUN, the constant here can be 706: * removed. The current value of zero for DID_UNDERRUN results in underrun 707: * conditions being ignored. 708: */ 709: #define DID_UNDERRUN 0 710: 711: 712: /* 713: * --- Driver Options 714: */ 715: 716: /* Enable driver assertions. */ 717: #define ADVANSYS_ASSERT 718: 719: /* Enable driver tracing. */ 720: /* #define ADVANSYS_DEBUG */ 721: 722: /* 723: * Because of no /proc to display them, statistics are disabled 724: * for versions prior to v1.3.0. 725: */ 726: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0) 727: #undef ADVANSYS_STATS /* Disable statistics */ 728: #else /* version >= v1.3.0 */ 729: #define ADVANSYS_STATS /* Enable statistics. */ 730: #endif /* version >= v1.3.0 */ 731: 732: 733: /* 734: * --- Debugging Header 735: */ 736: 737: #ifdef ADVANSYS_DEBUG 738: #define STATIC 739: #else /* ADVANSYS_DEBUG */ 740: #define STATIC static 741: #endif /* ADVANSYS_DEBUG */ 742: 743: 744: /* 745: * --- Asc Library Constants and Macros 746: */ 747: 748: #define ASC_LIB_VERSION_MAJOR 1 749: #define ASC_LIB_VERSION_MINOR 22 750: #define ASC_LIB_SERIAL_NUMBER 113 751: 752: typedef unsigned char uchar; 753: 754: #ifndef NULL 755: #define NULL (0) 756: #endif 757: #ifndef TRUE 758: #define TRUE (1) 759: #endif 760: #ifndef FALSE 761: #define FALSE (0) 762: #endif 763: #define REG register 764: #define rchar REG __s8 765: #define rshort REG __s16 766: #define rint REG __s32 767: #define rlong REG __s32 768: #define ruchar REG __u8 769: #define rushort REG __u16 770: #define ruint REG __u32 771: #define rulong REG __u32 772: #define NULLPTR (void *)0 773: #define FNULLPTR (void *)0UL 774: #define EOF (-1) 775: #define EOS '\0' 776: #define ERR (-1) 777: #define UB_ERR (uchar)(0xFF) 778: #define UW_ERR (uint)(0xFFFF) 779: #define UL_ERR (ulong)(0xFFFFFFFFUL) 780: #define iseven_word(val) ((((uint)val) & (uint)0x0001) == 0) 781: #define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0) 782: #define toeven_word(val) (((uint)val) & (uint)0xFFFE) 783: #define biton(val, bits) (((uint)(val >> bits) & (uint)0x0001) != 0) 784: #define bitoff(val, bits) (((uint)(val >> bits) & (uint)0x0001) == 0) 785: #define lbiton(val, bits) (((ulong)(val >> bits) & (ulong)0x00000001UL) != 0) 786: #define lbitoff(val, bits) (((ulong)(val >> bits) & (ulong)0x00000001UL) == 0) 787: #define absh(val) ((val) < 0 ? -(val) : (val)) 788: #define swapbyte(ch) ((((ch) << 4) | ((ch) >> 4))) 789: #ifndef GBYTE 790: #define GBYTE (0x40000000UL) 791: #endif 792: #ifndef MBYTE 793: #define MBYTE (0x100000UL) 794: #endif 795: #ifndef KBYTE 796: #define KBYTE (0x400) 797: #endif 798: #define HI_BYTE(x) (*((__u8 *)(&x)+1)) 799: #define LO_BYTE(x) (*((__u8 *)&x)) 800: #define HI_WORD(x) (*((__u16 *)(&x)+1)) 801: #define LO_WORD(x) (*((__u16 *)&x)) 802: #ifndef MAKEWORD 803: #define MAKEWORD(lo, hi) ((__u16) (((__u16) lo) | ((__u16) hi << 8))) 804: #endif 805: #ifndef MAKELONG 806: #define MAKELONG(lo, hi) ((__u32) (((__u32) lo) | ((__u32) hi << 16))) 807: #endif 808: #define SwapWords(dWord) ((__u32) ((dWord >> 16) | (dWord << 16))) 809: #define SwapBytes(word) ((__u16) ((word >> 8) | (word << 8))) 810: #define BigToLittle(dWord) ((__u32) (SwapWords(MAKELONG(SwapBytes(LO_WORD(dWord)), SwapBytes(HI_WORD(dWord)))))) 811: #define LittleToBig(dWord) BigToLittle(dWord) 812: #define AscPCIConfigVendorIDRegister 0x0000 813: #define AscPCIConfigDeviceIDRegister 0x0002 814: #define AscPCIConfigCommandRegister 0x0004 815: #define AscPCIConfigStatusRegister 0x0006 816: #define AscPCIConfigRevisionIDRegister 0x0008 817: #define AscPCIConfigCacheSize 0x000C 818: #define AscPCIConfigLatencyTimer 0x000D 819: #define AscPCIIOBaseRegister 0x0010 820: #define AscPCICmdRegBits_IOMemBusMaster 0x0007 821: #define ASC_PCI_ID2BUS(id) ((id) & 0xFF) 822: #define ASC_PCI_ID2DEV(id) (((id) >> 11) & 0x1F) 823: #define ASC_PCI_ID2FUNC(id) (((id) >> 8) & 0x7) 824: #define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF)) 825: #define ASC_PCI_VENDORID 0x10CD 826: #define ASC_PCI_DEVICEID_1200A 0x1100 827: #define ASC_PCI_DEVICEID_1200B 0x1200 828: #define ASC_PCI_DEVICEID_ULTRA 0x1300 829: #define ASC_PCI_REVISION_3150 0x02 830: #define ASC_PCI_REVISION_3050 0x03 831: 832: #define ASC_DVCLIB_CALL_DONE (1) 833: #define ASC_DVCLIB_CALL_FAILED (0) 834: #define ASC_DVCLIB_CALL_ERROR (-1) 835: 836: #define PortAddr unsigned short /* port address size */ 837: #define Ptr2Func ulong 838: #define inp(port) inb(port) 839: #define inpw(port) inw(port) 840: #define inpl(port) inl(port) 841: #define outp(port, byte) outb((byte), (port)) 842: #define outpw(port, word) outw((word), (port)) 843: #define outpl(port, long) outl((long), (port)) 844: #define ASC_MAX_SG_QUEUE 7 845: #define ASC_MAX_SG_LIST SG_ALL 846: 847: #define ASC_CS_TYPE unsigned short 848: #ifndef asc_ptr_type 849: #define asc_ptr_type 850: #endif 851: 852: #ifndef ASC_GET_PTR2FUNC 853: #define ASC_GET_PTR2FUNC(fun) (Ptr2Func)(fun) 854: #endif 855: #define FLIP_BYTE_NIBBLE(x) (((x<<4)& 0xFF) | (x>>4)) 856: #define ASC_IS_ISA (0x0001) 857: #define ASC_IS_ISAPNP (0x0081) 858: #define ASC_IS_EISA (0x0002) 859: #define ASC_IS_PCI (0x0004) 860: #define ASC_IS_PCI_ULTRA (0x0104) 861: #define ASC_IS_PCMCIA (0x0008) 862: #define ASC_IS_MCA (0x0020) 863: #define ASC_IS_VL (0x0040) 864: #define ASC_ISA_PNP_PORT_ADDR (0x279) 865: #define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800) 866: #define ASC_IS_WIDESCSI_16 (0x0100) 867: #define ASC_IS_WIDESCSI_32 (0x0200) 868: #define ASC_IS_BIG_ENDIAN (0x8000) 869: #define ASC_CHIP_MIN_VER_VL (0x01) 870: #define ASC_CHIP_MAX_VER_VL (0x07) 871: #define ASC_CHIP_MIN_VER_PCI (0x09) 872: #define ASC_CHIP_MAX_VER_PCI (0x0F) 873: #define ASC_CHIP_VER_PCI_BIT (0x08) 874: #define ASC_CHIP_MIN_VER_ISA (0x11) 875: #define ASC_CHIP_MIN_VER_ISA_PNP (0x21) 876: #define ASC_CHIP_MAX_VER_ISA (0x27) 877: #define ASC_CHIP_VER_ISA_BIT (0x30) 878: #define ASC_CHIP_VER_ISAPNP_BIT (0x20) 879: #define ASC_CHIP_VER_ASYN_BUG (0x21) 880: #define ASC_CHIP_VER_PCI 0x08 881: #define ASC_CHIP_VER_PCI_ULTRA_3150 (ASC_CHIP_VER_PCI | 0x02) 882: #define ASC_CHIP_VER_PCI_ULTRA_3050 (ASC_CHIP_VER_PCI | 0x03) 883: #define ASC_CHIP_MIN_VER_EISA (0x41) 884: #define ASC_CHIP_MAX_VER_EISA (0x47) 885: #define ASC_CHIP_VER_EISA_BIT (0x40) 886: #define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3) 887: #define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER 0x21 888: #define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER 0x0A 889: #define ASC_MAX_VL_DMA_ADDR (0x07FFFFFFL) 890: #define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL) 891: #define ASC_MAX_PCI_DMA_ADDR (0xFFFFFFFFL) 892: #define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL) 893: #define ASC_MAX_ISA_DMA_ADDR (0x00FFFFFFL) 894: #define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL) 895: #define ASC_MAX_EISA_DMA_ADDR (0x07FFFFFFL) 896: #define ASC_MAX_EISA_DMA_COUNT (0x07FFFFFFL) 897: #ifndef inpw_noswap 898: #define inpw_noswap(port) inpw(port) 899: #endif 900: #ifndef outpw_noswap 901: #define outpw_noswap(port, data) outpw(port, data) 902: #endif 903: #define ASC_SCSI_ID_BITS 3 904: #define ASC_SCSI_TIX_TYPE uchar 905: #define ASC_ALL_DEVICE_BIT_SET 0xFF 906: #ifdef ASC_WIDESCSI_16 907: #undef ASC_SCSI_ID_BITS 908: #define ASC_SCSI_ID_BITS 4 909: #define ASC_ALL_DEVICE_BIT_SET 0xFFFF 910: #endif 911: #ifdef ASC_WIDESCSI_32 912: #undef ASC_SCSI_ID_BITS 913: #define ASC_SCSI_ID_BITS 5 914: #define ASC_ALL_DEVICE_BIT_SET 0xFFFFFFFFL 915: #endif 916: #if ASC_SCSI_ID_BITS == 3 917: #define ASC_SCSI_BIT_ID_TYPE uchar 918: #define ASC_MAX_TID 7 919: #define ASC_MAX_LUN 7 920: #define ASC_SCSI_WIDTH_BIT_SET 0xFF 921: #elif ASC_SCSI_ID_BITS == 4 922: #define ASC_SCSI_BIT_ID_TYPE ushort 923: #define ASC_MAX_TID 15 924: #define ASC_MAX_LUN 7 925: #define ASC_SCSI_WIDTH_BIT_SET 0xFFFF 926: #elif ASC_SCSI_ID_BITS == 5 927: #define ASC_SCSI_BIT_ID_TYPE ulong 928: #define ASC_MAX_TID 31 929: #define ASC_MAX_LUN 7 930: #define ASC_SCSI_WIDTH_BIT_SET 0xFFFFFFFF 931: #else 932: #error ASC_SCSI_ID_BITS definition is wrong 933: #endif 934: #define ASC_MAX_SENSE_LEN 32 935: #define ASC_MIN_SENSE_LEN 14 936: #define ASC_MAX_CDB_LEN 12 937: #define ASC_SCSI_RESET_HOLD_TIME_US 60 938: #define SCSICMD_TestUnitReady 0x00 939: #define SCSICMD_Rewind 0x01 940: #define SCSICMD_Rezero 0x01 941: #define SCSICMD_RequestSense 0x03 942: #define SCSICMD_Format 0x04 943: #define SCSICMD_FormatUnit 0x04 944: #define SCSICMD_Read6 0x08 945: #define SCSICMD_Write6 0x0A 946: #define SCSICMD_Seek6 0x0B 947: #define SCSICMD_Inquiry 0x12 948: #define SCSICMD_Verify6 0x13 949: #define SCSICMD_ModeSelect6 0x15 950: #define SCSICMD_ModeSense6 0x1A 951: #define SCSICMD_StartStopUnit 0x1B 952: #define SCSICMD_LoadUnloadTape 0x1B 953: #define SCSICMD_ReadCapacity 0x25 954: #define SCSICMD_Read10 0x28 955: #define SCSICMD_Write10 0x2A 956: #define SCSICMD_Seek10 0x2B 957: #define SCSICMD_Erase10 0x2C 958: #define SCSICMD_WriteAndVerify10 0x2E 959: #define SCSICMD_Verify10 0x2F 960: #define SCSICMD_WriteBuffer 0x3B 961: #define SCSICMD_ReadBuffer 0x3C 962: #define SCSICMD_ReadLong 0x3E 963: #define SCSICMD_WriteLong 0x3F 964: #define SCSICMD_ReadTOC 0x43 965: #define SCSICMD_ReadHeader 0x44 966: #define SCSICMD_ModeSelect10 0x55 967: #define SCSICMD_ModeSense10 0x5A 968: #define SCSI_TYPE_DASD 0x00 969: #define SCSI_TYPE_SASD 0x01 970: #define SCSI_TYPE_PRN 0x02 971: #define SCSI_TYPE_PROC 0x03 972: #define SCSI_TYPE_WORM 0x04 973: #define SCSI_TYPE_CDROM 0x05 974: #define SCSI_TYPE_SCANNER 0x06 975: #define SCSI_TYPE_OPTMEM 0x07 976: #define SCSI_TYPE_MED_CHG 0x08 977: #define SCSI_TYPE_COMM 0x09 978: #define SCSI_TYPE_UNKNOWN 0x1F 979: #define SCSI_TYPE_NO_DVC 0xFF 980: #define ASC_SCSIDIR_NOCHK 0x00 981: #define ASC_SCSIDIR_T2H 0x08 982: #define ASC_SCSIDIR_H2T 0x10 983: #define ASC_SCSIDIR_NODATA 0x18 984: #define SCSI_SENKEY_NO_SENSE 0x00 985: #define SCSI_SENKEY_UNDEFINED 0x01 986: #define SCSI_SENKEY_NOT_READY 0x02 987: #define SCSI_SENKEY_MEDIUM_ERR 0x03 988: #define SCSI_SENKEY_HW_ERR 0x04 989: #define SCSI_SENKEY_ILLEGAL 0x05 990: #define SCSI_SENKEY_ATTENTION 0x06 991: #define SCSI_SENKEY_PROTECTED 0x07 992: #define SCSI_SENKEY_BLANK 0x08 993: #define SCSI_SENKEY_V_UNIQUE 0x09 994: #define SCSI_SENKEY_CPY_ABORT 0x0A 995: #define SCSI_SENKEY_ABORT 0x0B 996: #define SCSI_SENKEY_EQUAL 0x0C 997: #define SCSI_SENKEY_VOL_OVERFLOW 0x0D 998: #define SCSI_SENKEY_MISCOMP 0x0E 999: #define SCSI_SENKEY_RESERVED 0x0F 1000: #define SCSI_ASC_NOMEDIA 0x3A 1001: #define ASC_SRB_HOST(x) ((uchar)((uchar)(x) >> 4)) 1002: #define ASC_SRB_TID(x) ((uchar)((uchar)(x) & (uchar)0x0F)) 1003: #define ASC_SRB_LUN(x) ((uchar)((uint)(x) >> 13)) 1004: #define PUT_CDB1(x) ((uchar)((uint)(x) >> 8)) 1005: #define SS_GOOD 0x00 1006: #define SS_CHK_CONDITION 0x02 1007: #define SS_CONDITION_MET 0x04 1008: #define SS_TARGET_BUSY 0x08 1009: #define SS_INTERMID 0x10 1010: #define SS_INTERMID_COND_MET 0x14 1011: #define SS_RSERV_CONFLICT 0x18 1012: #define SS_CMD_TERMINATED 0x22 1013: #define SS_QUEUE_FULL 0x28 1014: #define MS_CMD_DONE 0x00 1015: #define MS_EXTEND 0x01 1016: #define MS_SDTR_LEN 0x03 1017: #define MS_SDTR_CODE 0x01 1018: #define MS_WDTR_LEN 0x02 1019: #define MS_WDTR_CODE 0x03 1020: #define MS_MDP_LEN 0x05 1021: #define MS_MDP_CODE 0x00 1022: #define M1_SAVE_DATA_PTR 0x02 1023: #define M1_RESTORE_PTRS 0x03 1024: #define M1_DISCONNECT 0x04 1025: #define M1_INIT_DETECTED_ERR 0x05 1026: #define M1_ABORT 0x06 1027: #define M1_MSG_REJECT 0x07 1028: #define M1_NO_OP 0x08 1029: #define M1_MSG_PARITY_ERR 0x09 1030: #define M1_LINK_CMD_DONE 0x0A 1031: #define M1_LINK_CMD_DONE_WFLAG 0x0B 1032: #define M1_BUS_DVC_RESET 0x0C 1033: #define M1_ABORT_TAG 0x0D 1034: #define M1_CLR_QUEUE 0x0E 1035: #define M1_INIT_RECOVERY 0x0F 1036: #define M1_RELEASE_RECOVERY 0x10 1037: #define M1_KILL_IO_PROC 0x11 1038: #define M2_QTAG_MSG_SIMPLE 0x20 1039: #define M2_QTAG_MSG_HEAD 0x21 1040: #define M2_QTAG_MSG_ORDERED 0x22 1041: #define M2_IGNORE_WIDE_RESIDUE 0x23 1042: 1043: typedef struct { 1044: uchar peri_dvc_type:5; 1045: uchar peri_qualifier:3; 1046: } ASC_SCSI_INQ0; 1047: 1048: typedef struct { 1049: uchar dvc_type_modifier:7; 1050: uchar rmb:1; 1051: } ASC_SCSI_INQ1; 1052: 1053: typedef struct { 1054: uchar ansi_apr_ver:3; 1055: uchar ecma_ver:3; 1056: uchar iso_ver:2; 1057: } ASC_SCSI_INQ2; 1058: 1059: typedef struct { 1060: uchar rsp_data_fmt:4; 1061: uchar res:2; 1062: uchar TemIOP:1; 1063: uchar aenc:1; 1064: } ASC_SCSI_INQ3; 1065: 1066: typedef struct { 1067: uchar StfRe:1; 1068: uchar CmdQue:1; 1069: uchar Reserved:1; 1070: uchar Linked:1; 1071: uchar Sync:1; 1072: uchar WBus16:1; 1073: uchar WBus32:1; 1074: uchar RelAdr:1; 1075: } ASC_SCSI_INQ7; 1076: 1077: typedef struct { 1078: ASC_SCSI_INQ0 byte0; 1079: ASC_SCSI_INQ1 byte1; 1080: ASC_SCSI_INQ2 byte2; 1081: ASC_SCSI_INQ3 byte3; 1082: uchar add_len; 1083: uchar res1; 1084: uchar res2; 1085: ASC_SCSI_INQ7 byte7; 1086: uchar vendor_id[8]; 1087: uchar product_id[16]; 1088: uchar product_rev_level[4]; 1089: } ASC_SCSI_INQUIRY; 1090: 1091: typedef struct asc_req_sense { 1092: uchar err_code:7; 1093: uchar info_valid:1; 1094: uchar segment_no; 1095: uchar sense_key:4; 1096: uchar reserved_bit:1; 1097: uchar sense_ILI:1; 1098: uchar sense_EOM:1; 1099: uchar file_mark:1; 1100: uchar info1[4]; 1101: uchar add_sense_len; 1102: uchar cmd_sp_info[4]; 1103: uchar asc; 1104: uchar ascq; 1105: uchar fruc; 1106: uchar sks_byte0:7; 1107: uchar sks_valid:1; 1108: uchar sks_bytes[2]; 1109: uchar notused[2]; 1110: uchar ex_sense_code; 1111: uchar info2[4]; 1112: } ASC_REQ_SENSE; 1113: 1114: #define ASC_SG_LIST_PER_Q 7 1115: #define QS_FREE 0x00 1116: #define QS_READY 0x01 1117: #define QS_DISC1 0x02 1118: #define QS_DISC2 0x04 1119: #define QS_BUSY 0x08 1120: #define QS_ABORTED 0x40 1121: #define QS_DONE 0x80 1122: #define QC_NO_CALLBACK 0x01 1123: #define QC_SG_SWAP_QUEUE 0x02 1124: #define QC_SG_HEAD 0x04 1125: #define QC_DATA_IN 0x08 1126: #define QC_DATA_OUT 0x10 1127: #define QC_URGENT 0x20 1128: #define QC_MSG_OUT 0x40 1129: #define QC_REQ_SENSE 0x80 1130: #define QCSG_SG_XFER_LIST 0x02 1131: #define QCSG_SG_XFER_MORE 0x04 1132: #define QCSG_SG_XFER_END 0x08 1133: #define QD_IN_PROGRESS 0x00 1134: #define QD_NO_ERROR 0x01 1135: #define QD_ABORTED_BY_HOST 0x02 1136: #define QD_WITH_ERROR 0x04 1137: #define QD_INVALID_REQUEST 0x80 1138: #define QD_INVALID_HOST_NUM 0x81 1139: #define QD_INVALID_DEVICE 0x82 1140: #define QD_ERR_INTERNAL 0xFF 1141: #define QHSTA_NO_ERROR 0x00 1142: #define QHSTA_M_SEL_TIMEOUT 0x11 1143: #define QHSTA_M_DATA_OVER_RUN 0x12 1144: #define QHSTA_M_DATA_UNDER_RUN 0x12 1145: #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13 1146: #define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14 1147: #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21 1148: #define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22 1149: #define QHSTA_D_HOST_ABORT_FAILED 0x23 1150: #define QHSTA_D_EXE_SCSI_Q_FAILED 0x24 1151: #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25 1152: #define QHSTA_D_ASPI_NO_BUF_POOL 0x26 1153: #define QHSTA_M_WTM_TIMEOUT 0x41 1154: #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42 1155: #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43 1156: #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44 1157: #define QHSTA_M_TARGET_STATUS_BUSY 0x45 1158: #define QHSTA_M_BAD_TAG_CODE 0x46 1159: #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47 1160: #define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48 1161: #define QHSTA_D_LRAM_CMP_ERROR 0x81 1162: #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1 1163: #define ASC_FLAG_SCSIQ_REQ 0x01 1164: #define ASC_FLAG_BIOS_SCSIQ_REQ 0x02 1165: #define ASC_FLAG_BIOS_ASYNC_IO 0x04 1166: #define ASC_FLAG_SRB_LINEAR_ADDR 0x08 1167: #define ASC_FLAG_WIN16 0x10 1168: #define ASC_FLAG_WIN32 0x20 1169: #define ASC_FLAG_ISA_OVER_16MB 0x40 1170: #define ASC_FLAG_DOS_VM_CALLBACK 0x80 1171: #define ASC_TAG_FLAG_EXTRA_BYTES 0x10 1172: #define ASC_TAG_FLAG_DISABLE_DISCONNECT 0x04 1173: #define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 0x08 1174: #define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40 1175: #define ASC_SCSIQ_CPY_BEG 4 1176: #define ASC_SCSIQ_SGHD_CPY_BEG 2 1177: #define ASC_SCSIQ_B_FWD 0 1178: #define ASC_SCSIQ_B_BWD 1 1179: #define ASC_SCSIQ_B_STATUS 2 1180: #define ASC_SCSIQ_B_QNO 3 1181: #define ASC_SCSIQ_B_CNTL 4 1182: #define ASC_SCSIQ_B_SG_QUEUE_CNT 5 1183: #define ASC_SCSIQ_D_DATA_ADDR 8 1184: #define ASC_SCSIQ_D_DATA_CNT 12 1185: #define ASC_SCSIQ_B_SENSE_LEN 20 1186: #define ASC_SCSIQ_DONE_INFO_BEG 22 1187: #define ASC_SCSIQ_D_SRBPTR 22 1188: #define ASC_SCSIQ_B_TARGET_IX 26 1189: #define ASC_SCSIQ_B_CDB_LEN 28 1190: #define ASC_SCSIQ_B_TAG_CODE 29 1191: #define ASC_SCSIQ_W_VM_ID 30 1192: #define ASC_SCSIQ_DONE_STATUS 32 1193: #define ASC_SCSIQ_HOST_STATUS 33 1194: #define ASC_SCSIQ_SCSI_STATUS 34 1195: #define ASC_SCSIQ_CDB_BEG 36 1196: #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56 1197: #define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60 1198: #define ASC_SCSIQ_B_SG_WK_QP 49 1199: #define ASC_SCSIQ_B_SG_WK_IX 50 1200: #define ASC_SCSIQ_W_REQ_COUNT 52 1201: #define ASC_SCSIQ_B_LIST_CNT 6 1202: #define ASC_SCSIQ_B_CUR_LIST_CNT 7 1203: #define ASC_SGQ_B_SG_CNTL 4 1204: #define ASC_SGQ_B_SG_HEAD_QP 5 1205: #define ASC_SGQ_B_SG_LIST_CNT 6 1206: #define ASC_SGQ_B_SG_CUR_LIST_CNT 7 1207: #define ASC_SGQ_LIST_BEG 8 1208: #define ASC_DEF_SCSI1_QNG 4 1209: #define ASC_MAX_SCSI1_QNG 4 1210: #define ASC_DEF_SCSI2_QNG 16 1211: #define ASC_MAX_SCSI2_QNG 32 1212: #define ASC_TAG_CODE_MASK 0x23 1213: #define ASC_STOP_REQ_RISC_STOP 0x01 1214: #define ASC_STOP_ACK_RISC_STOP 0x03 1215: #define ASC_STOP_CLEAN_UP_BUSY_Q 0x10 1216: #define ASC_STOP_CLEAN_UP_DISC_Q 0x20 1217: #define ASC_STOP_HOST_REQ_RISC_HALT 0x40 1218: #define ASC_TIDLUN_TO_IX(tid, lun) (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS)) 1219: #define ASC_TID_TO_TARGET_ID(tid) (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid)) 1220: #define ASC_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ASC_MAX_TID)) 1221: #define ASC_TIX_TO_TID(tix) ((tix) & ASC_MAX_TID) 1222: #define ASC_TID_TO_TIX(tid) ((tid) & ASC_MAX_TID) 1223: #define ASC_TIX_TO_LUN(tix) (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN) 1224: #define ASC_QNO_TO_QADDR(q_no) ((ASC_QADR_BEG)+((int)(q_no) << 6)) 1225: 1226: typedef struct asc_scisq_1 { 1227: uchar status; 1228: uchar q_no; 1229: uchar cntl; 1230: uchar sg_queue_cnt; 1231: uchar target_id; 1232: uchar target_lun; 1233: ulong data_addr; 1234: ulong data_cnt; 1235: ulong sense_addr; 1236: uchar sense_len; 1237: uchar extra_bytes; 1238: } ASC_SCSIQ_1; 1239: 1240: typedef struct asc_scisq_2 { 1241: ulong srb_ptr; 1242: uchar target_ix; 1243: uchar flag; 1244: uchar cdb_len; 1245: uchar tag_code; 1246: ushort vm_id; 1247: } ASC_SCSIQ_2; 1248: 1249: typedef struct asc_scsiq_3 { 1250: uchar done_stat; 1251: uchar host_stat; 1252: uchar scsi_stat; 1253: uchar scsi_msg; 1254: } ASC_SCSIQ_3; 1255: 1256: typedef struct asc_scsiq_4 { 1257: uchar cdb[ASC_MAX_CDB_LEN]; 1258: uchar y_first_sg_list_qp; 1259: uchar y_working_sg_qp; 1260: uchar y_working_sg_ix; 1261: uchar y_res; 1262: ushort x_req_count; 1263: ushort x_reconnect_rtn; 1264: ulong x_saved_data_addr; 1265: ulong x_saved_data_cnt; 1266: } ASC_SCSIQ_4; 1267: 1268: typedef struct asc_q_done_info { 1269: ASC_SCSIQ_2 d2; 1270: ASC_SCSIQ_3 d3; 1271: uchar q_status; 1272: uchar q_no; 1273: uchar cntl; 1274: uchar sense_len; 1275: uchar extra_bytes; 1276: uchar res; 1277: ulong remain_bytes; 1278: } ASC_QDONE_INFO; 1279: 1280: typedef struct asc_sg_list { 1281: ulong addr; 1282: ulong bytes; 1283: } ASC_SG_LIST; 1284: 1285: typedef struct asc_sg_head { 1286: ushort entry_cnt; 1287: ushort queue_cnt; 1288: ushort entry_to_copy; 1289: ushort res; 1290: ASC_SG_LIST sg_list[ASC_MAX_SG_LIST]; 1291: } ASC_SG_HEAD; 1292: 1293: #define ASC_MIN_SG_LIST 2 1294: 1295: typedef struct asc_min_sg_head { 1296: ushort entry_cnt; 1297: ushort queue_cnt; 1298: ushort entry_to_copy; 1299: ushort res; 1300: ASC_SG_LIST sg_list[ASC_MIN_SG_LIST]; 1301: } ASC_MIN_SG_HEAD; 1302: 1303: #define QCX_SORT (0x0001) 1304: #define QCX_COALEASE (0x0002) 1305: 1306: typedef struct asc_scsi_q { 1307: ASC_SCSIQ_1 q1; 1308: ASC_SCSIQ_2 q2; 1309: uchar *cdbptr; 1310: ASC_SG_HEAD *sg_head; 1311: } ASC_SCSI_Q; 1312: 1313: typedef struct asc_scsi_req_q { 1314: ASC_SCSIQ_1 r1; 1315: ASC_SCSIQ_2 r2; 1316: uchar *cdbptr; 1317: ASC_SG_HEAD *sg_head; 1318: uchar *sense_ptr; 1319: ASC_SCSIQ_3 r3; 1320: uchar cdb[ASC_MAX_CDB_LEN]; 1321: uchar sense[ASC_MIN_SENSE_LEN]; 1322: } ASC_SCSI_REQ_Q; 1323: 1324: typedef struct asc_scsi_bios_req_q { 1325: ASC_SCSIQ_1 r1; 1326: ASC_SCSIQ_2 r2; 1327: uchar *cdbptr; 1328: ASC_SG_HEAD *sg_head; 1329: uchar *sense_ptr; 1330: ASC_SCSIQ_3 r3; 1331: uchar cdb[ASC_MAX_CDB_LEN]; 1332: uchar sense[ASC_MIN_SENSE_LEN]; 1333: } ASC_SCSI_BIOS_REQ_Q; 1334: 1335: typedef struct asc_risc_q { 1336: uchar fwd; 1337: uchar bwd; 1338: ASC_SCSIQ_1 i1; 1339: ASC_SCSIQ_2 i2; 1340: ASC_SCSIQ_3 i3; 1341: ASC_SCSIQ_4 i4; 1342: } ASC_RISC_Q; 1343: 1344: typedef struct asc_sg_list_q { 1345: uchar seq_no; 1346: uchar q_no; 1347: uchar cntl; 1348: uchar sg_head_qp; 1349: uchar sg_list_cnt; 1350: uchar sg_cur_list_cnt; 1351: } ASC_SG_LIST_Q; 1352: 1353: typedef struct asc_risc_sg_list_q { 1354: uchar fwd; 1355: uchar bwd; 1356: ASC_SG_LIST_Q sg; 1357: ASC_SG_LIST sg_list[7]; 1358: } ASC_RISC_SG_LIST_Q; 1359: 1360: #define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP 0x1000000UL 1361: #define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP 1024 1362: #define ASCQ_ERR_NO_ERROR 0 1363: #define ASCQ_ERR_IO_NOT_FOUND 1 1364: #define ASCQ_ERR_LOCAL_MEM 2 1365: #define ASCQ_ERR_CHKSUM 3 1366: #define ASCQ_ERR_START_CHIP 4 1367: #define ASCQ_ERR_INT_TARGET_ID 5 1368: #define ASCQ_ERR_INT_LOCAL_MEM 6 1369: #define ASCQ_ERR_HALT_RISC 7 1370: #define ASCQ_ERR_GET_ASPI_ENTRY 8 1371: #define ASCQ_ERR_CLOSE_ASPI 9 1372: #define ASCQ_ERR_HOST_INQUIRY 0x0A 1373: #define ASCQ_ERR_SAVED_SRB_BAD 0x0B 1374: #define ASCQ_ERR_QCNTL_SG_LIST 0x0C 1375: #define ASCQ_ERR_Q_STATUS 0x0D 1376: #define ASCQ_ERR_WR_SCSIQ 0x0E 1377: #define ASCQ_ERR_PC_ADDR 0x0F 1378: #define ASCQ_ERR_SYN_OFFSET 0x10 1379: #define ASCQ_ERR_SYN_XFER_TIME 0x11 1380: #define ASCQ_ERR_LOCK_DMA 0x12 1381: #define ASCQ_ERR_UNLOCK_DMA 0x13 1382: #define ASCQ_ERR_VDS_CHK_INSTALL 0x14 1383: #define ASCQ_ERR_MICRO_CODE_HALT 0x15 1384: #define ASCQ_ERR_SET_LRAM_ADDR 0x16 1385: #define ASCQ_ERR_CUR_QNG 0x17 1386: #define ASCQ_ERR_SG_Q_LINKS 0x18 1387: #define ASCQ_ERR_SCSIQ_PTR 0x19 1388: #define ASCQ_ERR_ISR_RE_ENTRY 0x1A 1389: #define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B 1390: #define ASCQ_ERR_ISR_ON_CRITICAL 0x1C 1391: #define ASCQ_ERR_SG_LIST_ODD_ADDRESS 0x1D 1392: #define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E 1393: #define ASCQ_ERR_SCSIQ_NULL_PTR 0x1F 1394: #define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR 0x20 1395: #define ASCQ_ERR_GET_NUM_OF_FREE_Q 0x21 1396: #define ASCQ_ERR_SEND_SCSI_Q 0x22 1397: #define ASCQ_ERR_HOST_REQ_RISC_HALT 0x23 1398: #define ASCQ_ERR_RESET_SDTR 0x24 1399: #define ASC_WARN_NO_ERROR 0x0000 1400: #define ASC_WARN_IO_PORT_ROTATE 0x0001 1401: #define ASC_WARN_EEPROM_CHKSUM 0x0002 1402: #define ASC_WARN_IRQ_MODIFIED 0x0004 1403: #define ASC_WARN_AUTO_CONFIG 0x0008 1404: #define ASC_WARN_CMD_QNG_CONFLICT 0x0010 1405: #define ASC_WARN_EEPROM_RECOVER 0x0020 1406: #define ASC_WARN_CFG_MSW_RECOVER 0x0040 1407: #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 1408: #define ASC_IERR_WRITE_EEPROM 0x0001 1409: #define ASC_IERR_MCODE_CHKSUM 0x0002 1410: #define ASC_IERR_SET_PC_ADDR 0x0004 1411: #define ASC_IERR_START_STOP_CHIP 0x0008 1412: #define ASC_IERR_IRQ_NO 0x0010 1413: #define ASC_IERR_SET_IRQ_NO 0x0020 1414: #define ASC_IERR_CHIP_VERSION 0x0040 1415: #define ASC_IERR_SET_SCSI_ID 0x0080 1416: #define ASC_IERR_GET_PHY_ADDR 0x0100 1417: #define ASC_IERR_BAD_SIGNATURE 0x0200 1418: #define ASC_IERR_NO_BUS_TYPE 0x0400 1419: #define ASC_IERR_SCAM 0x0800 1420: #define ASC_IERR_SET_SDTR 0x1000 1421: #define ASC_IERR_RW_LRAM 0x8000 1422: #define ASC_DEF_IRQ_NO 10 1423: #define ASC_MAX_IRQ_NO 15 1424: #define ASC_MIN_IRQ_NO 10 1425: #define ASC_MIN_REMAIN_Q (0x02) 1426: #define ASC_DEF_MAX_TOTAL_QNG (0xF0) 1427: #define ASC_MIN_TAG_Q_PER_DVC (0x04) 1428: #define ASC_DEF_TAG_Q_PER_DVC (0x04) 1429: #define ASC_MIN_FREE_Q ASC_MIN_REMAIN_Q 1430: #define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q)) 1431: #define ASC_MAX_TOTAL_QNG 240 1432: #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16 1433: #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8 1434: #define ASC_MAX_PCI_INRAM_TOTAL_QNG 20 1435: #define ASC_MAX_INRAM_TAG_QNG 16 1436: #define ASC_IOADR_TABLE_MAX_IX 11 1437: #define ASC_IOADR_GAP 0x10 1438: #define ASC_SEARCH_IOP_GAP 0x10 1439: #define ASC_MIN_IOP_ADDR (PortAddr)0x0100 1440: #define ASC_MAX_IOP_ADDR (PortAddr)0x3F0 1441: #define ASC_IOADR_1 (PortAddr)0x0110 1442: #define ASC_IOADR_2 (PortAddr)0x0130 1443: #define ASC_IOADR_3 (PortAddr)0x0150 1444: #define ASC_IOADR_4 (PortAddr)0x0190 1445: #define ASC_IOADR_5 (PortAddr)0x0210 1446: #define ASC_IOADR_6 (PortAddr)0x0230 1447: #define ASC_IOADR_7 (PortAddr)0x0250 1448: #define ASC_IOADR_8 (PortAddr)0x0330 1449: #define ASC_IOADR_DEF ASC_IOADR_8 1450: #define ASC_LIB_SCSIQ_WK_SP 256 1451: #define ASC_MAX_SYN_XFER_NO 16 1452: #define ASC_SYN_MAX_OFFSET 0x0F 1453: #define ASC_DEF_SDTR_OFFSET 0x0F 1454: #define ASC_DEF_SDTR_INDEX 0x00 1455: #define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02 1456: #define SYN_XFER_NS_0 25 1457: #define SYN_XFER_NS_1 30 1458: #define SYN_XFER_NS_2 35 1459: #define SYN_XFER_NS_3 40 1460: #define SYN_XFER_NS_4 50 1461: #define SYN_XFER_NS_5 60 1462: #define SYN_XFER_NS_6 70 1463: #define SYN_XFER_NS_7 85 1464: #define SYN_ULTRA_XFER_NS_0 12 1465: #define SYN_ULTRA_XFER_NS_1 19 1466: #define SYN_ULTRA_XFER_NS_2 25 1467: #define SYN_ULTRA_XFER_NS_3 32 1468: #define SYN_ULTRA_XFER_NS_4 38 1469: #define SYN_ULTRA_XFER_NS_5 44 1470: #define SYN_ULTRA_XFER_NS_6 50 1471: #define SYN_ULTRA_XFER_NS_7 57 1472: #define SYN_ULTRA_XFER_NS_8 63 1473: #define SYN_ULTRA_XFER_NS_9 69 1474: #define SYN_ULTRA_XFER_NS_10 75 1475: #define SYN_ULTRA_XFER_NS_11 82 1476: #define SYN_ULTRA_XFER_NS_12 88 1477: #define SYN_ULTRA_XFER_NS_13 94 1478: #define SYN_ULTRA_XFER_NS_14 100 1479: #define SYN_ULTRA_XFER_NS_15 107 1480: 1481: typedef struct ext_msg { 1482: uchar msg_type; 1483: uchar msg_len; 1484: uchar msg_req; 1485: union { 1486: struct { 1487: uchar sdtr_xfer_period; 1488: uchar sdtr_req_ack_offset; 1489: } sdtr; 1490: struct { 1491: uchar wdtr_width; 1492: } wdtr; 1493: struct { 1494: uchar mdp_b3; 1495: uchar mdp_b2; 1496: uchar mdp_b1; 1497: uchar mdp_b0; 1498: } mdp; 1499: } u_ext_msg; 1500: uchar res; 1501: } EXT_MSG; 1502: 1503: #define xfer_period u_ext_msg.sdtr.sdtr_xfer_period 1504: #define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset 1505: #define wdtr_width u_ext_msg.wdtr.wdtr_width 1506: #define mdp_b3 u_ext_msg.mdp_b3 1507: #define mdp_b2 u_ext_msg.mdp_b2 1508: #define mdp_b1 u_ext_msg.mdp_b1 1509: #define mdp_b0 u_ext_msg.mdp_b0 1510: 1511: typedef struct asc_dvc_cfg { 1512: ASC_SCSI_BIT_ID_TYPE can_tagged_qng; 1513: ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled; 1514: ASC_SCSI_BIT_ID_TYPE disc_enable; 1515: ASC_SCSI_BIT_ID_TYPE sdtr_enable; 1516: uchar chip_scsi_id:4; 1517: uchar isa_dma_speed:4; 1518: uchar isa_dma_channel; 1519: uchar chip_version; 1520: ushort pci_device_id; 1521: ushort lib_serial_no; 1522: ushort lib_version; 1523: ushort mcode_date; 1524: ushort mcode_version; 1525: uchar max_tag_qng[ASC_MAX_TID + 1]; 1526: uchar *overrun_buf; 1527: uchar sdtr_period_offset[ASC_MAX_TID + 1]; 1528: ushort pci_slot_info; 1529: uchar adapter_info[6]; 1530: } ASC_DVC_CFG; 1531: 1532: #define ASC_DEF_DVC_CNTL 0xFFFF 1533: #define ASC_DEF_CHIP_SCSI_ID 7 1534: #define ASC_DEF_ISA_DMA_SPEED 4 1535: #define ASC_INIT_STATE_NULL 0x0000 1536: #define ASC_INIT_STATE_BEG_GET_CFG 0x0001 1537: #define ASC_INIT_STATE_END_GET_CFG 0x0002 1538: #define ASC_INIT_STATE_BEG_SET_CFG 0x0004 1539: #define ASC_INIT_STATE_END_SET_CFG 0x0008 1540: #define ASC_INIT_STATE_BEG_LOAD_MC 0x0010 1541: #define ASC_INIT_STATE_END_LOAD_MC 0x0020 1542: #define ASC_INIT_STATE_BEG_INQUIRY 0x0040 1543: #define ASC_INIT_STATE_END_INQUIRY 0x0080 1544: #define ASC_INIT_RESET_SCSI_DONE 0x0100 1545: #define ASC_INIT_STATE_WITHOUT_EEP 0x8000 1546: #define ASC_PCI_DEVICE_ID_REV_A 0x1100 1547: #define ASC_PCI_DEVICE_ID_REV_B 0x1200 1548: #define ASC_BUG_FIX_IF_NOT_DWB 0x0001 1549: #define ASC_BUG_FIX_ASYN_USE_SYN 0x0002 1550: #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41 1551: #define ASC_MIN_TAGGED_CMD 7 1552: #define ASC_MAX_SCSI_RESET_WAIT 30 1553: 1554: typedef struct asc_dvc_var { 1555: PortAddr iop_base; 1556: ushort err_code; 1557: ushort dvc_cntl; 1558: ushort bug_fix_cntl; 1559: ushort bus_type; 1560: Ptr2Func isr_callback; 1561: Ptr2Func exe_callback; 1562: ASC_SCSI_BIT_ID_TYPE init_sdtr; 1563: ASC_SCSI_BIT_ID_TYPE sdtr_done; 1564: ASC_SCSI_BIT_ID_TYPE use_tagged_qng; 1565: ASC_SCSI_BIT_ID_TYPE unit_not_ready; 1566: ASC_SCSI_BIT_ID_TYPE queue_full_or_busy; 1567: ASC_SCSI_BIT_ID_TYPE start_motor; 1568: uchar scsi_reset_wait; 1569: uchar chip_no; 1570: char is_in_int; 1571: uchar max_total_qng; 1572: uchar cur_total_qng; 1573: uchar in_critical_cnt; 1574: uchar irq_no; 1575: uchar last_q_shortage; 1576: ushort init_state; 1577: uchar cur_dvc_qng[ASC_MAX_TID + 1]; 1578: uchar max_dvc_qng[ASC_MAX_TID + 1]; 1579: ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1]; 1580: ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1]; 1581: uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO]; 1582: ASC_DVC_CFG *cfg; 1583: Ptr2Func saved_ptr2func; 1584: ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always; 1585: char redo_scam; 1586: ushort res2; 1587: uchar dos_int13_table[ASC_MAX_TID + 1]; 1588: ulong max_dma_count; 1589: ASC_SCSI_BIT_ID_TYPE no_scam; 1590: ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer; 1591: uchar max_sdtr_index; 1592: uchar host_init_sdtr_index; 1593: ulong drv_ptr; 1594: ulong uc_break; 1595: ulong res7; 1596: ulong res8; 1597: } ASC_DVC_VAR; 1598: 1599: typedef int (* ASC_ISR_CALLBACK) (ASC_DVC_VAR asc_ptr_type *, ASC_QDONE_INFO *); 1600: typedef int (* ASC_EXE_CALLBACK) (ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q *); 1601: 1602: typedef struct asc_dvc_inq_info { 1603: uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1]; 1604: } ASC_DVC_INQ_INFO; 1605: 1606: typedef struct asc_cap_info { 1607: ulong lba; 1608: ulong blk_size; 1609: } ASC_CAP_INFO; 1610: 1611: typedef struct asc_cap_info_array { 1612: ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1]; 1613: } ASC_CAP_INFO_ARRAY; 1614: 1615: #define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001 1616: #define ASC_MCNTL_NULL_TARGET (ushort)0x0002 1617: #define ASC_CNTL_INITIATOR (ushort)0x0001 1618: #define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002 1619: #define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004 1620: #define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008 1621: #define ASC_CNTL_NO_SCAM (ushort)0x0010 1622: #define ASC_CNTL_INT_MULTI_Q (ushort)0x0080 1623: #define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040 1624: #define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100 1625: #define ASC_CNTL_RESET_SCSI (ushort)0x0200 1626: #define ASC_CNTL_INIT_INQUIRY (ushort)0x0400 1627: #define ASC_CNTL_INIT_VERBOSE (ushort)0x0800 1628: #define ASC_CNTL_SCSI_PARITY (ushort)0x1000 1629: #define ASC_CNTL_BURST_MODE (ushort)0x2000 1630: #define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000 1631: #define ASC_EEP_DVC_CFG_BEG_VL 2 1632: #define ASC_EEP_MAX_DVC_ADDR_VL 15 1633: #define ASC_EEP_DVC_CFG_BEG 32 1634: #define ASC_EEP_MAX_DVC_ADDR 45 1635: #define ASC_EEP_DEFINED_WORDS 10 1636: #define ASC_EEP_MAX_ADDR 63 1637: #define ASC_EEP_RES_WORDS 0 1638: #define ASC_EEP_MAX_RETRY 20 1639: #define ASC_MAX_INIT_BUSY_RETRY 8 1640: #define ASC_EEP_ISA_PNP_WSIZE 16 1641: 1642: typedef struct asceep_config { 1643: ushort cfg_lsw; 1644: ushort cfg_msw; 1645: uchar init_sdtr; 1646: uchar disc_enable; 1647: uchar use_cmd_qng; 1648: uchar start_motor; 1649: uchar max_total_qng; 1650: uchar max_tag_qng; 1651: uchar bios_scan; 1652: uchar power_up_wait; 1653: uchar no_scam; 1654: uchar chip_scsi_id:4; 1655: uchar isa_dma_speed:4; 1656: uchar dos_int13_table[ASC_MAX_TID + 1]; 1657: uchar adapter_info[6]; 1658: ushort cntl; 1659: ushort chksum; 1660: } ASCEEP_CONFIG; 1661: 1662: #define ASC_PCI_CFG_LSW_SCSI_PARITY 0x0800 1663: #define ASC_PCI_CFG_LSW_BURST_MODE 0x0080 1664: #define ASC_PCI_CFG_LSW_INTR_ABLE 0x0020 1665: 1666: #define ASC_EEP_CMD_READ 0x80 1667: #define ASC_EEP_CMD_WRITE 0x40 1668: #define ASC_EEP_CMD_WRITE_ABLE 0x30 1669: #define ASC_EEP_CMD_WRITE_DISABLE 0x00 1670: #define ASC_OVERRUN_BSIZE 0x00000048UL 1671: #define ASC_CTRL_BREAK_ONCE 0x0001 1672: #define ASC_CTRL_BREAK_STAY_IDLE 0x0002 1673: #define ASCV_MSGOUT_BEG 0x0000 1674: #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3) 1675: #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4) 1676: #define ASCV_BREAK_SAVED_CODE (ushort)0x0006 1677: #define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8) 1678: #define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3) 1679: #define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4) 1680: #define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8) 1681: #define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8) 1682: #define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020 1683: #define ASCV_BREAK_ADDR (ushort)0x0028 1684: #define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A 1685: #define ASCV_BREAK_CONTROL (ushort)0x002C 1686: #define ASCV_BREAK_HIT_COUNT (ushort)0x002E 1687: 1688: #define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030 1689: #define ASCV_MCODE_CHKSUM_W (ushort)0x0032 1690: #define ASCV_MCODE_SIZE_W (ushort)0x0034 1691: #define ASCV_STOP_CODE_B (ushort)0x0036 1692: #define ASCV_DVC_ERR_CODE_B (ushort)0x0037 1693: #define ASCV_OVERRUN_PADDR_D (ushort)0x0038 1694: #define ASCV_OVERRUN_BSIZE_D (ushort)0x003C 1695: #define ASCV_HALTCODE_W (ushort)0x0040 1696: #define ASCV_CHKSUM_W (ushort)0x0042 1697: #define ASCV_MC_DATE_W (ushort)0x0044 1698: #define ASCV_MC_VER_W (ushort)0x0046 1699: #define ASCV_NEXTRDY_B (ushort)0x0048 1700: #define ASCV_DONENEXT_B (ushort)0x0049 1701: #define ASCV_USE_TAGGED_QNG_B (ushort)0x004A 1702: #define ASCV_SCSIBUSY_B (ushort)0x004B 1703: #define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C 1704: #define ASCV_CURCDB_B (ushort)0x004D 1705: #define ASCV_RCLUN_B (ushort)0x004E 1706: #define ASCV_BUSY_QHEAD_B (ushort)0x004F 1707: #define ASCV_DISC1_QHEAD_B (ushort)0x0050 1708: #define ASCV_DISC_ENABLE_B (ushort)0x0052 1709: #define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053 1710: #define ASCV_HOSTSCSI_ID_B (ushort)0x0055 1711: #define ASCV_MCODE_CNTL_B (ushort)0x0056 1712: #define ASCV_NULL_TARGET_B (ushort)0x0057 1713: #define ASCV_FREE_Q_HEAD_W (ushort)0x0058 1714: #define ASCV_DONE_Q_TAIL_W (ushort)0x005A 1715: #define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1) 1716: #define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1) 1717: #define ASCV_HOST_FLAG_B (ushort)0x005D 1718: #define ASCV_TOTAL_READY_Q_B (ushort)0x0064 1719: #define ASCV_VER_SERIAL_B (ushort)0x0065 1720: #define ASCV_HALTCODE_SAVED_W (ushort)0x0066 1721: #define ASCV_WTM_FLAG_B (ushort)0x0068 1722: #define ASCV_RISC_FLAG_B (ushort)0x006A 1723: #define ASCV_REQ_SG_LIST_QP (ushort)0x006B 1724: #define ASC_HOST_FLAG_IN_ISR 0x01 1725: #define ASC_HOST_FLAG_ACK_INT 0x02 1726: #define ASC_RISC_FLAG_GEN_INT 0x01 1727: #define ASC_RISC_FLAG_REQ_SG_LIST 0x02 1728: #define IOP_CTRL (0x0F) 1729: #define IOP_STATUS (0x0E) 1730: #define IOP_INT_ACK IOP_STATUS 1731: #define IOP_REG_IFC (0x0D) 1732: #define IOP_SYN_OFFSET (0x0B) 1733: #define IOP_EXTRA_CONTROL (0x0D) 1734: #define IOP_REG_PC (0x0C) 1735: #define IOP_RAM_ADDR (0x0A) 1736: #define IOP_RAM_DATA (0x08) 1737: #define IOP_EEP_DATA (0x06) 1738: #define IOP_EEP_CMD (0x07) 1739: #define IOP_VERSION (0x03) 1740: #define IOP_CONFIG_HIGH (0x04) 1741: #define IOP_CONFIG_LOW (0x02) 1742: #define IOP_SIG_BYTE (0x01) 1743: #define IOP_SIG_WORD (0x00) 1744: #define IOP_REG_DC1 (0x0E) 1745: #define IOP_REG_DC0 (0x0C) 1746: #define IOP_REG_SB (0x0B) 1747: #define IOP_REG_DA1 (0x0A) 1748: #define IOP_REG_DA0 (0x08) 1749: #define IOP_REG_SC (0x09) 1750: #define IOP_DMA_SPEED (0x07) 1751: #define IOP_REG_FLAG (0x07) 1752: #define IOP_FIFO_H (0x06) 1753: #define IOP_FIFO_L (0x04) 1754: #define IOP_REG_ID (0x05) 1755: #define IOP_REG_QP (0x03) 1756: #define IOP_REG_IH (0x02) 1757: #define IOP_REG_IX (0x01) 1758: #define IOP_REG_AX (0x00) 1759: #define IFC_REG_LOCK (0x00) 1760: #define IFC_REG_UNLOCK (0x09) 1761: #define IFC_WR_EN_FILTER (0x10) 1762: #define IFC_RD_NO_EEPROM (0x10) 1763: #define IFC_SLEW_RATE (0x20) 1764: #define IFC_ACT_NEG (0x40) 1765: #define IFC_INP_FILTER (0x80) 1766: #define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK) 1767: #define SC_SEL (uchar)(0x80) 1768: #define SC_BSY (uchar)(0x40) 1769: #define SC_ACK (uchar)(0x20) 1770: #define SC_REQ (uchar)(0x10) 1771: #define SC_ATN (uchar)(0x08) 1772: #define SC_IO (uchar)(0x04) 1773: #define SC_CD (uchar)(0x02) 1774: #define SC_MSG (uchar)(0x01) 1775: #define SEC_SCSI_CTL (uchar)(0x80) 1776: #define SEC_ACTIVE_NEGATE (uchar)(0x40) 1777: #define SEC_SLEW_RATE (uchar)(0x20) 1778: #define SEC_ENABLE_FILTER (uchar)(0x10) 1779: #define ASC_HALT_EXTMSG_IN (ushort)0x8000 1780: #define ASC_HALT_CHK_CONDITION (ushort)0x8100 1781: #define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200 1782: #define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300 1783: #define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400 1784: #define ASC_HALT_SDTR_REJECTED (ushort)0x4000 1785: #define ASC_MAX_QNO 0xF8 1786: #define ASC_DATA_SEC_BEG (ushort)0x0080 1787: #define ASC_DATA_SEC_END (ushort)0x0080 1788: #define ASC_CODE_SEC_BEG (ushort)0x0080 1789: #define ASC_CODE_SEC_END (ushort)0x0080 1790: #define ASC_QADR_BEG (0x4000) 1791: #define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64) 1792: #define ASC_QADR_END (ushort)0x7FFF 1793: #define ASC_QLAST_ADR (ushort)0x7FC0 1794: #define ASC_QBLK_SIZE 0x40 1795: #define ASC_BIOS_DATA_QBEG 0xF8 1796: #define ASC_MIN_ACTIVE_QNO 0x01 1797: #define ASC_QLINK_END 0xFF 1798: #define ASC_EEPROM_WORDS 0x10 1799: #define ASC_MAX_MGS_LEN 0x10 1800: #define ASC_BIOS_ADDR_DEF 0xDC00 1801: #define ASC_BIOS_SIZE 0x3800 1802: #define ASC_BIOS_RAM_OFF 0x3800 1803: #define ASC_BIOS_RAM_SIZE 0x800 1804: #define ASC_BIOS_MIN_ADDR 0xC000 1805: #define ASC_BIOS_MAX_ADDR 0xEC00 1806: #define ASC_BIOS_BANK_SIZE 0x0400 1807: #define ASC_MCODE_START_ADDR 0x0080 1808: #define ASC_CFG0_HOST_INT_ON 0x0020 1809: #define ASC_CFG0_BIOS_ON 0x0040 1810: #define ASC_CFG0_VERA_BURST_ON 0x0080 1811: #define ASC_CFG0_SCSI_PARITY_ON 0x0800 1812: #define ASC_CFG1_SCSI_TARGET_ON 0x0080 1813: #define ASC_CFG1_LRAM_8BITS_ON 0x0800 1814: #define ASC_CFG_MSW_CLR_MASK 0x3080 1815: #define CSW_TEST1 (ASC_CS_TYPE)0x8000 1816: #define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000 1817: #define CSW_RESERVED1 (ASC_CS_TYPE)0x2000 1818: #define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000 1819: #define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800 1820: #define CSW_TEST2 (ASC_CS_TYPE)0x0400 1821: #define CSW_TEST3 (ASC_CS_TYPE)0x0200 1822: #define CSW_RESERVED2 (ASC_CS_TYPE)0x0100 1823: #define CSW_DMA_DONE (ASC_CS_TYPE)0x0080 1824: #define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040 1825: #define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020 1826: #define CSW_HALTED (ASC_CS_TYPE)0x0010 1827: #define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008 1828: #define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004 1829: #define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002 1830: #define CSW_INT_PENDING (ASC_CS_TYPE)0x0001 1831: #define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000 1832: #define CIW_INT_ACK (ASC_CS_TYPE)0x0100 1833: #define CIW_TEST1 (ASC_CS_TYPE)0x0200 1834: #define CIW_TEST2 (ASC_CS_TYPE)0x0400 1835: #define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800 1836: #define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000 1837: #define CC_CHIP_RESET (uchar)0x80 1838: #define CC_SCSI_RESET (uchar)0x40 1839: #define CC_HALT (uchar)0x20 1840: #define CC_SINGLE_STEP (uchar)0x10 1841: #define CC_DMA_ABLE (uchar)0x08 1842: #define CC_TEST (uchar)0x04 1843: #define CC_BANK_ONE (uchar)0x02 1844: #define CC_DIAG (uchar)0x01 1845: #define ASC_1000_ID0W 0x04C1 1846: #define ASC_1000_ID0W_FIX 0x00C1 1847: #define ASC_1000_ID1B 0x25 1848: #define ASC_EISA_BIG_IOP_GAP (0x1C30-0x0C50) 1849: #define ASC_EISA_SMALL_IOP_GAP (0x0020) 1850: #define ASC_EISA_MIN_IOP_ADDR (0x0C30) 1851: #define ASC_EISA_MAX_IOP_ADDR (0xFC50) 1852: #define ASC_EISA_REV_IOP_MASK (0x0C83) 1853: #define ASC_EISA_PID_IOP_MASK (0x0C80) 1854: #define ASC_EISA_CFG_IOP_MASK (0x0C86) 1855: #define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000) 1856: #define ASC_EISA_ID_740 0x01745004UL 1857: #define ASC_EISA_ID_750 0x01755004UL 1858: #define INS_HALTINT (ushort)0x6281 1859: #define INS_HALT (ushort)0x6280 1860: #define INS_SINT (ushort)0x6200 1861: #define INS_RFLAG_WTM (ushort)0x7380 1862: #define ASC_MC_SAVE_CODE_WSIZE 0x500 1863: #define ASC_MC_SAVE_DATA_WSIZE 0x40 1864: 1865: typedef struct asc_mc_saved { 1866: ushort data[ASC_MC_SAVE_DATA_WSIZE]; 1867: ushort code[ASC_MC_SAVE_CODE_WSIZE]; 1868: } ASC_MC_SAVED; 1869: 1870: #define AscGetQDoneInProgress(port) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B) 1871: #define AscPutQDoneInProgress(port, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val) 1872: #define AscGetVarFreeQHead(port) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W) 1873: #define AscGetVarDoneQTail(port) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W) 1874: #define AscPutVarFreeQHead(port, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val) 1875: #define AscPutVarDoneQTail(port, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val) 1876: #define AscGetRiscVarFreeQHead(port) AscReadLramByte((port), ASCV_NEXTRDY_B) 1877: #define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B) 1878: #define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val) 1879: #define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val) 1880: #define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data)) ; 1881: #define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id)) ; 1882: #define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data) ; 1883: #define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id)) ; 1884: #define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ]) 1885: #define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE) 1886: #define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD) 1887: #define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION) 1888: #define AscGetChipCfgLsw(port) (ushort)inpw((port)+IOP_CONFIG_LOW) 1889: #define AscGetChipCfgMsw(port) (ushort)inpw((port)+IOP_CONFIG_HIGH) 1890: #define AscSetChipCfgLsw(port, data) outpw((port)+IOP_CONFIG_LOW, data) 1891: #define AscSetChipCfgMsw(port, data) outpw((port)+IOP_CONFIG_HIGH, data) 1892: #define AscGetChipEEPCmd(port) (uchar)inp((port)+IOP_EEP_CMD) 1893: #define AscSetChipEEPCmd(port, data) outp((port)+IOP_EEP_CMD, data) 1894: #define AscGetChipEEPData(port) (ushort)inpw((port)+IOP_EEP_DATA) 1895: #define AscSetChipEEPData(port, data) outpw((port)+IOP_EEP_DATA, data) 1896: #define AscGetChipLramAddr(port) (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR)) 1897: #define AscSetChipLramAddr(port, addr) outpw((PortAddr)((port)+IOP_RAM_ADDR), addr) 1898: #define AscGetChipLramData(port) (ushort)inpw((port)+IOP_RAM_DATA) 1899: #define AscSetChipLramData(port, data) outpw((port)+IOP_RAM_DATA, data) 1900: #define AscGetChipLramDataNoSwap(port) (ushort)inpw_noswap((port)+IOP_RAM_DATA) 1901: #define AscSetChipLramDataNoSwap(port, data) outpw_noswap((port)+IOP_RAM_DATA, data) 1902: #define AscGetChipIFC(port) (uchar)inp((port)+IOP_REG_IFC) 1903: #define AscSetChipIFC(port, data) outp((port)+IOP_REG_IFC, data) 1904: #define AscGetChipStatus(port) (ASC_CS_TYPE)inpw((port)+IOP_STATUS) 1905: #define AscSetChipStatus(port, cs_val) outpw((port)+IOP_STATUS, cs_val) 1906: #define AscGetChipControl(port) (uchar)inp((port)+IOP_CTRL) 1907: #define AscSetChipControl(port, cc_val) outp((port)+IOP_CTRL, cc_val) 1908: #define AscGetChipSyn(port) (uchar)inp((port)+IOP_SYN_OFFSET) 1909: #define AscSetChipSyn(port, data) outp((port)+IOP_SYN_OFFSET, data) 1910: #define AscSetPCAddr(port, data) outpw((port)+IOP_REG_PC, data) 1911: #define AscGetPCAddr(port) (ushort)inpw((port)+IOP_REG_PC) 1912: #define AscIsIntPending(port) (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH)) 1913: #define AscGetChipScsiID(port) ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID) 1914: #define AscGetExtraControl(port) (uchar)inp((port)+IOP_EXTRA_CONTROL) 1915: #define AscSetExtraControl(port, data) outp((port)+IOP_EXTRA_CONTROL, data) 1916: #define AscReadChipAX(port) (ushort)inpw((port)+IOP_REG_AX) 1917: #define AscWriteChipAX(port, data) outpw((port)+IOP_REG_AX, data) 1918: #define AscReadChipIX(port) (uchar)inp((port)+IOP_REG_IX) 1919: #define AscWriteChipIX(port, data) outp((port)+IOP_REG_IX, data) 1920: #define AscReadChipIH(port) (ushort)inpw((port)+IOP_REG_IH) 1921: #define AscWriteChipIH(port, data) outpw((port)+IOP_REG_IH, data) 1922: #define AscReadChipQP(port) (uchar)inp((port)+IOP_REG_QP) 1923: #define AscWriteChipQP(port, data) outp((port)+IOP_REG_QP, data) 1924: #define AscReadChipFIFO_L(port) (ushort)inpw((port)+IOP_REG_FIFO_L) 1925: #define AscWriteChipFIFO_L(port, data) outpw((port)+IOP_REG_FIFO_L, data) 1926: #define AscReadChipFIFO_H(port) (ushort)inpw((port)+IOP_REG_FIFO_H) 1927: #define AscWriteChipFIFO_H(port, data) outpw((port)+IOP_REG_FIFO_H, data) 1928: #define AscReadChipDmaSpeed(port) (uchar)inp((port)+IOP_DMA_SPEED) 1929: #define AscWriteChipDmaSpeed(port, data) outp((port)+IOP_DMA_SPEED, data) 1930: #define AscReadChipDA0(port) (ushort)inpw((port)+IOP_REG_DA0) 1931: #define AscWriteChipDA0(port) outpw((port)+IOP_REG_DA0, data) 1932: #define AscReadChipDA1(port) (ushort)inpw((port)+IOP_REG_DA1) 1933: #define AscWriteChipDA1(port) outpw((port)+IOP_REG_DA1, data) 1934: #define AscReadChipDC0(port) (ushort)inpw((port)+IOP_REG_DC0) 1935: #define AscWriteChipDC0(port) outpw((port)+IOP_REG_DC0, data) 1936: #define AscReadChipDC1(port) (ushort)inpw((port)+IOP_REG_DC1) 1937: #define AscWriteChipDC1(port) outpw((port)+IOP_REG_DC1, data) 1938: #define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID) 1939: #define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data) 1940: 1941: STATIC int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg); 1942: STATIC int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg); 1943: STATIC void AscWaitEEPRead(void); 1944: STATIC void AscWaitEEPWrite(void); 1945: STATIC ushort AscReadEEPWord(PortAddr, uchar); 1946: STATIC ushort AscWriteEEPWord(PortAddr, uchar, ushort); 1947: STATIC ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort); 1948: STATIC int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort); 1949: STATIC int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort); 1950: STATIC int AscStartChip(PortAddr); 1951: STATIC int AscStopChip(PortAddr); 1952: STATIC void AscSetChipIH(PortAddr, ushort); 1953: STATIC int AscIsChipHalted(PortAddr); 1954: STATIC void AscAckInterrupt(PortAddr); 1955: STATIC void AscDisableInterrupt(PortAddr); 1956: STATIC void AscEnableInterrupt(PortAddr); 1957: STATIC void AscSetBank(PortAddr, uchar); 1958: STATIC int AscResetChipAndScsiBus(ASC_DVC_VAR *); 1959: STATIC ushort AscGetIsaDmaChannel(PortAddr); 1960: STATIC ushort AscSetIsaDmaChannel(PortAddr, ushort); 1961: STATIC uchar AscSetIsaDmaSpeed(PortAddr, uchar); 1962: STATIC uchar AscGetIsaDmaSpeed(PortAddr); 1963: STATIC uchar AscReadLramByte(PortAddr, ushort); 1964: STATIC ushort AscReadLramWord(PortAddr, ushort); 1965: STATIC ulong AscReadLramDWord(PortAddr, ushort); 1966: STATIC void AscWriteLramWord(PortAddr, ushort, ushort); 1967: STATIC void AscWriteLramDWord(PortAddr, ushort, ulong); 1968: STATIC void AscWriteLramByte(PortAddr, ushort, uchar); 1969: STATIC ulong AscMemSumLramWord(PortAddr, ushort, rint); 1970: STATIC void AscMemWordSetLram(PortAddr, ushort, ushort, rint); 1971: STATIC void AscMemWordCopyToLram(PortAddr, ushort, ushort *, int); 1972: STATIC void AscMemDWordCopyToLram(PortAddr, ushort, ulong *, int); 1973: STATIC void AscMemWordCopyFromLram(PortAddr, ushort, ushort *, int); 1974: STATIC ushort AscInitAscDvcVar(ASC_DVC_VAR asc_ptr_type *); 1975: STATIC ushort AscInitFromEEP(ASC_DVC_VAR asc_ptr_type *); 1976: STATIC ushort AscInitFromAscDvcVar(ASC_DVC_VAR asc_ptr_type *); 1977: STATIC ushort AscInitMicroCodeVar(ASC_DVC_VAR asc_ptr_type * asc_dvc); 1978: STATIC int AscTestExternalLram(ASC_DVC_VAR asc_ptr_type *); 1979: STATIC uchar AscMsgOutSDTR(ASC_DVC_VAR asc_ptr_type *, uchar, uchar); 1980: STATIC uchar AscCalSDTRData(ASC_DVC_VAR asc_ptr_type *, uchar, uchar); 1981: STATIC void AscSetChipSDTR(PortAddr, uchar, uchar); 1982: STATIC uchar AscGetSynPeriodIndex(ASC_DVC_VAR asc_ptr_type *, ruchar); 1983: STATIC uchar AscAllocFreeQueue(PortAddr, uchar); 1984: STATIC uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar); 1985: STATIC int AscRiscHaltedAbortSRB(ASC_DVC_VAR asc_ptr_type *, ulong); 1986: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89) 1987: STATIC int AscRiscHaltedAbortTIX(ASC_DVC_VAR asc_ptr_type *, uchar); 1988: #endif /* version >= v1.3.89 */ 1989: STATIC int AscHostReqRiscHalt(PortAddr); 1990: STATIC int AscStopQueueExe(PortAddr); 1991: STATIC int AscStartQueueExe(PortAddr); 1992: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89) 1993: STATIC int AscCleanUpDiscQueue(PortAddr); 1994: #endif /* version >= v1.3.89 */ 1995: STATIC int AscCleanUpBusyQueue(PortAddr); 1996: STATIC int AscWaitTixISRDone(ASC_DVC_VAR asc_ptr_type *, uchar); 1997: STATIC int AscWaitISRDone(ASC_DVC_VAR asc_ptr_type *); 1998: STATIC ulong AscGetOnePhyAddr(ASC_DVC_VAR asc_ptr_type *, uchar *, 1999: ulong); 2000: STATIC int AscSendScsiQueue(ASC_DVC_VAR asc_ptr_type * asc_dvc, 2001: ASC_SCSI_Q * scsiq, 2002: uchar n_q_required); 2003: STATIC int AscPutReadyQueue(ASC_DVC_VAR asc_ptr_type *, 2004: ASC_SCSI_Q *, uchar); 2005: STATIC int AscPutReadySgListQueue(ASC_DVC_VAR asc_ptr_type *, 2006: ASC_SCSI_Q *, uchar); 2007: STATIC int AscSetChipSynRegAtID(PortAddr, uchar, uchar); 2008: STATIC int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar); 2009: STATIC ushort AscInitLram(ASC_DVC_VAR asc_ptr_type *); 2010: STATIC int AscReInitLram(ASC_DVC_VAR asc_ptr_type *); 2011: STATIC ushort AscInitQLinkVar(ASC_DVC_VAR asc_ptr_type *); 2012: STATIC int AscSetLibErrorCode(ASC_DVC_VAR asc_ptr_type *, ushort); 2013: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89) 2014: STATIC int _AscWaitQDone(PortAddr, ASC_SCSI_Q *); 2015: #endif /* version >= v1.3.89 */ 2016: STATIC int AscIsrChipHalted(ASC_DVC_VAR asc_ptr_type *); 2017: STATIC uchar _AscCopyLramScsiDoneQ(PortAddr, ushort, 2018: ASC_QDONE_INFO *, ulong); 2019: STATIC int AscIsrQDone(ASC_DVC_VAR asc_ptr_type *); 2020: STATIC int AscCompareString(uchar *, uchar *, int); 2021: STATIC ushort AscGetEisaChipCfg(PortAddr); 2022: STATIC ulong AscGetEisaProductID(PortAddr); 2023: STATIC PortAddr AscSearchIOPortAddrEISA(PortAddr); 2024: STATIC uchar AscGetChipScsiCtrl(PortAddr); 2025: STATIC uchar AscSetChipScsiID(PortAddr, uchar); 2026: STATIC uchar AscGetChipVersion(PortAddr, ushort); 2027: STATIC ushort AscGetChipBusType(PortAddr); 2028: STATIC ulong AscLoadMicroCode(PortAddr, ushort, ushort *, ushort); 2029: STATIC int AscFindSignature(PortAddr); 2030: STATIC PortAddr AscSearchIOPortAddr11(PortAddr); 2031: STATIC void AscToggleIRQAct(PortAddr); 2032: STATIC void AscSetISAPNPWaitForKey(void); 2033: STATIC uchar AscGetChipIRQ(PortAddr, ushort); 2034: STATIC uchar AscSetChipIRQ(PortAddr, uchar, ushort); 2035: STATIC ushort AscGetChipBiosAddress(PortAddr, ushort); 1.1.1.2 ! root 2036: STATIC long DvcEnterCritical(void); ! 2037: STATIC void DvcLeaveCritical(long); 1.1 root 2038: STATIC void DvcInPortWords(PortAddr, ushort *, int); 2039: STATIC void DvcOutPortWords(PortAddr, ushort *, int); 2040: STATIC void DvcOutPortDWords(PortAddr, ulong *, int); 2041: STATIC uchar DvcReadPCIConfigByte(ASC_DVC_VAR asc_ptr_type *, ushort); 2042: STATIC void DvcWritePCIConfigByte(ASC_DVC_VAR asc_ptr_type *, 2043: ushort, uchar); 2044: STATIC ushort AscGetChipBiosAddress(PortAddr, ushort); 2045: STATIC void DvcSleepMilliSecond(ulong); 2046: STATIC void DvcDelayNanoSecond(ASC_DVC_VAR asc_ptr_type *, ulong); 2047: STATIC ulong DvcGetSGList(ASC_DVC_VAR asc_ptr_type *, uchar *, 2048: ulong, ASC_SG_HEAD *); 2049: STATIC void DvcPutScsiQ(PortAddr, ushort, ushort *, int); 2050: STATIC void DvcGetQinfo(PortAddr, ushort, ushort *, int); 2051: STATIC PortAddr AscSearchIOPortAddr(PortAddr, ushort); 2052: STATIC ushort AscInitGetConfig(ASC_DVC_VAR asc_ptr_type *); 2053: STATIC ushort AscInitSetConfig(ASC_DVC_VAR asc_ptr_type *); 2054: STATIC ushort AscInitAsc1000Driver(ASC_DVC_VAR asc_ptr_type *); 2055: STATIC void AscAsyncFix(ASC_DVC_VAR asc_ptr_type *, uchar, 2056: ASC_SCSI_INQUIRY *); 2057: STATIC int AscTagQueuingSafe(ASC_SCSI_INQUIRY *); 2058: STATIC void AscInquiryHandling(ASC_DVC_VAR asc_ptr_type *, 2059: uchar, ASC_SCSI_INQUIRY *); 2060: STATIC int AscExeScsiQueue(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q *); 2061: STATIC int AscISR(ASC_DVC_VAR asc_ptr_type *); 2062: STATIC uint AscGetNumOfFreeQueue(ASC_DVC_VAR asc_ptr_type *, uchar, 2063: uchar); 2064: STATIC int AscSgListToQueue(int); 2065: STATIC int AscAbortSRB(ASC_DVC_VAR asc_ptr_type *, ulong); 2066: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89) 2067: STATIC int AscResetDevice(ASC_DVC_VAR asc_ptr_type *, uchar); 2068: #endif /* version >= v1.3.89 */ 2069: STATIC int AscResetSB(ASC_DVC_VAR asc_ptr_type *); 2070: STATIC void AscEnableIsaDma(uchar); 2071: STATIC ulong AscGetMaxDmaCount(ushort); 2072: 2073: 2074: /* 2075: * --- Adv Library Constants and Macros 2076: */ 2077: 2078: #define ADV_LIB_VERSION_MAJOR 3 2079: #define ADV_LIB_VERSION_MINOR 45 2080: 2081: /* d_os_dep.h */ 2082: #define ADV_OS_LINUX 2083: 2084: /* 2085: * Define Adv Library required special types. 2086: */ 2087: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0) 2088: #define AdvPortAddr unsigned short /* I/O Port address size */ 2089: #else /* version >= v1,3,0 */ 2090: #define AdvPortAddr unsigned long /* Virtual memory address size */ 2091: #endif /* version >= v1,3,0 */ 2092: 2093: /* 2094: * Define Adv Library required memory access macros. 2095: */ 2096: #define ADV_MEM_READB(addr) readb(addr) 2097: #define ADV_MEM_READW(addr) readw(addr) 2098: #define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr) 2099: #define ADV_MEM_WRITEW(addr, word) writew(word, addr) 2100: 2101: /* 2102: * The I/O memory mapping function names changed in 2.1.X. 2103: */ 2104: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,0) 2105: #define ioremap vremap 2106: #define iounmap vfree 2107: #endif /* version < v2.1.0 */ 2108: 2109: /* 2110: * Define total number of simultaneous maximum element scatter-gather 2111: * requests, i.e. ADV_TOT_SG_LIST * ADV_MAX_SG_LIST is the total number 2112: * of simultaneous scatter-gather elements supported per wide adapter. 2113: */ 2114: #define ADV_TOT_SG_LIST 64 2115: 2116: /* 2117: * Define Adv Library required per request scatter-gather element limit. 2118: */ 2119: #define ADV_MAX_SG_LIST 64 2120: 2121: /* 2122: * Scatter-Gather Definitions per request. 2123: * 2124: * Because SG block memory is allocated in virtual memory but is 2125: * referenced by the microcode as physical memory, we need to do 2126: * calculations to insure there will be enough physically contiguous 2127: * memory to support ADV_MAX_SG_LIST SG entries. 2128: */ 2129: 2130: /* Number of SG blocks needed. */ 2131: #define ADV_NUM_SG_BLOCK \ 2132: ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK) 2133: 2134: /* Total contiguous memory needed for SG blocks. */ 2135: #define ADV_SG_TOTAL_MEM_SIZE \ 2136: (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK) 2137: 2138: #define ASC_PAGE_SIZE PAGE_SIZE 2139: 2140: /* 2141: * Number of page crossings possible for the total contiguous virtual memory 2142: * needed for SG blocks. 2143: * 2144: * We need to allocate this many additional SG blocks in virtual memory to 2145: * insure there will be space for ADV_NUM_SG_BLOCK physically contiguous 2146: * scatter-gather blocks. 2147: */ 2148: #define ADV_NUM_PAGE_CROSSING \ 2149: ((ADV_SG_TOTAL_MEM_SIZE + (ASC_PAGE_SIZE - 1))/ASC_PAGE_SIZE) 2150: 2151: /* 2152: * Define Adv Library Assertion Macro. 2153: */ 2154: 2155: #define ADV_ASSERT(a) ASC_ASSERT(a) 2156: 2157: /* a_condor.h */ 2158: #define ADV_PCI_VENDOR_ID 0x10CD 2159: #define ADV_PCI_DEVICE_ID_REV_A 0x2300 2160: 2161: #define ASC_EEP_DVC_CFG_BEGIN (0x00) 2162: #define ASC_EEP_DVC_CFG_END (0x15) 2163: #define ASC_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */ 2164: #define ASC_EEP_MAX_WORD_ADDR (0x1E) 2165: 2166: #define ASC_EEP_DELAY_MS 100 2167: 2168: /* 2169: * EEPROM bits reference by the RISC after initialization. 2170: */ 2171: #define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */ 2172: #define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */ 2173: #define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */ 2174: 2175: /* 2176: * EEPROM configuration format 2177: * 2178: * Field naming convention: 2179: * 2180: * *_enable indicates the field enables or disables the feature. The 2181: * value is never reset. 2182: * 2183: * *_able indicates both whether a feature should be enabled or disabled 2184: * and whether a device isi capable of the feature. At initialization 2185: * this field may be set, but later if a device is found to be incapable 2186: * of the feature, the field is cleared. 2187: * 2188: * Default values are maintained in a_init.c in the structure 2189: * Default_EEPROM_Config. 2190: */ 2191: typedef struct adveep_config 2192: { 2193: /* Word Offset, Description */ 2194: 2195: ushort cfg_lsw; /* 00 power up initialization */ 2196: /* bit 13 set - Term Polarity Control */ 2197: /* bit 14 set - BIOS Enable */ 2198: /* bit 15 set - Big Endian Mode */ 2199: ushort cfg_msw; /* 01 unused */ 2200: ushort disc_enable; /* 02 disconnect enable */ 2201: ushort wdtr_able; /* 03 Wide DTR able */ 2202: ushort sdtr_able; /* 04 Synchronous DTR able */ 2203: ushort start_motor; /* 05 send start up motor */ 2204: ushort tagqng_able; /* 06 tag queuing able */ 2205: ushort bios_scan; /* 07 BIOS device control */ 2206: ushort scam_tolerant; /* 08 no scam */ 2207: 2208: uchar adapter_scsi_id; /* 09 Host Adapter ID */ 2209: uchar bios_boot_delay; /* power up wait */ 2210: 2211: uchar scsi_reset_delay; /* 10 reset delay */ 2212: uchar bios_id_lun; /* first boot device scsi id & lun */ 2213: /* high nibble is lun */ 2214: /* low nibble is scsi id */ 2215: 2216: uchar termination; /* 11 0 - automatic */ 2217: /* 1 - low off / high off */ 2218: /* 2 - low off / high on */ 2219: /* 3 - low on / high on */ 2220: /* There is no low on / high off */ 2221: 2222: uchar reserved1; /* reserved byte (not used) */ 2223: 2224: ushort bios_ctrl; /* 12 BIOS control bits */ 2225: /* bit 0 set: BIOS don't act as initiator. */ 2226: /* bit 1 set: BIOS > 1 GB support */ 2227: /* bit 2 set: BIOS > 2 Disk Support */ 2228: /* bit 3 set: BIOS don't support removables */ 2229: /* bit 4 set: BIOS support bootable CD */ 2230: /* bit 5 set: */ 2231: /* bit 6 set: BIOS support multiple LUNs */ 2232: /* bit 7 set: BIOS display of message */ 2233: /* bit 8 set: */ 2234: /* bit 9 set: Reset SCSI bus during init. */ 2235: /* bit 10 set: */ 2236: /* bit 11 set: No verbose initialization. */ 2237: /* bit 12 set: SCSI parity enabled */ 2238: /* bit 13 set: */ 2239: /* bit 14 set: */ 2240: /* bit 15 set: */ 2241: ushort ultra_able; /* 13 ULTRA speed able */ 2242: ushort reserved2; /* 14 reserved */ 2243: uchar max_host_qng; /* 15 maximum host queuing */ 2244: uchar max_dvc_qng; /* maximum per device queuing */ 2245: ushort dvc_cntl; /* 16 control bit for driver */ 2246: ushort bug_fix; /* 17 control bit for bug fix */ 2247: ushort serial_number_word1; /* 18 Board serial number word 1 */ 2248: ushort serial_number_word2; /* 19 Board serial number word 2 */ 2249: ushort serial_number_word3; /* 20 Board serial number word 3 */ 2250: ushort check_sum; /* 21 EEP check sum */ 2251: uchar oem_name[16]; /* 22 OEM name */ 2252: ushort dvc_err_code; /* 30 last device driver error code */ 2253: ushort adv_err_code; /* 31 last uc and Adv Lib error code */ 2254: ushort adv_err_addr; /* 32 last uc error address */ 2255: ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */ 2256: ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */ 2257: ushort saved_adv_err_addr; /* 35 saved last uc error address */ 2258: ushort num_of_err; /* 36 number of error */ 2259: } ADVEEP_CONFIG; 2260: 2261: /* 2262: * EEPROM Commands 2263: */ 2264: #define ASC_EEP_CMD_DONE 0x0200 2265: #define ASC_EEP_CMD_DONE_ERR 0x0001 2266: 2267: /* cfg_word */ 2268: #define EEP_CFG_WORD_BIG_ENDIAN 0x8000 2269: 2270: /* bios_ctrl */ 2271: #define BIOS_CTRL_BIOS 0x0001 2272: #define BIOS_CTRL_EXTENDED_XLAT 0x0002 2273: #define BIOS_CTRL_GT_2_DISK 0x0004 2274: #define BIOS_CTRL_BIOS_REMOVABLE 0x0008 2275: #define BIOS_CTRL_BOOTABLE_CD 0x0010 2276: #define BIOS_CTRL_MULTIPLE_LUN 0x0040 2277: #define BIOS_CTRL_DISPLAY_MSG 0x0080 2278: #define BIOS_CTRL_NO_SCAM 0x0100 2279: #define BIOS_CTRL_RESET_SCSI_BUS 0x0200 2280: #define BIOS_CTRL_INIT_VERBOSE 0x0800 2281: #define BIOS_CTRL_SCSI_PARITY 0x1000 2282: 2283: /* 2284: * ASC 3550 Internal Memory Size - 8KB 2285: */ 2286: #define ADV_CONDOR_MEMSIZE 0x2000 /* 8 KB Internal Memory */ 2287: 2288: /* 2289: * ASC 3550 I/O Length - 64 bytes 2290: */ 2291: #define ADV_CONDOR_IOLEN 0x40 /* I/O Port Range in bytes */ 2292: 2293: /* 2294: * Byte I/O register address from base of 'iop_base'. 2295: */ 2296: #define IOPB_INTR_STATUS_REG 0x00 2297: #define IOPB_CHIP_ID_1 0x01 2298: #define IOPB_INTR_ENABLES 0x02 2299: #define IOPB_CHIP_TYPE_REV 0x03 2300: #define IOPB_RES_ADDR_4 0x04 2301: #define IOPB_RES_ADDR_5 0x05 2302: #define IOPB_RAM_DATA 0x06 2303: #define IOPB_RES_ADDR_7 0x07 2304: #define IOPB_FLAG_REG 0x08 2305: #define IOPB_RES_ADDR_9 0x09 2306: #define IOPB_RISC_CSR 0x0A 2307: #define IOPB_RES_ADDR_B 0x0B 2308: #define IOPB_RES_ADDR_C 0x0C 2309: #define IOPB_RES_ADDR_D 0x0D 2310: #define IOPB_RES_ADDR_E 0x0E 2311: #define IOPB_RES_ADDR_F 0x0F 2312: #define IOPB_MEM_CFG 0x10 2313: #define IOPB_RES_ADDR_11 0x11 2314: #define IOPB_RES_ADDR_12 0x12 2315: #define IOPB_RES_ADDR_13 0x13 2316: #define IOPB_FLASH_PAGE 0x14 2317: #define IOPB_RES_ADDR_15 0x15 2318: #define IOPB_RES_ADDR_16 0x16 2319: #define IOPB_RES_ADDR_17 0x17 2320: #define IOPB_FLASH_DATA 0x18 2321: #define IOPB_RES_ADDR_19 0x19 2322: #define IOPB_RES_ADDR_1A 0x1A 2323: #define IOPB_RES_ADDR_1B 0x1B 2324: #define IOPB_RES_ADDR_1C 0x1C 2325: #define IOPB_RES_ADDR_1D 0x1D 2326: #define IOPB_RES_ADDR_1E 0x1E 2327: #define IOPB_RES_ADDR_1F 0x1F 2328: #define IOPB_DMA_CFG0 0x20 2329: #define IOPB_DMA_CFG1 0x21 2330: #define IOPB_TICKLE 0x22 2331: #define IOPB_DMA_REG_WR 0x23 2332: #define IOPB_SDMA_STATUS 0x24 2333: #define IOPB_SCSI_BYTE_CNT 0x25 2334: #define IOPB_HOST_BYTE_CNT 0x26 2335: #define IOPB_BYTE_LEFT_TO_XFER 0x27 2336: #define IOPB_BYTE_TO_XFER_0 0x28 2337: #define IOPB_BYTE_TO_XFER_1 0x29 2338: #define IOPB_BYTE_TO_XFER_2 0x2A 2339: #define IOPB_BYTE_TO_XFER_3 0x2B 2340: #define IOPB_ACC_GRP 0x2C 2341: #define IOPB_RES_ADDR_2D 0x2D 2342: #define IOPB_DEV_ID 0x2E 2343: #define IOPB_RES_ADDR_2F 0x2F 2344: #define IOPB_SCSI_DATA 0x30 2345: #define IOPB_RES_ADDR_31 0x31 2346: #define IOPB_RES_ADDR_32 0x32 2347: #define IOPB_SCSI_DATA_HSHK 0x33 2348: #define IOPB_SCSI_CTRL 0x34 2349: #define IOPB_RES_ADDR_35 0x35 2350: #define IOPB_RES_ADDR_36 0x36 2351: #define IOPB_RES_ADDR_37 0x37 2352: #define IOPB_RES_ADDR_38 0x38 2353: #define IOPB_RES_ADDR_39 0x39 2354: #define IOPB_RES_ADDR_3A 0x3A 2355: #define IOPB_RES_ADDR_3B 0x3B 2356: #define IOPB_RFIFO_CNT 0x3C 2357: #define IOPB_RES_ADDR_3D 0x3D 2358: #define IOPB_RES_ADDR_3E 0x3E 2359: #define IOPB_RES_ADDR_3F 0x3F 2360: 2361: /* 2362: * Word I/O register address from base of 'iop_base'. 2363: */ 2364: #define IOPW_CHIP_ID_0 0x00 /* CID0 */ 2365: #define IOPW_CTRL_REG 0x02 /* CC */ 2366: #define IOPW_RAM_ADDR 0x04 /* LA */ 2367: #define IOPW_RAM_DATA 0x06 /* LD */ 2368: #define IOPW_RES_ADDR_08 0x08 2369: #define IOPW_RISC_CSR 0x0A /* CSR */ 2370: #define IOPW_SCSI_CFG0 0x0C /* CFG0 */ 2371: #define IOPW_SCSI_CFG1 0x0E /* CFG1 */ 2372: #define IOPW_RES_ADDR_10 0x10 2373: #define IOPW_SEL_MASK 0x12 /* SM */ 2374: #define IOPW_RES_ADDR_14 0x14 2375: #define IOPW_FLASH_ADDR 0x16 /* FA */ 2376: #define IOPW_RES_ADDR_18 0x18 2377: #define IOPW_EE_CMD 0x1A /* EC */ 2378: #define IOPW_EE_DATA 0x1C /* ED */ 2379: #define IOPW_SFIFO_CNT 0x1E /* SFC */ 2380: #define IOPW_RES_ADDR_20 0x20 2381: #define IOPW_Q_BASE 0x22 /* QB */ 2382: #define IOPW_QP 0x24 /* QP */ 2383: #define IOPW_IX 0x26 /* IX */ 2384: #define IOPW_SP 0x28 /* SP */ 2385: #define IOPW_PC 0x2A /* PC */ 2386: #define IOPW_RES_ADDR_2C 0x2C 2387: #define IOPW_RES_ADDR_2E 0x2E 2388: #define IOPW_SCSI_DATA 0x30 /* SD */ 2389: #define IOPW_SCSI_DATA_HSHK 0x32 /* SDH */ 2390: #define IOPW_SCSI_CTRL 0x34 /* SC */ 2391: #define IOPW_HSHK_CFG 0x36 /* HCFG */ 2392: #define IOPW_SXFR_STATUS 0x36 /* SXS */ 2393: #define IOPW_SXFR_CNTL 0x38 /* SXL */ 2394: #define IOPW_SXFR_CNTH 0x3A /* SXH */ 2395: #define IOPW_RES_ADDR_3C 0x3C 2396: #define IOPW_RFIFO_DATA 0x3E /* RFD */ 2397: 2398: /* 2399: * Doubleword I/O register address from base of 'iop_base'. 2400: */ 2401: #define IOPDW_RES_ADDR_0 0x00 2402: #define IOPDW_RAM_DATA 0x04 2403: #define IOPDW_RES_ADDR_8 0x08 2404: #define IOPDW_RES_ADDR_C 0x0C 2405: #define IOPDW_RES_ADDR_10 0x10 2406: #define IOPDW_RES_ADDR_14 0x14 2407: #define IOPDW_RES_ADDR_18 0x18 2408: #define IOPDW_RES_ADDR_1C 0x1C 2409: #define IOPDW_SDMA_ADDR0 0x20 2410: #define IOPDW_SDMA_ADDR1 0x24 2411: #define IOPDW_SDMA_COUNT 0x28 2412: #define IOPDW_SDMA_ERROR 0x2C 2413: #define IOPDW_RDMA_ADDR0 0x30 2414: #define IOPDW_RDMA_ADDR1 0x34 2415: #define IOPDW_RDMA_COUNT 0x38 2416: #define IOPDW_RDMA_ERROR 0x3C 2417: 2418: #define ADV_CHIP_ID_BYTE 0x25 2419: #define ADV_CHIP_ID_WORD 0x04C1 2420: 2421: #define ADV_SC_SCSI_BUS_RESET 0x2000 2422: 2423: #define ADV_INTR_ENABLE_HOST_INTR 0x01 2424: #define ADV_INTR_ENABLE_SEL_INTR 0x02 2425: #define ADV_INTR_ENABLE_DPR_INTR 0x04 2426: #define ADV_INTR_ENABLE_RTA_INTR 0x08 2427: #define ADV_INTR_ENABLE_RMA_INTR 0x10 2428: #define ADV_INTR_ENABLE_RST_INTR 0x20 2429: #define ADV_INTR_ENABLE_DPE_INTR 0x40 2430: #define ADV_INTR_ENABLE_GLOBAL_INTR 0x80 2431: 2432: #define ADV_INTR_STATUS_INTRA 0x01 2433: #define ADV_INTR_STATUS_INTRB 0x02 2434: #define ADV_INTR_STATUS_INTRC 0x04 2435: 2436: #define ADV_RISC_CSR_STOP (0x0000) 2437: #define ADV_RISC_TEST_COND (0x2000) 2438: #define ADV_RISC_CSR_RUN (0x4000) 2439: #define ADV_RISC_CSR_SINGLE_STEP (0x8000) 2440: 2441: #define ADV_CTRL_REG_HOST_INTR 0x0100 2442: #define ADV_CTRL_REG_SEL_INTR 0x0200 2443: #define ADV_CTRL_REG_DPR_INTR 0x0400 2444: #define ADV_CTRL_REG_RTA_INTR 0x0800 2445: #define ADV_CTRL_REG_RMA_INTR 0x1000 2446: #define ADV_CTRL_REG_RES_BIT14 0x2000 2447: #define ADV_CTRL_REG_DPE_INTR 0x4000 2448: #define ADV_CTRL_REG_POWER_DONE 0x8000 2449: #define ADV_CTRL_REG_ANY_INTR 0xFF00 2450: 2451: #define ADV_CTRL_REG_CMD_RESET 0x00C6 2452: #define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5 2453: #define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4 2454: #define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3 2455: #define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2 2456: 2457: #define ADV_SCSI_CTRL_RSTOUT 0x2000 2458: 2459: #define AdvIsIntPending(port) \ 2460: (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR) 2461: 2462: /* 2463: * SCSI_CFG0 Register bit definitions 2464: */ 2465: #define TIMER_MODEAB 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */ 2466: #define PARITY_EN 0x2000 /* Enable SCSI Parity Error detection */ 2467: #define EVEN_PARITY 0x1000 /* Select Even Parity */ 2468: #define WD_LONG 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */ 2469: #define QUEUE_128 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */ 2470: #define PRIM_MODE 0x0100 /* Primitive SCSI mode */ 2471: #define SCAM_EN 0x0080 /* Enable SCAM selection */ 2472: #define SEL_TMO_LONG 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */ 2473: #define CFRM_ID 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */ 2474: #define OUR_ID_EN 0x0010 /* Enable OUR_ID bits */ 2475: #define OUR_ID 0x000F /* SCSI ID */ 2476: 2477: /* 2478: * SCSI_CFG1 Register bit definitions 2479: */ 2480: #define BIG_ENDIAN 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */ 2481: #define TERM_POL 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */ 2482: #define SLEW_RATE 0x1000 /* SCSI output buffer slew rate */ 2483: #define FILTER_SEL 0x0C00 /* Filter Period Selection */ 2484: #define FLTR_DISABLE 0x0000 /* Input Filtering Disabled */ 2485: #define FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */ 2486: #define FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */ 2487: #define ACTIVE_DBL 0x0200 /* Disable Active Negation */ 2488: #define DIFF_MODE 0x0100 /* SCSI differential Mode (Read-Only) */ 2489: #define DIFF_SENSE 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */ 2490: #define TERM_CTL_SEL 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */ 2491: #define TERM_CTL 0x0030 /* External SCSI Termination Bits */ 2492: #define TERM_CTL_H 0x0020 /* Enable External SCSI Upper Termination */ 2493: #define TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */ 2494: #define CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */ 2495: 2496: #define CABLE_ILLEGAL_A 0x7 2497: /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */ 2498: 2499: #define CABLE_ILLEGAL_B 0xB 2500: /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */ 2501: 2502: /* 2503: The following table details the SCSI_CFG1 Termination Polarity, 2504: Termination Control and Cable Detect bits. 2505: 2506: Cable Detect | Termination 2507: Bit 3 2 1 0 | 5 4 | Notes 2508: _____________|________|____________________ 2509: 1 1 1 0 | on on | Internal wide only 2510: 1 1 0 1 | on on | Internal narrow only 2511: 1 0 1 1 | on on | External narrow only 2512: 0 x 1 1 | on on | External wide only 2513: 1 1 0 0 | on off| Internal wide and internal narrow 2514: 1 0 1 0 | on off| Internal wide and external narrow 2515: 0 x 1 0 | off off| Internal wide and external wide 2516: 1 0 0 1 | on off| Internal narrow and external narrow 2517: 0 x 0 1 | on off| Internal narrow and external wide 2518: 1 1 1 1 | on on | No devices are attached 2519: x 0 0 0 | on on | Illegal (all 3 connectors are used) 2520: 0 x 0 0 | on on | Illegal (all 3 connectors are used) 2521: 2522: x means don't-care (either '0' or '1') 2523: 2524: If term_pol (bit 13) is '0' (active-low terminator enable), then: 2525: 'on' is '0' and 'off' is '1'. 2526: 2527: If term_pol bit is '1' (meaning active-hi terminator enable), then: 2528: 'on' is '1' and 'off' is '0'. 2529: */ 2530: 2531: /* 2532: * MEM_CFG Register bit definitions 2533: */ 2534: #define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */ 2535: #define FAST_EE_CLK 0x20 /* Diagnostic Bit */ 2536: #define RAM_SZ 0x1C /* Specify size of RAM to RISC */ 2537: #define RAM_SZ_2KB 0x00 /* 2 KB */ 2538: #define RAM_SZ_4KB 0x04 /* 4 KB */ 2539: #define RAM_SZ_8KB 0x08 /* 8 KB */ 2540: #define RAM_SZ_16KB 0x0C /* 16 KB */ 2541: #define RAM_SZ_32KB 0x10 /* 32 KB */ 2542: #define RAM_SZ_64KB 0x14 /* 64 KB */ 2543: 2544: /* 2545: * DMA_CFG0 Register bit definitions 2546: * 2547: * This register is only accessible to the host. 2548: */ 2549: #define BC_THRESH_ENB 0x80 /* PCI DMA Start Conditions */ 2550: #define FIFO_THRESH 0x70 /* PCI DMA FIFO Threshold */ 2551: #define FIFO_THRESH_16B 0x00 /* 16 bytes */ 2552: #define FIFO_THRESH_32B 0x20 /* 32 bytes */ 2553: #define FIFO_THRESH_48B 0x30 /* 48 bytes */ 2554: #define FIFO_THRESH_64B 0x40 /* 64 bytes */ 2555: #define FIFO_THRESH_80B 0x50 /* 80 bytes (default) */ 2556: #define FIFO_THRESH_96B 0x60 /* 96 bytes */ 2557: #define FIFO_THRESH_112B 0x70 /* 112 bytes */ 2558: #define START_CTL 0x0C /* DMA start conditions */ 2559: #define START_CTL_TH 0x00 /* Wait threshold level (default) */ 2560: #define START_CTL_ID 0x04 /* Wait SDMA/SBUS idle */ 2561: #define START_CTL_THID 0x08 /* Wait threshold and SDMA/SBUS idle */ 2562: #define START_CTL_EMFU 0x0C /* Wait SDMA FIFO empty/full */ 2563: #define READ_CMD 0x03 /* Memory Read Method */ 2564: #define READ_CMD_MR 0x00 /* Memory Read */ 2565: #define READ_CMD_MRL 0x02 /* Memory Read Long */ 2566: #define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */ 2567: 2568: /* a_advlib.h */ 2569: 2570: /* 2571: * Adv Library Status Definitions 2572: */ 2573: #define ADV_TRUE 1 2574: #define ADV_FALSE 0 2575: #define ADV_NOERROR 1 2576: #define ADV_SUCCESS 1 2577: #define ADV_BUSY 0 2578: #define ADV_ERROR (-1) 2579: 2580: 2581: /* 2582: * ASC_DVC_VAR 'warn_code' values 2583: */ 2584: #define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */ 2585: #define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */ 2586: #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 /* PCI config space set error */ 2587: #define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */ 2588: 2589: #define ADV_MAX_TID 15 /* max. target identifier */ 2590: #define ADV_MAX_LUN 7 /* max. logical unit number */ 2591: 2592: 2593: /* 2594: * AscInitGetConfig() and AscInitAsc1000Driver() Definitions 2595: * 2596: * Error code values are set in ASC_DVC_VAR 'err_code'. 2597: */ 2598: #define ASC_IERR_WRITE_EEPROM 0x0001 /* write EEPROM error */ 2599: #define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */ 2600: #define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */ 2601: #define ASC_IERR_CHIP_VERSION 0x0040 /* wrong chip version */ 2602: #define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */ 2603: #define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */ 2604: #define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */ 2605: #define ASC_IERR_SINGLE_END_DEVICE 0x0800 /* Single-end used w/differential */ 2606: #define ASC_IERR_REVERSED_CABLE 0x1000 /* Narrow flat cable reversed */ 2607: #define ASC_IERR_RW_LRAM 0x8000 /* read/write local RAM error */ 2608: 2609: /* 2610: * Fixed locations of microcode operating variables. 2611: */ 2612: #define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */ 2613: #define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */ 2614: #define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */ 2615: #define ASC_MC_STACK_BEGIN 0x002E /* microcode stack begin */ 2616: #define ASC_MC_STACK_END 0x0030 /* microcode stack end */ 2617: #define ASC_MC_VERSION_DATE 0x0038 /* microcode version */ 2618: #define ASC_MC_VERSION_NUM 0x003A /* microcode number */ 2619: #define ASCV_VER_SERIAL_W 0x003C /* used in dos_init */ 2620: #define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */ 2621: #define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */ 2622: #define ASC_MC_HALTCODE 0x0094 /* microcode halt code */ 2623: #define ASC_MC_CALLERPC 0x0096 /* microcode halt caller PC */ 2624: #define ASC_MC_ADAPTER_SCSI_ID 0x0098 /* one ID byte + reserved */ 2625: #define ASC_MC_ULTRA_ABLE 0x009C 2626: #define ASC_MC_SDTR_ABLE 0x009E 2627: #define ASC_MC_TAGQNG_ABLE 0x00A0 2628: #define ASC_MC_DISC_ENABLE 0x00A2 2629: #define ASC_MC_IDLE_CMD 0x00A6 2630: #define ASC_MC_IDLE_PARA_STAT 0x00A8 2631: #define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC 2632: #define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE 2633: #define ASC_MC_DEFAULT_MEM_CFG 0x00B0 2634: #define ASC_MC_DEFAULT_SEL_MASK 0x00B2 2635: #define ASC_MC_RISC_NEXT_READY 0x00B4 2636: #define ASC_MC_RISC_NEXT_DONE 0x00B5 2637: #define ASC_MC_SDTR_DONE 0x00B6 2638: #define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0 2639: #define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0 2640: #define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100 2641: #define ASC_MC_WDTR_ABLE 0x0120 /* Wide Transfer TID bitmask. */ 2642: #define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */ 2643: #define ASC_MC_WDTR_DONE 0x0124 2644: #define ASC_MC_HOST_NEXT_READY 0x0128 /* Host Next Ready RQL Entry. */ 2645: #define ASC_MC_HOST_NEXT_DONE 0x0129 /* Host Next Done RQL Entry. */ 2646: 2647: /* 2648: * BIOS LRAM variable absolute offsets. 2649: */ 2650: #define BIOS_CODESEG 0x54 2651: #define BIOS_CODELEN 0x56 2652: #define BIOS_SIGNATURE 0x58 2653: #define BIOS_VERSION 0x5A 2654: #define BIOS_SIGNATURE 0x58 2655: 2656: /* 2657: * Microcode Control Flags 2658: * 2659: * Flags set by the Adv Library in RISC variable 'control_flag' (0x122) 2660: * and handled by the microcode. 2661: */ 2662: #define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */ 2663: 2664: /* 2665: * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format 2666: */ 2667: #define HSHK_CFG_WIDE_XFR 0x8000 2668: #define HSHK_CFG_RATE 0x0F00 2669: #define HSHK_CFG_OFFSET 0x001F 2670: 2671: /* 2672: * LRAM RISC Queue Lists (LRAM addresses 0x1200 - 0x19FF) 2673: * 2674: * Each of the 255 Adv Library/Microcode RISC queue lists or mailboxes 2675: * starting at LRAM address 0x1200 is 8 bytes and has the following 2676: * structure. Only 253 of these are actually used for command queues. 2677: */ 2678: 2679: #define ASC_MC_RISC_Q_LIST_BASE 0x1200 2680: #define ASC_MC_RISC_Q_LIST_SIZE 0x0008 2681: #define ASC_MC_RISC_Q_TOTAL_CNT 0x00FF /* Num. queue slots in LRAM. */ 2682: #define ASC_MC_RISC_Q_FIRST 0x0001 2683: #define ASC_MC_RISC_Q_LAST 0x00FF 2684: 2685: #define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */ 2686: #define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */ 2687: #define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */ 2688: #define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */ 2689: 2690: /* RISC Queue List structure - 8 bytes */ 2691: #define RQL_FWD 0 /* forward pointer (1 byte) */ 2692: #define RQL_BWD 1 /* backward pointer (1 byte) */ 2693: #define RQL_STATE 2 /* state byte - free, ready, done, aborted (1 byte) */ 2694: #define RQL_TID 3 /* request target id (1 byte) */ 2695: #define RQL_PHYADDR 4 /* request physical pointer (4 bytes) */ 2696: 2697: /* RISC Queue List state values */ 2698: #define ASC_MC_QS_FREE 0x00 2699: #define ASC_MC_QS_READY 0x01 2700: #define ASC_MC_QS_DONE 0x40 2701: #define ASC_MC_QS_ABORTED 0x80 2702: 2703: /* RISC Queue List pointer values */ 2704: #define ASC_MC_NULL_Q 0x00 /* NULL_Q == 0 */ 2705: #define ASC_MC_BIOS_Q 0xFF /* BIOS_Q = 255 */ 2706: 2707: /* ASC_SCSI_REQ_Q 'cntl' field values */ 2708: #define ASC_MC_QC_START_MOTOR 0x02 /* Issue start motor. */ 2709: #define ASC_MC_QC_NO_OVERRUN 0x04 /* Don't report overrun. */ 2710: #define ASC_MC_QC_FIRST_DMA 0x08 /* Internal microcode flag. */ 2711: #define ASC_MC_QC_ABORTED 0x10 /* Request aborted by host. */ 2712: #define ASC_MC_QC_REQ_SENSE 0x20 /* Auto-Request Sense. */ 2713: #define ASC_MC_QC_DOS_REQ 0x80 /* Request issued by DOS. */ 2714: 2715: 2716: /* 2717: * ASC_SCSI_REQ_Q 'a_flag' definitions 2718: * 2719: * The Adv Library should limit use to the lower nibble (4 bits) of 2720: * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag. 2721: */ 2722: #define ADV_POLL_REQUEST 0x01 /* poll for request completion */ 2723: #define ADV_SCSIQ_DONE 0x02 /* request done */ 2724: 2725: /* 2726: * Adapter temporary configuration structure 2727: * 2728: * This structure can be discarded after initialization. Don't add 2729: * fields here needed after initialization. 2730: * 2731: * Field naming convention: 2732: * 2733: * *_enable indicates the field enables or disables a feature. The 2734: * value of the field is never reset. 2735: */ 2736: typedef struct adv_dvc_cfg { 2737: ushort disc_enable; /* enable disconnection */ 2738: uchar chip_version; /* chip version */ 2739: uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */ 2740: ushort pci_device_id; /* PCI device code number */ 2741: ushort lib_version; /* Adv Library version number */ 2742: ushort control_flag; /* Microcode Control Flag */ 2743: ushort mcode_date; /* Microcode date */ 2744: ushort mcode_version; /* Microcode version */ 2745: ushort pci_slot_info; /* high byte device/function number */ 2746: /* bits 7-3 device num., bits 2-0 function num. */ 2747: /* low byte bus num. */ 2748: ushort bios_boot_wait; /* BIOS boot time delay */ 2749: ushort serial1; /* EEPROM serial number word 1 */ 2750: ushort serial2; /* EEPROM serial number word 2 */ 2751: ushort serial3; /* EEPROM serial number word 3 */ 2752: } ADV_DVC_CFG; 2753: 2754: /* 2755: * Adapter operation variable structure. 2756: * 2757: * One structure is required per host adapter. 2758: * 2759: * Field naming convention: 2760: * 2761: * *_able indicates both whether a feature should be enabled or disabled 2762: * and whether a device isi capable of the feature. At initialization 2763: * this field may be set, but later if a device is found to be incapable 2764: * of the feature, the field is cleared. 2765: */ 2766: typedef struct adv_dvc_var { 2767: AdvPortAddr iop_base; /* I/O port address */ 2768: ushort err_code; /* fatal error code */ 2769: ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */ 2770: Ptr2Func isr_callback; /* pointer to function, called in AdvISR() */ 2771: Ptr2Func sbreset_callback; /* pointer to function, called in AdvISR() */ 2772: ushort wdtr_able; /* try WDTR for a device */ 2773: ushort sdtr_able; /* try SDTR for a device */ 2774: ushort ultra_able; /* try SDTR Ultra speed for a device */ 2775: ushort tagqng_able; /* try tagged queuing with a device */ 2776: uchar max_dvc_qng; /* maximum number of tagged commands per device */ 2777: ushort start_motor; /* start motor command allowed */ 2778: uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */ 2779: uchar chip_no; /* should be assigned by caller */ 2780: uchar max_host_qng; /* maximum number of Q'ed command allowed */ 2781: uchar cur_host_qng; /* total number of queue command */ 2782: uchar irq_no; /* IRQ number */ 2783: ushort no_scam; /* scam_tolerant of EEPROM */ 2784: ushort idle_cmd_done; /* microcode idle command done set by AdvISR() */ 2785: ulong drv_ptr; /* driver pointer to private structure */ 2786: uchar chip_scsi_id; /* chip SCSI target ID */ 2787: /* 2788: * Note: The following fields will not be used after initialization. The 2789: * driver may discard the buffer after initialization is done. 2790: */ 2791: ADV_DVC_CFG *cfg; /* temporary configuration structure */ 2792: } ADV_DVC_VAR; 2793: 2794: #define NO_OF_SG_PER_BLOCK 15 2795: 2796: typedef struct asc_sg_block { 2797: uchar reserved1; 2798: uchar reserved2; 2799: uchar first_entry_no; /* starting entry number */ 2800: uchar last_entry_no; /* last entry number */ 2801: struct asc_sg_block *sg_ptr; /* links to the next sg block */ 2802: struct { 2803: ulong sg_addr; /* SG element address */ 2804: ulong sg_count; /* SG element count */ 2805: } sg_list[NO_OF_SG_PER_BLOCK]; 2806: } ADV_SG_BLOCK; 2807: 2808: /* 2809: * ASC_SCSI_REQ_Q - microcode request structure 2810: * 2811: * All fields in this structure up to byte 60 are used by the microcode. 2812: * The microcode makes assumptions about the size and ordering of fields 2813: * in this structure. Do not change the structure definition here without 2814: * coordinating the change with the microcode. 2815: */ 2816: typedef struct adv_scsi_req_q { 2817: uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */ 2818: uchar sg_entry_cnt; /* SG element count. Zero for no SG. */ 2819: uchar target_id; /* Device target identifier. */ 2820: uchar target_lun; /* Device target logical unit number. */ 2821: ulong data_addr; /* Data buffer physical address. */ 2822: ulong data_cnt; /* Data count. Ucode sets to residual. */ 2823: ulong sense_addr; /* Sense buffer physical address. */ 2824: ulong srb_ptr; /* Driver request pointer. */ 2825: uchar a_flag; /* Adv Library flag field. */ 2826: uchar sense_len; /* Auto-sense length. Ucode sets to residual. */ 2827: uchar cdb_len; /* SCSI CDB length. */ 2828: uchar tag_code; /* SCSI-2 Tag Queue Code: 00, 20-22. */ 2829: uchar done_status; /* Completion status. */ 2830: uchar scsi_status; /* SCSI status byte. */ 2831: uchar host_status; /* Ucode host status. */ 2832: uchar ux_sg_ix; /* Ucode working SG variable. */ 2833: uchar cdb[12]; /* SCSI command block. */ 2834: ulong sg_real_addr; /* SG list physical address. */ 2835: struct adv_scsi_req_q *free_scsiq_link; 2836: ulong ux_wk_data_cnt; /* Saved data count at disconnection. */ 2837: struct adv_scsi_req_q *scsiq_ptr; 2838: ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */ 2839: /* 2840: * End of microcode structure - 60 bytes. The rest of the structure 2841: * is used by the Adv Library and ignored by the microcode. 2842: */ 2843: ulong vsense_addr; /* Sense buffer virtual address. */ 2844: ulong vdata_addr; /* Data buffer virtual address. */ 2845: uchar orig_sense_len; /* Original length of sense buffer. */ 2846: } ADV_SCSI_REQ_Q; /* BIOS - 70 bytes, DOS - 76 bytes, W95, WNT - 69 bytes */ 2847: 2848: /* 2849: * Microcode idle loop commands 2850: */ 2851: #define IDLE_CMD_COMPLETED 0 2852: #define IDLE_CMD_STOP_CHIP 0x0001 2853: #define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002 2854: #define IDLE_CMD_SEND_INT 0x0004 2855: #define IDLE_CMD_ABORT 0x0008 2856: #define IDLE_CMD_DEVICE_RESET 0x0010 2857: #define IDLE_CMD_SCSI_RESET 0x0020 2858: 2859: /* 2860: * AdvSendIdleCmd() flag definitions. 2861: */ 2862: #define ADV_NOWAIT 0x01 2863: 2864: /* 2865: * Wait loop time out values. 2866: */ 2867: #define SCSI_WAIT_10_SEC 10 /* 10 seconds */ 2868: #define SCSI_MS_PER_SEC 1000 /* milliseconds per second */ 2869: 2870: /* 2871: * Device drivers must define the following functions. 2872: */ 1.1.1.2 ! root 2873: STATIC long DvcEnterCritical(void); ! 2874: STATIC void DvcLeaveCritical(long); 1.1 root 2875: STATIC void DvcSleepMilliSecond(ulong); 2876: STATIC uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort); 2877: STATIC void DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar); 2878: STATIC ulong DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *, 2879: uchar *, long *, int); 2880: STATIC void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort); 2881: 2882: /* 2883: * Adv Library functions available to drivers. 2884: */ 2885: STATIC int AdvExeScsiQueue(ADV_DVC_VAR *, 2886: ADV_SCSI_REQ_Q *); 2887: STATIC int AdvISR(ADV_DVC_VAR *); 2888: STATIC int AdvInitGetConfig(ADV_DVC_VAR *); 2889: STATIC int AdvInitAsc3550Driver(ADV_DVC_VAR *); 2890: STATIC int AdvResetSB(ADV_DVC_VAR *); 2891: 2892: /* 2893: * Internal Adv Library functions. 2894: */ 2895: STATIC int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ulong, int); 2896: STATIC void AdvResetChip(ADV_DVC_VAR *); 2897: STATIC int AdvSendScsiCmd(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *); 2898: STATIC void AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *); 2899: STATIC int AdvInitFromEEP(ADV_DVC_VAR *); 2900: STATIC ushort AdvGetEEPConfig(AdvPortAddr, ADVEEP_CONFIG *); 2901: STATIC void AdvSetEEPConfig(AdvPortAddr, ADVEEP_CONFIG *); 2902: STATIC void AdvWaitEEPCmd(AdvPortAddr); 2903: STATIC ushort AdvReadEEPWord(AdvPortAddr, int); 2904: STATIC void AdvResetSCSIBus(ADV_DVC_VAR *); 2905: 2906: /* 2907: * PCI Bus Definitions 2908: */ 2909: #define AscPCICmdRegBits_BusMastering 0x0007 2910: #define AscPCICmdRegBits_ParErrRespCtrl 0x0040 2911: 2912: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0) 2913: 2914: /* Read byte from a register. */ 2915: #define AdvReadByteRegister(iop_base, reg_off) \ 2916: (inp((iop_base) + (reg_off))) 2917: 2918: /* Write byte to a register. */ 2919: #define AdvWriteByteRegister(iop_base, reg_off, byte) \ 2920: (outp((iop_base) + (reg_off), (byte))) 2921: 2922: /* Read word (2 bytes) from a register. */ 2923: #define AdvReadWordRegister(iop_base, reg_off) \ 2924: (inpw((iop_base) + (reg_off))) 2925: 2926: /* Write word (2 bytes) to a register. */ 2927: #define AdvWriteWordRegister(iop_base, reg_off, word) \ 2928: (outpw((iop_base) + (reg_off), (word))) 2929: 2930: /* Read byte from LRAM. */ 2931: #define AdvReadByteLram(iop_base, addr, byte) \ 2932: do { \ 2933: outpw((iop_base) + IOPW_RAM_ADDR, (addr)); \ 2934: (byte) = inp((iop_base) + IOPB_RAM_DATA); \ 2935: } while (0) 2936: 2937: /* Write byte to LRAM. */ 2938: #define AdvWriteByteLram(iop_base, addr, byte) \ 2939: (outpw((iop_base) + IOPW_RAM_ADDR, (addr)), \ 2940: outp((iop_base) + IOPB_RAM_DATA, (byte))) 2941: 2942: /* Read word (2 bytes) from LRAM. */ 2943: #define AdvReadWordLram(iop_base, addr, word) \ 2944: do { \ 2945: outpw((iop_base) + IOPW_RAM_ADDR, (addr)); \ 2946: (word) = inpw((iop_base) + IOPW_RAM_DATA); \ 2947: } while (0) 2948: 2949: /* Write word (2 bytes) to LRAM. */ 2950: #define AdvWriteWordLram(iop_base, addr, word) \ 2951: (outpw((iop_base) + IOPW_RAM_ADDR, (addr)), \ 2952: outpw((iop_base) + IOPW_RAM_DATA, (word))) 2953: 2954: /* Write double word (4 bytes) to LRAM */ 2955: /* Because of unspecified C language ordering don't use auto-increment. */ 2956: #define AdvWriteDWordLram(iop_base, addr, dword) \ 2957: ((outpw((iop_base) + IOPW_RAM_ADDR, (addr)), \ 2958: outpw((iop_base) + IOPW_RAM_DATA, (ushort) ((dword) & 0xFFFF))), \ 2959: (outpw((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \ 2960: outpw((iop_base) + IOPW_RAM_DATA, (ushort) ((dword >> 16) & 0xFFFF)))) 2961: 2962: /* Read word (2 bytes) from LRAM assuming that the address is already set. */ 2963: #define AdvReadWordAutoIncLram(iop_base) \ 2964: (inpw((iop_base) + IOPW_RAM_DATA)) 2965: 2966: /* Write word (2 bytes) to LRAM assuming that the address is already set. */ 2967: #define AdvWriteWordAutoIncLram(iop_base, word) \ 2968: (outpw((iop_base) + IOPW_RAM_DATA, (word))) 2969: 2970: #else /* version >= v1,3,0 */ 2971: 2972: /* Read byte from a register. */ 2973: #define AdvReadByteRegister(iop_base, reg_off) \ 2974: (ADV_MEM_READB((iop_base) + (reg_off))) 2975: 2976: /* Write byte to a register. */ 2977: #define AdvWriteByteRegister(iop_base, reg_off, byte) \ 2978: (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte))) 2979: 2980: /* Read word (2 bytes) from a register. */ 2981: #define AdvReadWordRegister(iop_base, reg_off) \ 2982: (ADV_MEM_READW((iop_base) + (reg_off))) 2983: 2984: /* Write word (2 bytes) to a register. */ 2985: #define AdvWriteWordRegister(iop_base, reg_off, word) \ 2986: (ADV_MEM_WRITEW((iop_base) + (reg_off), (word))) 2987: 2988: /* Read byte from LRAM. */ 2989: #define AdvReadByteLram(iop_base, addr, byte) \ 2990: do { \ 2991: ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \ 2992: (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \ 2993: } while (0) 2994: 2995: /* Write byte to LRAM. */ 2996: #define AdvWriteByteLram(iop_base, addr, byte) \ 2997: (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \ 2998: ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte))) 2999: 3000: /* Read word (2 bytes) from LRAM. */ 3001: #define AdvReadWordLram(iop_base, addr, word) \ 3002: do { \ 3003: ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \ 3004: (word) = ADV_MEM_READW((iop_base) + IOPW_RAM_DATA); \ 3005: } while (0) 3006: 3007: /* Write word (2 bytes) to LRAM. */ 3008: #define AdvWriteWordLram(iop_base, addr, word) \ 3009: (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \ 3010: ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word))) 3011: 3012: /* Write double word (4 bytes) to LRAM */ 3013: /* Because of unspecified C language ordering don't use auto-increment. */ 3014: #define AdvWriteDWordLram(iop_base, addr, dword) \ 3015: ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \ 3016: ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \ 3017: (ushort) ((dword) & 0xFFFF))), \ 3018: (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \ 3019: ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \ 3020: (ushort) ((dword >> 16) & 0xFFFF)))) 3021: 3022: /* Read word (2 bytes) from LRAM assuming that the address is already set. */ 3023: #define AdvReadWordAutoIncLram(iop_base) \ 3024: (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)) 3025: 3026: /* Write word (2 bytes) to LRAM assuming that the address is already set. */ 3027: #define AdvWriteWordAutoIncLram(iop_base, word) \ 3028: (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word))) 3029: 3030: #endif /* version >= v1,3,0 */ 3031: 3032: /* 3033: * Define macro to check for Condor signature. 3034: * 3035: * Evaluate to ADV_TRUE if a Condor chip is found the specified port 3036: * address 'iop_base'. Otherwise evalue to ADV_FALSE. 3037: */ 3038: #define AdvFindSignature(iop_base) \ 3039: (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \ 3040: ADV_CHIP_ID_BYTE) && \ 3041: (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \ 3042: ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE) 3043: 3044: /* 3045: * Define macro to Return the version number of the chip at 'iop_base'. 3046: * 3047: * The second parameter 'bus_type' is currently unused. 3048: */ 3049: #define AdvGetChipVersion(iop_base, bus_type) \ 3050: AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV) 3051: 3052: /* 3053: * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must 3054: * match the ASC_SCSI_REQ_Q 'srb_ptr' field. 3055: * 3056: * If the request has not yet been sent to the device it will simply be 3057: * aborted from RISC memory. If the request is disconnected it will be 3058: * aborted on reselection by sending an Abort Message to the target ID. 3059: * 3060: * Return value: 3061: * ADV_TRUE(1) - Queue was successfully aborted. 3062: * ADV_FALSE(0) - Queue was not found on the active queue list. 3063: */ 3064: #define AdvAbortSRB(asc_dvc, srb_ptr) \ 3065: AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \ 3066: (ulong) (srb_ptr), 0) 3067: 3068: /* 3069: * Send a Bus Device Reset Message to the specified target ID. 3070: * 3071: * All outstanding commands will be purged if sending the 3072: * Bus Device Reset Message is successful. 3073: * 3074: * Return Value: 3075: * ADV_TRUE(1) - All requests on the target are purged. 3076: * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests 3077: * are not purged. 3078: */ 3079: #define AdvResetDevice(asc_dvc, target_id) \ 3080: AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \ 3081: (ulong) (target_id), 0) 3082: 3083: /* 3084: * SCSI Wide Type definition. 3085: */ 3086: #define ADV_SCSI_BIT_ID_TYPE ushort 3087: 3088: /* 3089: * AdvInitScsiTarget() 'cntl_flag' options. 3090: */ 3091: #define ADV_SCAN_LUN 0x01 3092: #define ADV_CAPINFO_NOLUN 0x02 3093: 3094: /* 3095: * Convert target id to target id bit mask. 3096: */ 3097: #define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID)) 3098: 3099: /* 3100: * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values. 3101: */ 3102: 3103: #define QD_NO_STATUS 0x00 /* Request not completed yet. */ 3104: #define QD_NO_ERROR 0x01 3105: #define QD_ABORTED_BY_HOST 0x02 3106: #define QD_WITH_ERROR 0x04 3107: 3108: #define QHSTA_NO_ERROR 0x00 3109: #define QHSTA_M_SEL_TIMEOUT 0x11 3110: #define QHSTA_M_DATA_OVER_RUN 0x12 3111: #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13 3112: #define QHSTA_M_QUEUE_ABORTED 0x15 3113: #define QHSTA_M_SXFR_SDMA_ERR 0x16 /* SXFR_STATUS SCSI DMA Error */ 3114: #define QHSTA_M_SXFR_SXFR_PERR 0x17 /* SXFR_STATUS SCSI Bus Parity Error */ 3115: #define QHSTA_M_RDMA_PERR 0x18 /* RISC PCI DMA parity error */ 3116: #define QHSTA_M_SXFR_OFF_UFLW 0x19 /* SXFR_STATUS Offset Underflow */ 3117: #define QHSTA_M_SXFR_OFF_OFLW 0x20 /* SXFR_STATUS Offset Overflow */ 3118: #define QHSTA_M_SXFR_WD_TMO 0x21 /* SXFR_STATUS Watchdog Timeout */ 3119: #define QHSTA_M_SXFR_DESELECTED 0x22 /* SXFR_STATUS Deselected */ 3120: /* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */ 3121: #define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */ 3122: #define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */ 3123: #define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */ 3124: #define QHSTA_M_WTM_TIMEOUT 0x41 3125: #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42 3126: #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43 3127: #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44 3128: #define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */ 3129: 3130: typedef int (* ADV_ISR_CALLBACK) 3131: (ADV_DVC_VAR *, ADV_SCSI_REQ_Q *); 3132: 3133: typedef int (* ADV_SBRESET_CALLBACK) 3134: (ADV_DVC_VAR *); 3135: 3136: /* 3137: * Default EEPROM Configuration structure defined in a_init.c. 3138: */ 1.1.1.2 ! root 3139: STATIC ADVEEP_CONFIG Default_EEPROM_Config; 1.1 root 3140: 3141: /* 3142: * DvcGetPhyAddr() flag arguments 3143: */ 3144: #define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */ 3145: #define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */ 3146: #define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */ 3147: #define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */ 3148: #define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */ 3149: 3150: /* Return the address that is aligned at the next doubleword >= to 'addr'. */ 3151: #define ADV_DWALIGN(addr) (((ulong) (addr) + 0x3) & ~0x3) 3152: 3153: /* 3154: * Total contiguous memory needed for driver SG blocks. 3155: * 3156: * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum 3157: * number of scatter-gather elements the driver supports in a 3158: * single request. 3159: */ 3160: 3161: #ifndef ADV_MAX_SG_LIST 3162: Forced Error: Driver must define ADV_MAX_SG_LIST. 3163: #endif /* ADV_MAX_SG_LIST */ 3164: 3165: #define ADV_SG_LIST_MAX_BYTE_SIZE \ 3166: (sizeof(ADV_SG_BLOCK) * \ 3167: ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)) 3168: 3169: /* 3170: * A driver may optionally define the assertion macro ADV_ASSERT() in 3171: * its d_os_dep.h file. If the macro has not already been defined, 3172: * then define the macro to a no-op. 3173: */ 3174: #ifndef ADV_ASSERT 3175: #define ADV_ASSERT(a) 3176: #endif /* ADV_ASSERT */ 3177: 3178: 3179: /* 3180: * --- Driver Constants and Macros 3181: */ 3182: 3183: #define ASC_NUM_BOARD_SUPPORTED 16 3184: #define ASC_NUM_IOPORT_PROBE 4 3185: #define ASC_NUM_BUS 4 3186: 3187: /* Reference Scsi_Host hostdata */ 3188: #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata)) 3189: 3190: /* asc_board_t flags */ 3191: #define ASC_HOST_IN_RESET 0x01 3192: #define ASC_HOST_IN_ABORT 0x02 3193: #define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */ 3194: #define ASC_SELECT_QUEUE_DEPTHS 0x08 3195: 3196: #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0) 3197: #define ASC_WIDE_BOARD(boardp) ((boardp)->flags & ASC_IS_WIDE_BOARD) 3198: 3199: #define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */ 3200: 3201: /* 3202: * If the Linux kernel version supports freeing initialization code 3203: * and data after loading, define macros for this purpose. These macros 3204: * are not used when the driver is built as a module, cf. linux/init.h. 3205: */ 3206: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,23) 3207: #define ASC_INITFUNC(func) func 3208: #define ASC_INITDATA 3209: #define ASC_INIT 3210: #else /* version >= v2.1.23 */ 3211: #define ASC_INITFUNC(func) __initfunc(func) 3212: #define ASC_INITDATA __initdata 3213: #define ASC_INIT __init 3214: #endif /* version >= v2.1.23 */ 3215: 3216: #define ASC_INFO_SIZE 128 /* advansys_info() line size */ 3217: 3218: /* /proc/scsi/advansys/[0...] related definitions */ 3219: #define ASC_PRTBUF_SIZE 2048 3220: #define ASC_PRTLINE_SIZE 160 3221: 3222: #define ASC_PRT_NEXT() \ 3223: if (cp) { \ 3224: totlen += len; \ 3225: leftlen -= len; \ 3226: if (leftlen == 0) { \ 3227: return totlen; \ 3228: } \ 3229: cp += len; \ 3230: } 3231: 3232: #define ASC_MIN(a, b) (((a) < (b)) ? (a) : (b)) 3233: 3234: /* Asc Library return codes */ 3235: #define ASC_TRUE 1 3236: #define ASC_FALSE 0 3237: #define ASC_NOERROR 1 3238: #define ASC_BUSY 0 3239: #define ASC_ERROR (-1) 3240: 3241: /* Scsi_Cmnd function return codes */ 3242: #define STATUS_BYTE(byte) (byte) 3243: #define MSG_BYTE(byte) ((byte) << 8) 3244: #define HOST_BYTE(byte) ((byte) << 16) 3245: #define DRIVER_BYTE(byte) ((byte) << 24) 3246: 3247: /* 3248: * The following definitions and macros are OS independent interfaces to 3249: * the queue functions: 3250: * REQ - SCSI request structure 3251: * REQP - pointer to SCSI request structure 3252: * REQPTID(reqp) - reqp's target id 3253: * REQPNEXT(reqp) - reqp's next pointer 3254: * REQPNEXTP(reqp) - pointer to reqp's next pointer 3255: * REQPTIME(reqp) - reqp's time stamp value 3256: * REQTIMESTAMP() - system time stamp value 3257: */ 3258: typedef Scsi_Cmnd REQ, *REQP; 1.1.1.2 ! root 3259: #define REQPNEXT(reqp) ((reqp)->host_scribble) 1.1 root 3260: #define REQPNEXTP(reqp) ((REQP *) &((reqp)->host_scribble)) 3261: #define REQPTID(reqp) ((reqp)->target) 3262: #define REQPTIME(reqp) ((reqp)->SCp.this_residual) 3263: #define REQTIMESTAMP() (jiffies) 3264: 3265: #define REQTIMESTAT(function, ascq, reqp, tid) \ 3266: { \ 3267: /* 3268: * If the request time stamp is less than the system time stamp, then \ 3269: * maybe the system time stamp wrapped. Set the request time to zero.\ 3270: */ \ 3271: if (REQPTIME(reqp) <= REQTIMESTAMP()) { \ 3272: REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \ 3273: } else { \ 3274: /* Indicate an error occurred with the assertion. */ \ 3275: ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \ 3276: REQPTIME(reqp) = 0; \ 3277: } \ 3278: /* Handle first minimum time case without external initialization. */ \ 3279: if (((ascq)->q_tot_cnt[tid] == 1) || \ 3280: (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \ 3281: (ascq)->q_min_tim[tid] = REQPTIME(reqp); \ 3282: ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \ 3283: (function), (tid), (ascq)->q_min_tim[tid]); \ 3284: } \ 3285: if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \ 3286: (ascq)->q_max_tim[tid] = REQPTIME(reqp); \ 3287: ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \ 3288: (function), tid, (ascq)->q_max_tim[tid]); \ 3289: } \ 3290: (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \ 3291: /* Reset the time stamp field. */ \ 3292: REQPTIME(reqp) = 0; \ 3293: } 3294: 3295: /* asc_enqueue() flags */ 3296: #define ASC_FRONT 1 3297: #define ASC_BACK 2 3298: 3299: /* asc_dequeue_list() argument */ 3300: #define ASC_TID_ALL (-1) 3301: 3302: /* Return non-zero, if the queue is empty. */ 3303: #define ASC_QUEUE_EMPTY(ascq) ((ascq)->q_tidmask == 0) 3304: 3305: /* PCI configuration declarations */ 3306: 3307: #define PCI_BASE_CLASS_PREDEFINED 0x00 3308: #define PCI_BASE_CLASS_MASS_STORAGE 0x01 3309: #define PCI_BASE_CLASS_NETWORK 0x02 3310: #define PCI_BASE_CLASS_DISPLAY 0x03 3311: #define PCI_BASE_CLASS_MULTIMEDIA 0x04 3312: #define PCI_BASE_CLASS_MEMORY_CONTROLLER 0x05 3313: #define PCI_BASE_CLASS_BRIDGE_DEVICE 0x06 3314: 3315: /* MASS STORAGE */ 3316: #define PCI_SUB_CLASS_SCSI_CONTROLLER 0x00 3317: #define PCI_SUB_CLASS_IDE_CONTROLLER 0x01 3318: #define PCI_SUB_CLASS_FLOPPY_DISK_CONTROLLER 0x02 3319: #define PCI_SUB_CLASS_IPI_BUS_CONTROLLER 0x03 3320: #define PCI_SUB_CLASS_OTHER_MASS_CONTROLLER 0x80 3321: 3322: /* NETWORK CONTROLLER */ 3323: #define PCI_SUB_CLASS_ETHERNET_CONTROLLER 0x00 3324: #define PCI_SUB_CLASS_TOKEN_RING_CONTROLLER 0x01 3325: #define PCI_SUB_CLASS_FDDI_CONTROLLER 0x02 3326: #define PCI_SUB_CLASS_OTHER_NETWORK_CONTROLLER 0x80 3327: 3328: /* DISPLAY CONTROLLER */ 3329: #define PCI_SUB_CLASS_VGA_CONTROLLER 0x00 3330: #define PCI_SUB_CLASS_XGA_CONTROLLER 0x01 3331: #define PCI_SUB_CLASS_OTHER_DISPLAY_CONTROLLER 0x80 3332: 3333: /* MULTIMEDIA CONTROLLER */ 3334: #define PCI_SUB_CLASS_VIDEO_DEVICE 0x00 3335: #define PCI_SUB_CLASS_AUDIO_DEVICE 0x01 3336: #define PCI_SUB_CLASS_OTHER_MULTIMEDIA_DEVICE 0x80 3337: 3338: /* MEMORY CONTROLLER */ 3339: #define PCI_SUB_CLASS_RAM_CONTROLLER 0x00 3340: #define PCI_SUB_CLASS_FLASH_CONTROLLER 0x01 3341: #define PCI_SUB_CLASS_OTHER_MEMORY_CONTROLLER 0x80 3342: 3343: /* BRIDGE CONTROLLER */ 3344: #define PCI_SUB_CLASS_HOST_BRIDGE_CONTROLLER 0x00 3345: #define PCI_SUB_CLASS_ISA_BRIDGE_CONTROLLER 0x01 3346: #define PCI_SUB_CLASS_EISA_BRIDGE_CONTROLLER 0x02 3347: #define PCI_SUB_CLASS_MC_BRIDGE_CONTROLLER 0x03 3348: #define PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER 0x04 3349: #define PCI_SUB_CLASS_PCMCIA_BRIDGE_CONTROLLER 0x05 3350: #define PCI_SUB_CLASS_OTHER_BRIDGE_CONTROLLER 0x80 3351: 3352: #define PCI_MAX_SLOT 0x1F 3353: #define PCI_MAX_BUS 0xFF 3354: #define PCI_IOADDRESS_MASK 0xFFFE 3355: #define ASC_PCI_VENDORID 0x10CD 3356: #define ASC_PCI_DEVICE_ID_CNT 4 /* PCI Device ID count. */ 3357: #define ASC_PCI_DEVICE_ID_1100 0x1100 3358: #define ASC_PCI_DEVICE_ID_1200 0x1200 3359: #define ASC_PCI_DEVICE_ID_1300 0x1300 3360: #define ASC_PCI_DEVICE_ID_2300 0x2300 3361: 3362: /* PCI IO Port Addresses to generate special cycle */ 3363: 3364: #define PCI_CONFIG_ADDRESS_MECH1 0x0CF8 3365: #define PCI_CONFIG_DATA_MECH1 0x0CFC 3366: 3367: #define PCI_CONFIG_FORWARD_REGISTER 0x0CFA /* 0=type 0; 1=type 1; */ 3368: 3369: #define PCI_CONFIG_BUS_NUMBER_MASK 0x00FF0000 3370: #define PCI_CONFIG_DEVICE_FUNCTION_MASK 0x0000FF00 3371: #define PCI_CONFIG_REGISTER_NUMBER_MASK 0x000000F8 3372: 3373: #define PCI_DEVICE_FOUND 0x0000 3374: #define PCI_DEVICE_NOT_FOUND 0xffff 3375: 3376: #define SUBCLASS_OFFSET 0x0A 3377: #define CLASSCODE_OFFSET 0x0B 3378: #define VENDORID_OFFSET 0x00 3379: #define DEVICEID_OFFSET 0x02 3380: 3381: #ifndef ADVANSYS_STATS 3382: #define ASC_STATS(shp, counter) 3383: #define ASC_STATS_ADD(shp, counter, count) 3384: #else /* ADVANSYS_STATS */ 3385: #define ASC_STATS(shp, counter) \ 3386: (ASC_BOARDP(shp)->asc_stats.counter++) 3387: 3388: #define ASC_STATS_ADD(shp, counter, count) \ 3389: (ASC_BOARDP(shp)->asc_stats.counter += (count)) 3390: #endif /* ADVANSYS_STATS */ 3391: 3392: #define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit)) 3393: 3394: /* If the result wraps when calculating tenths, return 0. */ 3395: #define ASC_TENTHS(num, den) \ 3396: (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \ 3397: 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den))))) 3398: 3399: /* 3400: * Display a message to the console. 3401: */ 3402: #define ASC_PRINT(s) \ 3403: { \ 3404: printk("advansys: "); \ 3405: printk(s); \ 3406: } 3407: 3408: #define ASC_PRINT1(s, a1) \ 3409: { \ 3410: printk("advansys: "); \ 3411: printk((s), (a1)); \ 3412: } 3413: 3414: #define ASC_PRINT2(s, a1, a2) \ 3415: { \ 3416: printk("advansys: "); \ 3417: printk((s), (a1), (a2)); \ 3418: } 3419: 3420: #define ASC_PRINT3(s, a1, a2, a3) \ 3421: { \ 3422: printk("advansys: "); \ 3423: printk((s), (a1), (a2), (a3)); \ 3424: } 3425: 3426: #define ASC_PRINT4(s, a1, a2, a3, a4) \ 3427: { \ 3428: printk("advansys: "); \ 3429: printk((s), (a1), (a2), (a3), (a4)); \ 3430: } 3431: 3432: 3433: #ifndef ADVANSYS_DEBUG 3434: 3435: #define ASC_DBG(lvl, s) 3436: #define ASC_DBG1(lvl, s, a1) 3437: #define ASC_DBG2(lvl, s, a1, a2) 3438: #define ASC_DBG3(lvl, s, a1, a2, a3) 3439: #define ASC_DBG4(lvl, s, a1, a2, a3, a4) 3440: #define ASC_DBG_PRT_SCSI_HOST(lvl, s) 3441: #define ASC_DBG_PRT_SCSI_CMND(lvl, s) 3442: #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) 3443: #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) 3444: #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) 3445: #define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) 3446: #define ASC_DBG_PRT_HEX(lvl, name, start, length) 3447: #define ASC_DBG_PRT_CDB(lvl, cdb, len) 3448: #define ASC_DBG_PRT_SENSE(lvl, sense, len) 3449: #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) 3450: 3451: #else /* ADVANSYS_DEBUG */ 3452: 3453: /* 3454: * Debugging Message Levels: 3455: * 0: Errors Only 3456: * 1: High-Level Tracing 3457: * 2-N: Verbose Tracing 3458: */ 3459: 3460: #define ASC_DBG(lvl, s) \ 3461: { \ 3462: if (asc_dbglvl >= (lvl)) { \ 3463: printk(s); \ 3464: } \ 3465: } 3466: 3467: #define ASC_DBG1(lvl, s, a1) \ 3468: { \ 3469: if (asc_dbglvl >= (lvl)) { \ 3470: printk((s), (a1)); \ 3471: } \ 3472: } 3473: 3474: #define ASC_DBG2(lvl, s, a1, a2) \ 3475: { \ 3476: if (asc_dbglvl >= (lvl)) { \ 3477: printk((s), (a1), (a2)); \ 3478: } \ 3479: } 3480: 3481: #define ASC_DBG3(lvl, s, a1, a2, a3) \ 3482: { \ 3483: if (asc_dbglvl >= (lvl)) { \ 3484: printk((s), (a1), (a2), (a3)); \ 3485: } \ 3486: } 3487: 3488: #define ASC_DBG4(lvl, s, a1, a2, a3, a4) \ 3489: { \ 3490: if (asc_dbglvl >= (lvl)) { \ 3491: printk((s), (a1), (a2), (a3), (a4)); \ 3492: } \ 3493: } 3494: 3495: #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \ 3496: { \ 3497: if (asc_dbglvl >= (lvl)) { \ 3498: asc_prt_scsi_host(s); \ 3499: } \ 3500: } 3501: 3502: #define ASC_DBG_PRT_SCSI_CMND(lvl, s) \ 3503: { \ 3504: if (asc_dbglvl >= (lvl)) { \ 3505: asc_prt_scsi_cmnd(s); \ 3506: } \ 3507: } 3508: 3509: #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \ 3510: { \ 3511: if (asc_dbglvl >= (lvl)) { \ 3512: asc_prt_asc_scsi_q(scsiqp); \ 3513: } \ 3514: } 3515: 3516: #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \ 3517: { \ 3518: if (asc_dbglvl >= (lvl)) { \ 3519: asc_prt_asc_qdone_info(qdone); \ 3520: } \ 3521: } 3522: 3523: #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \ 3524: { \ 3525: if (asc_dbglvl >= (lvl)) { \ 3526: asc_prt_adv_scsi_req_q(scsiqp); \ 3527: } \ 3528: } 3529: 3530: #define ASC_DBG_PRT_HEX(lvl, name, start, length) \ 3531: { \ 3532: if (asc_dbglvl >= (lvl)) { \ 3533: asc_prt_hex((name), (start), (length)); \ 3534: } \ 3535: } 3536: 3537: #define ASC_DBG_PRT_CDB(lvl, cdb, len) \ 3538: ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len)); 3539: 3540: #define ASC_DBG_PRT_SENSE(lvl, sense, len) \ 3541: ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len)); 3542: 3543: #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \ 3544: ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len)); 3545: #endif /* ADVANSYS_DEBUG */ 3546: 3547: #ifndef ADVANSYS_ASSERT 3548: #define ASC_ASSERT(a) 3549: #else /* ADVANSYS_ASSERT */ 3550: 3551: #define ASC_ASSERT(a) \ 3552: { \ 3553: if (!(a)) { \ 3554: printk("ASC_ASSERT() Failure: file %s, line %d\n", \ 3555: __FILE__, __LINE__); \ 3556: } \ 3557: } 3558: 3559: #endif /* ADVANSYS_ASSERT */ 3560: 3561: 3562: /* 3563: * --- Driver Structures 3564: */ 3565: 3566: #ifdef ADVANSYS_STATS 3567: 3568: /* Per board statistics structure */ 3569: struct asc_stats { 3570: /* Driver Entrypoint Statistics */ 3571: ulong command; /* # calls to advansys_command() */ 3572: ulong queuecommand; /* # calls to advansys_queuecommand() */ 3573: ulong abort; /* # calls to advansys_abort() */ 3574: ulong reset; /* # calls to advansys_reset() */ 3575: ulong biosparam; /* # calls to advansys_biosparam() */ 3576: ulong interrupt; /* # advansys_interrupt() calls */ 3577: ulong callback; /* # calls to asc/adv_isr_callback() */ 3578: ulong done; /* # calls to request's scsi_done function */ 3579: ulong build_error; /* # asc/adv_build_req() ASC_ERROR returns. */ 3580: ulong adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */ 3581: ulong adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */ 3582: /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */ 3583: ulong exe_noerror; /* # ASC_NOERROR returns. */ 3584: ulong exe_busy; /* # ASC_BUSY returns. */ 3585: ulong exe_error; /* # ASC_ERROR returns. */ 3586: ulong exe_unknown; /* # unknown returns. */ 3587: /* Data Transfer Statistics */ 3588: ulong cont_cnt; /* # non-scatter-gather I/O requests received */ 3589: ulong cont_xfer; /* # contiguous transfer 512-bytes */ 3590: ulong sg_cnt; /* # scatter-gather I/O requests received */ 3591: ulong sg_elem; /* # scatter-gather elements */ 3592: ulong sg_xfer; /* # scatter-gather transfer 512-bytes */ 3593: }; 3594: #endif /* ADVANSYS_STATS */ 3595: 3596: /* 3597: * Request queuing structure 3598: */ 3599: typedef struct asc_queue { 3600: ADV_SCSI_BIT_ID_TYPE q_tidmask; /* queue mask */ 3601: REQP q_first[ADV_MAX_TID+1]; /* first queued request */ 3602: REQP q_last[ADV_MAX_TID+1]; /* last queued request */ 3603: #ifdef ADVANSYS_STATS 3604: short q_cur_cnt[ADV_MAX_TID+1]; /* current queue count */ 3605: short q_max_cnt[ADV_MAX_TID+1]; /* maximum queue count */ 3606: ulong q_tot_cnt[ADV_MAX_TID+1]; /* total enqueue count */ 3607: ulong q_tot_tim[ADV_MAX_TID+1]; /* total time queued */ 3608: ushort q_max_tim[ADV_MAX_TID+1]; /* maximum time queued */ 3609: ushort q_min_tim[ADV_MAX_TID+1]; /* minimum time queued */ 3610: #endif /* ADVANSYS_STATS */ 3611: } asc_queue_t; 3612: 3613: /* 3614: * Adv Library Request Structures 3615: * 3616: * The following two se structures are used to process Wide Board requests. 3617: * One structure is needed for each command received from the Mid-Level SCSI 3618: * driver. 3619: * 3620: * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library 3621: * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the 3622: * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the 3623: * Mid-Level SCSI request structure. 3624: * 3625: * The adv_sgblk_t structure is used to handle requests that include 3626: * scatter-gather elements. 3627: */ 3628: typedef struct adv_sgblk { 3629: ADV_SG_BLOCK sg_block[ADV_NUM_SG_BLOCK + ADV_NUM_PAGE_CROSSING]; 3630: uchar align2[4]; /* Sgblock structure padding. */ 3631: struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */ 3632: } adv_sgblk_t; 3633: 3634: typedef struct adv_req { 3635: ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */ 3636: uchar align1[4]; /* Request structure padding. */ 3637: Scsi_Cmnd *cmndp; /* Mid-Level SCSI command pointer. */ 3638: adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */ 3639: struct adv_req *next_reqp; /* Next Request Structure. */ 3640: } adv_req_t; 3641: 3642: /* 3643: * Structure allocated for each board. 3644: * 3645: * This structure is allocated by scsi_register() at the end 3646: * of the 'Scsi_Host' structure starting at the 'hostdata' 3647: * field. It is guaranteed to be allocated from DMA-able memory. 3648: */ 3649: typedef struct asc_board { 3650: int id; /* Board Id */ 3651: uint flags; /* Board flags */ 3652: union { 3653: ASC_DVC_VAR asc_dvc_var; /* Narrow board */ 3654: ADV_DVC_VAR adv_dvc_var; /* Wide board */ 3655: } dvc_var; 3656: union { 3657: ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */ 3658: ADV_DVC_CFG adv_dvc_cfg; /* Wide board */ 3659: } dvc_cfg; 3660: asc_queue_t active; /* Active command queue */ 3661: asc_queue_t waiting; /* Waiting command queue */ 3662: asc_queue_t done; /* Done command queue */ 3663: ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */ 3664: Scsi_Device *device[ADV_MAX_TID+1]; /* Mid-Level Scsi Device */ 3665: ushort reqcnt[ADV_MAX_TID+1]; /* Starvation request count */ 3666: #if ASC_QUEUE_FLOW_CONTROL 3667: ushort nerrcnt[ADV_MAX_TID+1]; /* No error request count */ 3668: #endif /* ASC_QUEUE_FLOW_CONTROL */ 3669: ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */ 3670: ushort queue_full_cnt[ADV_MAX_TID+1]; /* Queue full count */ 3671: union { 3672: ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */ 3673: ADVEEP_CONFIG adv_eep; /* Wide EEPROM config. */ 3674: } eep_config; 3675: ulong last_reset; /* Saved last reset time */ 3676: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0) 3677: /* /proc/scsi/advansys/[0...] */ 3678: char *prtbuf; /* Statistics Print Buffer */ 3679: #endif /* version >= v1.3.0 */ 3680: #ifdef ADVANSYS_STATS 3681: struct asc_stats asc_stats; /* Board statistics */ 3682: #endif /* ADVANSYS_STATS */ 3683: /* 3684: * The following fields are used only for Narrow Boards. 3685: */ 3686: /* The following three structures must be in DMA-able memory. */ 3687: ASC_SCSI_REQ_Q scsireqq; 3688: ASC_CAP_INFO cap_info; 3689: ASC_SCSI_INQUIRY inquiry; 3690: uchar sdtr_data[ASC_MAX_TID+1]; /* SDTR information */ 3691: /* 3692: * The following fields are used only for Wide Boards. 3693: */ 3694: void *ioremap_addr; /* I/O Memory remap address. */ 3695: ushort ioport; /* I/O Port address. */ 3696: adv_req_t *orig_reqp; /* adv_req_t memory block. */ 3697: adv_req_t *adv_reqp; /* Request structures. */ 3698: adv_sgblk_t *orig_sgblkp; /* adv_sgblk_t memory block. */ 3699: adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */ 3700: ushort bios_signature; /* BIOS Signature. */ 3701: ushort bios_version; /* BIOS Version. */ 3702: ushort bios_codeseg; /* BIOS Code Segment. */ 3703: ushort bios_codelen; /* BIOS Code Segment Length. */ 3704: } asc_board_t; 3705: 3706: /* 3707: * PCI configuration structures 3708: */ 3709: typedef struct _PCI_DATA_ 3710: { 3711: uchar type; 3712: uchar bus; 3713: uchar slot; 3714: uchar func; 3715: uchar offset; 3716: } PCI_DATA; 3717: 3718: typedef struct _PCI_DEVICE_ 3719: { 3720: ushort vendorID; 3721: ushort deviceID; 3722: ushort slotNumber; 3723: ushort slotFound; 3724: uchar busNumber; 3725: uchar maxBusNumber; 3726: uchar devFunc; 3727: ushort startSlot; 3728: ushort endSlot; 3729: uchar bridge; 3730: uchar type; 3731: } PCI_DEVICE; 3732: 3733: typedef struct _PCI_CONFIG_SPACE_ 3734: { 3735: ushort vendorID; 3736: ushort deviceID; 3737: ushort command; 3738: ushort status; 3739: uchar revision; 3740: uchar classCode[3]; 3741: uchar cacheSize; 3742: uchar latencyTimer; 3743: uchar headerType; 3744: uchar bist; 3745: ulong baseAddress[6]; 3746: ushort reserved[4]; 3747: ulong optionRomAddr; 3748: ushort reserved2[4]; 3749: uchar irqLine; 3750: uchar irqPin; 3751: uchar minGnt; 3752: uchar maxLatency; 3753: } PCI_CONFIG_SPACE; 3754: 3755: 3756: /* 3757: * --- Driver Data 3758: */ 3759: 3760: /* Note: All driver global data should be initialized. */ 3761: 3762: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0) 3763: struct proc_dir_entry proc_scsi_advansys = 3764: { 3765: PROC_SCSI_ADVANSYS, /* unsigned short low_ino */ 3766: 8, /* unsigned short namelen */ 3767: "advansys", /* const char *name */ 3768: S_IFDIR | S_IRUGO | S_IXUGO, /* mode_t mode */ 3769: 2 /* nlink_t nlink */ 3770: }; 3771: #endif /* version >= v1.3.0 */ 3772: 3773: /* Number of boards detected in system. */ 3774: STATIC int asc_board_count = 0; 3775: STATIC struct Scsi_Host *asc_host[ASC_NUM_BOARD_SUPPORTED] = { 0 }; 3776: 3777: /* Overrun buffer shared between all boards. */ 3778: STATIC uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 }; 3779: 3780: /* 3781: * Global structures required to issue a command. 3782: */ 3783: STATIC ASC_SCSI_Q asc_scsi_q = { { 0 } }; 3784: STATIC ASC_SG_HEAD asc_sg_head = { 0 }; 3785: 3786: /* List of supported bus types. */ 3787: STATIC ushort asc_bus[ASC_NUM_BUS] ASC_INITDATA = { 3788: ASC_IS_ISA, 3789: ASC_IS_VL, 3790: ASC_IS_EISA, 3791: ASC_IS_PCI, 3792: }; 3793: 3794: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93) 3795: #ifdef ASC_CONFIG_PCI 3796: STATIC int pci_scan_method ASC_INITDATA = -1; 3797: #endif /* ASC_CONFIG_PCI */ 3798: #endif /* version < v2.1.93 */ 3799: 3800: /* 3801: * Used with the LILO 'advansys' option to eliminate or 3802: * limit I/O port probing at boot time, cf. advansys_setup(). 3803: */ 3804: STATIC int asc_iopflag = ASC_FALSE; 3805: STATIC int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 }; 3806: 3807: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0) 3808: /* 3809: * In kernels earlier than v1.3.0, kmalloc() does not work 3810: * during driver initialization. Therefore statically declare 3811: * 16 elements of each structure. v1.3.0 kernels will probably 3812: * not need any more than this number. 3813: */ 3814: uchar adv_req_buf[16 * sizeof(adv_req_t)] = { 0 }; 3815: uchar adv_sgblk_buf[16 * sizeof(adv_sgblk_t)] = { 0 }; 3816: #endif /* version >= v1,3,0 */ 3817: 3818: #ifdef ADVANSYS_DEBUG 3819: STATIC char * 3820: asc_bus_name[ASC_NUM_BUS] = { 3821: "ASC_IS_ISA", 3822: "ASC_IS_VL", 3823: "ASC_IS_EISA", 3824: "ASC_IS_PCI", 3825: }; 3826: 3827: STATIC int asc_dbglvl = 0; 3828: #endif /* ADVANSYS_DEBUG */ 3829: 3830: /* Declaration for Asc Library internal data referenced by driver. */ 3831: STATIC PortAddr _asc_def_iop_base[]; 3832: 3833: 3834: /* 3835: * --- Driver Function Prototypes 3836: * 3837: * advansys.h contains function prototypes for functions global to Linux. 3838: */ 3839: 3840: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0) 3841: STATIC int asc_proc_copy(off_t, off_t, char *, int , char *, int); 3842: #endif /* version >= v1.3.0 */ 3843: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70) 3844: STATIC void advansys_interrupt(int, struct pt_regs *); 3845: #else /* version >= v1.3.70 */ 3846: STATIC void advansys_interrupt(int, void *, struct pt_regs *); 3847: #endif /* version >= v1.3.70 */ 3848: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89) 3849: STATIC void advansys_select_queue_depths(struct Scsi_Host *, 3850: Scsi_Device *); 3851: #endif /* version >= v1.3.89 */ 3852: STATIC void advansys_command_done(Scsi_Cmnd *); 3853: STATIC void asc_scsi_done_list(Scsi_Cmnd *); 3854: STATIC int asc_execute_scsi_cmnd(Scsi_Cmnd *); 3855: STATIC int asc_build_req(asc_board_t *, Scsi_Cmnd *); 3856: STATIC int adv_build_req(asc_board_t *, Scsi_Cmnd *, ADV_SCSI_REQ_Q **); 3857: STATIC int adv_get_sglist(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *, Scsi_Cmnd *); 3858: STATIC void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *); 3859: STATIC void adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *); 3860: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93) 3861: #ifdef ASC_CONFIG_PCI 3862: STATIC int asc_srch_pci_dev(PCI_DEVICE *); 3863: STATIC uchar asc_scan_method(void); 3864: STATIC int asc_pci_find_dev(PCI_DEVICE *); 3865: STATIC void asc_get_pci_cfg(PCI_DEVICE *, PCI_CONFIG_SPACE *); 3866: STATIC ushort asc_get_cfg_word(PCI_DATA *); 3867: STATIC uchar asc_get_cfg_byte(PCI_DATA *); 3868: STATIC void asc_put_cfg_byte(PCI_DATA *, uchar); 3869: #endif /* ASC_CONFIG_PCI */ 3870: #endif /* version < v2.1.93 */ 3871: STATIC void asc_enqueue(asc_queue_t *, REQP, int); 3872: STATIC REQP asc_dequeue(asc_queue_t *, int); 3873: STATIC REQP asc_dequeue_list(asc_queue_t *, REQP *, int); 3874: STATIC int asc_rmqueue(asc_queue_t *, REQP); 3875: STATIC int asc_isqueued(asc_queue_t *, REQP); 3876: STATIC void asc_execute_queue(asc_queue_t *); 3877: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0) 3878: STATIC int asc_prt_board_devices(struct Scsi_Host *, char *, int); 3879: STATIC int asc_prt_adv_bios(struct Scsi_Host *, char *, int); 3880: STATIC int asc_get_eeprom_string(ushort *serialnum, uchar *cp); 3881: STATIC int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int); 3882: STATIC int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int); 3883: STATIC int asc_prt_driver_conf(struct Scsi_Host *, char *, int); 3884: STATIC int asc_prt_asc_board_info(struct Scsi_Host *, char *, int); 3885: STATIC int asc_prt_adv_board_info(struct Scsi_Host *, char *, int); 3886: STATIC int asc_prt_line(char *, int, char *fmt, ...); 3887: #endif /* version >= v1.3.0 */ 3888: 3889: /* Declaration for Asc Library internal functions reference by driver. */ 3890: STATIC int AscFindSignature(PortAddr); 3891: STATIC ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort); 3892: 3893: #ifdef ADVANSYS_STATS 3894: STATIC int asc_prt_board_stats(struct Scsi_Host *, char *, int); 3895: #endif /* ADVANSYS_STATS */ 3896: 3897: #ifdef ADVANSYS_DEBUG 3898: STATIC void asc_prt_scsi_host(struct Scsi_Host *); 3899: STATIC void asc_prt_scsi_cmnd(Scsi_Cmnd *); 3900: STATIC void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *); 3901: STATIC void asc_prt_asc_dvc_var(ASC_DVC_VAR *); 3902: STATIC void asc_prt_asc_scsi_q(ASC_SCSI_Q *); 3903: STATIC void asc_prt_asc_qdone_info(ASC_QDONE_INFO *); 3904: STATIC void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *); 3905: STATIC void asc_prt_adv_dvc_var(ADV_DVC_VAR *); 3906: STATIC void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *); 3907: STATIC void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *); 3908: STATIC void asc_prt_hex(char *f, uchar *, int); 3909: #endif /* ADVANSYS_DEBUG */ 3910: 3911: #ifdef ADVANSYS_ASSERT 3912: STATIC int interrupts_enabled(void); 3913: #endif /* ADVANSYS_ASSERT */ 3914: 3915: 3916: /* 3917: * --- Linux 'Scsi_Host_Template' and advansys_setup() Functions 3918: */ 3919: 3920: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0) 3921: /* 3922: * advansys_proc_info() - /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)] 3923: * 3924: * *buffer: I/O buffer 3925: * **start: if inout == FALSE pointer into buffer where user read should start 3926: * offset: current offset into a /proc/scsi/advansys/[0...] file 3927: * length: length of buffer 3928: * hostno: Scsi_Host host_no 3929: * inout: TRUE - user is writing; FALSE - user is reading 3930: * 3931: * Return the number of bytes read from or written to a 3932: * /proc/scsi/advansys/[0...] file. 3933: * 3934: * Note: This function uses the per board buffer 'prtbuf' which is 3935: * allocated when the board is initialized in advansys_detect(). The 3936: * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is 3937: * used to write to the buffer. The way asc_proc_copy() is written 3938: * if 'prtbuf' is too small it will not be overwritten. Instead the 3939: * user just won't get all the available statistics. 3940: */ 3941: int 3942: advansys_proc_info(char *buffer, char **start, off_t offset, int length, 3943: int hostno, int inout) 3944: { 3945: struct Scsi_Host *shp; 3946: asc_board_t *boardp; 3947: int i; 3948: char *cp; 3949: int cplen; 3950: int cnt; 3951: int totcnt; 3952: int leftlen; 3953: char *curbuf; 3954: off_t advoffset; 3955: Scsi_Device *scd; 3956: 3957: ASC_DBG(1, "advansys_proc_info: begin\n"); 3958: 3959: /* 3960: * User write not supported. 3961: */ 3962: if (inout == TRUE) { 3963: return(-ENOSYS); 3964: } 3965: 3966: /* 3967: * User read of /proc/scsi/advansys/[0...] file. 3968: */ 3969: 3970: /* Find the specified board. */ 3971: for (i = 0; i < asc_board_count; i++) { 3972: if (asc_host[i]->host_no == hostno) { 3973: break; 3974: } 3975: } 3976: if (i == asc_board_count) { 3977: return(-ENOENT); 3978: } 3979: 3980: shp = asc_host[i]; 3981: boardp = ASC_BOARDP(shp); 3982: 3983: /* Copy read data starting at the beginning of the buffer. */ 3984: *start = buffer; 3985: curbuf = buffer; 3986: advoffset = 0; 3987: totcnt = 0; 3988: leftlen = length; 3989: 3990: /* 3991: * Get board configuration information. 3992: * 3993: * advansys_info() returns the board string from its own static buffer. 3994: */ 3995: cp = (char *) advansys_info(shp); 3996: strcat(cp, "\n"); 3997: cplen = strlen(cp); 3998: /* Copy board information. */ 3999: cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); 4000: totcnt += cnt; 4001: leftlen -= cnt; 4002: if (leftlen == 0) { 4003: ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); 4004: return totcnt; 4005: } 4006: advoffset += cplen; 4007: curbuf += cnt; 4008: 4009: /* 4010: * Display Wide Board BIOS Information. 4011: */ 4012: if (ASC_WIDE_BOARD(boardp)) { 4013: cp = boardp->prtbuf; 4014: cplen = asc_prt_adv_bios(shp, cp, ASC_PRTBUF_SIZE); 4015: ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); 4016: cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); 4017: totcnt += cnt; 4018: leftlen -= cnt; 4019: if (leftlen == 0) { 4020: ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); 4021: return totcnt; 4022: } 4023: advoffset += cplen; 4024: curbuf += cnt; 4025: } 4026: 4027: /* 4028: * Display driver information for each device attached to the board. 4029: */ 4030: cp = boardp->prtbuf; 4031: cplen = asc_prt_board_devices(shp, cp, ASC_PRTBUF_SIZE); 4032: ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); 4033: cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); 4034: totcnt += cnt; 4035: leftlen -= cnt; 4036: if (leftlen == 0) { 4037: ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); 4038: return totcnt; 4039: } 4040: advoffset += cplen; 4041: curbuf += cnt; 4042: 4043: /* 4044: * Display target driver information for each device attached 4045: * to the board. 4046: */ 4047: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,75) 4048: for (scd = scsi_devices; scd; scd = scd->next) 4049: #else /* version >= v2.1.75 */ 4050: for (scd = shp->host_queue; scd; scd = scd->next) 4051: #endif /* version >= v2.1.75 */ 4052: { 4053: if (scd->host == shp) { 4054: cp = boardp->prtbuf; 4055: /* 4056: * Note: If proc_print_scsidevice() writes more than 4057: * ASC_PRTBUF_SIZE bytes, it will overrun 'prtbuf'. 4058: */ 4059: proc_print_scsidevice(scd, cp, &cplen, 0); 4060: ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); 4061: cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); 4062: totcnt += cnt; 4063: leftlen -= cnt; 4064: if (leftlen == 0) { 4065: ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); 4066: return totcnt; 4067: } 4068: advoffset += cplen; 4069: curbuf += cnt; 4070: } 4071: } 4072: 4073: /* 4074: * Display EEPROM configuration for the board. 4075: */ 4076: cp = boardp->prtbuf; 4077: if (ASC_NARROW_BOARD(boardp)) { 4078: cplen = asc_prt_asc_board_eeprom(shp, cp, ASC_PRTBUF_SIZE); 4079: } else { 4080: cplen = asc_prt_adv_board_eeprom(shp, cp, ASC_PRTBUF_SIZE); 4081: } 4082: ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); 4083: cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); 4084: totcnt += cnt; 4085: leftlen -= cnt; 4086: if (leftlen == 0) { 4087: ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); 4088: return totcnt; 4089: } 4090: advoffset += cplen; 4091: curbuf += cnt; 4092: 4093: /* 4094: * Display driver configuration and information for the board. 4095: */ 4096: cp = boardp->prtbuf; 4097: cplen = asc_prt_driver_conf(shp, cp, ASC_PRTBUF_SIZE); 4098: ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); 4099: cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); 4100: totcnt += cnt; 4101: leftlen -= cnt; 4102: if (leftlen == 0) { 4103: ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); 4104: return totcnt; 4105: } 4106: advoffset += cplen; 4107: curbuf += cnt; 4108: 4109: #ifdef ADVANSYS_STATS 4110: /* 4111: * Display driver statistics for the board. 4112: */ 4113: cp = boardp->prtbuf; 4114: cplen = asc_prt_board_stats(shp, cp, ASC_PRTBUF_SIZE); 4115: ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); 4116: cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); 4117: totcnt += cnt; 4118: leftlen -= cnt; 4119: if (leftlen == 0) { 4120: ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); 4121: return totcnt; 4122: } 4123: advoffset += cplen; 4124: curbuf += cnt; 4125: #endif /* ADVANSYS_STATS */ 4126: 4127: /* 4128: * Display Asc Library dynamic configuration information 4129: * for the board. 4130: */ 4131: cp = boardp->prtbuf; 4132: if (ASC_NARROW_BOARD(boardp)) { 4133: cplen = asc_prt_asc_board_info(shp, cp, ASC_PRTBUF_SIZE); 4134: } else { 4135: cplen = asc_prt_adv_board_info(shp, cp, ASC_PRTBUF_SIZE); 4136: } 4137: ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); 4138: cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); 4139: totcnt += cnt; 4140: leftlen -= cnt; 4141: if (leftlen == 0) { 4142: ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); 4143: return totcnt; 4144: } 4145: advoffset += cplen; 4146: curbuf += cnt; 4147: 4148: ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); 4149: 4150: return totcnt; 4151: } 4152: #endif /* version >= v1.3.0 */ 4153: 4154: /* 4155: * advansys_detect() 4156: * 4157: * Detect function for AdvanSys adapters. 4158: * 4159: * Argument is a pointer to the host driver's scsi_hosts entry. 4160: * 4161: * Return number of adapters found. 4162: * 4163: * Note: Because this function is called during system initialization 4164: * it must not call SCSI mid-level functions including scsi_malloc() 4165: * and scsi_free(). 4166: */ 4167: ASC_INITFUNC( 4168: int 4169: advansys_detect(Scsi_Host_Template *tpnt) 4170: ) 4171: { 4172: static int detect_called = ASC_FALSE; 4173: int iop; 4174: int bus; 4175: struct Scsi_Host *shp; 4176: asc_board_t *boardp; 4177: ASC_DVC_VAR *asc_dvc_varp = NULL; 4178: ADV_DVC_VAR *adv_dvc_varp = NULL; 4179: int ioport = 0; 4180: int share_irq = FALSE; 4181: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93) 4182: #ifdef ASC_CONFIG_PCI 4183: PCI_DEVICE pciDevice; 4184: PCI_CONFIG_SPACE pciConfig; 4185: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0) 4186: unsigned long pci_memory_address; 4187: #endif /* version >= v1,3,0 */ 4188: #endif /* ASC_CONFIG_PCI */ 4189: #else /* version >= v2.1.93 */ 4190: #ifdef CONFIG_PCI 4191: struct pci_dev *pci_devp = NULL; 4192: int pci_device_id_cnt = 0; 4193: unsigned int pci_device_id[ASC_PCI_DEVICE_ID_CNT] = { 4194: ASC_PCI_DEVICE_ID_1100, 4195: ASC_PCI_DEVICE_ID_1200, 4196: ASC_PCI_DEVICE_ID_1300, 4197: ASC_PCI_DEVICE_ID_2300 4198: }; 4199: unsigned long pci_memory_address; 4200: #endif /* CONFIG_PCI */ 4201: #endif /* version >= v2.1.93 */ 4202: int warn_code, err_code; 4203: int ret; 4204: 4205: if (detect_called == ASC_FALSE) { 4206: detect_called = ASC_TRUE; 4207: } else { 4208: printk("AdvanSys SCSI: advansys_detect() multiple calls ignored\n"); 4209: return 0; 4210: } 4211: 4212: ASC_DBG(1, "advansys_detect: begin\n"); 4213: 4214: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0) 4215: tpnt->proc_dir = &proc_scsi_advansys; 4216: #endif /* version >= v1.3.0 */ 4217: 4218: asc_board_count = 0; 4219: 4220: /* 4221: * If I/O port probing has been modified, then verify and 4222: * clean-up the 'asc_ioport' list. 4223: */ 4224: if (asc_iopflag == ASC_TRUE) { 4225: for (ioport = 0; ioport < ASC_NUM_IOPORT_PROBE; ioport++) { 4226: ASC_DBG2(1, "advansys_detect: asc_ioport[%d] %x\n", 4227: ioport, asc_ioport[ioport]); 4228: if (asc_ioport[ioport] != 0) { 4229: for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX; iop++) { 4230: if (_asc_def_iop_base[iop] == asc_ioport[ioport]) { 4231: break; 4232: } 4233: } 4234: if (iop == ASC_IOADR_TABLE_MAX_IX) { 4235: printk( 4236: "AdvanSys SCSI: specified I/O Port 0x%X is invalid\n", 4237: asc_ioport[ioport]); 4238: asc_ioport[ioport] = 0; 4239: } 4240: } 4241: } 4242: ioport = 0; 4243: } 4244: 4245: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93) 4246: #ifdef ASC_CONFIG_PCI 4247: memset(&pciDevice, 0, sizeof(PCI_DEVICE)); 4248: memset(&pciConfig, 0, sizeof(PCI_CONFIG_SPACE)); 4249: pciDevice.maxBusNumber = PCI_MAX_BUS; 4250: pciDevice.endSlot = PCI_MAX_SLOT; 4251: #endif /* ASC_CONFIG_PCI */ 4252: #endif /* version < v2.1.93 */ 4253: 4254: for (bus = 0; bus < ASC_NUM_BUS; bus++) { 4255: 4256: ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n", 4257: bus, asc_bus_name[bus]); 4258: iop = 0; 4259: 4260: while (asc_board_count < ASC_NUM_BOARD_SUPPORTED) { 4261: 4262: ASC_DBG1(2, "advansys_detect: asc_board_count %d\n", 4263: asc_board_count); 4264: 4265: switch (asc_bus[bus]) { 4266: case ASC_IS_ISA: 4267: case ASC_IS_VL: 4268: if (asc_iopflag == ASC_FALSE) { 4269: iop = AscSearchIOPortAddr(iop, asc_bus[bus]); 4270: } else { 4271: /* 4272: * ISA and VL I/O port scanning has either been 4273: * eliminated or limited to selected ports on 4274: * the LILO command line, /etc/lilo.conf, or 4275: * by setting variables when the module was loaded. 4276: */ 4277: ASC_DBG(1, "advansys_detect: I/O port scanning modified\n"); 4278: ioport_try_again: 4279: iop = 0; 4280: for (; ioport < ASC_NUM_IOPORT_PROBE; ioport++) { 4281: if ((iop = asc_ioport[ioport]) != 0) { 4282: break; 4283: } 4284: } 4285: if (iop) { 4286: ASC_DBG1(1, "advansys_detect: probing I/O port %x...\n", 4287: iop); 4288: if (check_region(iop, ASC_IOADR_GAP) != 0) { 4289: printk( 4290: "AdvanSys SCSI: specified I/O Port 0x%X is busy\n", iop); 4291: /* Don't try this I/O port twice. */ 4292: asc_ioport[ioport] = 0; 4293: goto ioport_try_again; 4294: } else if (AscFindSignature(iop) == ASC_FALSE) { 4295: printk( 4296: "AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n", iop); 4297: /* Don't try this I/O port twice. */ 4298: asc_ioport[ioport] = 0; 4299: goto ioport_try_again; 4300: } else { 4301: /* 4302: * If this isn't an ISA board, then it must be 4303: * a VL board. If currently looking an ISA 4304: * board is being looked for then try for 4305: * another ISA board in 'asc_ioport'. 4306: */ 4307: if (asc_bus[bus] == ASC_IS_ISA && 4308: (AscGetChipVersion(iop, ASC_IS_ISA) & 4309: ASC_CHIP_VER_ISA_BIT) == 0) { 4310: /* 4311: * Don't clear 'asc_ioport[ioport]'. Try 4312: * this board again for VL. Increment 4313: * 'ioport' past this board. 4314: */ 4315: ioport++; 4316: goto ioport_try_again; 4317: } 4318: } 4319: /* 4320: * This board appears good, don't try the I/O port 4321: * again by clearing its value. Increment 'ioport' 4322: * for the next iteration. 4323: */ 4324: asc_ioport[ioport++] = 0; 4325: } 4326: } 4327: break; 4328: 4329: case ASC_IS_EISA: 4330: iop = AscSearchIOPortAddr(iop, asc_bus[bus]); 4331: break; 4332: 4333: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93) 4334: #ifdef ASC_CONFIG_PCI 4335: case ASC_IS_PCI: 4336: if (asc_srch_pci_dev(&pciDevice) != PCI_DEVICE_FOUND) { 4337: iop = 0; 4338: } else { 4339: ASC_DBG2(2, 4340: "advansys_detect: slotFound %d, busNumber %d\n", 4341: pciDevice.slotFound, pciDevice.busNumber); 4342: asc_get_pci_cfg(&pciDevice, &pciConfig); 4343: iop = pciConfig.baseAddress[0] & PCI_IOADDRESS_MASK; 4344: ASC_DBG2(1, 4345: "advansys_detect: vendorID %X, deviceID %X\n", 4346: pciConfig.vendorID, pciConfig.deviceID); 4347: ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n", 4348: iop, pciConfig.irqLine); 4349: } 4350: break; 4351: #endif /* ASC_CONFIG_PCI */ 4352: #else /* version >= v2.1.93 */ 4353: #ifdef CONFIG_PCI 4354: case ASC_IS_PCI: 4355: while (pci_device_id_cnt < ASC_PCI_DEVICE_ID_CNT) { 4356: if ((pci_devp = pci_find_device(ASC_PCI_VENDORID, 4357: pci_device_id[pci_device_id_cnt], pci_devp)) == NULL) { 4358: pci_device_id_cnt++; 4359: } else { 4360: break; 4361: } 4362: } 4363: if (pci_devp == NULL) { 4364: iop = 0; 4365: } else { 4366: ASC_DBG2(2, 4367: "advansys_detect: devfn %d, bus number %d\n", 4368: pci_devp->devfn, pci_devp->bus->number); 4369: iop = pci_devp->base_address[0] & PCI_IOADDRESS_MASK; 4370: ASC_DBG2(1, 4371: "advansys_detect: vendorID %X, deviceID %X\n", 4372: pci_devp->vendor, pci_devp->device); 4373: ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n", 4374: iop, pci_devp->irq); 4375: } 4376: break; 4377: #endif /* CONFIG_PCI */ 4378: #endif /* version >= v2.1.93 */ 4379: 4380: default: 4381: ASC_PRINT1("advansys_detect: unknown bus type: %d\n", 4382: asc_bus[bus]); 4383: break; 4384: } 4385: ASC_DBG1(1, "advansys_detect: iop %x\n", iop); 4386: 4387: /* 4388: * Adapter not found, try next bus type. 4389: */ 4390: if (iop == 0) { 4391: break; 4392: } 4393: 4394: /* 4395: * Adapter found. 4396: * 4397: * Register the adapter, get its configuration, and 4398: * initialize it. 4399: */ 4400: ASC_DBG(2, "advansys_detect: scsi_register()\n"); 4401: shp = scsi_register(tpnt, sizeof(asc_board_t)); 4402: 4403: /* Save a pointer to the Scsi_host of each board found. */ 4404: asc_host[asc_board_count++] = shp; 4405: 4406: /* Initialize private per board data */ 4407: boardp = ASC_BOARDP(shp); 4408: memset(boardp, 0, sizeof(asc_board_t)); 4409: boardp->id = asc_board_count - 1; 4410: 4411: /* 4412: * Handle both narrow and wide boards. 4413: * 4414: * If a Wide board was detected, set the board structure 4415: * wide board flag. Set-up the board structure based on 4416: * the board type. 4417: */ 4418: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93) 4419: #ifdef ASC_CONFIG_PCI 4420: if (asc_bus[bus] == ASC_IS_PCI && 4421: pciConfig.deviceID == ASC_PCI_DEVICE_ID_2300) { 4422: boardp->flags |= ASC_IS_WIDE_BOARD; 4423: } 4424: #endif /* ASC_CONFIG_PCI */ 4425: #else /* version >= v2.1.93 */ 4426: #ifdef CONFIG_PCI 4427: if (asc_bus[bus] == ASC_IS_PCI && 4428: pci_devp->device == ASC_PCI_DEVICE_ID_2300) { 4429: boardp->flags |= ASC_IS_WIDE_BOARD; 4430: } 4431: #endif /* CONFIG_PCI */ 4432: #endif /* version >= v2.1.93 */ 4433: 4434: if (ASC_NARROW_BOARD(boardp)) { 4435: ASC_DBG(1, "advansys_detect: narrow board\n"); 4436: asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; 4437: asc_dvc_varp->bus_type = asc_bus[bus]; 4438: asc_dvc_varp->drv_ptr = (ulong) boardp; 4439: asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg; 4440: asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0]; 4441: asc_dvc_varp->iop_base = iop; 4442: asc_dvc_varp->isr_callback = (Ptr2Func) asc_isr_callback; 4443: } else { 4444: ASC_DBG(1, "advansys_detect: wide board\n"); 4445: adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; 4446: adv_dvc_varp->drv_ptr = (ulong) boardp; 4447: adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg; 4448: adv_dvc_varp->isr_callback = (Ptr2Func) adv_isr_callback; 4449: 4450: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0) 4451: adv_dvc_varp->iop_base = iop; 4452: #else /* version >= v1,3,0 */ 4453: /* 4454: * Map the board's registers into virtual memory for 4455: * PCI slave access. Only memory accesses are used to 4456: * access the board's registers. 4457: * 4458: * Note: The PCI register base address is not always 4459: * page aligned, but the address passed to ioremap() 4460: * must be page aligned. It is guaranteed that the 4461: * PCI register base address will not cross a page 4462: * boundary. 4463: */ 4464: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93) 4465: #ifdef ASC_CONFIG_PCI 4466: pci_memory_address = pciConfig.baseAddress[1]; 4467: if ((boardp->ioremap_addr = 4468: ioremap(pci_memory_address & PAGE_MASK, 4469: PAGE_SIZE)) == 0) { 4470: ASC_PRINT3( 4471: "advansys_detect: board %d: ioremap(%lx, %d) returned NULL\n", 4472: boardp->id, pci_memory_address, ADV_CONDOR_IOLEN); 4473: scsi_unregister(shp); 4474: asc_board_count--; 4475: continue; 4476: } 4477: adv_dvc_varp->iop_base = (AdvPortAddr) 4478: (boardp->ioremap_addr + 4479: (pci_memory_address - (pci_memory_address & PAGE_MASK))); 4480: #endif /* ASC_CONFIG_PCI */ 4481: #else /* version >= v2.1.93 */ 4482: #ifdef CONFIG_PCI 4483: pci_memory_address = pci_devp->base_address[1]; 4484: if ((boardp->ioremap_addr = 4485: ioremap(pci_memory_address & PAGE_MASK, 4486: PAGE_SIZE)) == 0) { 4487: ASC_PRINT3( 4488: "advansys_detect: board %d: ioremap(%lx, %d) returned NULL\n", 4489: boardp->id, pci_memory_address, ADV_CONDOR_IOLEN); 4490: scsi_unregister(shp); 4491: asc_board_count--; 4492: continue; 4493: } 4494: adv_dvc_varp->iop_base = (AdvPortAddr) 4495: (boardp->ioremap_addr + 4496: (pci_memory_address - (pci_memory_address & PAGE_MASK))); 4497: #endif /* CONFIG_PCI */ 4498: #endif /* version >= v2.1.93 */ 4499: #endif /* version >= v1,3,0 */ 4500: 4501: /* 4502: * Even though it isn't used to access the board in 4503: * kernels greater than or equal to v1.3.0, save 4504: * the I/O Port address so that it can be reported and 4505: * displayed. 4506: */ 4507: boardp->ioport = iop; 4508: } 4509: 4510: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0) 4511: /* 4512: * Allocate buffer for printing information from 4513: * /proc/scsi/advansys/[0...]. 4514: */ 4515: if ((boardp->prtbuf = 4516: kmalloc(ASC_PRTBUF_SIZE, GFP_ATOMIC)) == NULL) { 4517: ASC_PRINT3( 4518: "advansys_detect: board %d: kmalloc(%d, %d) returned NULL\n", 4519: boardp->id, ASC_PRTBUF_SIZE, GFP_ATOMIC); 4520: scsi_unregister(shp); 4521: asc_board_count--; 4522: continue; 4523: } 4524: #endif /* version >= v1.3.0 */ 4525: 4526: if (ASC_NARROW_BOARD(boardp)) { 4527: /* 4528: * Set the board bus type and PCI IRQ before 4529: * calling AscInitGetConfig(). 4530: */ 4531: switch (asc_dvc_varp->bus_type) { 4532: case ASC_IS_ISA: 4533: shp->unchecked_isa_dma = TRUE; 4534: share_irq = FALSE; 4535: break; 4536: case ASC_IS_VL: 4537: shp->unchecked_isa_dma = FALSE; 4538: share_irq = FALSE; 4539: break; 4540: case ASC_IS_EISA: 4541: shp->unchecked_isa_dma = FALSE; 4542: share_irq = TRUE; 4543: break; 4544: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93) 4545: #ifdef ASC_CONFIG_PCI 4546: case ASC_IS_PCI: 4547: shp->irq = asc_dvc_varp->irq_no = pciConfig.irqLine; 4548: asc_dvc_varp->cfg->pci_device_id = pciConfig.deviceID; 4549: asc_dvc_varp->cfg->pci_slot_info = 4550: ASC_PCI_MKID(pciDevice.busNumber, 4551: pciDevice.slotFound, 4552: pciDevice.devFunc); 4553: shp->unchecked_isa_dma = FALSE; 4554: share_irq = TRUE; 4555: break; 4556: #endif /* ASC_CONFIG_PCI */ 4557: #else /* version >= v2.1.93 */ 4558: #ifdef CONFIG_PCI 4559: case ASC_IS_PCI: 4560: shp->irq = asc_dvc_varp->irq_no = pci_devp->irq; 4561: asc_dvc_varp->cfg->pci_device_id = pci_devp->device; 4562: asc_dvc_varp->cfg->pci_slot_info = 4563: ASC_PCI_MKID(pci_devp->bus->number, 4564: PCI_SLOT(pci_devp->devfn), 4565: PCI_FUNC(pci_devp->devfn)); 4566: shp->unchecked_isa_dma = FALSE; 4567: share_irq = TRUE; 4568: break; 4569: #endif /* CONFIG_PCI */ 4570: #endif /* version >= v2.1.93 */ 4571: default: 4572: ASC_PRINT2( 4573: "advansys_detect: board %d: unknown adapter type: %d\n", 4574: boardp->id, asc_dvc_varp->bus_type); 4575: shp->unchecked_isa_dma = TRUE; 4576: share_irq = FALSE; 4577: break; 4578: } 4579: } else { 4580: /* 4581: * For Wide boards set PCI information before calling 4582: * AdvInitGetConfig(). 4583: */ 4584: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93) 4585: #ifdef ASC_CONFIG_PCI 4586: shp->irq = adv_dvc_varp->irq_no = pciConfig.irqLine; 4587: adv_dvc_varp->cfg->pci_device_id = pciConfig.deviceID; 4588: adv_dvc_varp->cfg->pci_slot_info = 4589: ASC_PCI_MKID(pciDevice.busNumber, 4590: pciDevice.slotFound, 4591: pciDevice.devFunc); 4592: shp->unchecked_isa_dma = FALSE; 4593: share_irq = TRUE; 4594: #endif /* ASC_CONFIG_PCI */ 4595: #else /* version >= v2.1.93 */ 4596: #ifdef CONFIG_PCI 4597: shp->irq = adv_dvc_varp->irq_no = pci_devp->irq; 4598: adv_dvc_varp->cfg->pci_device_id = pci_devp->device; 4599: adv_dvc_varp->cfg->pci_slot_info = 4600: ASC_PCI_MKID(pci_devp->bus->number, 4601: PCI_SLOT(pci_devp->devfn), 4602: PCI_FUNC(pci_devp->devfn)); 4603: shp->unchecked_isa_dma = FALSE; 4604: share_irq = TRUE; 4605: #endif /* CONFIG_PCI */ 4606: #endif /* version >= v2.1.93 */ 4607: } 4608: 4609: /* 4610: * Read the board configuration. 4611: */ 4612: if (ASC_NARROW_BOARD(boardp)) { 4613: /* 4614: * NOTE: AscInitGetConfig() may change the board's 4615: * bus_type value. The asc_bus[bus] value should no 4616: * longer be used. If the bus_type field must be 4617: * referenced only use the bit-wise AND operator "&". 4618: */ 4619: ASC_DBG(2, "advansys_detect: AscInitGetConfig()\n"); 4620: switch(ret = AscInitGetConfig(asc_dvc_varp)) { 4621: case 0: /* No error */ 4622: break; 4623: case ASC_WARN_IO_PORT_ROTATE: 4624: ASC_PRINT1( 4625: "AscInitGetConfig: board %d: I/O port address modified\n", 4626: boardp->id); 4627: break; 4628: case ASC_WARN_AUTO_CONFIG: 4629: ASC_PRINT1( 4630: "AscInitGetConfig: board %d: I/O port increment switch enabled\n", 4631: boardp->id); 4632: break; 4633: case ASC_WARN_EEPROM_CHKSUM: 4634: ASC_PRINT1( 4635: "AscInitGetConfig: board %d: EEPROM checksum error\n", 4636: boardp->id); 4637: break; 4638: case ASC_WARN_IRQ_MODIFIED: 4639: ASC_PRINT1( 4640: "AscInitGetConfig: board %d: IRQ modified\n", 4641: boardp->id); 4642: break; 4643: case ASC_WARN_CMD_QNG_CONFLICT: 4644: ASC_PRINT1( 4645: "AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n", 4646: boardp->id); 4647: break; 4648: default: 4649: ASC_PRINT2( 4650: "AscInitGetConfig: board %d: unknown warning: %x\n", 4651: boardp->id, ret); 4652: break; 4653: } 4654: if ((err_code = asc_dvc_varp->err_code) != 0) { 4655: ASC_PRINT3( 4656: "AscInitGetConfig: board %d error: init_state %x, err_code %x\n", 4657: boardp->id, asc_dvc_varp->init_state, 4658: asc_dvc_varp->err_code); 4659: } 4660: } else { 4661: ASC_DBG(2, "advansys_detect: AdvInitGetConfig()\n"); 4662: if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) { 4663: ASC_PRINT2("AdvInitGetConfig: board %d: warning: %x\n", 4664: boardp->id, ret); 4665: } 4666: if ((err_code = adv_dvc_varp->err_code) != 0) { 4667: ASC_PRINT2( 4668: "AdvInitGetConfig: board %d error: err_code %x\n", 4669: boardp->id, adv_dvc_varp->err_code); 4670: } 4671: } 4672: 4673: if (err_code != 0) { 4674: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0) 4675: kfree(boardp->prtbuf); 4676: #endif /* version >= v1.3.0 */ 4677: scsi_unregister(shp); 4678: asc_board_count--; 4679: continue; 4680: } 4681: 4682: /* 4683: * Save the EEPROM configuration so that it can be displayed 4684: * from /proc/scsi/advansys/[0...]. 4685: */ 4686: if (ASC_NARROW_BOARD(boardp)) { 4687: 4688: ASCEEP_CONFIG *ep; 4689: 4690: /* 4691: * Set the adapter's target id bit in the 'init_tidmask' field. 4692: */ 4693: boardp->init_tidmask |= 4694: ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id); 4695: 4696: /* 4697: * Save EEPROM settings for the board. 4698: */ 4699: ep = &boardp->eep_config.asc_eep; 4700: 4701: ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable; 4702: ep->disc_enable = asc_dvc_varp->cfg->disc_enable; 4703: ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled; 4704: ep->isa_dma_speed = asc_dvc_varp->cfg->isa_dma_speed; 4705: ep->start_motor = asc_dvc_varp->start_motor; 4706: ep->cntl = asc_dvc_varp->dvc_cntl; 4707: ep->no_scam = asc_dvc_varp->no_scam; 4708: ep->max_total_qng = asc_dvc_varp->max_total_qng; 4709: ep->chip_scsi_id = asc_dvc_varp->cfg->chip_scsi_id; 4710: /* 'max_tag_qng' is set to the same value for every device. */ 4711: ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0]; 4712: ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0]; 4713: ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1]; 4714: ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2]; 4715: ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3]; 4716: ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4]; 4717: ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5]; 4718: ep->adapter_info[6] = asc_dvc_varp->cfg->adapter_info[6]; 4719: 4720: /* 4721: * Modify board configuration. 4722: */ 4723: ASC_DBG(2, "advansys_detect: AscInitSetConfig()\n"); 4724: switch (ret = AscInitSetConfig(asc_dvc_varp)) { 4725: case 0: /* No error. */ 4726: break; 4727: case ASC_WARN_IO_PORT_ROTATE: 4728: ASC_PRINT1( 4729: "AscInitSetConfig: board %d: I/O port address modified\n", 4730: boardp->id); 4731: break; 4732: case ASC_WARN_AUTO_CONFIG: 4733: ASC_PRINT1( 4734: "AscInitSetConfig: board %d: I/O port increment switch enabled\n", 4735: boardp->id); 4736: break; 4737: case ASC_WARN_EEPROM_CHKSUM: 4738: ASC_PRINT1( 4739: "AscInitSetConfig: board %d: EEPROM checksum error\n", 4740: boardp->id); 4741: break; 4742: case ASC_WARN_IRQ_MODIFIED: 4743: ASC_PRINT1( 4744: "AscInitSetConfig: board %d: IRQ modified\n", 4745: boardp->id); 4746: break; 4747: case ASC_WARN_CMD_QNG_CONFLICT: 4748: ASC_PRINT1( 4749: "AscInitSetConfig: board %d: tag queuing w/o disconnects\n", 4750: boardp->id); 4751: break; 4752: default: 4753: ASC_PRINT2( 4754: "AscInitSetConfig: board %d: unknown warning: %x\n", 4755: boardp->id, ret); 4756: break; 4757: } 4758: if (asc_dvc_varp->err_code != 0) { 4759: ASC_PRINT3( 4760: "AscInitSetConfig: board %d error: init_state %x, err_code %x\n", 4761: boardp->id, asc_dvc_varp->init_state, 4762: asc_dvc_varp->err_code); 4763: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0) 4764: kfree(boardp->prtbuf); 4765: #endif /* version >= v1.3.0 */ 4766: scsi_unregister(shp); 4767: asc_board_count--; 4768: continue; 4769: } 4770: 4771: /* 4772: * Finish initializing the 'Scsi_Host' structure. 4773: */ 4774: /* AscInitSetConfig() will set the IRQ for non-PCI boards. */ 4775: if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) { 4776: shp->irq = asc_dvc_varp->irq_no; 4777: } 4778: } else { 4779: 4780: ADVEEP_CONFIG *ep; 4781: 4782: /* 4783: * Save Wide EEP Configuration Information. 4784: */ 4785: ep = &boardp->eep_config.adv_eep; 4786: 4787: ep->adapter_scsi_id = adv_dvc_varp->chip_scsi_id; 4788: ep->max_host_qng = adv_dvc_varp->max_host_qng; 4789: ep->max_dvc_qng = adv_dvc_varp->max_dvc_qng; 4790: ep->termination = adv_dvc_varp->cfg->termination; 4791: ep->disc_enable = adv_dvc_varp->cfg->disc_enable; 4792: ep->bios_ctrl = adv_dvc_varp->bios_ctrl; 4793: ep->wdtr_able = adv_dvc_varp->wdtr_able; 4794: ep->sdtr_able = adv_dvc_varp->sdtr_able; 4795: ep->ultra_able = adv_dvc_varp->ultra_able; 4796: ep->tagqng_able = adv_dvc_varp->tagqng_able; 4797: ep->start_motor = adv_dvc_varp->start_motor; 4798: ep->scsi_reset_delay = adv_dvc_varp->scsi_reset_wait; 4799: ep->bios_boot_delay = adv_dvc_varp->cfg->bios_boot_wait; 4800: ep->serial_number_word1 = adv_dvc_varp->cfg->serial1; 4801: ep->serial_number_word2 = adv_dvc_varp->cfg->serial2; 4802: ep->serial_number_word3 = adv_dvc_varp->cfg->serial3; 4803: 4804: /* 4805: * Set the adapter's target id bit in the 'init_tidmask' field. 4806: */ 4807: boardp->init_tidmask |= 4808: ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id); 4809: 4810: /* 4811: * Finish initializing the 'Scsi_Host' structure. 4812: */ 4813: shp->irq = adv_dvc_varp->irq_no; 4814: } 4815: 4816: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89) 4817: /* 4818: * Channels are numbered beginning with 0. For AdvanSys One host 4819: * structure supports one channel. Multi-channel boards have a 4820: * separate host structure for each channel. 4821: */ 4822: shp->max_channel = 0; 4823: #endif /* version >= v1.3.89 */ 4824: if (ASC_NARROW_BOARD(boardp)) { 4825: shp->max_id = ASC_MAX_TID + 1; 4826: shp->max_lun = ASC_MAX_LUN + 1; 4827: 4828: shp->io_port = asc_dvc_varp->iop_base; 4829: shp->n_io_port = ASC_IOADR_GAP; 4830: shp->this_id = asc_dvc_varp->cfg->chip_scsi_id; 4831: 4832: /* Set maximum number of queues the adapter can handle. */ 4833: shp->can_queue = asc_dvc_varp->max_total_qng; 4834: } else { 4835: shp->max_id = ADV_MAX_TID + 1; 4836: shp->max_lun = ADV_MAX_LUN + 1; 4837: 4838: /* 4839: * Save the I/O Port address and length even though the 4840: * in v1.3.0 and greater kernels the region is not used 4841: * by a Wide board. Instead the board is accessed with 4842: * Memory Mapped I/O. 4843: */ 4844: shp->io_port = iop; 4845: shp->n_io_port = ADV_CONDOR_IOLEN; 4846: 4847: shp->this_id = adv_dvc_varp->chip_scsi_id; 4848: 4849: /* Set maximum number of queues the adapter can handle. */ 4850: shp->can_queue = adv_dvc_varp->max_host_qng; 4851: } 4852: 4853: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89) 4854: /* 4855: * In old kernels without tag queuing support and with memory 4856: * allocation problems set a conservative 'cmd_per_lun' value. 4857: */ 4858: #ifdef MODULE 4859: shp->cmd_per_lun = 1; 4860: #else /* MODULE */ 4861: shp->cmd_per_lun = 4; 4862: #endif /* MODULE */ 4863: ASC_DBG1(1, "advansys_detect: cmd_per_lun: %d\n", shp->cmd_per_lun); 4864: #else /* version >= v1.3.89 */ 4865: /* 4866: * Following v1.3.89, 'cmd_per_lun' is no longer needed 4867: * and should be set to zero. 4868: * 4869: * But because of a bug introduced in v1.3.89 if the driver is 4870: * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level 4871: * SCSI function 'allocate_device' will panic. To allow the driver 4872: * to work as a module in these kernels set 'cmd_per_lun' to 1. 4873: */ 4874: #ifdef MODULE 4875: shp->cmd_per_lun = 1; 4876: #else /* MODULE */ 4877: shp->cmd_per_lun = 0; 4878: #endif /* MODULE */ 4879: /* 4880: * Use the host 'select_queue_depths' function to determine 4881: * the number of commands to queue per device. 4882: */ 4883: shp->select_queue_depths = advansys_select_queue_depths; 4884: #endif /* version >= v1.3.89 */ 4885: 4886: /* 4887: * Set the maximum number of scatter-gather elements the 4888: * adapter can handle. 4889: */ 4890: if (ASC_NARROW_BOARD(boardp)) { 4891: /* 4892: * Allow two commands with 'sg_tablesize' scatter-gather 4893: * elements to be executed simultaneously. This value is 4894: * the theoretical hardware limit. It may be decreased 4895: * below. 4896: */ 4897: shp->sg_tablesize = 4898: (((asc_dvc_varp->max_total_qng - 2) / 2) * 4899: ASC_SG_LIST_PER_Q) + 1; 4900: } else { 4901: shp->sg_tablesize = ADV_MAX_SG_LIST; 4902: } 4903: 4904: #ifdef MODULE 4905: /* 4906: * If the driver is compiled as a module, set a limit on the 4907: * 'sg_tablesize' value to prevent memory allocation failures. 4908: * Memory allocation errors are more likely to occur at module 4909: * load time, then at driver initialization time. 4910: */ 4911: if (shp->sg_tablesize > 64) { 4912: shp->sg_tablesize = 64; 4913: } 4914: #endif /* MODULE */ 4915: 4916: /* 4917: * The value of 'sg_tablesize' can not exceed the SCSI 4918: * mid-level driver definition of SG_ALL. SG_ALL also 4919: * must not be exceeded, because it is used to define the 4920: * size of the scatter-gather table in 'struct asc_sg_head'. 4921: */ 4922: if (shp->sg_tablesize > SG_ALL) { 4923: shp->sg_tablesize = SG_ALL; 4924: } 4925: 4926: ASC_DBG1(1, "advansys_detect: sg_tablesize: %d\n", 4927: shp->sg_tablesize); 4928: 4929: /* BIOS start address. */ 4930: if (ASC_NARROW_BOARD(boardp)) { 4931: shp->base = (char *) ((ulong) AscGetChipBiosAddress( 4932: asc_dvc_varp->iop_base, 4933: asc_dvc_varp->bus_type)); 4934: } else { 4935: /* 4936: * Fill-in BIOS board variables. The Wide BIOS saves 4937: * information in LRAM that is used by the driver. 4938: */ 4939: AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_SIGNATURE, 4940: boardp->bios_signature); 4941: AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_VERSION, 4942: boardp->bios_version); 4943: AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODESEG, 4944: boardp->bios_codeseg); 4945: AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODELEN, 4946: boardp->bios_codelen); 4947: 4948: ASC_DBG2(1, 4949: "advansys_detect: bios_signature %x, bios_version %x\n", 4950: boardp->bios_signature, boardp->bios_version); 4951: 4952: ASC_DBG2(1, 4953: "advansys_detect: bios_codeseg %x, bios_codelen %x\n", 4954: boardp->bios_codeseg, boardp->bios_codelen); 4955: 4956: /* 4957: * If the BIOS saved a valid signature, then fill in 4958: * the BIOS code segment base address. 4959: */ 4960: if (boardp->bios_signature == 0x55AA) { 4961: /* 4962: * Convert x86 realmode code segment to a linear 4963: * address by shifting left 4. 4964: */ 4965: shp->base = (uchar *) (boardp->bios_codeseg << 4); 4966: } else { 4967: shp->base = 0; 4968: } 4969: } 4970: 4971: /* 4972: * Register Board Resources - I/O Port, DMA, IRQ 4973: */ 4974: 4975: /* Register I/O port range. */ 4976: ASC_DBG(2, "advansys_detect: request_region()\n"); 4977: request_region(shp->io_port, shp->n_io_port, "advansys"); 4978: 4979: /* Register DMA Channel for Narrow boards. */ 4980: shp->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */ 4981: if (ASC_NARROW_BOARD(boardp)) { 4982: /* Register DMA channel for ISA bus. */ 4983: if (asc_dvc_varp->bus_type & ASC_IS_ISA) { 4984: shp->dma_channel = asc_dvc_varp->cfg->isa_dma_channel; 4985: if ((ret = 4986: request_dma(shp->dma_channel, "advansys")) != 0) { 4987: ASC_PRINT3( 4988: "advansys_detect: board %d: request_dma() %d failed %d\n", 4989: boardp->id, shp->dma_channel, ret); 4990: release_region(shp->io_port, shp->n_io_port); 4991: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0) 4992: kfree(boardp->prtbuf); 4993: #endif /* version >= v1.3.0 */ 4994: scsi_unregister(shp); 4995: asc_board_count--; 4996: continue; 4997: } 4998: AscEnableIsaDma(shp->dma_channel); 4999: } 5000: } 5001: 5002: /* Register IRQ Number. */ 5003: ASC_DBG1(2, "advansys_detect: request_irq() %d\n", shp->irq); 5004: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70) 5005: if ((ret = request_irq(shp->irq, advansys_interrupt, 5006: SA_INTERRUPT, "advansys")) != 0) 5007: #else /* version >= v1.3.70 */ 5008: /* 5009: * If request_irq() fails with the SA_INTERRUPT flag set, 5010: * then try again without the SA_INTERRUPT flag set. This 5011: * allows IRQ sharing to work even with other drivers that 5012: * do not set the SA_INTERRUPT flag. 5013: * 5014: * If SA_INTERRUPT is not set, then interrupts are enabled 5015: * before the driver interrupt function is called. 5016: */ 5017: if (((ret = request_irq(shp->irq, advansys_interrupt, 5018: SA_INTERRUPT | (share_irq == TRUE ? SA_SHIRQ : 0), 5019: "advansys", boardp)) != 0) && 5020: ((ret = request_irq(shp->irq, advansys_interrupt, 5021: (share_irq == TRUE ? SA_SHIRQ : 0), 5022: "advansys", boardp)) != 0)) 5023: #endif /* version >= v1.3.70 */ 5024: { 5025: if (ret == -EBUSY) { 5026: ASC_PRINT2( 5027: "advansys_detect: board %d: request_irq(): IRQ %d already in use.\n", 5028: boardp->id, shp->irq); 5029: } else if (ret == -EINVAL) { 5030: ASC_PRINT2( 5031: "advansys_detect: board %d: request_irq(): IRQ %d not valid.\n", 5032: boardp->id, shp->irq); 5033: } else { 5034: ASC_PRINT3( 5035: "advansys_detect: board %d: request_irq(): IRQ %d failed with %d\n", 5036: boardp->id, shp->irq, ret); 5037: } 5038: release_region(shp->io_port, shp->n_io_port); 5039: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0) 5040: iounmap(boardp->ioremap_addr); 5041: #endif /* version >= v1,3,0 */ 5042: if (shp->dma_channel != NO_ISA_DMA) { 5043: free_dma(shp->dma_channel); 5044: } 5045: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0) 5046: kfree(boardp->prtbuf); 5047: #endif /* version >= v1.3.0 */ 5048: scsi_unregister(shp); 5049: asc_board_count--; 5050: continue; 5051: } 5052: 5053: /* 5054: * Initialize board RISC chip and enable interrupts. 5055: */ 5056: if (ASC_NARROW_BOARD(boardp)) { 5057: ASC_DBG(2, "advansys_detect: AscInitAsc1000Driver()\n"); 5058: warn_code = AscInitAsc1000Driver(asc_dvc_varp); 5059: err_code = asc_dvc_varp->err_code; 5060: 5061: if (warn_code || err_code) { 5062: ASC_PRINT4( 5063: "AscInitAsc1000Driver: board %d: error: init_state %x, warn %x error %x\n", 5064: boardp->id, asc_dvc_varp->init_state, 5065: warn_code, err_code); 5066: } 5067: } else { 5068: int req_cnt; 5069: adv_req_t *reqp = NULL; 5070: int sg_cnt; 5071: adv_sgblk_t *sgp = NULL; 5072: 5073: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0) 5074: req_cnt = sizeof(adv_req_buf)/sizeof(adv_req_t); 5075: sg_cnt = sizeof(adv_sgblk_buf)/sizeof(adv_sgblk_t); 5076: reqp = (adv_req_t *) &adv_req_buf[0]; 5077: sgp = (adv_sgblk_t *) &adv_sgblk_buf[0]; 5078: #else /* version >= v1.3.0 */ 5079: /* 5080: * Allocate up to 'max_host_qng' request structures for 5081: * the Wide board. 5082: */ 5083: for (req_cnt = adv_dvc_varp->max_host_qng; 5084: req_cnt > 0; req_cnt--) { 5085: 5086: reqp = (adv_req_t *) 5087: kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC); 5088: 5089: ASC_DBG3(1, 5090: "advansys_detect: reqp %x, req_cnt %d, bytes %d\n", 5091: (unsigned) reqp, req_cnt, sizeof(adv_req_t) * req_cnt); 5092: 5093: if (reqp != NULL) { 5094: break; 5095: } 5096: } 5097: 5098: /* 5099: * Allocate up to ADV_TOT_SG_LIST request structures for 5100: * the Wide board. 5101: */ 5102: for (sg_cnt = ADV_TOT_SG_LIST; sg_cnt > 0; sg_cnt--) { 5103: 5104: sgp = (adv_sgblk_t *) 5105: kmalloc(sizeof(adv_sgblk_t) * sg_cnt, GFP_ATOMIC); 5106: 5107: ASC_DBG3(1, 5108: "advansys_detect: sgp %x, sg_cnt %d, bytes %d\n", 5109: (unsigned) sgp, sg_cnt, sizeof(adv_sgblk_t) * sg_cnt); 5110: 5111: if (sgp != NULL) { 5112: break; 5113: } 5114: } 5115: #endif /* version >= v1.3.0 */ 5116: 5117: /* 5118: * If no request structures or scatter-gather structures could 5119: * be allocated, then return an error. Otherwise continue with 5120: * initialization. 5121: */ 5122: if (reqp == NULL) { 5123: ASC_PRINT1( 5124: "advansys_detect: board %d: error: failed to kmalloc() adv_req_t buffer.\n", 5125: boardp->id); 5126: err_code = ADV_ERROR; 5127: } else if (sgp == NULL) { 5128: kfree(reqp); 5129: ASC_PRINT1( 5130: "advansys_detect: board %d: error: failed to kmalloc() adv_sgblk_t buffer.\n", 5131: boardp->id); 5132: err_code = ADV_ERROR; 5133: } else { 5134: 5135: /* 5136: * Save original pointer for kfree() in case the 5137: * driver is built as a module and can be unloaded. 5138: */ 5139: boardp->orig_reqp = reqp; 5140: 5141: /* 5142: * Point 'adv_reqp' to the request structures and 5143: * link them together. 5144: */ 5145: req_cnt--; 5146: reqp[req_cnt].next_reqp = NULL; 5147: for (; req_cnt > 0; req_cnt--) { 5148: reqp[req_cnt - 1].next_reqp = &reqp[req_cnt]; 5149: } 5150: boardp->adv_reqp = &reqp[0]; 5151: 5152: /* 5153: * Save original pointer for kfree() in case the 5154: * driver is built as a module and can be unloaded. 5155: */ 5156: boardp->orig_sgblkp = sgp; 5157: 5158: /* 5159: * Point 'adv_sgblkp' to the request structures and 5160: * link them together. 5161: */ 5162: sg_cnt--; 5163: sgp[sg_cnt].next_sgblkp = NULL; 5164: for (; sg_cnt > 0; sg_cnt--) { 5165: sgp[sg_cnt - 1].next_sgblkp = &sgp[sg_cnt]; 5166: } 5167: boardp->adv_sgblkp = &sgp[0]; 5168: 5169: ASC_DBG(2, "advansys_detect: AdvInitAsc3550Driver()\n"); 5170: warn_code = AdvInitAsc3550Driver(adv_dvc_varp); 5171: err_code = adv_dvc_varp->err_code; 5172: 5173: if (warn_code || err_code) { 5174: ASC_PRINT3( 5175: "AdvInitAsc3550Driver: board %d: error: warn %x, error %x\n", 5176: boardp->id, warn_code, adv_dvc_varp->err_code); 5177: } 5178: } 5179: } 5180: 5181: if (err_code != 0) { 5182: release_region(shp->io_port, shp->n_io_port); 5183: if (ASC_WIDE_BOARD(boardp)) { 5184: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0) 5185: iounmap(boardp->ioremap_addr); 5186: #endif /* version >= v1,3,0 */ 5187: if (boardp->orig_reqp) { 5188: kfree(boardp->orig_reqp); 5189: boardp->orig_reqp = boardp->adv_reqp = NULL; 5190: } 5191: if (boardp->orig_sgblkp) { 5192: kfree(boardp->orig_sgblkp); 5193: boardp->orig_sgblkp = boardp->adv_sgblkp = NULL; 5194: } 5195: } 5196: if (shp->dma_channel != NO_ISA_DMA) { 5197: free_dma(shp->dma_channel); 5198: } 5199: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0) 5200: kfree(boardp->prtbuf); 5201: #endif /* version >= v1.3.0 */ 5202: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70) 5203: free_irq(shp->irq); 5204: #else /* version >= v1.3.70 */ 5205: free_irq(shp->irq, boardp); 5206: #endif /* version >= v1.3.70 */ 5207: scsi_unregister(shp); 5208: asc_board_count--; 5209: continue; 5210: } 5211: ASC_DBG_PRT_SCSI_HOST(2, shp); 5212: } 5213: } 5214: ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n", asc_board_count); 5215: return asc_board_count; 5216: } 5217: 5218: /* 5219: * advansys_release() 5220: * 5221: * Release resources allocated for a single AdvanSys adapter. 5222: */ 5223: int 5224: advansys_release(struct Scsi_Host *shp) 5225: { 5226: asc_board_t *boardp; 5227: 5228: ASC_DBG(1, "advansys_release: begin\n"); 5229: boardp = ASC_BOARDP(shp); 5230: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70) 5231: free_irq(shp->irq); 5232: #else /* version >= v1.3.70 */ 5233: free_irq(shp->irq, boardp); 5234: #endif /* version >= v1.3.70 */ 5235: if (shp->dma_channel != NO_ISA_DMA) { 5236: ASC_DBG(1, "advansys_release: free_dma()\n"); 5237: free_dma(shp->dma_channel); 5238: } 5239: release_region(shp->io_port, shp->n_io_port); 5240: if (ASC_WIDE_BOARD(boardp)) { 5241: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0) 5242: iounmap(boardp->ioremap_addr); 5243: #endif /* version >= v1,3,0 */ 5244: if (boardp->orig_reqp) { 5245: kfree(boardp->orig_reqp); 5246: boardp->orig_reqp = boardp->adv_reqp = NULL; 5247: } 5248: if (boardp->orig_sgblkp) { 5249: kfree(boardp->orig_sgblkp); 5250: boardp->orig_sgblkp = boardp->adv_sgblkp = NULL; 5251: } 5252: } 5253: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0) 5254: ASC_ASSERT(boardp->prtbuf != NULL); 5255: kfree(boardp->prtbuf); 5256: #endif /* version >= v1.3.0 */ 5257: scsi_unregister(shp); 5258: ASC_DBG(1, "advansys_release: end\n"); 5259: return 0; 5260: } 5261: 5262: /* 5263: * advansys_info() 5264: * 5265: * Return suitable for printing on the console with the argument 5266: * adapter's configuration information. 5267: * 5268: * Note: The information line should not exceed ASC_INFO_SIZE bytes, 5269: * otherwise the static 'info' array will be overrun. 5270: */ 5271: const char * 5272: advansys_info(struct Scsi_Host *shp) 5273: { 5274: static char info[ASC_INFO_SIZE]; 5275: asc_board_t *boardp; 5276: ASC_DVC_VAR *asc_dvc_varp; 5277: ADV_DVC_VAR *adv_dvc_varp; 5278: char *busname; 5279: 5280: boardp = ASC_BOARDP(shp); 5281: if (ASC_NARROW_BOARD(boardp)) { 5282: asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; 5283: ASC_DBG(1, "advansys_info: begin\n"); 5284: if (asc_dvc_varp->bus_type & ASC_IS_ISA) { 5285: if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) == ASC_IS_ISAPNP) { 5286: busname = "ISA PnP"; 5287: } else { 5288: busname = "ISA"; 5289: } 5290: sprintf(info, 5291: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,92) 5292: "AdvanSys SCSI %s: %s %u CDB: BIOS %X, IO %X/%X, IRQ %u, DMA %u", 5293: #else /* version >= v2.1.92 */ 5294: "AdvanSys SCSI %s: %s %u CDB: BIOS %X, IO %lX/%X, IRQ %u, DMA %u", 5295: #endif /* version >= v2.1.92 */ 5296: ASC_VERSION, busname, asc_dvc_varp->max_total_qng, 5297: (unsigned) shp->base, 5298: shp->io_port, shp->n_io_port - 1, 5299: shp->irq, shp->dma_channel); 5300: } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) { 5301: if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA) 5302: == ASC_IS_PCI_ULTRA) { 5303: busname = "PCI Ultra"; 5304: } else { 5305: busname = "PCI"; 5306: } 5307: sprintf(info, 5308: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,92) 5309: "AdvanSys SCSI %s: %s %u CDB: IO %X/%X, IRQ %u", 5310: #else /* version >= v2.1.92 */ 5311: "AdvanSys SCSI %s: %s %u CDB: IO %lX/%X, IRQ %u", 5312: #endif /* version >= v2.1.92 */ 5313: ASC_VERSION, busname, asc_dvc_varp->max_total_qng, 5314: shp->io_port, shp->n_io_port - 1, shp->irq); 5315: } else { 5316: if (asc_dvc_varp->bus_type & ASC_IS_VL) { 5317: busname = "VL"; 5318: } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) { 5319: busname = "EISA"; 5320: } else { 5321: busname = "?"; 5322: ASC_PRINT2( 5323: "advansys_info: board %d: unknown bus type %d\n", 5324: boardp->id, asc_dvc_varp->bus_type); 5325: } 5326: sprintf(info, 5327: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,92) 5328: "AdvanSys SCSI %s: %s %u CDB: BIOS %X, IO %X/%X, IRQ %u", 5329: #else /* version >= v2.1.92 */ 5330: "AdvanSys SCSI %s: %s %u CDB: BIOS %X, IO %lX/%X, IRQ %u", 5331: #endif /* version >= v2.1.92 */ 5332: ASC_VERSION, busname, asc_dvc_varp->max_total_qng, 5333: (unsigned) shp->base, shp->io_port - 1, 5334: shp->n_io_port, shp->irq); 5335: } 5336: } else { 5337: /* 5338: * Wide Adapter Information 5339: * 5340: * Memory-mapped I/O is used instead of I/O space to access 5341: * the adapter, but display the I/O Port range. The Memory 5342: * I/O address is displayed through the driver /proc file. 5343: */ 5344: adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; 5345: if (boardp->bios_signature == 0x55AA) { 5346: sprintf(info, 5347: "AdvanSys SCSI %s: PCI Ultra-Wide: BIOS %X/%X, IO %X/%X, IRQ %u", 5348: ASC_VERSION, 5349: boardp->bios_codeseg << 4, 5350: boardp->bios_codelen > 0 ? 5351: (boardp->bios_codelen << 9) - 1 : 0, 5352: (unsigned) boardp->ioport, ADV_CONDOR_IOLEN - 1, 5353: shp->irq); 5354: } else { 5355: sprintf(info, 5356: "AdvanSys SCSI %s: PCI Ultra-Wide: IO %X/%X, IRQ %u", 5357: ASC_VERSION, 5358: (unsigned) boardp->ioport, 5359: (ADV_CONDOR_IOLEN - 1), 5360: shp->irq); 5361: } 5362: } 5363: ASC_ASSERT(strlen(info) < ASC_INFO_SIZE); 5364: ASC_DBG(1, "advansys_info: end\n"); 5365: return info; 5366: } 5367: 5368: /* 5369: * advansys_command() - polled I/O entrypoint. 5370: * 5371: * Apparently host drivers shouldn't return until the command 5372: * is finished. 5373: * 5374: * Note: This is an old interface that is no longer used by the SCSI 5375: * mid-level driver. The new interface, advansys_queuecommand(), 5376: * currently handles all requests. 5377: */ 5378: int 5379: advansys_command(Scsi_Cmnd *scp) 5380: { 5381: ASC_DBG1(1, "advansys_command: scp %x\n", (unsigned) scp); 5382: ASC_STATS(scp->host, command); 5383: scp->SCp.Status = 0; /* Set to a known state */ 5384: advansys_queuecommand(scp, advansys_command_done); 5385: while (scp->SCp.Status == 0) { 5386: continue; 5387: } 5388: ASC_DBG1(1, "advansys_command: result %x\n", scp->result); 5389: return scp->result; 5390: } 5391: 5392: /* 5393: * advansys_queuecommand() - interrupt-driven I/O entrypoint. 5394: * 5395: * This function always returns 0. Command return status is saved 5396: * in the 'scp' result field. 5397: */ 5398: int 5399: advansys_queuecommand(Scsi_Cmnd *scp, void (*done)(Scsi_Cmnd *)) 5400: { 5401: struct Scsi_Host *shp; 5402: asc_board_t *boardp; 1.1.1.2 ! root 5403: long flags; 1.1 root 5404: Scsi_Cmnd *done_scp; 5405: 5406: shp = scp->host; 5407: boardp = ASC_BOARDP(shp); 5408: ASC_STATS(shp, queuecommand); 5409: 5410: /* 5411: * Disable interrupts to preserve request ordering and provide 5412: * mutually exclusive access to global structures used to initiate 5413: * a request. 5414: */ 5415: save_flags(flags); 5416: cli(); 5417: 5418: /* 5419: * Block new commands while handling a reset or abort request. 5420: */ 5421: if (boardp->flags & (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) { 5422: if (boardp->flags & ASC_HOST_IN_RESET) { 5423: ASC_DBG1(1, 5424: "advansys_queuecommand: scp %x blocked for reset request\n", 5425: (unsigned) scp); 5426: scp->result = HOST_BYTE(DID_RESET); 5427: } else { 5428: ASC_DBG1(1, 5429: "advansys_queuecommand: scp %x blocked for abort request\n", 5430: (unsigned) scp); 5431: scp->result = HOST_BYTE(DID_ABORT); 5432: } 5433: 5434: /* 5435: * Add blocked requests to the board's 'done' queue. The queued 5436: * requests will be completed at the end of the abort or reset 5437: * handling. 5438: */ 5439: asc_enqueue(&boardp->done, scp, ASC_BACK); 5440: restore_flags(flags); 5441: return 0; 5442: } 5443: 5444: /* 5445: * Attempt to execute any waiting commands for the board. 5446: */ 5447: if (!ASC_QUEUE_EMPTY(&boardp->waiting)) { 5448: ASC_DBG(1, 5449: "advansys_queuecommand: before asc_execute_queue() waiting\n"); 5450: asc_execute_queue(&boardp->waiting); 5451: } 5452: 5453: /* 5454: * Save the function pointer to Linux mid-level 'done' function 5455: * and attempt to execute the command. 5456: * 5457: * If ASC_ERROR is returned the request has been added to the 5458: * board's 'active' queue and will be completed by the interrupt 5459: * handler. 5460: * 5461: * If ASC_BUSY is returned add the request to the board's per 5462: * target waiting list. 5463: * 5464: * If an error occurred, the request will have been placed on the 5465: * board's 'done' queue and must be completed before returning. 5466: */ 5467: scp->scsi_done = done; 5468: switch (asc_execute_scsi_cmnd(scp)) { 5469: case ASC_NOERROR: 5470: break; 5471: case ASC_BUSY: 5472: asc_enqueue(&boardp->waiting, scp, ASC_BACK); 5473: break; 5474: case ASC_ERROR: 5475: default: 5476: done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL); 5477: /* Interrupts could be enabled here. */ 5478: asc_scsi_done_list(done_scp); 5479: break; 5480: } 5481: 5482: restore_flags(flags); 5483: return 0; 5484: } 5485: 5486: /* 5487: * advansys_abort() 5488: * 5489: * Abort the command specified by 'scp'. 5490: */ 5491: int 5492: advansys_abort(Scsi_Cmnd *scp) 5493: { 5494: struct Scsi_Host *shp; 5495: asc_board_t *boardp; 5496: ASC_DVC_VAR *asc_dvc_varp; 5497: ADV_DVC_VAR *adv_dvc_varp; 1.1.1.2 ! root 5498: long flags; 1.1 root 5499: int do_scsi_done; 5500: int scp_found; 5501: Scsi_Cmnd *done_scp = NULL; 5502: int ret; 5503: 5504: /* Save current flags and disable interrupts. */ 5505: save_flags(flags); 5506: cli(); 5507: 5508: ASC_DBG1(1, "advansys_abort: scp %x\n", (unsigned) scp); 5509: 5510: #ifdef ADVANSYS_STATS 5511: if (scp->host != NULL) { 5512: ASC_STATS(scp->host, abort); 5513: } 5514: #endif /* ADVANSYS_STATS */ 5515: 5516: #ifdef ADVANSYS_ASSERT 5517: do_scsi_done = ASC_ERROR; 5518: scp_found = ASC_ERROR; 5519: ret = ASC_ERROR; 5520: #endif /* ADVANSYS_ASSERT */ 5521: 5522: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89) 5523: if (scp->serial_number != scp->serial_number_at_timeout) { 5524: ASC_PRINT1( 5525: "advansys_abort: timeout serial number changed for request %x\n", 5526: (unsigned) scp); 5527: do_scsi_done = ASC_FALSE; 5528: scp_found = ASC_FALSE; 5529: ret = SCSI_ABORT_NOT_RUNNING; 5530: } else 5531: #endif /* version >= v1.3.89 */ 5532: if ((shp = scp->host) == NULL) { 5533: scp->result = HOST_BYTE(DID_ERROR); 5534: do_scsi_done = ASC_TRUE; 5535: scp_found = ASC_FALSE; 5536: ret = SCSI_ABORT_ERROR; 5537: } else if ((boardp = ASC_BOARDP(shp))->flags & 5538: (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) { 5539: ASC_PRINT2( 5540: "advansys_abort: board %d: Nested host reset or abort, flags 0x%x\n", 5541: boardp->id, boardp->flags); 5542: do_scsi_done = ASC_TRUE; 5543: if ((asc_rmqueue(&boardp->active, scp) == ASC_TRUE) || 5544: (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE)) { 5545: scp_found = ASC_TRUE; 5546: } else { 5547: scp_found = ASC_FALSE; 5548: } 5549: scp->result = HOST_BYTE(DID_ERROR); 5550: ret = SCSI_ABORT_ERROR; 5551: } else { 5552: /* Set abort flag to avoid nested reset or abort requests. */ 5553: boardp->flags |= ASC_HOST_IN_ABORT; 5554: 5555: do_scsi_done = ASC_TRUE; 5556: if (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE) { 5557: /* 5558: * If asc_rmqueue() found the command on the waiting 5559: * queue, it had not been sent to the device. After 5560: * the queue is removed, no other handling is required. 5561: */ 5562: ASC_DBG1(1, "advansys_abort: scp %x found on waiting queue\n", 5563: (unsigned) scp); 5564: scp_found = ASC_TRUE; 5565: scp->result = HOST_BYTE(DID_ABORT); 5566: ret = SCSI_ABORT_SUCCESS; 5567: } else if (asc_isqueued(&boardp->active, scp) == ASC_TRUE) { 5568: /* 5569: * If asc_isqueued() found the command on the active 5570: * queue, it has been sent to the device. The command 5571: * will be returned through the interrupt handler after 5572: * it has been aborted. 5573: */ 5574: 5575: if (ASC_NARROW_BOARD(boardp)) { 5576: /* 5577: * Narrow Board 5578: */ 5579: asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; 5580: scp->result = HOST_BYTE(DID_ABORT); 5581: 5582: sti(); /* Enable interrupts for AscAbortSRB(). */ 5583: ASC_DBG1(1, "advansys_abort: before AscAbortSRB(), scp %x\n", 5584: (unsigned) scp); 5585: switch (AscAbortSRB(asc_dvc_varp, (ulong) scp)) { 5586: case ASC_TRUE: 5587: /* asc_isr_callback() will be called */ 5588: ASC_DBG(1, "advansys_abort: AscAbortSRB() TRUE\n"); 5589: ret = SCSI_ABORT_PENDING; 5590: break; 5591: case ASC_FALSE: 5592: /* Request has apparently already completed. */ 5593: ASC_DBG(1, "advansys_abort: AscAbortSRB() FALSE\n"); 5594: ret = SCSI_ABORT_NOT_RUNNING; 5595: break; 5596: case ASC_ERROR: 5597: default: 5598: ASC_DBG(1, "advansys_abort: AscAbortSRB() ERROR\n"); 5599: ret = SCSI_ABORT_ERROR; 5600: break; 5601: } 5602: cli(); 5603: } else { 5604: /* 5605: * Wide Board 5606: */ 5607: adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; 5608: scp->result = HOST_BYTE(DID_ABORT); 5609: 5610: ASC_DBG1(1, "advansys_abort: before AdvAbortSRB(), scp %x\n", 5611: (unsigned) scp); 5612: switch (AdvAbortSRB(adv_dvc_varp, (ulong) scp)) { 5613: case ASC_TRUE: 5614: /* asc_isr_callback() will be called */ 5615: ASC_DBG(1, "advansys_abort: AdvAbortSRB() TRUE\n"); 5616: ret = SCSI_ABORT_PENDING; 5617: break; 5618: case ASC_FALSE: 5619: /* Request has apparently already completed. */ 5620: ASC_DBG(1, "advansys_abort: AdvAbortSRB() FALSE\n"); 5621: ret = SCSI_ABORT_NOT_RUNNING; 5622: break; 5623: case ASC_ERROR: 5624: default: 5625: ASC_DBG(1, "advansys_abort: AdvAbortSRB() ERROR\n"); 5626: ret = SCSI_ABORT_ERROR; 5627: break; 5628: } 5629: /* 5630: * Ensure all requests completed by the microcode have 5631: * been processed by calling AdvISR(). 5632: */ 5633: (void) AdvISR(adv_dvc_varp); 5634: } 5635: 5636: /* 5637: * The request will either still be on the active queue 5638: * or have been added to the board's done queue. 5639: */ 5640: if (asc_rmqueue(&boardp->active, scp) == ASC_TRUE) { 5641: scp->result = HOST_BYTE(DID_ABORT); 5642: scp_found = ASC_TRUE; 5643: } else { 5644: scp_found = asc_rmqueue(&boardp->done, scp); 5645: ASC_ASSERT(scp_found == ASC_TRUE); 5646: } 5647: 5648: } else { 5649: /* 5650: * The command was not found on the active or waiting queues. 5651: */ 5652: do_scsi_done = ASC_TRUE; 5653: scp_found = ASC_FALSE; 5654: ret = SCSI_ABORT_NOT_RUNNING; 5655: } 5656: 5657: /* Clear abort flag. */ 5658: boardp->flags &= ~ASC_HOST_IN_ABORT; 5659: 5660: /* 5661: * Because the ASC_HOST_IN_ABORT flag causes both 5662: * 'advansys_interrupt' and 'asc_isr_callback' to 5663: * queue requests to the board's 'done' queue and 5664: * prevents waiting commands from being executed, 5665: * these queued requests must be handled here. 5666: */ 5667: done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL); 5668: 5669: /* 5670: * Start any waiting commands for the board. 5671: */ 5672: if (!ASC_QUEUE_EMPTY(&boardp->waiting)) { 5673: ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n"); 5674: asc_execute_queue(&boardp->waiting); 5675: } 5676: } 5677: 5678: /* Interrupts could be enabled here. */ 5679: 5680: /* 5681: * Complete the request to be aborted, unless it has been 5682: * restarted as detected above, even if it was not found on 5683: * the device active or waiting queues. 5684: */ 5685: ASC_ASSERT(do_scsi_done != ASC_ERROR); 5686: ASC_ASSERT(scp_found != ASC_ERROR); 5687: if (do_scsi_done == ASC_TRUE) { 5688: if (scp->scsi_done == NULL) { 5689: ASC_PRINT1( 5690: "advansys_abort: aborted request scsi_done() is NULL, %x\n", 5691: (unsigned) scp); 5692: } else { 5693: if (scp_found == ASC_FALSE) { 5694: ASC_PRINT1( 5695: "advansys_abort: abort request not active or waiting, completing anyway %x\n", 5696: (unsigned) scp); 5697: } 5698: ASC_STATS(scp->host, done); 5699: scp->scsi_done(scp); 5700: } 5701: } 5702: 5703: /* 5704: * It is possible for the request done function to re-enable 5705: * interrupts without confusing the driver. But here interrupts 5706: * aren't enabled until all requests have been completed. 5707: */ 5708: if (done_scp != NULL) { 5709: asc_scsi_done_list(done_scp); 5710: } 5711: 5712: ASC_DBG1(1, "advansys_abort: ret %d\n", ret); 5713: 5714: /* Re-enable interrupts, if they were enabled on entry. */ 5715: restore_flags(flags); 5716: 5717: ASC_ASSERT(ret != ASC_ERROR); 5718: return ret; 5719: } 5720: 5721: /* 5722: * advansys_reset() 5723: * 5724: * Reset the device associated with the command 'scp'. 5725: */ 5726: int 5727: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89) 5728: advansys_reset(Scsi_Cmnd *scp) 5729: #else /* version >= v1.3.89 */ 5730: advansys_reset(Scsi_Cmnd *scp, unsigned int reset_flags) 5731: #endif /* version >= v1.3.89 */ 5732: { 5733: struct Scsi_Host *shp; 5734: asc_board_t *boardp; 5735: ASC_DVC_VAR *asc_dvc_varp; 5736: ADV_DVC_VAR *adv_dvc_varp; 1.1.1.2 ! root 5737: long flags; 1.1 root 5738: Scsi_Cmnd *done_scp = NULL, *last_scp = NULL; 5739: Scsi_Cmnd *tscp, *new_last_scp; 5740: int do_scsi_done; 5741: int scp_found; 5742: int status; 5743: int target; 5744: int ret; 5745: int device_reset = ASC_FALSE; 5746: 5747: /* Save current flags and disable interrupts. */ 5748: save_flags(flags); 5749: cli(); 5750: 5751: ASC_DBG1(1, "advansys_reset: %x\n", (unsigned) scp); 5752: 5753: #ifdef ADVANSYS_STATS 5754: if (scp->host != NULL) { 5755: ASC_STATS(scp->host, reset); 5756: } 5757: #endif /* ADVANSYS_STATS */ 5758: 5759: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89) 5760: if ((reset_flags & SCSI_RESET_ASYNCHRONOUS) && 5761: (scp->serial_number != scp->serial_number_at_timeout)) { 5762: ASC_PRINT1( 5763: "advansys_reset: timeout serial number changed for request %x\n", 5764: (unsigned) scp); 5765: do_scsi_done = ASC_FALSE; 5766: scp_found = ASC_FALSE; 5767: ret = SCSI_RESET_NOT_RUNNING; 5768: } else 5769: #endif /* version >= v1.3.89 */ 5770: if ((shp = scp->host) == NULL) { 5771: scp->result = HOST_BYTE(DID_ERROR); 5772: do_scsi_done = ASC_TRUE; 5773: scp_found = ASC_FALSE; 5774: ret = SCSI_RESET_ERROR; 5775: } else if ((boardp = ASC_BOARDP(shp))->flags & 5776: (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) { 5777: ASC_PRINT2( 5778: "advansys_reset: board %d: Nested host reset or abort, flags 0x%x\n", 5779: boardp->id, boardp->flags); 5780: do_scsi_done = ASC_TRUE; 5781: if ((asc_rmqueue(&boardp->active, scp) == ASC_TRUE) || 5782: (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE)) { 5783: scp_found = ASC_TRUE; 5784: } else { 5785: scp_found = ASC_FALSE; 5786: } 5787: scp->result = HOST_BYTE(DID_ERROR); 5788: ret = SCSI_RESET_ERROR; 5789: } else if (jiffies >= boardp->last_reset && 5790: jiffies < (boardp->last_reset + (10 * HZ))) { 5791: /* 5792: * Don't allow a reset to be attempted within 10 seconds 5793: * of the last reset. 5794: * 5795: * If 'jiffies' wrapping occurs, the reset request will go 5796: * through, because a wrapped 'jiffies' would not pass the 5797: * test above. 5798: */ 5799: ASC_DBG(1, 5800: "advansys_reset: reset within 10 sec of last reset ignored\n"); 5801: do_scsi_done = ASC_TRUE; 5802: if ((asc_rmqueue(&boardp->active, scp) == ASC_TRUE) || 5803: (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE)) { 5804: scp_found = ASC_TRUE; 5805: } else { 5806: scp_found = ASC_FALSE; 5807: } 5808: scp->result = HOST_BYTE(DID_ERROR); 5809: ret = SCSI_RESET_ERROR; 5810: } else { 5811: do_scsi_done = ASC_TRUE; 5812: 5813: /* Set reset flag to avoid nested reset or abort requests. */ 5814: boardp->flags |= ASC_HOST_IN_RESET; 5815: 5816: /* 5817: * If the request is on the target waiting or active queue 5818: * or the board done queue, then remove it and note that it 5819: * was found. 5820: */ 5821: if (asc_rmqueue(&boardp->active, scp) == ASC_TRUE) { 5822: ASC_DBG(1, "advansys_reset: active scp_found = TRUE\n"); 5823: scp_found = ASC_TRUE; 5824: } else if (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE) { 5825: ASC_DBG(1, "advansys_reset: waiting scp_found = TRUE\n"); 5826: scp_found = ASC_TRUE; 5827: } else if (asc_rmqueue(&boardp->done, scp) == ASC_TRUE) { 5828: scp_found = ASC_TRUE; 5829: } else { 5830: scp_found = ASC_FALSE; 5831: } 5832: 5833: 5834: if (ASC_NARROW_BOARD(boardp)) { 5835: /* 5836: * Narrow Board 5837: * 5838: * If the suggest reset bus flags are set, then reset the bus. 5839: * Otherwise only reset the device. 5840: */ 5841: asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; 5842: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89) 5843: if (reset_flags & 5844: (SCSI_RESET_SUGGEST_BUS_RESET | 5845: SCSI_RESET_SUGGEST_HOST_RESET)) { 5846: #endif /* version >= v1.3.89 */ 5847: 5848: /* 5849: * Reset the target's SCSI bus. 5850: */ 5851: ASC_DBG(1, "advansys_reset: before AscResetSB()\n"); 5852: sti(); /* Enable interrupts for AscResetSB(). */ 5853: status = AscResetSB(asc_dvc_varp); 5854: cli(); 5855: switch (status) { 5856: case ASC_TRUE: 5857: ASC_DBG(1, "advansys_reset: AscResetSB() success\n"); 5858: ret = SCSI_RESET_SUCCESS; 5859: break; 5860: case ASC_ERROR: 5861: default: 5862: ASC_DBG(1, "advansys_reset: AscResetSB() failed\n"); 5863: ret = SCSI_RESET_ERROR; 5864: break; 5865: } 5866: 5867: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89) 5868: } else { 5869: /* 5870: * Reset the specified device. If the device reset fails, 5871: * then reset the SCSI bus. 5872: */ 5873: 5874: ASC_DBG1(1, 5875: "advansys_reset: before AscResetDevice(), target %d\n", 5876: scp->target); 5877: sti(); /* Enable interrupts for AscResetDevice(). */ 5878: status = AscResetDevice(asc_dvc_varp, scp->target); 5879: cli(); 5880: 5881: switch (status) { 5882: case ASC_TRUE: 5883: ASC_DBG(1, "advansys_reset: AscResetDevice() success\n"); 5884: device_reset = ASC_TRUE; 5885: ret = SCSI_RESET_SUCCESS; 5886: break; 5887: case ASC_ERROR: 5888: default: 5889: ASC_DBG(1, 5890: "advansys_reset: AscResetDevice() failed; Calling AscResetSB()\n"); 5891: sti(); /* Enable interrupts for AscResetSB(). */ 5892: status = AscResetSB(asc_dvc_varp); 5893: cli(); 5894: switch (status) { 5895: case ASC_TRUE: 5896: ASC_DBG(1, "advansys_reset: AscResetSB() TRUE\n"); 5897: ret = SCSI_RESET_SUCCESS; 5898: break; 5899: case ASC_ERROR: 5900: default: 5901: ASC_DBG(1, "advansys_reset: AscResetSB() ERROR\n"); 5902: ret = SCSI_RESET_ERROR; 5903: break; 5904: } 5905: break; 5906: } 5907: } 5908: #endif /* version >= v1.3.89 */ 5909: } else { 5910: /* 5911: * Wide Board 5912: * 5913: * If the suggest reset bus flags are set, then reset the bus. 5914: * Otherwise only reset the device. 5915: */ 5916: adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; 5917: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89) 5918: if (reset_flags & 5919: (SCSI_RESET_SUGGEST_BUS_RESET | 5920: SCSI_RESET_SUGGEST_HOST_RESET)) { 5921: #endif /* version >= v1.3.89 */ 5922: 5923: /* 5924: * Reset the target's SCSI bus. 5925: */ 5926: ASC_DBG(1, "advansys_reset: before AdvResetSB()\n"); 5927: switch (AdvResetSB(adv_dvc_varp)) { 5928: case ASC_TRUE: 5929: ASC_DBG(1, "advansys_reset: AdvResetSB() success\n"); 5930: ret = SCSI_RESET_SUCCESS; 5931: break; 5932: case ASC_FALSE: 5933: default: 5934: ASC_DBG(1, "advansys_reset: AdvResetSB() failed\n"); 5935: ret = SCSI_RESET_ERROR; 5936: break; 5937: } 5938: /* 5939: * Ensure all requests completed by the microcode have 5940: * been processed by calling AdvISR(). 5941: */ 5942: (void) AdvISR(adv_dvc_varp); 5943: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89) 5944: } else { 5945: /* 5946: * Reset the specified device. If the device reset fails, 5947: * then reset the SCSI bus. 5948: */ 5949: 5950: ASC_DBG1(1, 5951: "advansys_reset: before AdvResetDevice(), target %d\n", 5952: scp->target); 5953: 5954: switch (AdvResetDevice(adv_dvc_varp, scp->target)) { 5955: case ASC_TRUE: 5956: ASC_DBG(1, "advansys_reset: AdvResetDevice() success\n"); 5957: device_reset = ASC_TRUE; 5958: ret = SCSI_RESET_SUCCESS; 5959: break; 5960: case ASC_FALSE: 5961: default: 5962: ASC_DBG(1, 5963: "advansys_reset: AdvResetDevice() failed; Calling AdvResetSB()\n"); 5964: 5965: switch (AdvResetSB(adv_dvc_varp)) { 5966: case ASC_TRUE: 5967: ASC_DBG(1, "advansys_reset: AdvResetSB() TRUE\n"); 5968: ret = SCSI_RESET_SUCCESS; 5969: break; 5970: case ASC_FALSE: 5971: default: 5972: ASC_DBG(1, "advansys_reset: AdvResetSB() ERROR\n"); 5973: ret = SCSI_RESET_ERROR; 5974: break; 5975: } 5976: break; 5977: } 5978: /* 5979: * Ensure all requests completed by the microcode have 5980: * been processed by calling AdvISR(). 5981: */ 5982: (void) AdvISR(adv_dvc_varp); 5983: } 5984: #endif /* version >= v1.3.89 */ 5985: } 5986: 5987: /* 5988: * Because the ASC_HOST_IN_RESET flag causes both 5989: * 'advansys_interrupt' and 'asc_isr_callback' to 5990: * queue requests to the board's 'done' queue and 5991: * prevents waiting commands from being executed, 5992: * these queued requests must be handled here. 5993: */ 5994: done_scp = asc_dequeue_list(&boardp->done, &last_scp, 5995: ASC_TID_ALL); 5996: 5997: /* 5998: * If a device reset was performed dequeue all waiting 5999: * and active requests for the device and set the request 6000: * status to DID_RESET. 6001: * 6002: * If a SCSI bus reset was performed dequeue all waiting 6003: * and active requests for all devices and set the request 6004: * status to DID_RESET. 6005: */ 6006: if (device_reset == ASC_TRUE) { 6007: target = scp->target; 6008: } else { 6009: target = ASC_TID_ALL; 6010: } 6011: 6012: /* 6013: * Add active requests to 'done_scp' and set the request status 6014: * to DID_RESET. 6015: */ 6016: if (done_scp == NULL) { 6017: done_scp = asc_dequeue_list(&boardp->active, &last_scp, target); 1.1.1.2 ! root 6018: for (tscp = done_scp; tscp; tscp = (REQP) REQPNEXT(tscp)) { 1.1 root 6019: tscp->result = HOST_BYTE(DID_RESET); 6020: } 6021: } else { 6022: ASC_ASSERT(last_scp != NULL); 1.1.1.2 ! root 6023: REQPNEXT(last_scp) = ! 6024: (unsigned char *) asc_dequeue_list(&boardp->active, ! 6025: &new_last_scp, target); ! 6026: if (new_last_scp != (Scsi_Cmnd *) NULL) { ! 6027: ASC_ASSERT((REQP) REQPNEXT(last_scp) != NULL); ! 6028: for (tscp = (Scsi_Cmnd *) REQPNEXT(last_scp); ! 6029: tscp; ! 6030: tscp = (Scsi_Cmnd *) REQPNEXT(tscp)) { 1.1 root 6031: tscp->result = HOST_BYTE(DID_RESET); 6032: } 6033: last_scp = new_last_scp; 6034: } 6035: } 6036: 6037: /* 6038: * Add waiting requests to 'done_scp' and set the request status 6039: * to DID_RESET. 6040: */ 6041: if (done_scp == NULL) { 6042: done_scp = asc_dequeue_list(&boardp->waiting, &last_scp, target); 1.1.1.2 ! root 6043: for (tscp = done_scp; tscp; tscp = (REQP) REQPNEXT(tscp)) { 1.1 root 6044: tscp->result = HOST_BYTE(DID_RESET); 6045: } 6046: } else { 6047: ASC_ASSERT(last_scp != NULL); 1.1.1.2 ! root 6048: REQPNEXT(last_scp) = ! 6049: (unsigned char *) asc_dequeue_list(&boardp->waiting, ! 6050: &new_last_scp, target); 1.1 root 6051: if (new_last_scp != NULL) { 1.1.1.2 ! root 6052: ASC_ASSERT((REQP) REQPNEXT(last_scp) != NULL); ! 6053: for (tscp = (REQP) REQPNEXT(last_scp); ! 6054: tscp; ! 6055: tscp = (REQP) REQPNEXT(tscp)) { 1.1 root 6056: tscp->result = HOST_BYTE(DID_RESET); 6057: } 6058: last_scp = new_last_scp; 6059: } 6060: } 6061: 6062: /* Save the time of the most recently completed reset. */ 6063: boardp->last_reset = jiffies; 6064: 6065: /* Clear reset flag. */ 6066: boardp->flags &= ~ASC_HOST_IN_RESET; 6067: 6068: /* 6069: * Start any waiting commands for the board. 6070: */ 6071: if (!ASC_QUEUE_EMPTY(&boardp->waiting)) { 6072: ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n"); 6073: asc_execute_queue(&boardp->waiting); 6074: } 6075: ret = SCSI_RESET_SUCCESS; 6076: } 6077: 6078: /* Interrupts could be enabled here. */ 6079: 6080: ASC_ASSERT(do_scsi_done != ASC_ERROR); 6081: ASC_ASSERT(scp_found != ASC_ERROR); 6082: if (do_scsi_done == ASC_TRUE) { 6083: if (scp->scsi_done == NULL) { 6084: ASC_PRINT1( 6085: "advansys_reset: reset request scsi_done() is NULL, %x\n", 6086: (unsigned) scp); 6087: } else { 6088: if (scp_found == ASC_FALSE) { 6089: ASC_PRINT1( 6090: "advansys_reset: reset request not active or waiting, completing anyway %x\n", 6091: (unsigned) scp); 6092: } 6093: ASC_STATS(scp->host, done); 6094: scp->scsi_done(scp); 6095: } 6096: } 6097: 6098: /* 6099: * It is possible for the request done function to re-enable 6100: * interrupts without confusing the driver. But here interrupts 6101: * aren't enabled until requests have been completed. 6102: */ 6103: if (done_scp != NULL) { 6104: asc_scsi_done_list(done_scp); 6105: } 6106: 6107: ASC_DBG1(1, "advansys_reset: ret %d\n", ret); 6108: 6109: /* Re-enable interrupts, if they were enabled on entry. */ 6110: restore_flags(flags); 6111: 6112: ASC_ASSERT(ret != ASC_ERROR); 6113: return ret; 6114: } 6115: 6116: /* 6117: * advansys_biosparam() 6118: * 6119: * Translate disk drive geometry if the "BIOS greater than 1 GB" 6120: * support is enabled for a drive. 6121: * 6122: * ip (information pointer) is an int array with the following definition: 6123: * ip[0]: heads 6124: * ip[1]: sectors 6125: * ip[2]: cylinders 6126: */ 6127: int 6128: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0) 6129: advansys_biosparam(Disk *dp, int dep, int ip[]) 6130: #else /* version >= v1.3.0 */ 6131: advansys_biosparam(Disk *dp, kdev_t dep, int ip[]) 6132: #endif /* version >= v1.3.0 */ 6133: { 6134: asc_board_t *boardp; 6135: 6136: ASC_DBG(1, "advansys_biosparam: begin\n"); 6137: ASC_STATS(dp->device->host, biosparam); 6138: boardp = ASC_BOARDP(dp->device->host); 6139: if (ASC_NARROW_BOARD(boardp)) { 6140: if ((boardp->dvc_var.asc_dvc_var.dvc_cntl & 6141: ASC_CNTL_BIOS_GT_1GB) && dp->capacity > 0x200000) { 6142: ip[0] = 255; 6143: ip[1] = 63; 6144: } else { 6145: ip[0] = 64; 6146: ip[1] = 32; 6147: } 6148: } else { 6149: if ((boardp->dvc_var.adv_dvc_var.bios_ctrl & 6150: BIOS_CTRL_EXTENDED_XLAT) && dp->capacity > 0x200000) { 6151: ip[0] = 255; 6152: ip[1] = 63; 6153: } else { 6154: ip[0] = 64; 6155: ip[1] = 32; 6156: } 6157: } 6158: ip[2] = dp->capacity / (ip[0] * ip[1]); 6159: ASC_DBG(1, "advansys_biosparam: end\n"); 6160: return 0; 6161: } 6162: 6163: /* 6164: * advansys_setup() 6165: * 6166: * This function is called from init/main.c at boot time. 6167: * It it passed LILO parameters that can be set from the 6168: * LILO command line or in /etc/lilo.conf. 6169: * 6170: * It is used by the AdvanSys driver to either disable I/O 6171: * port scanning or to limit scanning to 1 - 4 I/O ports. 6172: * Regardless of the option setting EISA and PCI boards 6173: * will still be searched for and detected. This option 6174: * only affects searching for ISA and VL boards. 6175: * 6176: * If ADVANSYS_DEBUG is defined the driver debug level may 6177: * be set using the 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. 6178: * 6179: * Examples: 6180: * 1. Eliminate I/O port scanning: 6181: * boot: linux advansys= 6182: * or 6183: * boot: linux advansys=0x0 6184: * 2. Limit I/O port scanning to one I/O port: 6185: * boot: linux advansys=0x110 6186: * 3. Limit I/O port scanning to four I/O ports: 6187: * boot: linux advansys=0x110,0x210,0x230,0x330 6188: * 4. If ADVANSYS_DEBUG, limit I/O port scanning to four I/O ports and 6189: * set the driver debug level to 2. 6190: * boot: linux advansys=0x110,0x210,0x230,0x330,0xdeb2 6191: * 6192: * ints[0] - number of arguments 6193: * ints[1] - first argument 6194: * ints[2] - second argument 6195: * ... 6196: */ 6197: ASC_INITFUNC( 6198: void 6199: advansys_setup(char *str, int *ints) 6200: ) 6201: { 6202: int i; 6203: 6204: if (asc_iopflag == ASC_TRUE) { 6205: printk("AdvanSys SCSI: 'advansys' LILO option may appear only once\n"); 6206: return; 6207: } 6208: 6209: asc_iopflag = ASC_TRUE; 6210: 6211: if (ints[0] > ASC_NUM_IOPORT_PROBE) { 6212: #ifdef ADVANSYS_DEBUG 6213: if ((ints[0] == ASC_NUM_IOPORT_PROBE + 1) && 6214: (ints[ASC_NUM_IOPORT_PROBE + 1] >> 4 == 0xdeb)) { 6215: asc_dbglvl = ints[ASC_NUM_IOPORT_PROBE + 1] & 0xf; 6216: } else { 6217: #endif /* ADVANSYS_DEBUG */ 6218: printk("AdvanSys SCSI: only %d I/O ports accepted\n", 6219: ASC_NUM_IOPORT_PROBE); 6220: #ifdef ADVANSYS_DEBUG 6221: } 6222: #endif /* ADVANSYS_DEBUG */ 6223: } 6224: 6225: #ifdef ADVANSYS_DEBUG 6226: ASC_DBG1(1, "advansys_setup: ints[0] %d\n", ints[0]); 6227: for (i = 1; i < ints[0]; i++) { 6228: ASC_DBG2(1, " ints[%d] %x", i, ints[i]); 6229: } 6230: ASC_DBG(1, "\n"); 6231: #endif /* ADVANSYS_DEBUG */ 6232: 6233: for (i = 1; i <= ints[0] && i <= ASC_NUM_IOPORT_PROBE; i++) { 6234: asc_ioport[i-1] = ints[i]; 6235: ASC_DBG2(1, "advansys_setup: asc_ioport[%d] %x\n", 6236: i - 1, asc_ioport[i-1]); 6237: } 6238: } 6239: 6240: 6241: /* 6242: * --- Loadable Driver Support 6243: */ 6244: 6245: #ifdef MODULE 6246: Scsi_Host_Template driver_template = ADVANSYS; 6247: # include "scsi_module.c" 6248: #endif /* MODULE */ 6249: 6250: 6251: /* 6252: * --- Miscellaneous Driver Functions 6253: */ 6254: 6255: /* 6256: * First-level interrupt handler. 6257: * 6258: * For versions > v1.3.70, 'dev_id' is a pointer to the interrupting 6259: * adapter's asc_board_t. Because all boards are currently checked 6260: * for interrupts on each interrupt, 'dev_id' is not referenced. 'dev_id' 6261: * could be used to identify an interrupt passed to the AdvanSys driver, 6262: * which is for a device sharing an interrupt with an AdvanSys adapter. 6263: */ 6264: STATIC void 6265: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70) 6266: advansys_interrupt(int irq, struct pt_regs *regs) 6267: #else /* version >= v1.3.70 */ 6268: advansys_interrupt(int irq, void *dev_id, struct pt_regs *regs) 6269: #endif /* version >= v1.3.70 */ 6270: { 6271: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,95) 1.1.1.2 ! root 6272: long flags; 1.1 root 6273: #else /* version >= v2.1.95 */ 6274: unsigned long flags; 6275: #endif /* version >= v2.1.95 */ 6276: int i; 6277: asc_board_t *boardp; 6278: Scsi_Cmnd *done_scp = NULL, *last_scp = NULL; 6279: Scsi_Cmnd *new_last_scp; 6280: 6281: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,95) 6282: /* Disable interrupts, if they aren't already disabled. */ 6283: save_flags(flags); 6284: cli(); 6285: #else /* version >= v2.1.95 */ 6286: /* 6287: * Disable interrupts, if they aren't already disabled and acquire 6288: * the I/O spinlock. 6289: */ 6290: spin_lock_irqsave(&io_request_lock, flags); 6291: #endif /* version >= v2.1.95 */ 6292: 6293: ASC_DBG(1, "advansys_interrupt: begin\n"); 6294: 6295: /* 6296: * Check for interrupts on all boards. 6297: * AscISR() will call asc_isr_callback(). 6298: */ 6299: for (i = 0; i < asc_board_count; i++) { 6300: boardp = ASC_BOARDP(asc_host[i]); 6301: ASC_DBG2(2, "advansys_interrupt: i %d, boardp %lx\n", 6302: i, (ulong) boardp) 6303: if (ASC_NARROW_BOARD(boardp)) { 6304: /* 6305: * Narrow Board 6306: */ 6307: if (AscIsIntPending(asc_host[i]->io_port)) { 6308: ASC_STATS(asc_host[i], interrupt); 6309: ASC_DBG(1, "advansys_interrupt: before AscISR()\n"); 6310: AscISR(&boardp->dvc_var.asc_dvc_var); 6311: } 6312: } else { 6313: /* 6314: * Wide Board 6315: */ 6316: ASC_DBG(1, "advansys_interrupt: before AdvISR()\n"); 6317: if (AdvISR(&boardp->dvc_var.adv_dvc_var)) { 6318: ASC_STATS(asc_host[i], interrupt); 6319: } 6320: } 6321: 6322: /* 6323: * Start waiting requests and create a list of completed requests. 6324: * 6325: * If a reset or abort request is being performed for the board, 6326: * the reset or abort handler will complete pending requests after 6327: * it has completed. 6328: */ 6329: if ((boardp->flags & (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) == 0) { 6330: ASC_DBG2(1, "advansys_interrupt: done_scp %lx, last_scp %lx\n", 6331: (ulong) done_scp, (ulong) last_scp); 6332: 6333: /* Start any waiting commands for the board. */ 6334: if (!ASC_QUEUE_EMPTY(&boardp->waiting)) { 6335: ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n"); 6336: asc_execute_queue(&boardp->waiting); 6337: } 6338: 6339: /* 6340: * Add to the list of requests that must be completed. 6341: * 6342: * 'done_scp' will always be NULL on the first iteration 6343: * of this loop. 'last_scp' is set at the same time as 6344: * 'done_scp'. 6345: */ 6346: if (done_scp == NULL) { 6347: done_scp = asc_dequeue_list(&boardp->done, &last_scp, 6348: ASC_TID_ALL); 6349: } else { 6350: ASC_ASSERT(last_scp != NULL); 1.1.1.2 ! root 6351: REQPNEXT(last_scp) = ! 6352: (unsigned char *) asc_dequeue_list(&boardp->done, ! 6353: &new_last_scp, ! 6354: ASC_TID_ALL); 1.1 root 6355: if (new_last_scp != NULL) { 6356: ASC_ASSERT(REQPNEXT(last_scp) != NULL); 6357: last_scp = new_last_scp; 6358: } 6359: } 6360: } 6361: } 6362: 6363: /* Interrupts could be enabled here. */ 6364: 6365: /* 6366: * It is possible for the request done function to re-enable 6367: * interrupts without confusing the driver. But here the 6368: * original flags aren't restored until all requests have been 6369: * completed. 6370: */ 6371: asc_scsi_done_list(done_scp); 6372: 6373: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,95) 6374: /* 6375: * Restore the original flags which will enable interrupts 6376: * if and only if they were enabled on entry. 6377: */ 6378: restore_flags(flags); 6379: #else /* version >= v2.1.95 */ 6380: /* 6381: * Release the I/O spinlock and restore the original flags 6382: * which will enable interrupts if and only if they were 6383: * enabled on entry. 6384: */ 6385: spin_unlock_irqrestore(&io_request_lock, flags); 6386: #endif /* version >= v2.1.95 */ 6387: 6388: ASC_DBG(1, "advansys_interrupt: end\n"); 6389: return; 6390: } 6391: 6392: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89) 6393: /* 6394: * Set the number of commands to queue per device for the 6395: * specified host adapter. 6396: */ 6397: STATIC void 6398: advansys_select_queue_depths(struct Scsi_Host *shp, Scsi_Device *devicelist) 6399: { 6400: Scsi_Device *device; 6401: asc_board_t *boardp; 6402: 6403: boardp = ASC_BOARDP(shp); 6404: boardp->flags |= ASC_SELECT_QUEUE_DEPTHS; 6405: for (device = devicelist; device != NULL; device = device->next) { 6406: if (device->host != shp) { 6407: continue; 6408: } 6409: /* 6410: * Save a pointer to the device and set its initial/maximum 6411: * queue depth. 6412: */ 6413: boardp->device[device->id] = device; 6414: if (ASC_NARROW_BOARD(boardp)) { 6415: device->queue_depth = 6416: boardp->dvc_var.asc_dvc_var.max_dvc_qng[device->id]; 6417: } else { 6418: device->queue_depth = 6419: boardp->dvc_var.adv_dvc_var.max_dvc_qng; 6420: } 6421: ASC_DBG3(1, "advansys_select_queue_depths: shp %x, id %d, depth %d\n", 6422: (unsigned) shp, device->id, device->queue_depth); 6423: } 6424: } 6425: #endif /* version >= v1.3.89 */ 6426: 6427: /* 6428: * Function used only with polled I/O requests that are initiated by 6429: * advansys_command(). 6430: */ 6431: STATIC void 6432: advansys_command_done(Scsi_Cmnd *scp) 6433: { 6434: ASC_DBG1(1, "advansys_command_done: scp %x\n", (unsigned) scp); 6435: scp->SCp.Status = 1; 6436: } 6437: 6438: /* 6439: * Complete all requests on the singly linked list pointed 6440: * to by 'scp'. 6441: * 6442: * Interrupts can be enabled on entry. 6443: */ 6444: STATIC void 6445: asc_scsi_done_list(Scsi_Cmnd *scp) 6446: { 6447: Scsi_Cmnd *tscp; 6448: 6449: ASC_DBG(2, "asc_scsi_done_list: begin\n"); 6450: while (scp != NULL) { 6451: ASC_DBG1(3, "asc_scsi_done_list: scp %x\n", (unsigned) scp); 1.1.1.2 ! root 6452: tscp = (REQP) REQPNEXT(scp); 1.1 root 6453: REQPNEXT(scp) = NULL; 6454: ASC_STATS(scp->host, done); 6455: ASC_ASSERT(scp->scsi_done != NULL); 6456: scp->scsi_done(scp); 6457: scp = tscp; 6458: } 6459: ASC_DBG(2, "asc_scsi_done_list: done\n"); 6460: return; 6461: } 6462: 6463: /* 6464: * Execute a single 'Scsi_Cmnd'. 6465: * 6466: * The function 'done' is called when the request has been completed. 6467: * 6468: * Scsi_Cmnd: 6469: * 6470: * host - board controlling device 6471: * device - device to send command 6472: * target - target of device 6473: * lun - lun of device 6474: * cmd_len - length of SCSI CDB 6475: * cmnd - buffer for SCSI 8, 10, or 12 byte CDB 6476: * use_sg - if non-zero indicates scatter-gather request with use_sg elements 6477: * 6478: * if (use_sg == 0) { 6479: * request_buffer - buffer address for request 6480: * request_bufflen - length of request buffer 6481: * } else { 6482: * request_buffer - pointer to scatterlist structure 6483: * } 6484: * 6485: * sense_buffer - sense command buffer 6486: * 6487: * result (4 bytes of an int): 6488: * Byte Meaning 6489: * 0 SCSI Status Byte Code 6490: * 1 SCSI One Byte Message Code 6491: * 2 Host Error Code 6492: * 3 Mid-Level Error Code 6493: * 6494: * host driver fields: 6495: * SCp - Scsi_Pointer used for command processing status 6496: * scsi_done - used to save caller's done function 6497: * host_scribble - used for pointer to another Scsi_Cmnd 6498: * 6499: * If this function returns ASC_NOERROR or ASC_ERROR the request 6500: * has been enqueued on the board's 'done' queue and must be 6501: * completed by the caller. 6502: * 6503: * If ASC_BUSY is returned the request must be enqueued by the 6504: * caller and re-tried later. 6505: */ 6506: STATIC int 6507: asc_execute_scsi_cmnd(Scsi_Cmnd *scp) 6508: { 6509: asc_board_t *boardp; 6510: ASC_DVC_VAR *asc_dvc_varp; 6511: ADV_DVC_VAR *adv_dvc_varp; 6512: ADV_SCSI_REQ_Q *adv_scsiqp; 6513: Scsi_Device *device; 6514: int ret; 6515: 6516: ASC_ASSERT(interrupts_enabled() == ASC_FALSE); 6517: ASC_DBG2(1, "asc_execute_scsi_cmnd: scp %x, done %x\n", 6518: (unsigned) scp, (unsigned) scp->scsi_done); 6519: 6520: boardp = ASC_BOARDP(scp->host); 6521: device = boardp->device[scp->target]; 6522: 6523: if (ASC_NARROW_BOARD(boardp)) { 6524: /* 6525: * Build and execute Narrow Board request. 6526: */ 6527: 6528: asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; 6529: 6530: /* 6531: * Build Asc Library request structure using the 6532: * global structures 'asc_scsi_req' and 'asc_sg_head'. 6533: * 6534: * asc_build_req() can not return ASC_BUSY. 6535: */ 6536: if (asc_build_req(boardp, scp) == ASC_ERROR) { 6537: ASC_STATS(scp->host, build_error); 6538: return ASC_ERROR; 6539: } 6540: 6541: /* 6542: * Execute the command. If there is no error, add the command 6543: * to the active queue. 6544: */ 6545: switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) { 6546: case ASC_NOERROR: 6547: ASC_STATS(scp->host, exe_noerror); 6548: /* 6549: * Increment monotonically increasing per device successful 6550: * request counter. Wrapping doesn't matter. 6551: */ 6552: boardp->reqcnt[scp->target]++; 6553: 6554: #if ASC_QUEUE_FLOW_CONTROL 6555: /* 6556: * Conditionally increment the device queue depth. 6557: * 6558: * If no error occurred and there have been 100 consecutive 6559: * successful requests and the current queue depth is less 6560: * than the maximum queue depth, then increment the current 6561: * queue depth. 6562: */ 6563: if (boardp->nerrcnt[scp->target]++ > 100) { 6564: boardp->nerrcnt[scp->target] = 0; 6565: if (device != NULL && 6566: (device->queue_curr_depth < device->queue_depth) && 6567: (!(boardp->queue_full & 6568: ADV_TID_TO_TIDMASK(scp->target)) || 6569: (boardp->queue_full_cnt[scp->target] > 6570: device->queue_curr_depth))) { 6571: device->queue_curr_depth++; 6572: } 6573: } 6574: #endif /* ASC_QUEUE_FLOW_CONTROL */ 6575: asc_enqueue(&boardp->active, scp, ASC_BACK); 6576: ASC_DBG(1, 6577: "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n"); 6578: break; 6579: case ASC_BUSY: 6580: /* Caller must enqueue request and retry later. */ 6581: ASC_STATS(scp->host, exe_busy); 6582: #if ASC_QUEUE_FLOW_CONTROL 6583: /* 6584: * Clear consecutive no error counter and if possible decrement 6585: * queue depth. 6586: */ 6587: boardp->nerrcnt[scp->target] = 0; 6588: if (device != NULL && device->queue_curr_depth > 1) { 6589: device->queue_curr_depth--; 6590: } 6591: #endif /* ASC_QUEUE_FLOW_CONTROL */ 6592: break; 6593: case ASC_ERROR: 6594: ASC_PRINT2( 6595: "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code %x\n", 6596: boardp->id, asc_dvc_varp->err_code); 6597: ASC_STATS(scp->host, exe_error); 6598: #if ASC_QUEUE_FLOW_CONTROL 6599: /* Clear consecutive no error counter. */ 6600: boardp->nerrcnt[scp->target] = 0; 6601: #endif /* ASC_QUEUE_FLOW_CONTROL */ 6602: scp->result = HOST_BYTE(DID_ERROR); 6603: asc_enqueue(&boardp->done, scp, ASC_BACK); 6604: break; 6605: default: 6606: ASC_PRINT2( 6607: "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code %x\n", 6608: boardp->id, asc_dvc_varp->err_code); 6609: ASC_STATS(scp->host, exe_unknown); 6610: #if ASC_QUEUE_FLOW_CONTROL 6611: /* Clear consecutive no error counter. */ 6612: boardp->nerrcnt[scp->target] = 0; 6613: #endif /* ASC_QUEUE_FLOW_CONTROL */ 6614: scp->result = HOST_BYTE(DID_ERROR); 6615: asc_enqueue(&boardp->done, scp, ASC_BACK); 6616: break; 6617: } 6618: } else { 6619: /* 6620: * Build and execute Wide Board request. 6621: */ 6622: adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; 6623: 6624: /* 6625: * Build and get a pointer to an Adv Library request structure. 6626: * 6627: * If the request is successfully built then send it below, 6628: * otherwise return with an error. 6629: */ 6630: switch (adv_build_req(boardp, scp, &adv_scsiqp)) { 6631: case ASC_NOERROR: 6632: ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n"); 6633: break; 6634: case ASC_BUSY: 6635: ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n"); 6636: return ASC_BUSY; 6637: case ASC_ERROR: 6638: default: 6639: ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n"); 6640: ASC_STATS(scp->host, build_error); 6641: return ASC_ERROR; 6642: } 6643: 6644: /* 6645: * Execute the command. If there is no error, add the command 6646: * to the active queue. 6647: */ 6648: switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) { 6649: case ASC_NOERROR: 6650: ASC_STATS(scp->host, exe_noerror); 6651: /* 6652: * Increment monotonically increasing per device successful 6653: * request counter. Wrapping doesn't matter. 6654: */ 6655: boardp->reqcnt[scp->target]++; 6656: asc_enqueue(&boardp->active, scp, ASC_BACK); 6657: ASC_DBG(1, 6658: "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n"); 6659: break; 6660: case ASC_BUSY: 6661: /* Caller must enqueue request and retry later. */ 6662: ASC_STATS(scp->host, exe_busy); 6663: break; 6664: case ASC_ERROR: 6665: ASC_PRINT2( 6666: "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code %x\n", 6667: boardp->id, adv_dvc_varp->err_code); 6668: ASC_STATS(scp->host, exe_error); 6669: scp->result = HOST_BYTE(DID_ERROR); 6670: asc_enqueue(&boardp->done, scp, ASC_BACK); 6671: break; 6672: default: 6673: ASC_PRINT2( 6674: "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code %x\n", 6675: boardp->id, adv_dvc_varp->err_code); 6676: ASC_STATS(scp->host, exe_unknown); 6677: scp->result = HOST_BYTE(DID_ERROR); 6678: asc_enqueue(&boardp->done, scp, ASC_BACK); 6679: break; 6680: } 6681: } 6682: 6683: ASC_DBG(1, "asc_execute_scsi_cmnd: end\n"); 6684: ASC_ASSERT(interrupts_enabled() == ASC_FALSE); 6685: return ret; 6686: } 6687: 6688: /* 6689: * Build a request structure for the Asc Library (Narrow Board). 6690: * 6691: * The global structures 'asc_scsi_q' and 'asc_sg_head' are 6692: * used to build the request. 6693: * 6694: * If an error occurs, then return ASC_ERROR. 6695: */ 6696: STATIC int 6697: asc_build_req(asc_board_t *boardp, Scsi_Cmnd *scp) 6698: { 6699: /* 6700: * Mutually exclusive access is required to 'asc_scsi_q' and 6701: * 'asc_sg_head' until after the request is started. 6702: */ 6703: memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q)); 6704: 6705: /* 6706: * Point the ASC_SCSI_Q to the 'Scsi_Cmnd'. 6707: */ 6708: asc_scsi_q.q2.srb_ptr = (ulong) scp; 6709: 6710: /* 6711: * Build the ASC_SCSI_Q request. 6712: */ 6713: ASC_ASSERT(scp->cmd_len <= ASC_MAX_CDB_LEN); 6714: if (scp->cmd_len > ASC_MAX_CDB_LEN) { 6715: scp->cmd_len = ASC_MAX_CDB_LEN; 6716: } 6717: asc_scsi_q.cdbptr = &scp->cmnd[0]; 6718: asc_scsi_q.q2.cdb_len = scp->cmd_len; 6719: asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->target); 6720: asc_scsi_q.q1.target_lun = scp->lun; 6721: asc_scsi_q.q2.target_ix = ASC_TIDLUN_TO_IX(scp->target, scp->lun); 6722: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0) 6723: asc_scsi_q.q1.sense_addr = (ulong) &scp->sense_buffer[0]; 6724: #else /* version >= v2.0.0 */ 6725: asc_scsi_q.q1.sense_addr = virt_to_bus(&scp->sense_buffer[0]); 6726: #endif /* version >= v2.0.0 */ 6727: asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer); 6728: 6729: /* 6730: * If there are any outstanding requests for the current target, 6731: * then every 255th request send an ORDERED request. This heuristic 6732: * tries to retain the benefit of request sorting while preventing 6733: * request starvation. 255 is the max number of tags or pending commands 6734: * a device may have outstanding. 6735: * 6736: * The request count is incremented below for every successfully 6737: * started request. 6738: * 6739: */ 6740: if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->target] > 0) && 6741: (boardp->reqcnt[scp->target] % 255) == 0) { 6742: asc_scsi_q.q2.tag_code = M2_QTAG_MSG_ORDERED; 6743: } else { 6744: asc_scsi_q.q2.tag_code = M2_QTAG_MSG_SIMPLE; 6745: } 6746: 6747: /* 6748: * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather 6749: * buffer command. 6750: */ 6751: if (scp->use_sg == 0) { 6752: /* 6753: * CDB request of single contiguous buffer. 6754: */ 6755: ASC_STATS(scp->host, cont_cnt); 6756: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0) 6757: asc_scsi_q.q1.data_addr = (ulong) scp->request_buffer; 6758: #else /* version >= v2.0.0 */ 6759: asc_scsi_q.q1.data_addr = virt_to_bus(scp->request_buffer); 6760: #endif /* version >= v2.0.0 */ 6761: asc_scsi_q.q1.data_cnt = scp->request_bufflen; 6762: ASC_STATS_ADD(scp->host, cont_xfer, 6763: ASC_CEILING(scp->request_bufflen, 512)); 6764: asc_scsi_q.q1.sg_queue_cnt = 0; 6765: asc_scsi_q.sg_head = NULL; 6766: } else { 6767: /* 6768: * CDB scatter-gather request list. 6769: */ 6770: int sgcnt; 6771: struct scatterlist *slp; 6772: 6773: if (scp->use_sg > scp->host->sg_tablesize) { 6774: ASC_PRINT3( 6775: "asc_build_req: board %d: use_sg %d > sg_tablesize %d\n", 6776: boardp->id, scp->use_sg, scp->host->sg_tablesize); 6777: scp->result = HOST_BYTE(DID_ERROR); 6778: asc_enqueue(&boardp->done, scp, ASC_BACK); 6779: return ASC_ERROR; 6780: } 6781: 6782: ASC_STATS(scp->host, sg_cnt); 6783: 6784: /* 6785: * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q 6786: * structure to point to it. 6787: */ 6788: memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD)); 6789: 6790: asc_scsi_q.q1.cntl |= QC_SG_HEAD; 6791: asc_scsi_q.sg_head = &asc_sg_head; 6792: asc_scsi_q.q1.data_cnt = 0; 6793: asc_scsi_q.q1.data_addr = 0; 6794: asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = scp->use_sg; 6795: ASC_STATS_ADD(scp->host, sg_elem, asc_sg_head.entry_cnt); 6796: 6797: /* 6798: * Convert scatter-gather list into ASC_SG_HEAD list. 6799: */ 6800: slp = (struct scatterlist *) scp->request_buffer; 6801: for (sgcnt = 0; sgcnt < scp->use_sg; sgcnt++, slp++) { 6802: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0) 6803: asc_sg_head.sg_list[sgcnt].addr = (ulong) slp->address; 6804: #else /* version >= v2.0.0 */ 6805: asc_sg_head.sg_list[sgcnt].addr = virt_to_bus(slp->address); 6806: #endif /* version >= v2.0.0 */ 6807: asc_sg_head.sg_list[sgcnt].bytes = slp->length; 6808: ASC_STATS_ADD(scp->host, sg_xfer, ASC_CEILING(slp->length, 512)); 6809: } 6810: } 6811: 6812: ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q); 6813: ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len); 6814: 6815: return ASC_NOERROR; 6816: } 6817: 6818: /* 6819: * Build a request structure for the Adv Library (Wide Board). 6820: * 6821: * If an adv_req_t can not be allocated to issue the request, 6822: * then return ASC_BUSY. If an error occurs, then return ASC_ERROR. 6823: */ 6824: STATIC int 6825: adv_build_req(asc_board_t *boardp, Scsi_Cmnd *scp, 6826: ADV_SCSI_REQ_Q **adv_scsiqpp) 6827: { 6828: adv_req_t *reqp; 6829: ADV_SCSI_REQ_Q *scsiqp; 6830: int i; 6831: 6832: /* 6833: * Allocate an adv_req_t structure from the board to execute 6834: * the command. 6835: */ 6836: if (boardp->adv_reqp == NULL) { 6837: ASC_DBG(1, "adv_build_req: no free adv_req_t\n"); 6838: ASC_STATS(scp->host, adv_build_noreq); 6839: return ASC_BUSY; 6840: } else { 6841: reqp = boardp->adv_reqp; 6842: boardp->adv_reqp = reqp->next_reqp; 6843: reqp->next_reqp = NULL; 6844: } 6845: 6846: /* 6847: * Get 4-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers. 6848: */ 6849: scsiqp = (ADV_SCSI_REQ_Q *) ADV_DWALIGN(&reqp->scsi_req_q); 6850: memset(scsiqp, 0, sizeof(ADV_SCSI_REQ_Q)); 6851: 6852: /* 6853: * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure. 6854: */ 6855: scsiqp->srb_ptr = (ulong) reqp; 6856: 6857: /* 6858: * Set the adv_req_t 'cmndp' to point to the Scsi_Cmnd structure. 6859: */ 6860: reqp->cmndp = scp; 6861: 6862: /* 6863: * Build the ADV_SCSI_REQ_Q request. 6864: */ 6865: 6866: /* 6867: * Set CDB length and copy it to the request structure. 6868: */ 6869: ASC_ASSERT(scp->cmd_len <= ASC_MAX_CDB_LEN); 6870: if (scp->cmd_len > ASC_MAX_CDB_LEN) { 6871: scp->cmd_len = ASC_MAX_CDB_LEN; 6872: } 6873: scsiqp->cdb_len = scp->cmd_len; 6874: for (i = 0; i < scp->cmd_len; i++) { 6875: scsiqp->cdb[i] = scp->cmnd[i]; 6876: } 6877: 6878: scsiqp->target_id = scp->target; 6879: scsiqp->target_lun = scp->lun; 6880: 6881: scsiqp->vsense_addr = (ulong) &scp->sense_buffer[0]; 6882: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0) 6883: scsiqp->sense_addr = (ulong) &scp->sense_buffer[0]; 6884: #else /* version >= v2.0.0 */ 6885: scsiqp->sense_addr = virt_to_bus(&scp->sense_buffer[0]); 6886: #endif /* version >= v2.0.0 */ 6887: scsiqp->sense_len = sizeof(scp->sense_buffer); 6888: 6889: /* 6890: * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather 6891: * buffer command. 6892: */ 6893: scsiqp->data_cnt = scp->request_bufflen; 6894: scsiqp->vdata_addr = (ulong) scp->request_buffer; 6895: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0) 6896: scsiqp->data_addr = (ulong) scp->request_buffer; 6897: #else /* version >= v2.0.0 */ 6898: scsiqp->data_addr = virt_to_bus(scp->request_buffer); 6899: #endif /* version >= v2.0.0 */ 6900: 6901: if (scp->use_sg == 0) { 6902: /* 6903: * CDB request of single contiguous buffer. 6904: */ 6905: reqp->sgblkp = NULL; 6906: scsiqp->sg_list_ptr = NULL; 6907: ASC_STATS(scp->host, cont_cnt); 6908: ASC_STATS_ADD(scp->host, cont_xfer, 6909: ASC_CEILING(scp->request_bufflen, 512)); 6910: } else { 6911: /* 6912: * CDB scatter-gather request list. 6913: */ 6914: if (scp->use_sg > ADV_MAX_SG_LIST) { 6915: ASC_PRINT3( 6916: "adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n", 6917: boardp->id, scp->use_sg, scp->host->sg_tablesize); 6918: scp->result = HOST_BYTE(DID_ERROR); 6919: asc_enqueue(&boardp->done, scp, ASC_BACK); 6920: 6921: /* 6922: * Free the 'adv_req_t' structure by adding it back to the 6923: * board free list. 6924: */ 6925: reqp->next_reqp = boardp->adv_reqp; 6926: boardp->adv_reqp = reqp; 6927: 6928: return ASC_ERROR; 6929: } 6930: 6931: /* 6932: * Allocate an 'adv_sgblk_t' structure from the board to 6933: * execute the command. 6934: */ 6935: if (boardp->adv_sgblkp == NULL) { 6936: ASC_DBG(1, "adv_build_req: no free adv_sgblk_t\n"); 6937: ASC_STATS(scp->host, adv_build_nosg); 6938: /* 6939: * Free the 'adv_req_t' structure by adding it back to the 6940: * board free list. 6941: */ 6942: reqp->next_reqp = boardp->adv_reqp; 6943: boardp->adv_reqp = reqp; 6944: return ASC_BUSY; 6945: } else { 6946: reqp->sgblkp = boardp->adv_sgblkp; 6947: boardp->adv_sgblkp = reqp->sgblkp->next_sgblkp; 6948: reqp->sgblkp->next_sgblkp = NULL; 6949: } 6950: 6951: /* 6952: * Build scatter-gather list. 6953: */ 6954: scsiqp->sg_list_ptr = (ADV_SG_BLOCK *) 6955: ADV_DWALIGN(&reqp->sgblkp->sg_block[0]); 6956: 6957: memset(scsiqp->sg_list_ptr, 0, sizeof(ADV_SG_BLOCK) * 6958: (ADV_NUM_SG_BLOCK + ADV_NUM_PAGE_CROSSING)); 6959: 6960: if (adv_get_sglist(&boardp->dvc_var.adv_dvc_var, scsiqp, scp) == 6961: ADV_ERROR) { 6962: 6963: /* 6964: * Free the adv_sgblk_t structure, if any, by adding it back 6965: * to the board free list. 6966: */ 6967: ASC_ASSERT(reqp->sgblkp != NULL); 6968: reqp->sgblkp->next_sgblkp = boardp->adv_sgblkp; 6969: boardp->adv_sgblkp = reqp->sgblkp; 6970: 6971: /* 6972: * Free the adv_req_t structure by adding it back to the 6973: * board free list. 6974: */ 6975: reqp->next_reqp = boardp->adv_reqp; 6976: boardp->adv_reqp = reqp; 6977: 6978: return ADV_ERROR; 6979: } 6980: 6981: ASC_STATS(scp->host, sg_cnt); 6982: ASC_STATS_ADD(scp->host, sg_elem, scp->use_sg); 6983: } 6984: 6985: ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp); 6986: ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len); 6987: 6988: *adv_scsiqpp = scsiqp; 6989: 6990: return ASC_NOERROR; 6991: } 6992: 6993: /* 6994: * Build scatter-gather list for Adv Library (Wide Board). 6995: * 6996: * Return: 6997: * ADV_SUCCESS(1) - SG List successfully created 6998: * ADV_ERROR(-1) - SG List creation failed 6999: */ 7000: STATIC int 7001: adv_get_sglist(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp, 7002: Scsi_Cmnd *scp) 7003: { 7004: ADV_SG_BLOCK *sg_block; /* virtual address of a SG */ 7005: ulong sg_block_next_addr; /* block and its next */ 7006: ulong sg_block_physical_addr; 7007: int sg_block_index, i; /* how many SG entries */ 7008: struct scatterlist *slp; 7009: int sg_elem_cnt; 7010: 7011: slp = (struct scatterlist *) scp->request_buffer; 7012: sg_elem_cnt = scp->use_sg; 7013: 7014: sg_block = scsiqp->sg_list_ptr; 7015: sg_block_next_addr = (ulong) sg_block; /* allow math operation */ 7016: sg_block_physical_addr = 7017: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0) 7018: (ulong) scsiqp->sg_list_ptr; 7019: #else /* version >= v2.0.0 */ 7020: virt_to_bus(scsiqp->sg_list_ptr); 7021: #endif /* version >= v2.0.0 */ 7022: ADV_ASSERT(ADV_DWALIGN(sg_block_physical_addr) == 7023: sg_block_physical_addr); 7024: scsiqp->sg_real_addr = sg_block_physical_addr; 7025: 7026: sg_block_index = 0; 7027: do 7028: { 7029: sg_block->first_entry_no = sg_block_index; 7030: for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) 7031: { 7032: sg_block->sg_list[i].sg_addr = 7033: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0) 7034: (ulong) slp->address; 7035: #else /* version >= v2.0.0 */ 7036: virt_to_bus(slp->address); 7037: #endif /* version >= v2.0.0 */ 7038: sg_block->sg_list[i].sg_count = slp->length; 7039: ASC_STATS_ADD(scp->host, sg_xfer, ASC_CEILING(slp->length, 512)); 7040: 7041: if (--sg_elem_cnt == 0) 7042: { /* last entry, get out */ 7043: scsiqp->sg_entry_cnt = sg_block_index + i + 1; 7044: sg_block->last_entry_no = sg_block_index + i; 7045: sg_block->sg_ptr = 0L; /* next link = NULL */ 7046: return ADV_SUCCESS; 7047: } 7048: slp++; 7049: } 7050: sg_block_next_addr += sizeof(ADV_SG_BLOCK); 7051: sg_block_physical_addr += sizeof(ADV_SG_BLOCK); 7052: ADV_ASSERT(ADV_DWALIGN(sg_block_physical_addr) == 7053: sg_block_physical_addr); 7054: 7055: sg_block_index += NO_OF_SG_PER_BLOCK; 7056: sg_block->sg_ptr = (ADV_SG_BLOCK *) sg_block_physical_addr; 7057: sg_block->last_entry_no = sg_block_index - 1; 7058: sg_block = (ADV_SG_BLOCK *) sg_block_next_addr; /* virtual addr */ 7059: } 7060: while (1); 7061: /* NOTREACHED */ 7062: } 7063: 7064: /* 7065: * asc_isr_callback() - Second Level Interrupt Handler called by AscISR(). 7066: * 7067: * Interrupt callback function for the Narrow SCSI Asc Library. 7068: */ 7069: STATIC void 7070: asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) 7071: { 7072: asc_board_t *boardp; 7073: Scsi_Cmnd *scp; 7074: struct Scsi_Host *shp; 7075: int underrun = ASC_FALSE; 7076: int i; 7077: 7078: ASC_ASSERT(interrupts_enabled() == ASC_FALSE); 7079: ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp %x, qdonep %x\n", 7080: (unsigned) asc_dvc_varp, (unsigned) qdonep); 7081: ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep); 7082: 7083: /* 7084: * Get the Scsi_Cmnd structure and Scsi_Host structure for the 7085: * command that has been completed. 7086: */ 7087: scp = (Scsi_Cmnd *) qdonep->d2.srb_ptr; 7088: ASC_DBG1(1, "asc_isr_callback: scp %x\n", (unsigned) scp); 7089: 7090: if (scp == NULL) { 7091: ASC_PRINT("asc_isr_callback: scp is NULL\n"); 7092: return; 7093: } 7094: ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len); 7095: 7096: /* 7097: * If the request's host pointer is not valid, display a 7098: * message and return. 7099: */ 7100: shp = scp->host; 7101: for (i = 0; i < asc_board_count; i++) { 7102: if (asc_host[i] == shp) { 7103: break; 7104: } 7105: } 7106: if (i == asc_board_count) { 7107: ASC_PRINT2("asc_isr_callback: scp %x has bad host pointer, host %x\n", 7108: (unsigned) scp, (unsigned) shp); 7109: return; 7110: } 7111: 7112: ASC_STATS(shp, callback); 7113: ASC_DBG1(1, "asc_isr_callback: shp %x\n", (unsigned) shp); 7114: 7115: /* 7116: * If the request isn't found on the active queue, it may 7117: * have been removed to handle a reset or abort request. 7118: * Display a message and return. 7119: */ 7120: boardp = ASC_BOARDP(shp); 7121: ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var); 7122: if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) { 7123: ASC_PRINT2("asc_isr_callback: board %d: scp %x not on active queue\n", 7124: boardp->id, (unsigned) scp); 7125: return; 7126: } 7127: 7128: /* 7129: * Check for an underrun condition. 7130: */ 7131: if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 && 7132: qdonep->remain_bytes <= scp->request_bufflen != 0) { 7133: ASC_DBG1(1, "asc_isr_callback: underrun condition %u bytes\n", 7134: (unsigned) qdonep->remain_bytes); 7135: underrun = ASC_TRUE; 7136: } 7137: 7138: /* 7139: * 'qdonep' contains the command's ending status. 7140: */ 7141: switch (qdonep->d3.done_stat) { 7142: case QD_NO_ERROR: 7143: ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n"); 7144: switch (qdonep->d3.host_stat) { 7145: case QHSTA_NO_ERROR: 7146: scp->result = 0; 7147: break; 7148: default: 7149: /* QHSTA error occurred */ 7150: scp->result = HOST_BYTE(DID_ERROR); 7151: break; 7152: } 7153: 7154: /* 7155: * If an INQUIRY command completed successfully, then call 7156: * the AscInquiryHandling() function to set-up the device. 7157: */ 7158: if (scp->cmnd[0] == SCSICMD_Inquiry && scp->lun == 0 && 7159: (scp->request_bufflen - qdonep->remain_bytes) >= 8) 7160: { 7161: AscInquiryHandling(asc_dvc_varp, scp->target & 0x7, 7162: (ASC_SCSI_INQUIRY *) scp->request_buffer); 7163: } 7164: 7165: /* 7166: * If there was an underrun without any other error, 7167: * set DID_ERROR to indicate the underrun error. 7168: * 7169: * Note: There is no way yet to indicate the number 7170: * of underrun bytes. 7171: */ 7172: if (scp->result == 0 && underrun == ASC_TRUE) { 7173: scp->result = HOST_BYTE(DID_UNDERRUN); 7174: } 7175: break; 7176: 7177: case QD_WITH_ERROR: 7178: ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n"); 7179: switch (qdonep->d3.host_stat) { 7180: case QHSTA_NO_ERROR: 7181: if (qdonep->d3.scsi_stat == SS_CHK_CONDITION) { 7182: ASC_DBG(2, "asc_isr_callback: SS_CHK_CONDITION\n"); 7183: ASC_DBG_PRT_SENSE(2, scp->sense_buffer, 7184: sizeof(scp->sense_buffer)); 7185: /* 7186: * Note: The 'status_byte()' macro used by target drivers 7187: * defined in scsi.h shifts the status byte returned by 7188: * host drivers right by 1 bit. This is why target drivers 7189: * also use right shifted status byte definitions. For 7190: * instance target drivers use CHECK_CONDITION, defined to 7191: * 0x1, instead of the SCSI defined check condition value 7192: * of 0x2. Host drivers are supposed to return the status 7193: * byte as it is defined by SCSI. 7194: */ 7195: scp->result = DRIVER_BYTE(DRIVER_SENSE) | 7196: STATUS_BYTE(qdonep->d3.scsi_stat); 7197: } else { 7198: scp->result = STATUS_BYTE(qdonep->d3.scsi_stat); 7199: } 7200: break; 7201: 7202: default: 7203: /* QHSTA error occurred */ 7204: ASC_DBG1(1, "asc_isr_callback: host_stat %x\n", 7205: qdonep->d3.host_stat); 7206: scp->result = HOST_BYTE(DID_BAD_TARGET); 7207: break; 7208: } 7209: break; 7210: 7211: case QD_ABORTED_BY_HOST: 7212: ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n"); 7213: scp->result = HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.scsi_msg) | 7214: STATUS_BYTE(qdonep->d3.scsi_stat); 7215: break; 7216: 7217: default: 7218: ASC_DBG1(1, "asc_isr_callback: done_stat %x\n", qdonep->d3.done_stat); 7219: scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.scsi_msg) | 7220: STATUS_BYTE(qdonep->d3.scsi_stat); 7221: break; 7222: } 7223: 7224: /* 7225: * If the 'init_tidmask' bit isn't already set for the target and the 7226: * current request finished normally, then set the bit for the target 7227: * to indicate that a device is present. 7228: */ 7229: if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->target)) == 0 && 7230: qdonep->d3.done_stat == QD_NO_ERROR && 7231: qdonep->d3.host_stat == QHSTA_NO_ERROR) { 7232: boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target); 7233: } 7234: 7235: /* 7236: * Because interrupts may be enabled by the 'Scsi_Cmnd' done 7237: * function, add the command to the end of the board's done queue. 7238: * The done function for the command will be called from 7239: * advansys_interrupt(). 7240: */ 7241: asc_enqueue(&boardp->done, scp, ASC_BACK); 7242: 7243: return; 7244: } 7245: 7246: /* 7247: * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR(). 7248: * 7249: * Callback function for the Wide SCSI Adv Library. 7250: */ 7251: STATIC void 7252: adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp) 7253: { 7254: asc_board_t *boardp; 7255: adv_req_t *reqp; 7256: Scsi_Cmnd *scp; 7257: struct Scsi_Host *shp; 7258: int underrun = ASC_FALSE; 7259: int i; 7260: 7261: ASC_ASSERT(interrupts_enabled() == ASC_FALSE); 7262: ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp %x, scsiqp %x\n", 7263: (unsigned) adv_dvc_varp, (unsigned) scsiqp); 7264: ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp); 7265: 7266: /* 7267: * Get the adv_req_t structure for the command that has been 7268: * completed. The adv_req_t structure actually contains the 7269: * completed ADV_SCSI_REQ_Q structure. 7270: */ 7271: reqp = (adv_req_t *) scsiqp->srb_ptr; 7272: ASC_DBG1(1, "adv_isr_callback: reqp %x\n", (unsigned) reqp); 7273: if (reqp == NULL) { 7274: ASC_PRINT("adv_isr_callback: reqp is NULL\n"); 7275: return; 7276: } 7277: 7278: /* 7279: * Get the Scsi_Cmnd structure and Scsi_Host structure for the 7280: * command that has been completed. 7281: * 7282: * Note: The adv_req_t request structure and adv_sgblk_t structure, 7283: * if any, * dropped, because a board structure pointer can not be 7284: * determined. 7285: */ 7286: scp = reqp->cmndp; 7287: ASC_DBG1(1, "adv_isr_callback: scp %x\n", (unsigned) scp); 7288: if (scp == NULL) { 7289: ASC_PRINT("adv_isr_callback: scp is NULL; adv_req_t dropped.\n"); 7290: return; 7291: } 7292: ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len); 7293: 7294: /* 7295: * If the request's host pointer is not valid, display a message 7296: * and return. 7297: */ 7298: shp = scp->host; 7299: for (i = 0; i < asc_board_count; i++) { 7300: if (asc_host[i] == shp) { 7301: break; 7302: } 7303: } 7304: /* 7305: * Note: If the host structure is not found, the adv_req_t request 7306: * structure and adv_sgblk_t structure, if any, is dropped. 7307: */ 7308: if (i == asc_board_count) { 7309: ASC_PRINT2("adv_isr_callback: scp %x has bad host pointer, host %x\n", 7310: (unsigned) scp, (unsigned) shp); 7311: return; 7312: } 7313: 7314: ASC_STATS(shp, callback); 7315: ASC_DBG1(1, "adv_isr_callback: shp %x\n", (unsigned) shp); 7316: 7317: /* 7318: * If the request isn't found on the active queue, it may have been 7319: * removed to handle a reset or abort request. Display a message and 7320: * return. 7321: * 7322: * Note: Because the structure may still be in use don't attempt 7323: * to free the adv_req_t and adv_sgblk_t, if any, structures. 7324: */ 7325: boardp = ASC_BOARDP(shp); 7326: ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var); 7327: if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) { 7328: ASC_PRINT2("adv_isr_callback: board %d: scp %x not on active queue\n", 7329: boardp->id, (unsigned) scp); 7330: return; 7331: } 7332: 7333: /* 7334: * Check for an underrun condition. 7335: */ 7336: if (scp->request_bufflen != 0 && scsiqp->data_cnt != 0) { 7337: ASC_DBG1(1, "adv_isr_callback: underrun condition %lu bytes\n", 7338: scsiqp->data_cnt); 7339: underrun = ASC_TRUE; 7340: } 7341: 7342: /* 7343: * 'done_status' contains the command's ending status. 7344: */ 7345: switch (scsiqp->done_status) { 7346: case QD_NO_ERROR: 7347: ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n"); 7348: switch (scsiqp->host_status) { 7349: case QHSTA_NO_ERROR: 7350: scp->result = 0; 7351: break; 7352: default: 7353: /* QHSTA error occurred. */ 7354: ASC_DBG1(2, "adv_isr_callback: host_status %x\n", 7355: scsiqp->host_status); 7356: scp->result = HOST_BYTE(DID_ERROR); 7357: break; 7358: } 7359: /* 7360: * If there was an underrun without any other error, 7361: * set DID_ERROR to indicate the underrun error. 7362: * 7363: * Note: There is no way yet to indicate the number 7364: * of underrun bytes. 7365: */ 7366: if (scp->result == 0 && underrun == ASC_TRUE) { 7367: scp->result = HOST_BYTE(DID_UNDERRUN); 7368: } 7369: break; 7370: 7371: case QD_WITH_ERROR: 7372: ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n"); 7373: switch (scsiqp->host_status) { 7374: case QHSTA_NO_ERROR: 7375: if (scsiqp->scsi_status == SS_CHK_CONDITION) { 7376: ASC_DBG(2, "adv_isr_callback: SS_CHK_CONDITION\n"); 7377: ASC_DBG_PRT_SENSE(2, scp->sense_buffer, 7378: sizeof(scp->sense_buffer)); 7379: /* 7380: * Note: The 'status_byte()' macro used by target drivers 7381: * defined in scsi.h shifts the status byte returned by 7382: * host drivers right by 1 bit. This is why target drivers 7383: * also use right shifted status byte definitions. For 7384: * instance target drivers use CHECK_CONDITION, defined to 7385: * 0x1, instead of the SCSI defined check condition value 7386: * of 0x2. Host drivers are supposed to return the status 7387: * byte as it is defined by SCSI. 7388: */ 7389: scp->result = DRIVER_BYTE(DRIVER_SENSE) | 7390: STATUS_BYTE(scsiqp->scsi_status); 7391: } else { 7392: scp->result = STATUS_BYTE(scsiqp->scsi_status); 7393: } 7394: break; 7395: 7396: default: 7397: /* Some other QHSTA error occurred. */ 7398: ASC_DBG1(1, "adv_isr_callback: host_status %x\n", 7399: scsiqp->host_status); 7400: scp->result = HOST_BYTE(DID_BAD_TARGET); 7401: break; 7402: } 7403: break; 7404: 7405: case QD_ABORTED_BY_HOST: 7406: ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n"); 7407: scp->result = HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status); 7408: break; 7409: 7410: default: 7411: ASC_DBG1(1, "adv_isr_callback: done_status %x\n", scsiqp->done_status); 7412: scp->result = HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status); 7413: break; 7414: } 7415: 7416: /* 7417: * If the 'init_tidmask' bit isn't already set for the target and the 7418: * current request finished normally, then set the bit for the target 7419: * to indicate that a device is present. 7420: */ 7421: if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->target)) == 0 && 7422: scsiqp->done_status == QD_NO_ERROR && 7423: scsiqp->host_status == QHSTA_NO_ERROR) { 7424: boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target); 7425: } 7426: 7427: /* 7428: * Because interrupts may be enabled by the 'Scsi_Cmnd' done 7429: * function, add the command to the end of the board's done queue. 7430: * The done function for the command will be called from 7431: * advansys_interrupt(). 7432: */ 7433: asc_enqueue(&boardp->done, scp, ASC_BACK); 7434: 7435: /* 7436: * Free the adv_sgblk_t structure, if any, by adding it back 7437: * to the board free list. 7438: */ 7439: if (reqp->sgblkp != NULL) { 7440: reqp->sgblkp->next_sgblkp = boardp->adv_sgblkp; 7441: boardp->adv_sgblkp = reqp->sgblkp; 7442: } 7443: 7444: /* 7445: * Free the adv_req_t structure used with the command by adding 7446: * it back to the board free list. 7447: */ 7448: reqp->next_reqp = boardp->adv_reqp; 7449: boardp->adv_reqp = reqp; 7450: 7451: ASC_DBG(1, "adv_isr_callback: done\n"); 7452: 7453: return; 7454: } 7455: 7456: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93) 7457: #ifdef ASC_CONFIG_PCI 7458: /* 7459: * Search for an AdvanSys PCI device in the PCI configuration space. 7460: */ 7461: ASC_INITFUNC( 7462: STATIC int 7463: asc_srch_pci_dev(PCI_DEVICE *pciDevice) 7464: ) 7465: { 7466: int ret = PCI_DEVICE_NOT_FOUND; 7467: 7468: ASC_DBG(2, "asc_srch_pci_dev: begin\n"); 7469: 7470: if (pci_scan_method == -1) { 7471: pci_scan_method = asc_scan_method(); 7472: } 7473: pciDevice->type = pci_scan_method; 7474: ASC_DBG1(2, "asc_srch_pci_dev: type %d\n", pciDevice->type); 7475: 7476: ret = asc_pci_find_dev(pciDevice); 7477: ASC_DBG1(2, "asc_srch_pci_dev: asc_pci_find_dev() return %d\n", ret); 7478: if (ret == PCI_DEVICE_FOUND) { 7479: pciDevice->slotNumber = pciDevice->slotFound + 1; 7480: pciDevice->startSlot = pciDevice->slotFound + 1; 7481: } else { 7482: if (pciDevice->bridge > pciDevice->busNumber) { 7483: ASC_DBG2(2, "asc_srch_pci_dev: bridge %x, busNumber %x\n", 7484: pciDevice->bridge, pciDevice->busNumber); 7485: pciDevice->busNumber++; 7486: pciDevice->slotNumber = 0; 7487: pciDevice->startSlot = 0; 7488: pciDevice->endSlot = 0x0f; 7489: ret = asc_srch_pci_dev(pciDevice); 7490: ASC_DBG1(2, "asc_srch_pci_dev: recursive call return %d\n", ret); 7491: } 7492: } 7493: 7494: ASC_DBG1(2, "asc_srch_pci_dev: return %d\n", ret); 7495: return ret; 7496: } 7497: 7498: /* 7499: * Determine the access method to be used for 'pciDevice'. 7500: */ 7501: ASC_INITFUNC( 7502: STATIC uchar 7503: asc_scan_method(void) 7504: ) 7505: { 7506: ushort data; 7507: PCI_DATA pciData; 7508: uchar type; 7509: uchar slot; 7510: 7511: ASC_DBG(2, "asc_scan_method: begin\n"); 7512: memset(&pciData, 0, sizeof(pciData)); 7513: for (type = 1; type < 3; type++) { 7514: pciData.type = type; 7515: for (slot = 0; slot < PCI_MAX_SLOT; slot++) { 7516: pciData.slot = slot; 7517: data = asc_get_cfg_word(&pciData); 7518: if ((data != 0xFFFF) && (data != 0x0000)) { 7519: ASC_DBG2(4, "asc_scan_method: data %x, type %d\n", data, type); 7520: return (type); 7521: } 7522: } 7523: } 7524: ASC_DBG1(4, "asc_scan_method: type %d\n", type); 7525: return (type); 7526: } 7527: 7528: /* 7529: * Check for an AdvanSys PCI device in 'pciDevice'. 7530: * 7531: * Return PCI_DEVICE_FOUND if found, otherwise return PCI_DEVICE_NOT_FOUND. 7532: */ 7533: ASC_INITFUNC( 7534: STATIC int 7535: asc_pci_find_dev(PCI_DEVICE *pciDevice) 7536: ) 7537: { 7538: PCI_DATA pciData; 7539: ushort vendorid, deviceid; 7540: uchar classcode, subclass; 7541: uchar lslot; 7542: 7543: ASC_DBG(3, "asc_pci_find_dev: begin\n"); 7544: pciData.type = pciDevice->type; 7545: pciData.bus = pciDevice->busNumber; 7546: pciData.func = pciDevice->devFunc; 7547: lslot = pciDevice->startSlot; 7548: for (; lslot < pciDevice->endSlot; lslot++) { 7549: pciData.slot = lslot; 7550: pciData.offset = VENDORID_OFFSET; 7551: vendorid = asc_get_cfg_word(&pciData); 7552: ASC_DBG1(3, "asc_pci_find_dev: vendorid %x\n", vendorid); 7553: if (vendorid != 0xffff) { 7554: pciData.offset = DEVICEID_OFFSET; 7555: deviceid = asc_get_cfg_word(&pciData); 7556: ASC_DBG1(3, "asc_pci_find_dev: deviceid %x\n", deviceid); 7557: if ((vendorid == ASC_PCI_VENDORID) && 7558: ((deviceid == ASC_PCI_DEVICE_ID_1100) || 7559: (deviceid == ASC_PCI_DEVICE_ID_1200) || 7560: (deviceid == ASC_PCI_DEVICE_ID_1300) || 7561: (deviceid == ASC_PCI_DEVICE_ID_2300))) { 7562: pciDevice->slotFound = lslot; 7563: ASC_DBG(3, "asc_pci_find_dev: PCI_DEVICE_FOUND\n"); 7564: return PCI_DEVICE_FOUND; 7565: } else { 7566: pciData.offset = SUBCLASS_OFFSET; 7567: subclass = asc_get_cfg_byte(&pciData); 7568: pciData.offset = CLASSCODE_OFFSET; 7569: classcode = asc_get_cfg_byte(&pciData); 7570: if ((classcode & PCI_BASE_CLASS_BRIDGE_DEVICE) && 7571: (subclass & PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER)) { 7572: pciDevice->bridge++; 7573: } 7574: ASC_DBG2(3, "asc_pci_find_dev: subclass %x, classcode %x\n", 7575: subclass, classcode); 7576: } 7577: } 7578: } 7579: return PCI_DEVICE_NOT_FOUND; 7580: } 7581: 7582: /* 7583: * Read PCI configuration data into 'pciConfig'. 7584: */ 7585: ASC_INITFUNC( 7586: STATIC void 7587: asc_get_pci_cfg(PCI_DEVICE *pciDevice, PCI_CONFIG_SPACE *pciConfig) 7588: ) 7589: { 7590: PCI_DATA pciData; 7591: uchar counter; 7592: uchar *localConfig; 7593: 7594: ASC_DBG1(4, "asc_get_pci_cfg: slotFound %d\n ", 7595: pciDevice->slotFound); 7596: 7597: pciData.type = pciDevice->type; 7598: pciData.bus = pciDevice->busNumber; 7599: pciData.slot = pciDevice->slotFound; 7600: pciData.func = pciDevice->devFunc; 7601: localConfig = (uchar *) pciConfig; 7602: 7603: for (counter = 0; counter < sizeof(PCI_CONFIG_SPACE); counter++) { 7604: pciData.offset = counter; 7605: *localConfig = asc_get_cfg_byte(&pciData); 7606: ASC_DBG1(4, "asc_get_pci_cfg: byte %x\n", *localConfig); 7607: localConfig++; 7608: } 7609: ASC_DBG1(4, "asc_get_pci_cfg: counter %d\n", counter); 7610: } 7611: 7612: /* 7613: * Read a word (16 bits) from the PCI configuration space. 7614: * 7615: * The configuration mechanism is checked for the correct access method. 7616: */ 7617: ASC_INITFUNC( 7618: STATIC ushort 7619: asc_get_cfg_word(PCI_DATA *pciData) 7620: ) 7621: { 7622: ushort tmp; 7623: ulong address; 7624: ulong lbus = pciData->bus; 7625: ulong lslot = pciData->slot; 7626: ulong lfunc = pciData->func; 7627: uchar t2CFA, t2CF8; 7628: ulong t1CF8, t1CFC; 7629: 7630: ASC_DBG4(4, "asc_get_cfg_word: type %d, bus %lu, slot %lu, func %lu\n", 7631: pciData->type, lbus, lslot, lfunc); 7632: 7633: /* 7634: * Check type of configuration mechanism. 7635: */ 7636: if (pciData->type == 2) { 7637: /* 7638: * Save registers to be restored later. 7639: */ 7640: t2CFA = inp(0xCFA); /* save PCI bus register */ 7641: t2CF8 = inp(0xCF8); /* save config space enable register */ 7642: 7643: /* 7644: * Write the bus and enable registers. 7645: */ 7646: /* set for type 1 cycle, if needed */ 7647: outp(0xCFA, pciData->bus); 7648: /* set the function number */ 7649: outp(0xCF8, 0x10 | (pciData->func << 1)) ; 7650: 7651: /* 7652: * Read the configuration space type 2 locations. 7653: */ 7654: tmp = (ushort) inpw(0xC000 | ((pciData->slot << 8) + pciData->offset)); 7655: 7656: outp(0xCFA, t2CFA); /* save PCI bus register */ 7657: outp(0xCF8, t2CF8); /* save config space enable register */ 7658: } else { 7659: /* 7660: * Type 1 or 3 configuration mechanism. 7661: * 7662: * Save the CONFIG_ADDRESS and CONFIG_DATA register values. 7663: */ 7664: t1CF8 = inpl(0xCF8); 7665: t1CFC = inpl(0xCFC); 7666: 7667: /* 7668: * enable <31>, bus = <23:16>, slot = <15:11>, 7669: * func = <10:8>, reg = <7:2> 7670: */ 7671: address = (ulong) ((lbus << 16) | (lslot << 11) | 7672: (lfunc << 8) | (pciData->offset & 0xFC) | 0x80000000L); 7673: 7674: /* 7675: * Write out the address to CONFIG_ADDRESS. 7676: */ 7677: outpl(0xCF8, address); 7678: 7679: /* 7680: * Read in word from CONFIG_DATA. 7681: */ 7682: tmp = (ushort) ((inpl(0xCFC) >> 7683: ((pciData->offset & 2) * 8)) & 0xFFFF); 7684: 7685: /* 7686: * Restore registers. 7687: */ 7688: outpl(0xCF8, t1CF8); 7689: outpl(0xCFC, t1CFC); 7690: } 7691: ASC_DBG1(4, "asc_get_cfg_word: config data: %x\n", tmp); 7692: return tmp; 7693: } 7694: 7695: /* 7696: * Reads a byte from the PCI configuration space. 7697: * 7698: * The configuration mechanism is checked for the correct access method. 7699: */ 7700: ASC_INITFUNC( 7701: STATIC uchar 7702: asc_get_cfg_byte(PCI_DATA *pciData) 7703: ) 7704: { 7705: uchar tmp; 7706: ulong address; 7707: ulong lbus = pciData->bus, lslot = pciData->slot, lfunc = pciData->func; 7708: uchar t2CFA, t2CF8; 7709: ulong t1CF8, t1CFC; 7710: 7711: ASC_DBG1(4, "asc_get_cfg_byte: type: %d\n", pciData->type); 7712: 7713: /* 7714: * Check type of configuration mechanism. 7715: */ 7716: if (pciData->type == 2) { 7717: /* 7718: * Save registers to be restored later. 7719: */ 7720: t2CFA = inp(0xCFA); /* save PCI bus register */ 7721: t2CF8 = inp(0xCF8); /* save config space enable register */ 7722: 7723: /* 7724: * Write the bus and enable registers. 7725: */ 7726: /* set for type 1 cycle, if needed */ 7727: outp(0xCFA, pciData->bus); 7728: /* set the function number */ 7729: outp(0xCF8, 0x10 | (pciData->func << 1)); 7730: 7731: /* 7732: * Read configuration space type 2 locations. 7733: */ 7734: tmp = inp(0xC000 | ((pciData->slot << 8) + pciData->offset)); 7735: 7736: /* 7737: * Restore registers. 7738: */ 7739: outp(0xCF8, t2CF8); /* restore the enable register */ 7740: outp(0xCFA, t2CFA); /* restore PCI bus register */ 7741: } else { 7742: /* 7743: * Type 1 or 3 configuration mechanism. 7744: * 7745: * Save CONFIG_ADDRESS and CONFIG_DATA register values. 7746: */ 7747: t1CF8 = inpl(0xCF8); 7748: t1CFC = inpl(0xCFC); 7749: 7750: /* 7751: * enable <31>, bus = <23:16>, slot = <15:11>, func = <10:8>, 7752: * reg = <7:2> 7753: */ 7754: address = (ulong) ((lbus << 16) | (lslot << 11) | 7755: (lfunc << 8) | (pciData->offset & 0xFC) | 0x80000000L); 7756: 7757: /* 7758: * Write out address to CONFIG_ADDRESS. 7759: */ 7760: outpl(0xCF8, address); 7761: 7762: /* 7763: * Read in word from CONFIG_DATA. 7764: */ 7765: tmp = (uchar) ((inpl(0xCFC) >> ((pciData->offset & 3) * 8)) & 0xFF); 7766: 7767: /* 7768: * Restore registers. 7769: */ 7770: outpl(0xCF8, t1CF8); 7771: outpl(0xCFC, t1CFC); 7772: } 7773: ASC_DBG1(4, "asc_get_cfg_byte: config data: %x\n", tmp); 7774: return tmp; 7775: } 7776: 7777: /* 7778: * Write a byte to the PCI configuration space. 7779: */ 7780: ASC_INITFUNC( 7781: STATIC void 7782: asc_put_cfg_byte(PCI_DATA *pciData, uchar byte_data) 7783: ) 7784: { 7785: ulong tmpl; 7786: ulong address; 7787: ulong lbus = pciData->bus, lslot = pciData->slot, lfunc = pciData->func; 7788: uchar t2CFA, t2CF8; 7789: ulong t1CF8, t1CFC; 7790: 7791: ASC_DBG2(4, "asc_put_cfg_byte: type: %d, byte_data %x\n", 7792: pciData->type, byte_data); 7793: 7794: /* 7795: * Check type of configuration mechanism. 7796: */ 7797: if (pciData->type == 2) { 7798: 7799: /* 7800: * Save registers to be restored later. 7801: */ 7802: t2CFA = inp(0xCFA); /* save PCI bus register */ 7803: t2CF8 = inp(0xCF8); /* save config space enable register */ 7804: 7805: /* 7806: * Write bus and enable registers. 7807: */ 7808: outp(0xCFA, pciData->bus); 7809: 7810: /* 7811: * Set the function number. 7812: */ 7813: outp(0xCF8, 0x10 | (pciData->func << 1)); 7814: 7815: /* 7816: * Write the configuration space type 2 locations. 7817: */ 7818: outp(0xC000 | ((pciData->slot << 8) + pciData->offset), byte_data); 7819: 7820: /* 7821: * Restore registers. 7822: */ 7823: outp(0xCF8, t2CF8); /* restore the enable register */ 7824: outp(0xCFA, t2CFA); /* restore PCI bus register */ 7825: } else { 7826: 7827: /* 7828: * Type 1 or 3 configuration mechanism. 7829: * 7830: * Save the CONFIG_ADDRESS and CONFIG_DATA register values. 7831: */ 7832: t1CF8 = inpl(0xCF8); 7833: t1CFC = inpl(0xCFC); 7834: 7835: /* 7836: * enable <31>, bus = <23:16>, slot = <15:11>, func = <10:8>, 7837: * reg = <7:2> 7838: */ 7839: address = (ulong) ((lbus << 16) | (lslot << 11) | (lfunc << 8) | 7840: (pciData->offset & 0xFC) | 0x80000000L); 7841: /* 7842: * Write out address to CONFIG_ADDRESS. 7843: */ 7844: outpl(0xCF8, address); 7845: 7846: /* 7847: * Write double word to CONFIG_DATA preserving the bytes 7848: * in the double not written. 7849: */ 7850: tmpl = inpl(0xCFC) & ~(0xFF << ((pciData->offset & 3) * 8)); 7851: outpl(0xCFC, tmpl | (byte_data << ((pciData->offset & 3) * 8))); 7852: 7853: /* 7854: * Restore registers. 7855: */ 7856: outpl(0xCF8, t1CF8); 7857: outpl(0xCFC, t1CFC); 7858: } 7859: ASC_DBG(4, "asc_put_cfg_byte: end\n"); 7860: } 7861: #endif /* ASC_CONFIG_PCI */ 7862: #endif /* version < v2.1.93 */ 7863: 7864: /* 7865: * Add a 'REQP' to the end of specified queue. Set 'tidmask' 7866: * to indicate a command is queued for the device. 7867: * 7868: * 'flag' may be either ASC_FRONT or ASC_BACK. 7869: * 7870: * 'REQPNEXT(reqp)' returns reqp's next pointer. 7871: */ 7872: STATIC void 7873: asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag) 7874: { 7875: int tid; 7876: 7877: ASC_DBG3(3, "asc_enqueue: ascq %x, reqp %x, flag %d\n", 7878: (unsigned) ascq, (unsigned) reqp, flag); 7879: ASC_ASSERT(interrupts_enabled() == ASC_FALSE); 7880: ASC_ASSERT(reqp != NULL); 7881: ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK); 7882: tid = REQPTID(reqp); 7883: ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID); 7884: if (flag == ASC_FRONT) { 1.1.1.2 ! root 7885: REQPNEXT(reqp) = (unsigned char *) ascq->q_first[tid]; 1.1 root 7886: ascq->q_first[tid] = reqp; 7887: /* If the queue was empty, set the last pointer. */ 7888: if (ascq->q_last[tid] == NULL) { 7889: ascq->q_last[tid] = reqp; 7890: } 7891: } else { /* ASC_BACK */ 7892: if (ascq->q_last[tid] != NULL) { 1.1.1.2 ! root 7893: REQPNEXT(ascq->q_last[tid]) = (unsigned char *) reqp; 1.1 root 7894: } 7895: ascq->q_last[tid] = reqp; 7896: REQPNEXT(reqp) = NULL; 7897: /* If the queue was empty, set the first pointer. */ 7898: if (ascq->q_first[tid] == NULL) { 7899: ascq->q_first[tid] = reqp; 7900: } 7901: } 7902: /* The queue has at least one entry, set its bit. */ 7903: ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid); 7904: #ifdef ADVANSYS_STATS 7905: /* Maintain request queue statistics. */ 7906: ascq->q_tot_cnt[tid]++; 7907: ascq->q_cur_cnt[tid]++; 7908: if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) { 7909: ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid]; 7910: ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n", 7911: tid, ascq->q_max_cnt[tid]); 7912: } 7913: REQPTIME(reqp) = REQTIMESTAMP(); 7914: #endif /* ADVANSYS_STATS */ 7915: ASC_DBG1(3, "asc_enqueue: reqp %x\n", (unsigned) reqp); 7916: return; 7917: } 7918: 7919: /* 7920: * Return first queued 'REQP' on the specified queue for 7921: * the specified target device. Clear the 'tidmask' bit for 7922: * the device if no more commands are left queued for it. 7923: * 7924: * 'REQPNEXT(reqp)' returns reqp's next pointer. 7925: */ 7926: STATIC REQP 7927: asc_dequeue(asc_queue_t *ascq, int tid) 7928: { 7929: REQP reqp; 7930: 7931: ASC_DBG2(3, "asc_dequeue: ascq %x, tid %d\n", (unsigned) ascq, tid); 7932: ASC_ASSERT(interrupts_enabled() == ASC_FALSE); 7933: ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID); 7934: if ((reqp = ascq->q_first[tid]) != NULL) { 7935: ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)); 1.1.1.2 ! root 7936: ascq->q_first[tid] = (REQP) REQPNEXT(reqp); 1.1 root 7937: /* If the queue is empty, clear its bit and the last pointer. */ 7938: if (ascq->q_first[tid] == NULL) { 7939: ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid); 7940: ASC_ASSERT(ascq->q_last[tid] == reqp); 7941: ascq->q_last[tid] = NULL; 7942: } 7943: #ifdef ADVANSYS_STATS 7944: /* Maintain request queue statistics. */ 7945: ascq->q_cur_cnt[tid]--; 7946: ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0); 7947: REQTIMESTAT("asc_dequeue", ascq, reqp, tid); 7948: #endif /* ADVANSYS_STATS */ 7949: } 7950: ASC_DBG1(3, "asc_dequeue: reqp %x\n", (unsigned) reqp); 7951: return reqp; 7952: } 7953: 7954: /* 7955: * Return a pointer to a singly linked list of all the requests queued 7956: * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'. 7957: * 7958: * If 'lastpp' is not NULL, '*lastpp' will be set to point to the 7959: * the last request returned in the singly linked list. 7960: * 7961: * 'tid' should either be a valid target id or if it is ASC_TID_ALL, 7962: * then all queued requests are concatenated into one list and 7963: * returned. 7964: * 7965: * Note: If 'lastpp' is used to append a new list to the end of 7966: * an old list, only change the old list last pointer if '*lastpp' 7967: * (or the function return value) is not NULL, i.e. use a temporary 7968: * variable for 'lastpp' and check its value after the function return 7969: * before assigning it to the list last pointer. 7970: * 7971: * Unfortunately collecting queuing time statistics adds overhead to 7972: * the function that isn't inherent to the function's algorithm. 7973: */ 7974: STATIC REQP 7975: asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid) 7976: { 7977: REQP firstp, lastp; 7978: int i; 7979: 7980: ASC_DBG2(3, "asc_dequeue_list: ascq %x, tid %d\n", (unsigned) ascq, tid); 7981: ASC_ASSERT(interrupts_enabled() == ASC_FALSE); 7982: ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID)); 7983: 7984: /* 7985: * If 'tid' is not ASC_TID_ALL, return requests only for 7986: * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all 7987: * requests for all tids. 7988: */ 7989: if (tid != ASC_TID_ALL) { 7990: /* Return all requests for the specified 'tid'. */ 7991: if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) { 7992: /* List is empty; Set first and last return pointers to NULL. */ 7993: firstp = lastp = NULL; 7994: } else { 7995: firstp = ascq->q_first[tid]; 7996: lastp = ascq->q_last[tid]; 7997: ascq->q_first[tid] = ascq->q_last[tid] = NULL; 7998: ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid); 7999: #ifdef ADVANSYS_STATS 8000: { 8001: REQP reqp; 8002: ascq->q_cur_cnt[tid] = 0; 1.1.1.2 ! root 8003: for (reqp = firstp; reqp; reqp = (REQP) REQPNEXT(reqp)) { 1.1 root 8004: REQTIMESTAT("asc_dequeue_list", ascq, reqp, tid); 8005: } 8006: } 8007: #endif /* ADVANSYS_STATS */ 8008: } 8009: } else { 8010: /* Return all requests for all tids. */ 8011: firstp = lastp = NULL; 8012: for (i = 0; i <= ADV_MAX_TID; i++) { 8013: if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) { 8014: if (firstp == NULL) { 8015: firstp = ascq->q_first[i]; 8016: lastp = ascq->q_last[i]; 8017: } else { 8018: ASC_ASSERT(lastp != NULL); 1.1.1.2 ! root 8019: REQPNEXT(lastp) = (unsigned char *) ascq->q_first[i]; 1.1 root 8020: lastp = ascq->q_last[i]; 8021: } 8022: ascq->q_first[i] = ascq->q_last[i] = NULL; 8023: ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i); 8024: #ifdef ADVANSYS_STATS 8025: ascq->q_cur_cnt[i] = 0; 8026: #endif /* ADVANSYS_STATS */ 8027: } 8028: } 8029: #ifdef ADVANSYS_STATS 8030: { 8031: REQP reqp; 1.1.1.2 ! root 8032: for (reqp = firstp; reqp; reqp = (REQP) REQPNEXT(reqp)) { 1.1 root 8033: REQTIMESTAT("asc_dequeue_list", ascq, reqp, reqp->target); 8034: } 8035: } 8036: #endif /* ADVANSYS_STATS */ 8037: } 8038: if (lastpp) { 8039: *lastpp = lastp; 8040: } 8041: ASC_DBG1(3, "asc_dequeue_list: firstp %x\n", (unsigned) firstp); 8042: return firstp; 8043: } 8044: 8045: /* 8046: * Remove the specified 'REQP' from the specified queue for 8047: * the specified target device. Clear the 'tidmask' bit for the 8048: * device if no more commands are left queued for it. 8049: * 8050: * 'REQPNEXT(reqp)' returns reqp's the next pointer. 8051: * 8052: * Return ASC_TRUE if the command was found and removed, 8053: * otherwise return ASC_FALSE. 8054: */ 8055: STATIC int 8056: asc_rmqueue(asc_queue_t *ascq, REQP reqp) 8057: { 8058: REQP currp, prevp; 8059: int tid; 8060: int ret = ASC_FALSE; 8061: 8062: ASC_DBG2(3, "asc_rmqueue: ascq %x, reqp %x\n", 8063: (unsigned) ascq, (unsigned) reqp); 8064: ASC_ASSERT(interrupts_enabled() == ASC_FALSE); 8065: ASC_ASSERT(reqp != NULL); 8066: 8067: tid = REQPTID(reqp); 8068: ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID); 8069: 8070: /* 8071: * Handle the common case of 'reqp' being the first 8072: * entry on the queue. 8073: */ 8074: if (reqp == ascq->q_first[tid]) { 8075: ret = ASC_TRUE; 1.1.1.2 ! root 8076: ascq->q_first[tid] = (REQP) REQPNEXT(reqp); 1.1 root 8077: /* If the queue is now empty, clear its bit and the last pointer. */ 8078: if (ascq->q_first[tid] == NULL) { 8079: ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid); 8080: ASC_ASSERT(ascq->q_last[tid] == reqp); 8081: ascq->q_last[tid] = NULL; 8082: } 8083: } else if (ascq->q_first[tid] != NULL) { 8084: ASC_ASSERT(ascq->q_last[tid] != NULL); 8085: /* 8086: * Because the case of 'reqp' being the first entry has been 8087: * handled above and it is known the queue is not empty, if 8088: * 'reqp' is found on the queue it is guaranteed the queue will 8089: * not become empty and that 'q_first[tid]' will not be changed. 8090: * 8091: * Set 'prevp' to the first entry, 'currp' to the second entry, 8092: * and search for 'reqp'. 8093: */ 1.1.1.2 ! root 8094: for (prevp = ascq->q_first[tid], currp = (REQP) REQPNEXT(prevp); ! 8095: currp; prevp = currp, currp = (REQP) REQPNEXT(currp)) { 1.1 root 8096: if (currp == reqp) { 8097: ret = ASC_TRUE; 8098: REQPNEXT(prevp) = REQPNEXT(currp); 8099: REQPNEXT(reqp) = NULL; 8100: if (ascq->q_last[tid] == reqp) { 8101: ascq->q_last[tid] = prevp; 8102: } 8103: break; 8104: } 8105: } 8106: } 8107: #ifdef ADVANSYS_STATS 8108: /* Maintain request queue statistics. */ 8109: if (ret == ASC_TRUE) { 8110: ascq->q_cur_cnt[tid]--; 8111: REQTIMESTAT("asc_rmqueue", ascq, reqp, tid); 8112: } 8113: ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0); 8114: #endif /* ADVANSYS_STATS */ 8115: ASC_DBG2(3, "asc_rmqueue: reqp %x, ret %d\n", (unsigned) reqp, ret); 8116: return ret; 8117: } 8118: 8119: /* 8120: * If the specified 'REQP' is queued on the specified queue for 8121: * the specified target device, return ASC_TRUE. 8122: */ 8123: STATIC int 8124: asc_isqueued(asc_queue_t *ascq, REQP reqp) 8125: { 8126: REQP treqp; 8127: int tid; 8128: int ret = ASC_FALSE; 8129: 8130: ASC_DBG2(3, "asc_isqueued: ascq %x, reqp %x\n", 8131: (unsigned) ascq, (unsigned) reqp); 8132: ASC_ASSERT(interrupts_enabled() == ASC_FALSE); 8133: ASC_ASSERT(reqp != NULL); 8134: 8135: tid = REQPTID(reqp); 8136: ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID); 8137: 1.1.1.2 ! root 8138: for (treqp = ascq->q_first[tid]; treqp; treqp = (REQP) REQPNEXT(treqp)) { 1.1 root 8139: ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)); 8140: if (treqp == reqp) { 8141: ret = ASC_TRUE; 8142: break; 8143: } 8144: } 8145: ASC_DBG1(3, "asc_isqueued: ret %x\n", ret); 8146: return ret; 8147: } 8148: 8149: /* 8150: * Execute as many queued requests as possible for the specified queue. 8151: * 8152: * Calls asc_execute_scsi_cmnd() to execute a REQP/Scsi_Cmnd. 8153: */ 8154: STATIC void 8155: asc_execute_queue(asc_queue_t *ascq) 8156: { 8157: ADV_SCSI_BIT_ID_TYPE scan_tidmask; 8158: REQP reqp; 8159: int i; 8160: 8161: ASC_DBG1(1, "asc_execute_queue: ascq %x\n", (unsigned) ascq); 8162: ASC_ASSERT(interrupts_enabled() == ASC_FALSE); 8163: /* 8164: * Execute queued commands for devices attached to 8165: * the current board in round-robin fashion. 8166: */ 8167: scan_tidmask = ascq->q_tidmask; 8168: do { 8169: for (i = 0; i <= ADV_MAX_TID; i++) { 8170: if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) { 8171: if ((reqp = asc_dequeue(ascq, i)) == NULL) { 8172: scan_tidmask &= ~ADV_TID_TO_TIDMASK(i); 8173: } else if (asc_execute_scsi_cmnd((Scsi_Cmnd *) reqp) 8174: == ASC_BUSY) { 8175: scan_tidmask &= ~ADV_TID_TO_TIDMASK(i); 8176: /* Put the request back at front of the list. */ 8177: asc_enqueue(ascq, reqp, ASC_FRONT); 8178: } 8179: } 8180: } 8181: } while (scan_tidmask); 8182: return; 8183: } 8184: 8185: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0) 8186: /* 8187: * asc_prt_board_devices() 8188: * 8189: * Print driver information for devices attached to the board. 8190: * 8191: * Note: no single line should be greater than ASC_PRTLINE_SIZE, 8192: * cf. asc_prt_line(). 8193: * 8194: * Return the number of characters copied into 'cp'. No more than 8195: * 'cplen' characters will be copied to 'cp'. 8196: */ 8197: STATIC int 8198: asc_prt_board_devices(struct Scsi_Host *shp, char *cp, int cplen) 8199: { 8200: asc_board_t *boardp; 8201: int leftlen; 8202: int totlen; 8203: int len; 8204: int chip_scsi_id; 8205: int i; 8206: 8207: boardp = ASC_BOARDP(shp); 8208: leftlen = cplen; 8209: totlen = len = 0; 8210: 8211: len = asc_prt_line(cp, leftlen, 8212: "\nDevice Information for AdvanSys SCSI Host %d:\n", shp->host_no); 8213: ASC_PRT_NEXT(); 8214: 8215: if (ASC_NARROW_BOARD(boardp)) { 8216: chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id; 8217: } else { 8218: chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id; 8219: } 8220: 8221: len = asc_prt_line(cp, leftlen, "Target IDs Detected:"); 8222: ASC_PRT_NEXT(); 8223: for (i = 0; i <= ADV_MAX_TID; i++) { 8224: if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) { 8225: len = asc_prt_line(cp, leftlen, " %X,", i); 8226: ASC_PRT_NEXT(); 8227: } 8228: } 8229: len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id); 8230: ASC_PRT_NEXT(); 8231: 8232: return totlen; 8233: } 8234: 8235: /* 8236: * Display Wide Board BIOS Information. 8237: */ 8238: STATIC int 8239: asc_prt_adv_bios(struct Scsi_Host *shp, char *cp, int cplen) 8240: { 8241: asc_board_t *boardp; 8242: int leftlen; 8243: int totlen; 8244: int len; 8245: int upgrade = ASC_FALSE; 8246: ushort major, minor, letter; 8247: 8248: boardp = ASC_BOARDP(shp); 8249: leftlen = cplen; 8250: totlen = len = 0; 8251: 8252: len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: "); 8253: ASC_PRT_NEXT(); 8254: 8255: /* 8256: * If the BIOS saved a valid signature, then fill in 8257: * the BIOS code segment base address. 8258: */ 8259: if (boardp->bios_signature != 0x55AA) { 8260: len = asc_prt_line(cp, leftlen, "Pre-3.1\n"); 8261: ASC_PRT_NEXT(); 8262: upgrade = ASC_TRUE; 8263: } else { 8264: major = (boardp->bios_version >> 12) & 0xF; 8265: minor = (boardp->bios_version >> 8) & 0xF; 8266: letter = (boardp->bios_version & 0xFF); 8267: 8268: len = asc_prt_line(cp, leftlen, "%d.%d%c\n", 8269: major, minor, letter >= 26 ? '?' : letter + 'A'); 8270: ASC_PRT_NEXT(); 8271: 8272: /* Current available ROM BIOS release is 3.1C. */ 8273: if (major < 3 || (major <= 3 && minor < 1) || 8274: (major <= 3 && minor <= 1 && letter < ('C'- 'A'))) { 8275: upgrade = ASC_TRUE; 8276: } 8277: } 8278: if (upgrade == ASC_TRUE) { 8279: len = asc_prt_line(cp, leftlen, 8280: "Newer version of ROM BIOS available: ftp://ftp.advansys.com/pub\n"); 8281: ASC_PRT_NEXT(); 8282: } 8283: 8284: return totlen; 8285: } 8286: 8287: /* 8288: * Add serial number to information bar if signature AAh 8289: * is found in at bit 15-9 (7 bits) of word 1. 8290: * 8291: * Serial Number consists fo 12 alpha-numeric digits. 8292: * 8293: * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits) 8294: * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits) 8295: * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits) 8296: * 5 - Product revision (A-J) Word0: " " 8297: * 8298: * Signature Word1: 15-9 (7 bits) 8299: * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit) 8300: * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits) 8301: * 8302: * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits) 8303: * 8304: * Note 1: Only production cards will have a serial number. 8305: * 8306: * Note 2: Signature is most significant 7 bits (0xFE). 8307: * 8308: * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE. 8309: */ 8310: STATIC int 8311: asc_get_eeprom_string(ushort *serialnum, uchar *cp) 8312: { 8313: ushort w, num; 8314: 8315: if ((serialnum[1] & 0xFE00) != ((ushort) 0xAA << 8)) { 8316: return ASC_FALSE; 8317: } else { 8318: /* 8319: * First word - 6 digits. 8320: */ 8321: w = serialnum[0]; 8322: 8323: /* Product type - 1st digit. */ 8324: if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') { 8325: /* Product type is P=Prototype */ 8326: *cp += 0x8; 8327: } 8328: cp++; 8329: 8330: /* Manufacturing location - 2nd digit. */ 8331: *cp++ = 'A' + ((w & 0x1C00) >> 10); 8332: 8333: /* Product ID - 3rd, 4th digits. */ 8334: num = w & 0x3FF; 8335: *cp++ = '0' + (num / 100); 8336: num %= 100; 8337: *cp++ = '0' + (num / 10); 8338: 8339: /* Product revision - 5th digit. */ 8340: *cp++ = 'A' + (num % 10); 8341: 8342: /* 8343: * Second word 8344: */ 8345: w = serialnum[1]; 8346: 8347: /* 8348: * Year - 6th digit. 8349: * 8350: * If bit 15 of third word is set, then the 8351: * last digit of the year is greater than 7. 8352: */ 8353: if (serialnum[2] & 0x8000) { 8354: *cp++ = '8' + ((w & 0x1C0) >> 6); 8355: } else { 8356: *cp++ = '0' + ((w & 0x1C0) >> 6); 8357: } 8358: 8359: /* Week of year - 7th, 8th digits. */ 8360: num = w & 0x003F; 8361: *cp++ = '0' + num / 10; 8362: num %= 10; 8363: *cp++ = '0' + num; 8364: 8365: /* 8366: * Third word 8367: */ 8368: w = serialnum[2] & 0x7FFF; 8369: 8370: /* Serial number - 9th digit. */ 8371: *cp++ = 'A' + (w / 1000); 8372: 8373: /* 10th, 11th, 12th digits. */ 8374: num = w % 1000; 8375: *cp++ = '0' + num / 100; 8376: num %= 100; 8377: *cp++ = '0' + num / 10; 8378: num %= 10; 8379: *cp++ = '0' + num; 8380: 8381: *cp = '\0'; /* Null Terminate the string. */ 8382: return ASC_TRUE; 8383: } 8384: } 8385: 8386: /* 8387: * asc_prt_asc_board_eeprom() 8388: * 8389: * Print board EEPROM configuration. 8390: * 8391: * Note: no single line should be greater than ASC_PRTLINE_SIZE, 8392: * cf. asc_prt_line(). 8393: * 8394: * Return the number of characters copied into 'cp'. No more than 8395: * 'cplen' characters will be copied to 'cp'. 8396: */ 8397: STATIC int 8398: asc_prt_asc_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen) 8399: { 8400: asc_board_t *boardp; 8401: ASC_DVC_VAR *asc_dvc_varp; 8402: int leftlen; 8403: int totlen; 8404: int len; 8405: ASCEEP_CONFIG *ep; 8406: int i; 8407: int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 }; 8408: uchar serialstr[13]; 8409: 8410: boardp = ASC_BOARDP(shp); 8411: asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; 8412: ep = &boardp->eep_config.asc_eep; 8413: 8414: leftlen = cplen; 8415: totlen = len = 0; 8416: 8417: len = asc_prt_line(cp, leftlen, 8418: "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no); 8419: ASC_PRT_NEXT(); 8420: 8421: if (asc_get_eeprom_string((ushort *) &ep->adapter_info[0], serialstr) == 8422: ASC_TRUE) { 8423: len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr); 8424: ASC_PRT_NEXT(); 8425: } else { 8426: if (ep->adapter_info[5] == 0xBB) { 8427: len = asc_prt_line(cp, leftlen, 8428: " Default Settings Used for EEPROM-less Adapter.\n"); 8429: ASC_PRT_NEXT(); 8430: } else { 8431: len = asc_prt_line(cp, leftlen, 8432: " Serial Number Signature Not Present.\n"); 8433: ASC_PRT_NEXT(); 8434: } 8435: } 8436: 8437: len = asc_prt_line(cp, leftlen, 8438: " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n", 8439: ep->chip_scsi_id, ep->max_total_qng, ep->max_tag_qng); 8440: ASC_PRT_NEXT(); 8441: 8442: len = asc_prt_line(cp, leftlen, 8443: " cntl %x, no_scam %x\n", 8444: ep->cntl, ep->no_scam); 8445: ASC_PRT_NEXT(); 8446: 8447: len = asc_prt_line(cp, leftlen, 8448: " Target ID: "); 8449: ASC_PRT_NEXT(); 8450: for (i = 0; i <= ASC_MAX_TID; i++) { 8451: len = asc_prt_line(cp, leftlen, " %d", i); 8452: ASC_PRT_NEXT(); 8453: } 8454: len = asc_prt_line(cp, leftlen, "\n"); 8455: ASC_PRT_NEXT(); 8456: 8457: len = asc_prt_line(cp, leftlen, 8458: " Disconnects: "); 8459: ASC_PRT_NEXT(); 8460: for (i = 0; i <= ASC_MAX_TID; i++) { 8461: len = asc_prt_line(cp, leftlen, " %c", 8462: (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); 8463: ASC_PRT_NEXT(); 8464: } 8465: len = asc_prt_line(cp, leftlen, "\n"); 8466: ASC_PRT_NEXT(); 8467: 8468: len = asc_prt_line(cp, leftlen, 8469: " Command Queuing: "); 8470: ASC_PRT_NEXT(); 8471: for (i = 0; i <= ASC_MAX_TID; i++) { 8472: len = asc_prt_line(cp, leftlen, " %c", 8473: (ep->use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); 8474: ASC_PRT_NEXT(); 8475: } 8476: len = asc_prt_line(cp, leftlen, "\n"); 8477: ASC_PRT_NEXT(); 8478: 8479: len = asc_prt_line(cp, leftlen, 8480: " Start Motor: "); 8481: ASC_PRT_NEXT(); 8482: for (i = 0; i <= ASC_MAX_TID; i++) { 8483: len = asc_prt_line(cp, leftlen, " %c", 8484: (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); 8485: ASC_PRT_NEXT(); 8486: } 8487: len = asc_prt_line(cp, leftlen, "\n"); 8488: ASC_PRT_NEXT(); 8489: 8490: len = asc_prt_line(cp, leftlen, 8491: " Synchronous Transfer:"); 8492: ASC_PRT_NEXT(); 8493: for (i = 0; i <= ASC_MAX_TID; i++) { 8494: len = asc_prt_line(cp, leftlen, " %c", 8495: (ep->init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); 8496: ASC_PRT_NEXT(); 8497: } 8498: len = asc_prt_line(cp, leftlen, "\n"); 8499: ASC_PRT_NEXT(); 8500: 8501: if (asc_dvc_varp->bus_type & ASC_IS_ISA) { 8502: len = asc_prt_line(cp, leftlen, 8503: " Host ISA DMA speed: %d MB/S\n", 8504: isa_dma_speed[ep->isa_dma_speed]); 8505: ASC_PRT_NEXT(); 8506: } 8507: 8508: return totlen; 8509: } 8510: 8511: /* 8512: * asc_prt_adv_board_eeprom() 8513: * 8514: * Print board EEPROM configuration. 8515: * 8516: * Note: no single line should be greater than ASC_PRTLINE_SIZE, 8517: * cf. asc_prt_line(). 8518: * 8519: * Return the number of characters copied into 'cp'. No more than 8520: * 'cplen' characters will be copied to 'cp'. 8521: */ 8522: STATIC int 8523: asc_prt_adv_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen) 8524: { 8525: asc_board_t *boardp; 8526: ADV_DVC_VAR *adv_dvc_varp; 8527: int leftlen; 8528: int totlen; 8529: int len; 8530: int i; 8531: char *termstr; 8532: uchar serialstr[13]; 8533: ADVEEP_CONFIG *ep; 8534: 8535: boardp = ASC_BOARDP(shp); 8536: adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; 8537: ep = &boardp->eep_config.adv_eep; 8538: 8539: leftlen = cplen; 8540: totlen = len = 0; 8541: 8542: len = asc_prt_line(cp, leftlen, 8543: "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no); 8544: ASC_PRT_NEXT(); 8545: 8546: if (asc_get_eeprom_string(&ep->serial_number_word1, serialstr) == 8547: ASC_TRUE) { 8548: len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr); 8549: ASC_PRT_NEXT(); 8550: } else { 8551: len = asc_prt_line(cp, leftlen, 8552: " Serial Number Signature Not Present.\n"); 8553: ASC_PRT_NEXT(); 8554: } 8555: 8556: len = asc_prt_line(cp, leftlen, 8557: " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n", 8558: ep->adapter_scsi_id, ep->max_host_qng, ep->max_dvc_qng); 8559: ASC_PRT_NEXT(); 8560: 8561: switch (ep->termination) { 8562: case 1: 8563: termstr = "Low Off/High Off"; 8564: break; 8565: case 2: 8566: termstr = "Low Off/High On"; 8567: break; 8568: case 3: 8569: termstr = "Low On/High On"; 8570: break; 8571: default: 8572: case 0: 8573: termstr = "Automatic"; 8574: break; 8575: } 8576: 8577: len = asc_prt_line(cp, leftlen, 8578: " termination: %u (%s), bios_ctrl: %x\n", 8579: ep->termination, termstr, ep->bios_ctrl); 8580: ASC_PRT_NEXT(); 8581: 8582: len = asc_prt_line(cp, leftlen, 8583: " Target ID: "); 8584: ASC_PRT_NEXT(); 8585: for (i = 0; i <= ADV_MAX_TID; i++) { 8586: len = asc_prt_line(cp, leftlen, " %X", i); 8587: ASC_PRT_NEXT(); 8588: } 8589: len = asc_prt_line(cp, leftlen, "\n"); 8590: ASC_PRT_NEXT(); 8591: 8592: len = asc_prt_line(cp, leftlen, 8593: " Disconnects: "); 8594: ASC_PRT_NEXT(); 8595: for (i = 0; i <= ADV_MAX_TID; i++) { 8596: len = asc_prt_line(cp, leftlen, " %c", 8597: (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); 8598: ASC_PRT_NEXT(); 8599: } 8600: len = asc_prt_line(cp, leftlen, "\n"); 8601: ASC_PRT_NEXT(); 8602: 8603: len = asc_prt_line(cp, leftlen, 8604: " Command Queuing: "); 8605: ASC_PRT_NEXT(); 8606: for (i = 0; i <= ADV_MAX_TID; i++) { 8607: len = asc_prt_line(cp, leftlen, " %c", 8608: (ep->tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); 8609: ASC_PRT_NEXT(); 8610: } 8611: len = asc_prt_line(cp, leftlen, "\n"); 8612: ASC_PRT_NEXT(); 8613: 8614: len = asc_prt_line(cp, leftlen, 8615: " Start Motor: "); 8616: ASC_PRT_NEXT(); 8617: for (i = 0; i <= ADV_MAX_TID; i++) { 8618: len = asc_prt_line(cp, leftlen, " %c", 8619: (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); 8620: ASC_PRT_NEXT(); 8621: } 8622: len = asc_prt_line(cp, leftlen, "\n"); 8623: ASC_PRT_NEXT(); 8624: 8625: len = asc_prt_line(cp, leftlen, 8626: " Synchronous Transfer:"); 8627: ASC_PRT_NEXT(); 8628: for (i = 0; i <= ADV_MAX_TID; i++) { 8629: len = asc_prt_line(cp, leftlen, " %c", 8630: (ep->sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); 8631: ASC_PRT_NEXT(); 8632: } 8633: len = asc_prt_line(cp, leftlen, "\n"); 8634: ASC_PRT_NEXT(); 8635: 8636: len = asc_prt_line(cp, leftlen, 8637: " Ultra Transfer: "); 8638: ASC_PRT_NEXT(); 8639: for (i = 0; i <= ADV_MAX_TID; i++) { 8640: len = asc_prt_line(cp, leftlen, " %c", 8641: (ep->ultra_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); 8642: ASC_PRT_NEXT(); 8643: } 8644: len = asc_prt_line(cp, leftlen, "\n"); 8645: ASC_PRT_NEXT(); 8646: 8647: len = asc_prt_line(cp, leftlen, 8648: " Wide Transfer: "); 8649: ASC_PRT_NEXT(); 8650: for (i = 0; i <= ADV_MAX_TID; i++) { 8651: len = asc_prt_line(cp, leftlen, " %c", 8652: (ep->wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); 8653: ASC_PRT_NEXT(); 8654: } 8655: len = asc_prt_line(cp, leftlen, "\n"); 8656: ASC_PRT_NEXT(); 8657: 8658: return totlen; 8659: } 8660: 8661: /* 8662: * asc_prt_driver_conf() 8663: * 8664: * Note: no single line should be greater than ASC_PRTLINE_SIZE, 8665: * cf. asc_prt_line(). 8666: * 8667: * Return the number of characters copied into 'cp'. No more than 8668: * 'cplen' characters will be copied to 'cp'. 8669: */ 8670: STATIC int 8671: asc_prt_driver_conf(struct Scsi_Host *shp, char *cp, int cplen) 8672: { 8673: asc_board_t *boardp; 8674: int leftlen; 8675: int totlen; 8676: int len; 8677: int chip_scsi_id; 8678: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89) 8679: int i; 8680: #endif /* version >= v1.3.89 */ 8681: 8682: boardp = ASC_BOARDP(shp); 8683: 8684: leftlen = cplen; 8685: totlen = len = 0; 8686: 8687: len = asc_prt_line(cp, leftlen, 8688: "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n", 8689: shp->host_no); 8690: ASC_PRT_NEXT(); 8691: 8692: len = asc_prt_line(cp, leftlen, 8693: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89) 8694: " host_busy %u, last_reset %u, max_id %u, max_lun %u\n", 8695: shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun); 8696: #else /* version >= v1.3.89 */ 8697: " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n", 8698: shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun, 8699: shp->max_channel); 8700: #endif /* version >= v1.3.89 */ 8701: ASC_PRT_NEXT(); 8702: 8703: len = asc_prt_line(cp, leftlen, 8704: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,57) 8705: " can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n", 8706: shp->can_queue, shp->this_id, shp->sg_tablesize, shp->cmd_per_lun); 8707: #else /* version >= v1.3.57 */ 8708: " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n", 8709: shp->unique_id, shp->can_queue, shp->this_id, shp->sg_tablesize, 8710: shp->cmd_per_lun); 8711: #endif /* version >= v1.3.57 */ 8712: ASC_PRT_NEXT(); 8713: 8714: len = asc_prt_line(cp, leftlen, 8715: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,57) 8716: " unchecked_isa_dma %d, loaded_as_module %d\n", 8717: shp->unchecked_isa_dma, shp->loaded_as_module); 8718: #else /* version >= v1.3.57 */ 8719: " unchecked_isa_dma %d, use_clustering %d, loaded_as_module %d\n", 8720: shp->unchecked_isa_dma, shp->use_clustering, shp->loaded_as_module); 8721: #endif /* version >= v1.3.57 */ 8722: ASC_PRT_NEXT(); 8723: 8724: len = asc_prt_line(cp, leftlen, " flags %x, last_reset %x, jiffies %x\n", 8725: boardp->flags, boardp->last_reset, jiffies); 8726: ASC_PRT_NEXT(); 8727: 8728: if (ASC_NARROW_BOARD(boardp)) { 8729: chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id; 8730: } else { 8731: chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id; 8732: } 8733: 8734: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89) 8735: if (boardp->flags & ASC_SELECT_QUEUE_DEPTHS) { 8736: len = asc_prt_line(cp, leftlen, " queue_depth:"); 8737: ASC_PRT_NEXT(); 8738: for (i = 0; i <= ADV_MAX_TID; i++) { 8739: if ((chip_scsi_id == i) || 8740: ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { 8741: continue; 8742: } 8743: if (boardp->device[i] == NULL) { 8744: continue; 8745: } 8746: len = asc_prt_line(cp, leftlen, " %X:%d", 8747: i, boardp->device[i]->queue_depth); 8748: ASC_PRT_NEXT(); 8749: } 8750: len = asc_prt_line(cp, leftlen, "\n"); 8751: ASC_PRT_NEXT(); 8752: } 8753: #endif /* version >= v1.3.89 */ 8754: 8755: #if ASC_QUEUE_FLOW_CONTROL 8756: if (ASC_NARROW_BOARD(boardp)) { 8757: len = asc_prt_line(cp, leftlen, " queue_curr_depth:"); 8758: ASC_PRT_NEXT(); 8759: /* Use ASC_MAX_TID for Narrow Board. */ 8760: for (i = 0; i <= ASC_MAX_TID; i++) { 8761: if ((boardp->asc_dvc_cfg.chip_scsi_id == i) || 8762: ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { 8763: continue; 8764: } 8765: if (boardp->device[i] == NULL) { 8766: continue; 8767: } 8768: len = asc_prt_line(cp, leftlen, " %d:%d", 8769: i, boardp->device[i]->queue_curr_depth); 8770: ASC_PRT_NEXT(); 8771: } 8772: len = asc_prt_line(cp, leftlen, "\n"); 8773: ASC_PRT_NEXT(); 8774: 8775: len = asc_prt_line(cp, leftlen, " queue_count:"); 8776: ASC_PRT_NEXT(); 8777: /* Use ASC_MAX_TID for Narrow Board. */ 8778: for (i = 0; i <= ASC_MAX_TID; i++) { 8779: if ((boardp->asc_dvc_cfg.chip_scsi_id == i) || 8780: ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { 8781: continue; 8782: } 8783: if (boardp->device[i] == NULL) { 8784: continue; 8785: } 8786: len = asc_prt_line(cp, leftlen, " %d:%d", 8787: i, boardp->device[i]->queue_count); 8788: ASC_PRT_NEXT(); 8789: } 8790: len = asc_prt_line(cp, leftlen, "\n"); 8791: ASC_PRT_NEXT(); 8792: } 8793: #endif /* ASC_QUEUE_FLOW_CONTROL */ 8794: 8795: return totlen; 8796: } 8797: 8798: /* 8799: * asc_prt_asc_board_info() 8800: * 8801: * Print dynamic board configuration information. 8802: * 8803: * Note: no single line should be greater than ASC_PRTLINE_SIZE, 8804: * cf. asc_prt_line(). 8805: * 8806: * Return the number of characters copied into 'cp'. No more than 8807: * 'cplen' characters will be copied to 'cp'. 8808: */ 8809: STATIC int 8810: asc_prt_asc_board_info(struct Scsi_Host *shp, char *cp, int cplen) 8811: { 8812: asc_board_t *boardp; 8813: int leftlen; 8814: int totlen; 8815: int len; 8816: ASC_DVC_VAR *v; 8817: ASC_DVC_CFG *c; 8818: int i; 8819: 8820: boardp = ASC_BOARDP(shp); 8821: v = &boardp->dvc_var.asc_dvc_var; 8822: c = &boardp->dvc_cfg.asc_dvc_cfg; 8823: 8824: leftlen = cplen; 8825: totlen = len = 0; 8826: 8827: len = asc_prt_line(cp, leftlen, 8828: "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n", 8829: shp->host_no); 8830: ASC_PRT_NEXT(); 8831: 8832: len = asc_prt_line(cp, leftlen, 8833: " chip_version %u, lib_version %x, lib_serial_no %u, mcode_date %x\n", 8834: c->chip_version, c->lib_version, c->lib_serial_no, c->mcode_date); 8835: ASC_PRT_NEXT(); 8836: 8837: len = asc_prt_line(cp, leftlen, 8838: " mcode_version %x, err_code %u\n", 8839: c->mcode_version, v->err_code); 8840: ASC_PRT_NEXT(); 8841: 8842: /* Current number of commands waiting for the host. */ 8843: len = asc_prt_line(cp, leftlen, 8844: " Total Command Pending: %d\n", v->cur_total_qng); 8845: ASC_PRT_NEXT(); 8846: 8847: len = asc_prt_line(cp, leftlen, 8848: " Command Queuing:"); 8849: ASC_PRT_NEXT(); 8850: for (i = 0; i <= ASC_MAX_TID; i++) { 8851: if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) || 8852: ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { 8853: continue; 8854: } 8855: len = asc_prt_line(cp, leftlen, " %d:%c", 8856: i, (v->use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); 8857: ASC_PRT_NEXT(); 8858: } 8859: len = asc_prt_line(cp, leftlen, "\n"); 8860: ASC_PRT_NEXT(); 8861: 8862: /* Current number of commands waiting for a device. */ 8863: len = asc_prt_line(cp, leftlen, 8864: " Command Queue Pending:"); 8865: ASC_PRT_NEXT(); 8866: for (i = 0; i <= ASC_MAX_TID; i++) { 8867: if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) || 8868: ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { 8869: continue; 8870: } 8871: len = asc_prt_line(cp, leftlen, " %d:%u", i, v->cur_dvc_qng[i]); 8872: ASC_PRT_NEXT(); 8873: } 8874: len = asc_prt_line(cp, leftlen, "\n"); 8875: ASC_PRT_NEXT(); 8876: 8877: /* Current limit on number of commands that can be sent to a device. */ 8878: len = asc_prt_line(cp, leftlen, 8879: " Command Queue Limit:"); 8880: ASC_PRT_NEXT(); 8881: for (i = 0; i <= ASC_MAX_TID; i++) { 8882: if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) || 8883: ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { 8884: continue; 8885: } 8886: len = asc_prt_line(cp, leftlen, " %d:%u", i, v->max_dvc_qng[i]); 8887: ASC_PRT_NEXT(); 8888: } 8889: len = asc_prt_line(cp, leftlen, "\n"); 8890: ASC_PRT_NEXT(); 8891: 8892: /* Indicate whether the device has returned queue full status. */ 8893: len = asc_prt_line(cp, leftlen, 8894: " Command Queue Full:"); 8895: ASC_PRT_NEXT(); 8896: for (i = 0; i <= ASC_MAX_TID; i++) { 8897: if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) || 8898: ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { 8899: continue; 8900: } 8901: if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) { 8902: len = asc_prt_line(cp, leftlen, " %d:Y-%d", 8903: i, boardp->queue_full_cnt[i]); 8904: } else { 8905: len = asc_prt_line(cp, leftlen, " %d:N", i); 8906: } 8907: ASC_PRT_NEXT(); 8908: } 8909: len = asc_prt_line(cp, leftlen, "\n"); 8910: ASC_PRT_NEXT(); 8911: 8912: len = asc_prt_line(cp, leftlen, 8913: " Synchronous Transfer:"); 8914: ASC_PRT_NEXT(); 8915: for (i = 0; i <= ASC_MAX_TID; i++) { 8916: if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) || 8917: ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { 8918: continue; 8919: } 8920: len = asc_prt_line(cp, leftlen, " %d:%c", 8921: i, (v->sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); 8922: ASC_PRT_NEXT(); 8923: } 8924: len = asc_prt_line(cp, leftlen, "\n"); 8925: ASC_PRT_NEXT(); 8926: 8927: for (i = 0; i <= ASC_MAX_TID; i++) { 8928: uchar syn_period_ix; 8929: 8930: if ((boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id == i) || 8931: ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { 8932: continue; 8933: } 8934: if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) { 8935: continue; 8936: } 8937: syn_period_ix = (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index - 1); 8938: len = asc_prt_line(cp, leftlen, " %d:", i); 8939: ASC_PRT_NEXT(); 8940: 8941: len = asc_prt_line(cp, leftlen, 8942: " Transfer Period Factor: %d (%d.%d Mhz),", 8943: v->sdtr_period_tbl[syn_period_ix], 8944: 250 / v->sdtr_period_tbl[syn_period_ix], 8945: ASC_TENTHS(250, v->sdtr_period_tbl[syn_period_ix])); 8946: ASC_PRT_NEXT(); 8947: 8948: len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d\n", 8949: boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET); 8950: ASC_PRT_NEXT(); 8951: } 8952: 8953: return totlen; 8954: } 8955: 8956: /* 8957: * asc_prt_adv_board_info() 8958: * 8959: * Print dynamic board configuration information. 8960: * 8961: * Note: no single line should be greater than ASC_PRTLINE_SIZE, 8962: * cf. asc_prt_line(). 8963: * 8964: * Return the number of characters copied into 'cp'. No more than 8965: * 'cplen' characters will be copied to 'cp'. 8966: */ 8967: STATIC int 8968: asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen) 8969: { 8970: asc_board_t *boardp; 8971: int leftlen; 8972: int totlen; 8973: int len; 8974: int i; 8975: ADV_DVC_VAR *v; 8976: ADV_DVC_CFG *c; 8977: AdvPortAddr iop_base; 8978: ushort chip_scsi_id; 8979: ushort lramword; 8980: uchar lrambyte; 8981: ushort sdtr_able; 8982: ushort period; 8983: 8984: boardp = ASC_BOARDP(shp); 8985: v = &boardp->dvc_var.adv_dvc_var; 8986: c = &boardp->dvc_cfg.adv_dvc_cfg; 8987: iop_base = v->iop_base; 8988: chip_scsi_id = v->chip_scsi_id; 8989: 8990: leftlen = cplen; 8991: totlen = len = 0; 8992: 8993: len = asc_prt_line(cp, leftlen, 8994: "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n", 8995: shp->host_no); 8996: ASC_PRT_NEXT(); 8997: 8998: len = asc_prt_line(cp, leftlen, 8999: " iop_base %lx, cable_detect: %X, err_code %u, idle_cmd_done %u\n", 9000: v->iop_base, 9001: AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1) & CABLE_DETECT, 9002: v->err_code, v->idle_cmd_done); 9003: ASC_PRT_NEXT(); 9004: 9005: len = asc_prt_line(cp, leftlen, 9006: " chip_version %u, lib_version %x, mcode_date %x, mcode_version %x\n", 9007: c->chip_version, c->lib_version, c->mcode_date, c->mcode_version); 9008: ASC_PRT_NEXT(); 9009: 9010: AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, lramword); 9011: len = asc_prt_line(cp, leftlen, 9012: " Queuing Enabled:"); 9013: ASC_PRT_NEXT(); 9014: for (i = 0; i <= ADV_MAX_TID; i++) { 9015: if ((chip_scsi_id == i) || 9016: ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { 9017: continue; 9018: } 9019: 9020: len = asc_prt_line(cp, leftlen, " %X:%c", 9021: i, (lramword & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); 9022: ASC_PRT_NEXT(); 9023: } 9024: len = asc_prt_line(cp, leftlen, "\n"); 9025: ASC_PRT_NEXT(); 9026: 9027: len = asc_prt_line(cp, leftlen, 9028: " Queue Limit:"); 9029: ASC_PRT_NEXT(); 9030: for (i = 0; i <= ADV_MAX_TID; i++) { 9031: if ((chip_scsi_id == i) || 9032: ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { 9033: continue; 9034: } 9035: 9036: AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i, lrambyte); 9037: 9038: len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte); 9039: ASC_PRT_NEXT(); 9040: } 9041: len = asc_prt_line(cp, leftlen, "\n"); 9042: ASC_PRT_NEXT(); 9043: 9044: len = asc_prt_line(cp, leftlen, 9045: " Command Pending:"); 9046: ASC_PRT_NEXT(); 9047: for (i = 0; i <= ADV_MAX_TID; i++) { 9048: if ((chip_scsi_id == i) || 9049: ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { 9050: continue; 9051: } 9052: 9053: AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i, lrambyte); 9054: 9055: len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte); 9056: ASC_PRT_NEXT(); 9057: } 9058: len = asc_prt_line(cp, leftlen, "\n"); 9059: ASC_PRT_NEXT(); 9060: 9061: AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, lramword); 9062: len = asc_prt_line(cp, leftlen, 9063: " Wide Enabled:"); 9064: ASC_PRT_NEXT(); 9065: for (i = 0; i <= ADV_MAX_TID; i++) { 9066: if ((chip_scsi_id == i) || 9067: ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { 9068: continue; 9069: } 9070: 9071: len = asc_prt_line(cp, leftlen, " %X:%c", 9072: i, (lramword & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); 9073: ASC_PRT_NEXT(); 9074: } 9075: len = asc_prt_line(cp, leftlen, "\n"); 9076: ASC_PRT_NEXT(); 9077: 9078: len = asc_prt_line(cp, leftlen, 9079: " Transfer Bit Width:"); 9080: ASC_PRT_NEXT(); 9081: for (i = 0; i <= ADV_MAX_TID; i++) { 9082: if ((chip_scsi_id == i) || 9083: ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { 9084: continue; 9085: } 9086: 9087: AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i), 9088: lramword); 9089: len = asc_prt_line(cp, leftlen, " %X:%d", 9090: i, (lramword & 0x8000) ? 16 : 8); 9091: ASC_PRT_NEXT(); 9092: } 9093: len = asc_prt_line(cp, leftlen, "\n"); 9094: ASC_PRT_NEXT(); 9095: 9096: AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); 9097: len = asc_prt_line(cp, leftlen, 9098: " Synchronous Enabled:"); 9099: ASC_PRT_NEXT(); 9100: for (i = 0; i <= ADV_MAX_TID; i++) { 9101: if ((chip_scsi_id == i) || 9102: ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { 9103: continue; 9104: } 9105: 9106: len = asc_prt_line(cp, leftlen, " %X:%c", 9107: i, (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); 9108: ASC_PRT_NEXT(); 9109: } 9110: len = asc_prt_line(cp, leftlen, "\n"); 9111: ASC_PRT_NEXT(); 9112: 9113: for (i = 0; i <= ADV_MAX_TID; i++) { 9114: 9115: AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i), 9116: lramword); 9117: lramword &= ~0x8000; 9118: 9119: if ((chip_scsi_id == i) || 9120: ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0) || 9121: (lramword == 0)) { 9122: continue; 9123: } 9124: 9125: len = asc_prt_line(cp, leftlen, " %X:", i); 9126: ASC_PRT_NEXT(); 9127: 9128: period = (((lramword >> 8) * 25) + 50)/4; 9129: 9130: len = asc_prt_line(cp, leftlen, 9131: " Transfer Period Factor: %d (%d.%d Mhz),", 9132: period, 250/period, ASC_TENTHS(250, period)); 9133: ASC_PRT_NEXT(); 9134: 9135: len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d\n", 9136: lramword & 0x1F); 9137: ASC_PRT_NEXT(); 9138: } 9139: 9140: return totlen; 9141: } 9142: 9143: /* 9144: * asc_proc_copy() 9145: * 9146: * Copy proc information to a read buffer taking into account the current 9147: * read offset in the file and the remaining space in the read buffer. 9148: */ 9149: STATIC int 9150: asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen, 9151: char *cp, int cplen) 9152: { 9153: int cnt = 0; 9154: 9155: ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n", 9156: (unsigned) offset, (unsigned) advoffset, cplen); 9157: if (offset <= advoffset) { 9158: /* Read offset below current offset, copy everything. */ 9159: cnt = ASC_MIN(cplen, leftlen); 9160: ASC_DBG3(2, "asc_proc_copy: curbuf %x, cp %x, cnt %d\n", 9161: (unsigned) curbuf, (unsigned) cp, cnt); 9162: memcpy(curbuf, cp, cnt); 9163: } else if (offset < advoffset + cplen) { 9164: /* Read offset within current range, partial copy. */ 9165: cnt = (advoffset + cplen) - offset; 9166: cp = (cp + cplen) - cnt; 9167: cnt = ASC_MIN(cnt, leftlen); 9168: ASC_DBG3(2, "asc_proc_copy: curbuf %x, cp %x, cnt %d\n", 9169: (unsigned) curbuf, (unsigned) cp, cnt); 9170: memcpy(curbuf, cp, cnt); 9171: } 9172: return cnt; 9173: } 9174: 9175: /* 9176: * asc_prt_line() 9177: * 9178: * If 'cp' is NULL print to the console, otherwise print to a buffer. 9179: * 9180: * Return 0 if printing to the console, otherwise return the number of 9181: * bytes written to the buffer. 9182: * 9183: * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack 9184: * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes. 9185: */ 9186: STATIC int 9187: asc_prt_line(char *buf, int buflen, char *fmt, ...) 9188: { 9189: va_list args; 9190: int ret; 9191: char s[ASC_PRTLINE_SIZE]; 9192: 9193: va_start(args, fmt); 9194: ret = vsprintf(s, fmt, args); 9195: ASC_ASSERT(ret < ASC_PRTLINE_SIZE); 9196: if (buf == NULL) { 1.1.1.2 ! root 9197: (void) printk("%s", s); 1.1 root 9198: ret = 0; 9199: } else { 9200: ret = ASC_MIN(buflen, ret); 9201: memcpy(buf, s, ret); 9202: } 9203: va_end(args); 9204: return ret; 9205: } 9206: #endif /* version >= v1.3.0 */ 9207: 9208: 9209: /* 9210: * --- Functions Required by the Asc Library 9211: */ 9212: 9213: /* 9214: * Delay for 'n' milliseconds. Don't use the 'jiffies' 9215: * global variable which is incremented once every 5 ms 9216: * from a timer interrupt, because this function may be 9217: * called when interrupts are disabled. 9218: */ 9219: STATIC void 9220: DvcSleepMilliSecond(ulong n) 9221: { 9222: ulong i; 9223: 9224: ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", n); 9225: for (i = 0; i < n; i++) { 9226: udelay(1000); 9227: } 9228: } 9229: 1.1.1.2 ! root 9230: STATIC long 1.1 root 9231: DvcEnterCritical(void) 9232: { 1.1.1.2 ! root 9233: long flags; 1.1 root 9234: 9235: save_flags(flags); 9236: cli(); 9237: return flags; 9238: } 9239: 9240: STATIC void 1.1.1.2 ! root 9241: DvcLeaveCritical(long flags) 1.1 root 9242: { 9243: restore_flags(flags); 9244: } 9245: 9246: STATIC ulong 9247: DvcGetSGList(ASC_DVC_VAR *asc_dvc_sg, uchar *buf_addr, ulong buf_len, 9248: ASC_SG_HEAD *asc_sg_head_ptr) 9249: { 9250: ulong buf_size; 9251: 9252: buf_size = buf_len; 9253: asc_sg_head_ptr->entry_cnt = 1; 9254: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0) 9255: asc_sg_head_ptr->sg_list[0].addr = (ulong) buf_addr; 9256: #else /* version >= v2.0.0 */ 9257: asc_sg_head_ptr->sg_list[0].addr = virt_to_bus(buf_addr); 9258: #endif /* version >= v2.0.0 */ 9259: asc_sg_head_ptr->sg_list[0].bytes = buf_size; 9260: return buf_size; 9261: } 9262: 9263: /* 9264: * void 9265: * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, ushort *outbuf, int words) 9266: * 9267: * Calling/Exit State: 9268: * none 9269: * 9270: * Description: 9271: * Output an ASC_SCSI_Q structure to the chip 9272: */ 9273: STATIC void 9274: DvcPutScsiQ(PortAddr iop_base, ushort s_addr, ushort *outbuf, int words) 9275: { 9276: int i; 9277: 9278: ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", (uchar *) outbuf, 2 * words); 9279: AscSetChipLramAddr(iop_base, s_addr); 9280: for (i = 0; i < words; i++, outbuf++) { 9281: if (i == 2 || i == 10) { 9282: continue; 9283: } 9284: AscSetChipLramDataNoSwap(iop_base, *outbuf); 9285: } 9286: } 9287: 9288: /* 9289: * void 9290: * DvcGetQinfo(PortAddr iop_base, ushort s_addr, ushort *inbuf, int words) 9291: * 9292: * Calling/Exit State: 9293: * none 9294: * 9295: * Description: 9296: * Input an ASC_QDONE_INFO structure from the chip 9297: */ 9298: STATIC void 9299: DvcGetQinfo(PortAddr iop_base, ushort s_addr, ushort *inbuf, int words) 9300: { 9301: int i; 9302: 9303: AscSetChipLramAddr(iop_base, s_addr); 9304: for (i = 0; i < words; i++, inbuf++) { 9305: if (i == 5) { 9306: continue; 9307: } 9308: *inbuf = AscGetChipLramDataNoSwap(iop_base); 9309: } 9310: ASC_DBG_PRT_HEX(2, "DvcGetQinfo", (uchar *) inbuf, 2 * words); 9311: } 9312: 9313: /* 9314: * void DvcOutPortWords(ushort iop_base, ushort &outbuf, int words) 9315: * 9316: * Calling/Exit State: 9317: * none 9318: * 9319: * Description: 9320: * output a buffer to an i/o port address 9321: */ 9322: STATIC void 9323: DvcOutPortWords(ushort iop_base, ushort *outbuf, int words) 9324: { 9325: int i; 9326: 9327: for (i = 0; i < words; i++, outbuf++) 9328: outpw(iop_base, *outbuf); 9329: } 9330: 9331: /* 9332: * void DvcInPortWords(ushort iop_base, ushort &outbuf, int words) 9333: * 9334: * Calling/Exit State: 9335: * none 9336: * 9337: * Description: 9338: * input a buffer from an i/o port address 9339: */ 9340: STATIC void 9341: DvcInPortWords(ushort iop_base, ushort *inbuf, int words) 9342: { 9343: int i; 9344: 9345: for (i = 0; i < words; i++, inbuf++) 9346: *inbuf = inpw(iop_base); 9347: } 9348: 9349: /* 9350: * void DvcOutPortDWords(PortAddr port, ulong *pdw, int dwords) 9351: * 9352: * Calling/Exit State: 9353: * none 9354: * 9355: * Description: 9356: * output a buffer of 32-bit integers to an i/o port address in 9357: * 16 bit integer units 9358: */ 9359: STATIC void 9360: DvcOutPortDWords(PortAddr port, ulong *pdw, int dwords) 9361: { 9362: int i; 9363: int words; 9364: ushort *pw; 9365: 9366: pw = (ushort *) pdw; 9367: words = dwords << 1; 9368: for(i = 0; i < words; i++, pw++) { 9369: outpw(port, *pw); 9370: } 9371: return; 9372: } 9373: 9374: /* 9375: * Read a PCI configuration byte. 9376: */ 9377: ASC_INITFUNC( 9378: STATIC uchar 9379: DvcReadPCIConfigByte( 9380: ASC_DVC_VAR asc_ptr_type *asc_dvc, 9381: ushort offset) 9382: ) 9383: { 9384: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93) 9385: #ifdef ASC_CONFIG_PCI 9386: PCI_DATA pciData; 9387: 9388: pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info); 9389: pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info); 9390: pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info); 9391: pciData.offset = offset; 9392: pciData.type = pci_scan_method; 9393: return asc_get_cfg_byte(&pciData); 9394: #else /* ASC_CONFIG_PCI */ 9395: return 0; 9396: #endif /* ASC_CONFIG_PCI */ 9397: #else /* version >= v2.1.93 */ 9398: #ifdef CONFIG_PCI 9399: uchar byte_data; 9400: pcibios_read_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info), 9401: PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info), 9402: ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)), 9403: offset, &byte_data); 9404: return byte_data; 9405: #else /* CONFIG_PCI */ 9406: return 0; 9407: #endif /* CONFIG_PCI */ 9408: #endif /* version >= v2.1.93 */ 9409: } 9410: 9411: /* 9412: * Write a PCI configuration byte. 9413: */ 9414: ASC_INITFUNC( 9415: STATIC void 9416: DvcWritePCIConfigByte( 9417: ASC_DVC_VAR asc_ptr_type *asc_dvc, 9418: ushort offset, 9419: uchar byte_data) 9420: ) 9421: { 9422: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93) 9423: #ifdef ASC_CONFIG_PCI 9424: PCI_DATA pciData; 9425: 9426: pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info); 9427: pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info); 9428: pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info); 9429: pciData.offset = offset; 9430: pciData.type = pci_scan_method; 9431: asc_put_cfg_byte(&pciData, byte_data); 9432: #endif /* ASC_CONFIG_PCI */ 9433: #else /* version >= v2.1.93 */ 9434: #ifdef CONFIG_PCI 9435: pcibios_write_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info), 9436: PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info), 9437: ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)), 9438: offset, byte_data); 9439: #endif /* CONFIG_PCI */ 9440: #endif /* version >= v2.1.93 */ 9441: } 9442: 9443: /* 9444: * Return the BIOS address of the adapter at the specified 9445: * I/O port and with the specified bus type. 9446: */ 9447: ASC_INITFUNC( 9448: STATIC ushort 9449: AscGetChipBiosAddress( 9450: PortAddr iop_base, 9451: ushort bus_type 9452: ) 9453: ) 9454: { 9455: ushort cfg_lsw ; 9456: ushort bios_addr ; 9457: 9458: /* 9459: * The PCI BIOS is re-located by the motherboard BIOS. Because 9460: * of this the driver can not determine where a PCI BIOS is 9461: * loaded and executes. 9462: */ 9463: if (bus_type & ASC_IS_PCI) 9464: { 9465: return(0); 9466: } 9467: 9468: if((bus_type & ASC_IS_EISA) != 0) 9469: { 9470: cfg_lsw = AscGetEisaChipCfg(iop_base) ; 9471: cfg_lsw &= 0x000F ; 9472: bios_addr = (ushort)(ASC_BIOS_MIN_ADDR + 9473: (cfg_lsw * ASC_BIOS_BANK_SIZE)) ; 9474: return(bios_addr) ; 9475: }/* if */ 9476: 9477: cfg_lsw = AscGetChipCfgLsw(iop_base) ; 9478: 9479: /* 9480: * ISA PnP uses the top bit as the 32K BIOS flag 9481: */ 9482: if (bus_type == ASC_IS_ISAPNP) 9483: { 9484: cfg_lsw &= 0x7FFF; 9485: }/* if */ 9486: 9487: bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) + 9488: ASC_BIOS_MIN_ADDR) ; 9489: return(bios_addr) ; 9490: } 9491: 9492: 9493: /* 9494: * --- Functions Required by the Adv Library 9495: */ 9496: 9497: /* 9498: * DvcGetPhyAddr() 9499: * 9500: * Return the physical address of 'vaddr' and set '*lenp' to the 9501: * number of physically contiguous bytes that follow 'vaddr'. 9502: * 'flag' indicates the type of structure whose physical address 9503: * is being translated. 9504: * 9505: * Note: Because Linux currently doesn't page the kernel and all 9506: * kernel buffers are physically contiguous, leave '*lenp' unchanged. 9507: */ 9508: ulong 9509: DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq, 9510: uchar *vaddr, long *lenp, int flag) 9511: { 9512: ulong paddr; 9513: 9514: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0) 9515: paddr = (ulong) vaddr; 9516: #else /* version >= v2.0.0 */ 9517: paddr = virt_to_bus(vaddr); 9518: #endif /* version >= v2.0.0 */ 9519: 9520: ASC_DBG4(4, 9521: "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n", 9522: (ulong) vaddr, (ulong) lenp, (ulong) *((ulong *) lenp), paddr); 9523: 9524: return paddr; 9525: } 9526: 9527: /* 9528: * Read a PCI configuration byte. 9529: */ 9530: ASC_INITFUNC( 9531: STATIC uchar 9532: DvcAdvReadPCIConfigByte( 9533: ADV_DVC_VAR *asc_dvc, 9534: ushort offset) 9535: ) 9536: { 9537: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93) 9538: #ifdef ASC_CONFIG_PCI 9539: PCI_DATA pciData; 9540: 9541: pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info); 9542: pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info); 9543: pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info); 9544: pciData.offset = offset; 9545: pciData.type = pci_scan_method; 9546: return asc_get_cfg_byte(&pciData); 9547: #else /* ASC_CONFIG_PCI */ 9548: return 0; 9549: #endif /* ASC_CONFIG_PCI */ 9550: #else /* version >= v2.1.93 */ 9551: #ifdef CONFIG_PCI 9552: uchar byte_data; 9553: pcibios_read_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info), 9554: PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info), 9555: ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)), 9556: offset, &byte_data); 9557: return byte_data; 9558: #else /* CONFIG_PCI */ 9559: return 0; 9560: #endif /* CONFIG_PCI */ 9561: #endif /* version >= v2.1.93 */ 9562: } 9563: 9564: /* 9565: * Write a PCI configuration byte. 9566: */ 9567: ASC_INITFUNC( 9568: STATIC void 9569: DvcAdvWritePCIConfigByte( 9570: ADV_DVC_VAR *asc_dvc, 9571: ushort offset, 9572: uchar byte_data) 9573: ) 9574: { 9575: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93) 9576: #ifdef ASC_CONFIG_PCI 9577: PCI_DATA pciData; 9578: 9579: pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info); 9580: pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info); 9581: pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info); 9582: pciData.offset = offset; 9583: pciData.type = pci_scan_method; 9584: asc_put_cfg_byte(&pciData, byte_data); 9585: #endif /* ASC_CONFIG_PCI */ 9586: #else /* version >= v2.1.93 */ 9587: #ifdef CONFIG_PCI 9588: pcibios_write_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info), 9589: PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info), 9590: ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)), 9591: offset, byte_data); 9592: #endif /* CONFIG_PCI */ 9593: #endif /* version >= v2.1.93 */ 9594: } 9595: 9596: /* 9597: * --- Tracing and Debugging Functions 9598: */ 9599: 9600: #ifdef ADVANSYS_STATS 9601: /* 9602: * asc_prt_board_stats() 9603: * 9604: * Note: no single line should be greater than ASC_PRTLINE_SIZE, 9605: * cf. asc_prt_line(). 9606: * 9607: * Return the number of characters copied into 'cp'. No more than 9608: * 'cplen' characters will be copied to 'cp'. 9609: */ 9610: STATIC int 9611: asc_prt_board_stats(struct Scsi_Host *shp, char *cp, int cplen) 9612: { 9613: int leftlen; 9614: int totlen; 9615: int len; 9616: struct asc_stats *s; 9617: int i; 9618: ushort chip_scsi_id; 9619: asc_board_t *boardp; 9620: asc_queue_t *active; 9621: asc_queue_t *waiting; 9622: 9623: leftlen = cplen; 9624: totlen = len = 0; 9625: 9626: boardp = ASC_BOARDP(shp); 9627: s = &boardp->asc_stats; 9628: 9629: len = asc_prt_line(cp, leftlen, 9630: "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", shp->host_no); 9631: ASC_PRT_NEXT(); 9632: 9633: len = asc_prt_line(cp, leftlen, 9634: " command %lu, queuecommand %lu, abort %lu, reset %lu, biosparam %lu\n", 9635: s->command, s->queuecommand, s->abort, s->reset, s->biosparam); 9636: ASC_PRT_NEXT(); 9637: 9638: len = asc_prt_line(cp, leftlen, 9639: " interrupt %lu, callback %lu, done %lu\n", 9640: s->interrupt, s->callback, s->done); 9641: ASC_PRT_NEXT(); 9642: 9643: len = asc_prt_line(cp, leftlen, 9644: " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n", 9645: s->exe_noerror, s->exe_busy, s->exe_error, s->exe_unknown); 9646: ASC_PRT_NEXT(); 9647: 9648: if (ASC_NARROW_BOARD(boardp)) { 9649: len = asc_prt_line(cp, leftlen, 9650: " build_error %lu\n", 9651: s->build_error); 9652: } else { 9653: len = asc_prt_line(cp, leftlen, 9654: " build_error %lu, build_noreq %lu, build_nosg %lu\n", 9655: s->build_error, s->adv_build_noreq, s->adv_build_nosg); 9656: } 9657: ASC_PRT_NEXT(); 9658: 9659: /* 9660: * Display data transfer statistics. 9661: */ 9662: if (s->cont_cnt > 0) { 9663: len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt); 9664: ASC_PRT_NEXT(); 9665: 9666: len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ", 9667: s->cont_xfer/2, 9668: ASC_TENTHS(s->cont_xfer, 2)); 9669: ASC_PRT_NEXT(); 9670: 9671: /* Contiguous transfer average size */ 9672: len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n", 9673: (s->cont_xfer/2)/s->cont_cnt, 9674: ASC_TENTHS((s->cont_xfer/2), s->cont_cnt)); 9675: ASC_PRT_NEXT(); 9676: } 9677: 9678: if (s->sg_cnt > 0) { 9679: 9680: len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ", 9681: s->sg_cnt, s->sg_elem); 9682: ASC_PRT_NEXT(); 9683: 9684: len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n", 9685: s->sg_xfer/2, 9686: ASC_TENTHS(s->sg_xfer, 2)); 9687: ASC_PRT_NEXT(); 9688: 9689: /* Scatter gather transfer statistics */ 9690: len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ", 9691: s->sg_elem/s->sg_cnt, 9692: ASC_TENTHS(s->sg_elem, s->sg_cnt)); 9693: ASC_PRT_NEXT(); 9694: 9695: len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ", 9696: (s->sg_xfer/2)/s->sg_elem, 9697: ASC_TENTHS((s->sg_xfer/2), s->sg_elem)); 9698: ASC_PRT_NEXT(); 9699: 9700: len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n", 9701: (s->sg_xfer/2)/s->sg_cnt, 9702: ASC_TENTHS((s->sg_xfer/2), s->sg_cnt)); 9703: ASC_PRT_NEXT(); 9704: } 9705: 9706: /* 9707: * Display request queuing statistics. 9708: */ 9709: len = asc_prt_line(cp, leftlen, 9710: " Active and Waiting Request Queues (Time Unit: %d HZ):\n", HZ); 9711: ASC_PRT_NEXT(); 9712: 9713: active = &ASC_BOARDP(shp)->active; 9714: waiting = &ASC_BOARDP(shp)->waiting; 9715: 9716: if (ASC_NARROW_BOARD(boardp)) { 9717: chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id; 9718: } else { 9719: chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id; 9720: } 9721: 9722: for (i = 0; i <= ADV_MAX_TID; i++) { 9723: 9724: if ((chip_scsi_id == i) || 9725: ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { 9726: continue; 9727: } 9728: 9729: if (active->q_tot_cnt[i] > 0 || waiting->q_tot_cnt[i] > 0) { 9730: len = asc_prt_line(cp, leftlen, " target %d\n", i); 9731: ASC_PRT_NEXT(); 9732: 9733: len = asc_prt_line(cp, leftlen, 9734: " active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n", 9735: active->q_cur_cnt[i], active->q_max_cnt[i], 9736: active->q_tot_cnt[i], 9737: active->q_min_tim[i], active->q_max_tim[i], 9738: (active->q_tot_cnt[i] == 0) ? 0 : 9739: (active->q_tot_tim[i]/active->q_tot_cnt[i]), 9740: (active->q_tot_cnt[i] == 0) ? 0 : 9741: ASC_TENTHS(active->q_tot_tim[i], active->q_tot_cnt[i])); 9742: ASC_PRT_NEXT(); 9743: 9744: len = asc_prt_line(cp, leftlen, 9745: " waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n", 9746: waiting->q_cur_cnt[i], waiting->q_max_cnt[i], 9747: waiting->q_tot_cnt[i], 9748: waiting->q_min_tim[i], waiting->q_max_tim[i], 9749: (waiting->q_tot_cnt[i] == 0) ? 0 : 9750: (waiting->q_tot_tim[i]/waiting->q_tot_cnt[i]), 9751: (waiting->q_tot_cnt[i] == 0) ? 0 : 9752: ASC_TENTHS(waiting->q_tot_tim[i], waiting->q_tot_cnt[i])); 9753: ASC_PRT_NEXT(); 9754: } 9755: } 9756: 9757: return totlen; 9758: } 9759: #endif /* ADVANSYS_STATS */ 9760: 9761: #ifdef ADVANSYS_DEBUG 9762: /* 9763: * asc_prt_scsi_host() 9764: */ 9765: STATIC void 9766: asc_prt_scsi_host(struct Scsi_Host *s) 9767: { 9768: asc_board_t *boardp; 9769: 9770: boardp = ASC_BOARDP(s); 9771: 9772: printk("Scsi_Host at addr %x\n", (unsigned) s); 9773: printk( 9774: " next %x, extra_bytes %u, host_busy %u, host_no %d, last_reset %d,\n", 9775: (unsigned) s->next, s->extra_bytes, s->host_busy, s->host_no, 9776: (unsigned) s->last_reset); 9777: 9778: printk( 9779: " host_wait %x, host_queue %x, hostt %x, block %x,\n", 9780: (unsigned) s->host_wait, (unsigned) s->host_queue, 9781: (unsigned) s->hostt, (unsigned) s->block); 9782: 9783: printk( 9784: " wish_block %d, base %x, io_port %d, n_io_port %d, irq %d, dma_channel %d,\n", 9785: s->wish_block, (unsigned) s->base, s->io_port, s->n_io_port, 9786: s->irq, s->dma_channel); 9787: 9788: printk( 9789: " this_id %d, can_queue %d,\n", s->this_id, s->can_queue); 9790: 9791: printk( 9792: " cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d, loaded_as_module %d\n", 9793: s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma, 9794: s->loaded_as_module); 9795: 9796: if (ASC_NARROW_BOARD(boardp)) { 9797: asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var); 9798: asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg); 9799: } else { 9800: asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var); 9801: asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg); 9802: } 9803: } 9804: 9805: /* 9806: * asc_prt_scsi_cmnd() 9807: */ 9808: STATIC void 9809: asc_prt_scsi_cmnd(Scsi_Cmnd *s) 9810: { 9811: printk("Scsi_Cmnd at addr %x\n", (unsigned) s); 9812: 9813: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0) 9814: printk( 9815: " host %x, device %x, target %u, lun %u\n", 9816: (unsigned) s->host, (unsigned) s->device, s->target, s->lun); 9817: #else /* version >= v1.3.0 */ 9818: printk( 9819: " host %x, device %x, target %u, lun %u, channel %u,\n", 9820: (unsigned) s->host, (unsigned) s->device, s->target, s->lun, 9821: s->channel); 9822: #endif /* version >= v1.3.0 */ 9823: 9824: asc_prt_hex(" CDB", s->cmnd, s->cmd_len); 9825: 9826: printk( 9827: " use_sg %u, sglist_len %u, abort_reason %x\n", 9828: s->use_sg, s->sglist_len, s->abort_reason); 9829: 9830: #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89) 9831: printk( 9832: " retries %d, allowed %d\n", 9833: s->retries, s->allowed); 9834: #else /* version >= v1.3.89 */ 9835: printk( 9836: " serial_number %x, serial_number_at_timeout %x, retries %d, allowed %d\n", 9837: (unsigned) s->serial_number, (unsigned) s->serial_number_at_timeout, 9838: s->retries, s->allowed); 9839: #endif /* version >= v1.3.89 */ 9840: 9841: printk( 9842: " timeout_per_command %d, timeout_total %d, timeout %d\n", 9843: s->timeout_per_command, s->timeout_total, s->timeout); 9844: 9845: printk( 9846: " internal_timeout %u, flags %u, this_count %d\n", 9847: s->internal_timeout, s->flags, s->this_count); 9848: 9849: printk( 9850: " scsi_done %x, done %x, host_scribble %x, result %x\n", 9851: (unsigned) s->scsi_done, (unsigned) s->done, 9852: (unsigned) s->host_scribble, s->result); 9853: 9854: printk( 9855: " tag %u, pid %u\n", 9856: (unsigned) s->tag, (unsigned) s->pid); 9857: } 9858: 9859: /* 9860: * asc_prt_asc_dvc_var() 9861: */ 9862: STATIC void 9863: asc_prt_asc_dvc_var(ASC_DVC_VAR *h) 9864: { 9865: printk("ASC_DVC_VAR at addr %x\n", (unsigned) h); 9866: 9867: printk( 9868: " iop_base %x, err_code %x, dvc_cntl %x, bug_fix_cntl %d,\n", 9869: h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl); 9870: 9871: printk( 9872: " bus_type %d, isr_callback %x, exe_callback %x, init_sdtr %x,\n", 9873: h->bus_type, (unsigned) h->isr_callback, (unsigned) h->exe_callback, 9874: (unsigned) h->init_sdtr); 9875: 9876: printk( 9877: " sdtr_done %x, use_tagged_qng %x, unit_not_ready %x, chip_no %x,\n", 9878: (unsigned) h->sdtr_done, (unsigned) h->use_tagged_qng, 9879: (unsigned) h->unit_not_ready, (unsigned) h->chip_no); 9880: 9881: printk( 9882: " queue_full_or_busy %x, start_motor %x, scsi_reset_wait %x, irq_no %x,\n", 9883: (unsigned) h->queue_full_or_busy, (unsigned) h->start_motor, 9884: (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no); 9885: 9886: printk( 9887: " is_in_int %x, max_total_qng %x, cur_total_qng %x, in_critical_cnt %x,\n", 9888: (unsigned) h->is_in_int, (unsigned) h->max_total_qng, 9889: (unsigned) h->cur_total_qng, (unsigned) h->in_critical_cnt); 9890: 9891: printk( 9892: " last_q_shortage %x, init_state %x, no_scam %x, pci_fix_asyn_xfer %x,\n", 9893: (unsigned) h->last_q_shortage, (unsigned) h->init_state, 9894: (unsigned) h->no_scam, (unsigned) h->pci_fix_asyn_xfer); 9895: 9896: printk( 9897: " cfg %x, saved_ptr2func %x\n", 9898: (unsigned) h->cfg, (unsigned) h->saved_ptr2func); 9899: } 9900: 9901: /* 9902: * asc_prt_asc_dvc_cfg() 9903: */ 9904: STATIC void 9905: asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h) 9906: { 9907: printk("ASC_DVC_CFG at addr %x\n", (unsigned) h); 9908: 9909: printk( 9910: " can_tagged_qng %x, cmd_qng_enabled %x, disc_enable %x, sdtr_enable %x,\n", 9911: h->can_tagged_qng, h->cmd_qng_enabled, h->disc_enable, 9912: h->sdtr_enable); 9913: 9914: printk( 9915: " chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n", 9916: h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel, 9917: h->chip_version); 9918: 9919: printk( 9920: " pci_device_id %d, lib_serial_no %x, lib_version %x, mcode_date %x,\n", 9921: h->pci_device_id, h->lib_serial_no, h->lib_version, h->mcode_date); 9922: 9923: printk( 9924: " mcode_version %d, overrun_buf %x\n", 9925: h->mcode_version, (unsigned) h->overrun_buf); 9926: } 9927: 9928: /* 9929: * asc_prt_asc_scsi_q() 9930: */ 9931: STATIC void 9932: asc_prt_asc_scsi_q(ASC_SCSI_Q *q) 9933: { 9934: ASC_SG_HEAD *sgp; 9935: int i; 9936: 9937: printk("ASC_SCSI_Q at addr %x\n", (unsigned) q); 9938: 9939: printk( 9940: " target_ix %u, target_lun %u, srb_ptr %x, tag_code %u,\n", 9941: q->q2.target_ix, q->q1.target_lun, 9942: (unsigned) q->q2.srb_ptr, q->q2.tag_code); 9943: 9944: printk( 9945: " data_addr %x, data_cnt %lu, sense_addr %x, sense_len %u,\n", 9946: (unsigned) q->q1.data_addr, q->q1.data_cnt, 9947: (unsigned) q->q1.sense_addr, q->q1.sense_len); 9948: 9949: printk( 9950: " cdbptr %x, cdb_len %u, sg_head %x, sg_queue_cnt %u\n", 9951: (unsigned) q->cdbptr, q->q2.cdb_len, 9952: (unsigned) q->sg_head, q->q1.sg_queue_cnt); 9953: 9954: if (q->sg_head) { 9955: sgp = q->sg_head; 9956: printk("ASC_SG_HEAD at addr %x\n", (unsigned) sgp); 9957: printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, sgp->queue_cnt); 9958: for (i = 0; i < sgp->entry_cnt; i++) { 9959: printk(" [%u]: addr %x, bytes %lu\n", 9960: i, (unsigned) sgp->sg_list[i].addr, sgp->sg_list[i].bytes); 9961: } 9962: 9963: } 9964: } 9965: 9966: /* 9967: * asc_prt_asc_qdone_info() 9968: */ 9969: STATIC void 9970: asc_prt_asc_qdone_info(ASC_QDONE_INFO *q) 9971: { 9972: printk("ASC_QDONE_INFO at addr %x\n", (unsigned) q); 9973: printk( 9974: " srb_ptr %x, target_ix %u, cdb_len %u, tag_code %u, done_stat %x\n", 9975: (unsigned) q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len, 9976: q->d2.tag_code, q->d3.done_stat); 9977: printk( 9978: " host_stat %x, scsi_stat %x, scsi_msg %x\n", 9979: q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg); 9980: } 9981: 9982: /* 9983: * asc_prt_adv_dvc_var() 9984: * 9985: * Display an ADV_DVC_VAR structure. 9986: */ 9987: STATIC void 9988: asc_prt_adv_dvc_var(ADV_DVC_VAR *h) 9989: { 9990: printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong) h); 9991: 9992: printk( 9993: " iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n", 9994: (ulong) h->iop_base, h->err_code, (unsigned) h->ultra_able); 9995: 9996: printk( 9997: " isr_callback 0x%x, sdtr_able 0x%x, wdtr_able 0x%x\n", 9998: (unsigned) h->isr_callback, (unsigned) h->wdtr_able, 9999: (unsigned) h->sdtr_able); 10000: 10001: printk( 10002: " start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n", 10003: (unsigned) h->start_motor, 10004: (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no); 10005: 10006: printk( 10007: " max_host_qng 0x%x, cur_host_qng 0x%x, max_dvc_qng 0x%x\n", 10008: (unsigned) h->max_host_qng, (unsigned) h->cur_host_qng, 10009: (unsigned) h->max_dvc_qng); 10010: 10011: printk( 10012: " no_scam 0x%x, tagqng_able 0x%x, chip_scsi_id 0x%x, cfg 0x%lx\n", 10013: (unsigned) h->no_scam, (unsigned) h->tagqng_able, 10014: (unsigned) h->chip_scsi_id, (ulong) h->cfg); 10015: 10016: } 10017: 10018: /* 10019: * asc_prt_adv_dvc_cfg() 10020: * 10021: * Display an ADV_DVC_CFG structure. 10022: */ 10023: STATIC void 10024: asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h) 10025: { 10026: printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong) h); 10027: 10028: printk( 10029: " disc_enable 0x%x, termination 0x%x\n", 10030: h->disc_enable, h->termination); 10031: 10032: printk( 10033: " chip_version 0x%x, mcode_date 0x%x\n", 10034: h->chip_version, h->mcode_date); 10035: 10036: printk( 10037: " mcode_version 0x%x, pci_device_id 0x%x, lib_version 0x%x\n", 10038: h->mcode_version, h->pci_device_id, h->lib_version); 10039: 10040: printk( 10041: " control_flag 0x%x, pci_slot_info 0x%x\n", 10042: h->control_flag, h->pci_slot_info); 10043: } 10044: 10045: /* 10046: * asc_prt_adv_scsi_req_q() 10047: * 10048: * Display an ADV_SCSI_REQ_Q structure. 10049: */ 10050: STATIC void 10051: asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q) 10052: { 10053: int i; 10054: struct asc_sg_block *sg_ptr; 10055: 10056: printk("ADV_SCSI_REQ_Q at addr %x\n", (unsigned) q); 10057: 10058: printk( 10059: " target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n", 10060: q->target_id, q->target_lun, q->srb_ptr, q->a_flag); 10061: 10062: printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n", 10063: q->cntl, q->data_addr, q->vdata_addr); 10064: 10065: printk( 10066: " data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n", 10067: q->data_cnt, q->sense_addr, q->sense_len); 10068: 10069: printk( 10070: " cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n", 10071: q->cdb_len, q->done_status, q->host_status, q->scsi_status); 10072: 10073: printk( 10074: " vsense_addr 0x%lx, scsiq_ptr 0x%lx, ux_wk_data_cnt %lu\n", 10075: (ulong) q->vsense_addr, (ulong) q->scsiq_ptr, 10076: (ulong) q->ux_wk_data_cnt); 10077: 10078: printk( 10079: " sg_list_ptr 0x%lx, sg_real_addr 0x%lx, sg_entry_cnt %u\n", 10080: (ulong) q->sg_list_ptr, (ulong) q->sg_real_addr, q->sg_entry_cnt); 10081: 10082: printk( 10083: " ux_sg_ix %u, orig_sense_len %u\n", 10084: q->ux_sg_ix, q->orig_sense_len); 10085: 10086: /* Display the request's ADV_SG_BLOCK structures. */ 10087: for (sg_ptr = q->sg_list_ptr, i = 0; sg_ptr != NULL; 10088: sg_ptr = sg_ptr->sg_ptr, i++) { 10089: /* 10090: * 'sg_ptr' is a physical address. Convert it to a virtual 10091: * address by indexing 'i' into the virtual address array 10092: * 'sg_list_ptr'. 10093: * 10094: * At the end of the each iteration of the loop 'sg_ptr' is 10095: * converted back into a physical address by setting 'sg_ptr' 10096: * to the next pointer 'sg_ptr->sg_ptr'. 10097: */ 10098: sg_ptr = &(((ADV_SG_BLOCK *) (q->sg_list_ptr))[i]); 10099: asc_prt_adv_sgblock(i, sg_ptr); 10100: } 10101: } 10102: 10103: /* 10104: * asc_prt_adv_sgblock() 10105: * 10106: * Display an ADV_SG_BLOCK structure. 10107: */ 10108: STATIC void 10109: asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b) 10110: { 10111: int i, s; 10112: 10113: /* Calculate starting entry number for the current block. */ 10114: s = sgblockno * NO_OF_SG_PER_BLOCK; 10115: 10116: printk(" ADV_SG_BLOCK at addr 0x%lx (sgblockno %lu)\n", 10117: (ulong) b, (ulong) sgblockno); 10118: printk( 10119: " first_entry_no %lu, last_entry_no %lu, sg_ptr 0x%lx\n", 10120: (ulong) b->first_entry_no, (ulong) b->last_entry_no, (ulong) b->sg_ptr); 10121: ASC_ASSERT(b->first_entry_no - s >= 0); 10122: ASC_ASSERT(b->last_entry_no - s >= 0); 10123: ASC_ASSERT(b->last_entry_no - s <= NO_OF_SG_PER_BLOCK); 10124: ASC_ASSERT(b->first_entry_no - s <= NO_OF_SG_PER_BLOCK); 10125: ASC_ASSERT(b->first_entry_no - s <= NO_OF_SG_PER_BLOCK); 10126: ASC_ASSERT(b->first_entry_no - s <= b->last_entry_no - s); 10127: for (i = b->first_entry_no - s; i <= b->last_entry_no - s; i++) { 10128: printk(" [%lu]: sg_addr 0x%lx, sg_count 0x%lx\n", 10129: (ulong) i, (ulong) b->sg_list[i].sg_addr, 10130: (ulong) b->sg_list[i].sg_count); 10131: } 10132: } 10133: 10134: /* 10135: * asc_prt_hex() 10136: * 10137: * Print hexadecimal output in 4 byte groupings 32 bytes 10138: * or 8 double-words per line. 10139: */ 10140: STATIC void 10141: asc_prt_hex(char *f, uchar *s, int l) 10142: { 10143: int i; 10144: int j; 10145: int k; 10146: int m; 10147: 10148: printk("%s: (%d bytes)\n", f, l); 10149: 10150: for (i = 0; i < l; i += 32) { 10151: 10152: /* Display a maximum of 8 double-words per line. */ 10153: if ((k = (l - i) / 4) >= 8) { 10154: k = 8; 10155: m = 0; 10156: } else { 10157: m = (l - i) % 4 ; 10158: } 10159: 10160: for (j = 0; j < k; j++) { 10161: printk(" %2.2X%2.2X%2.2X%2.2X", 10162: (unsigned) s[i+(j*4)], (unsigned) s[i+(j*4)+1], 10163: (unsigned) s[i+(j*4)+2], (unsigned) s[i+(j*4)+3]); 10164: } 10165: 10166: switch (m) { 10167: case 0: 10168: default: 10169: break; 10170: case 1: 10171: printk(" %2.2X", 10172: (unsigned) s[i+(j*4)]); 10173: break; 10174: case 2: 10175: printk(" %2.2X%2.2X", 10176: (unsigned) s[i+(j*4)], 10177: (unsigned) s[i+(j*4)+1]); 10178: break; 10179: case 3: 10180: printk(" %2.2X%2.2X%2.2X", 10181: (unsigned) s[i+(j*4)+1], 10182: (unsigned) s[i+(j*4)+2], 10183: (unsigned) s[i+(j*4)+3]); 10184: break; 10185: } 10186: 10187: printk("\n"); 10188: } 10189: } 10190: #endif /* ADVANSYS_DEBUG */ 10191: 10192: #ifdef ADVANSYS_ASSERT 10193: /* 10194: * interrupts_enabled() 10195: * 10196: * Return 1 if interrupts are enabled, otherwise return 0. 10197: */ 10198: STATIC int 10199: interrupts_enabled(void) 10200: { 1.1.1.2 ! root 10201: long flags; 1.1 root 10202: 10203: save_flags(flags); 10204: if (flags & 0x0200) { 10205: return ASC_TRUE; 10206: } else { 10207: return ASC_FALSE; 10208: } 10209: } 10210: #endif /* ADVANSYS_ASSERT */ 10211: 10212: 10213: /* 10214: * --- Asc Library Functions 10215: */ 10216: 10217: ASC_INITFUNC( 10218: STATIC ushort 10219: AscGetEisaChipCfg( 10220: PortAddr iop_base 10221: ) 10222: ) 10223: { 10224: PortAddr eisa_cfg_iop; 10225: 10226: eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) | 10227: (PortAddr) (ASC_EISA_CFG_IOP_MASK); 10228: return (inpw(eisa_cfg_iop)); 10229: } 10230: 10231: ASC_INITFUNC( 10232: STATIC uchar 10233: AscSetChipScsiID( 10234: PortAddr iop_base, 10235: uchar new_host_id 10236: ) 10237: ) 10238: { 10239: ushort cfg_lsw; 10240: 10241: if (AscGetChipScsiID(iop_base) == new_host_id) { 10242: return (new_host_id); 10243: } 10244: cfg_lsw = AscGetChipCfgLsw(iop_base); 10245: cfg_lsw &= 0xF8FF; 10246: cfg_lsw |= (ushort) ((new_host_id & ASC_MAX_TID) << 8); 10247: AscSetChipCfgLsw(iop_base, cfg_lsw); 10248: return (AscGetChipScsiID(iop_base)); 10249: } 10250: 10251: ASC_INITFUNC( 10252: STATIC uchar 10253: AscGetChipScsiCtrl( 10254: PortAddr iop_base 10255: ) 10256: ) 10257: { 10258: uchar sc; 10259: 10260: AscSetBank(iop_base, 1); 10261: sc = inp(iop_base + IOP_REG_SC); 10262: AscSetBank(iop_base, 0); 10263: return (sc); 10264: } 10265: 10266: ASC_INITFUNC( 10267: STATIC uchar 10268: AscGetChipVersion( 10269: PortAddr iop_base, 10270: ushort bus_type 10271: ) 10272: ) 10273: { 10274: if ((bus_type & ASC_IS_EISA) != 0) { 10275: PortAddr eisa_iop; 10276: uchar revision; 10277: eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) | 10278: (PortAddr) ASC_EISA_REV_IOP_MASK; 10279: revision = inp(eisa_iop); 10280: return ((uchar) ((ASC_CHIP_MIN_VER_EISA - 1) + revision)); 10281: } 10282: return (AscGetChipVerNo(iop_base)); 10283: } 10284: 10285: ASC_INITFUNC( 10286: STATIC ushort 10287: AscGetChipBusType( 10288: PortAddr iop_base 10289: ) 10290: ) 10291: { 10292: ushort chip_ver; 10293: 10294: chip_ver = AscGetChipVerNo(iop_base); 10295: if ( 10296: (chip_ver >= ASC_CHIP_MIN_VER_VL) 10297: && (chip_ver <= ASC_CHIP_MAX_VER_VL) 10298: ) { 10299: if ( 10300: ((iop_base & 0x0C30) == 0x0C30) 10301: || ((iop_base & 0x0C50) == 0x0C50) 10302: ) { 10303: return (ASC_IS_EISA); 10304: } 10305: return (ASC_IS_VL); 10306: } 10307: if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) && 10308: (chip_ver <= ASC_CHIP_MAX_VER_ISA)) { 10309: if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) { 10310: return (ASC_IS_ISAPNP); 10311: } 10312: return (ASC_IS_ISA); 10313: } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) && 10314: (chip_ver <= ASC_CHIP_MAX_VER_PCI)) { 10315: return (ASC_IS_PCI); 10316: } 10317: return (0); 10318: } 10319: 10320: ASC_INITFUNC( 10321: STATIC ulong 10322: AscLoadMicroCode( 10323: PortAddr iop_base, 10324: ushort s_addr, 10325: ushort *mcode_buf, 10326: ushort mcode_size 10327: ) 10328: ) 10329: { 10330: ulong chksum; 10331: ushort mcode_word_size; 10332: ushort mcode_chksum; 10333: 10334: mcode_word_size = (ushort) (mcode_size >> 1); 10335: AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size); 10336: AscMemWordCopyToLram(iop_base, s_addr, mcode_buf, mcode_word_size); 10337: chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size); 10338: mcode_chksum = (ushort) AscMemSumLramWord(iop_base, 10339: (ushort) ASC_CODE_SEC_BEG, 10340: (ushort) ((mcode_size - s_addr - (ushort) ASC_CODE_SEC_BEG) / 2)); 10341: AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum); 10342: AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size); 10343: return (chksum); 10344: } 10345: 10346: ASC_INITFUNC( 10347: STATIC int 10348: AscFindSignature( 10349: PortAddr iop_base 10350: ) 10351: ) 10352: { 10353: ushort sig_word; 10354: 10355: if (AscGetChipSignatureByte(iop_base) == (uchar) ASC_1000_ID1B) { 10356: sig_word = AscGetChipSignatureWord(iop_base); 10357: if ((sig_word == (ushort) ASC_1000_ID0W) || 10358: (sig_word == (ushort) ASC_1000_ID0W_FIX)) { 10359: return (1); 10360: } 10361: } 10362: return (0); 10363: } 10364: 10365: STATIC uchar _isa_pnp_inited ASC_INITDATA = 0; 10366: STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] ASC_INITDATA = 10367: { 10368: 0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4, 10369: ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8 10370: }; 10371: 10372: ASC_INITFUNC( 10373: STATIC PortAddr 10374: AscSearchIOPortAddr( 10375: PortAddr iop_beg, 10376: ushort bus_type 10377: ) 10378: ) 10379: { 10380: if (bus_type & ASC_IS_VL) { 10381: while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) { 10382: if (AscGetChipVersion(iop_beg, bus_type) <= ASC_CHIP_MAX_VER_VL) { 10383: return (iop_beg); 10384: } 10385: } 10386: return (0); 10387: } 10388: if (bus_type & ASC_IS_ISA) { 10389: if (_isa_pnp_inited == 0) { 10390: AscSetISAPNPWaitForKey(); 10391: _isa_pnp_inited++; 10392: } 10393: while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) { 10394: if ((AscGetChipVersion(iop_beg, bus_type) & ASC_CHIP_VER_ISA_BIT) != 0) { 10395: return (iop_beg); 10396: } 10397: } 10398: return (0); 10399: } 10400: if (bus_type & ASC_IS_EISA) { 10401: if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) { 10402: return (iop_beg); 10403: } 10404: return (0); 10405: } 10406: return (0); 10407: } 10408: 10409: ASC_INITFUNC( 10410: STATIC PortAddr 10411: AscSearchIOPortAddr11( 10412: PortAddr s_addr 10413: ) 10414: ) 10415: { 10416: int i; 10417: PortAddr iop_base; 10418: 10419: for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) { 10420: if (_asc_def_iop_base[i] > s_addr) { 10421: break; 10422: } 10423: } 10424: for (; i < ASC_IOADR_TABLE_MAX_IX; i++) { 10425: iop_base = _asc_def_iop_base[i]; 10426: if (check_region(iop_base, ASC_IOADR_GAP) != 0) { 10427: ASC_DBG1(1, 10428: "AscSearchIOPortAddr11: check_region() failed I/O port %x\n", 10429: iop_base); 10430: continue; 10431: } 10432: ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port %x\n", iop_base); 10433: if (AscFindSignature(iop_base)) { 10434: return (iop_base); 10435: } 10436: } 10437: return (0); 10438: } 10439: 10440: ASC_INITFUNC( 10441: STATIC void 10442: AscToggleIRQAct( 10443: PortAddr iop_base 10444: ) 10445: ) 10446: { 10447: AscSetChipStatus(iop_base, CIW_IRQ_ACT); 10448: AscSetChipStatus(iop_base, 0); 10449: return; 10450: } 10451: 10452: ASC_INITFUNC( 10453: STATIC void 10454: AscSetISAPNPWaitForKey( 10455: void) 10456: ) 10457: { 10458: outp(ASC_ISA_PNP_PORT_ADDR, 0x02); 10459: outp(ASC_ISA_PNP_PORT_WRITE, 0x02); 10460: return; 10461: } 10462: 10463: ASC_INITFUNC( 10464: STATIC uchar 10465: AscGetChipIRQ( 10466: PortAddr iop_base, 10467: ushort bus_type 10468: ) 10469: ) 10470: { 10471: ushort cfg_lsw; 10472: uchar chip_irq; 10473: 10474: if ((bus_type & ASC_IS_EISA) != 0) { 10475: cfg_lsw = AscGetEisaChipCfg(iop_base); 10476: chip_irq = (uchar) (((cfg_lsw >> 8) & 0x07) + 10); 10477: if ((chip_irq == 13) || (chip_irq > 15)) { 10478: return (0); 10479: } 10480: return (chip_irq); 10481: } 10482: if ((bus_type & ASC_IS_VL) != 0) { 10483: cfg_lsw = AscGetChipCfgLsw(iop_base); 10484: chip_irq = (uchar) (((cfg_lsw >> 2) & 0x07)); 10485: if ((chip_irq == 0) || 10486: (chip_irq == 4) || 10487: (chip_irq == 7)) { 10488: return (0); 10489: } 10490: return ((uchar) (chip_irq + (ASC_MIN_IRQ_NO - 1))); 10491: } 10492: cfg_lsw = AscGetChipCfgLsw(iop_base); 10493: chip_irq = (uchar) (((cfg_lsw >> 2) & 0x03)); 10494: if (chip_irq == 3) 10495: chip_irq += (uchar) 2; 10496: return ((uchar) (chip_irq + ASC_MIN_IRQ_NO)); 10497: } 10498: 10499: ASC_INITFUNC( 10500: STATIC uchar 10501: AscSetChipIRQ( 10502: PortAddr iop_base, 10503: uchar irq_no, 10504: ushort bus_type 10505: ) 10506: ) 10507: { 10508: ushort cfg_lsw; 10509: 10510: if ((bus_type & ASC_IS_VL) != 0) { 10511: if (irq_no != 0) { 10512: if ((irq_no < ASC_MIN_IRQ_NO) || (irq_no > ASC_MAX_IRQ_NO)) { 10513: irq_no = 0; 10514: } else { 10515: irq_no -= (uchar) ((ASC_MIN_IRQ_NO - 1)); 10516: } 10517: } 10518: cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE3); 10519: cfg_lsw |= (ushort) 0x0010; 10520: AscSetChipCfgLsw(iop_base, cfg_lsw); 10521: AscToggleIRQAct(iop_base); 10522: cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE0); 10523: cfg_lsw |= (ushort) ((irq_no & 0x07) << 2); 10524: AscSetChipCfgLsw(iop_base, cfg_lsw); 10525: AscToggleIRQAct(iop_base); 10526: return (AscGetChipIRQ(iop_base, bus_type)); 10527: } 10528: if ((bus_type & (ASC_IS_ISA)) != 0) { 10529: if (irq_no == 15) 10530: irq_no -= (uchar) 2; 10531: irq_no -= (uchar) ASC_MIN_IRQ_NO; 10532: cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFF3); 10533: cfg_lsw |= (ushort) ((irq_no & 0x03) << 2); 10534: AscSetChipCfgLsw(iop_base, cfg_lsw); 10535: return (AscGetChipIRQ(iop_base, bus_type)); 10536: } 10537: return (0); 10538: } 10539: 10540: ASC_INITFUNC( 10541: STATIC void 10542: AscEnableIsaDma( 10543: uchar dma_channel 10544: ) 10545: ) 10546: { 10547: if (dma_channel < 4) { 10548: outp(0x000B, (ushort) (0xC0 | dma_channel)); 10549: outp(0x000A, dma_channel); 10550: } else if (dma_channel < 8) { 10551: outp(0x00D6, (ushort) (0xC0 | (dma_channel - 4))); 10552: outp(0x00D4, (ushort) (dma_channel - 4)); 10553: } 10554: return; 10555: } 10556: 10557: STATIC int 10558: AscIsrChipHalted( 10559: REG ASC_DVC_VAR asc_ptr_type * asc_dvc 10560: ) 10561: { 10562: EXT_MSG ext_msg; 10563: EXT_MSG out_msg; 10564: ushort halt_q_addr; 10565: int sdtr_accept; 10566: ushort int_halt_code; 10567: ASC_SCSI_BIT_ID_TYPE scsi_busy; 10568: ASC_SCSI_BIT_ID_TYPE target_id; 10569: PortAddr iop_base; 10570: uchar tag_code; 10571: uchar q_status; 10572: uchar halt_qp; 10573: uchar sdtr_data; 10574: uchar target_ix; 10575: uchar q_cntl, tid_no; 10576: uchar cur_dvc_qng; 10577: uchar asyn_sdtr; 10578: uchar scsi_status; 10579: asc_board_t *boardp; 10580: 10581: ASC_ASSERT(asc_dvc->drv_ptr != 0); 10582: boardp = (asc_board_t *) asc_dvc->drv_ptr; 10583: 10584: iop_base = asc_dvc->iop_base; 10585: int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W); 10586: 10587: halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B); 10588: halt_q_addr = ASC_QNO_TO_QADDR(halt_qp); 10589: target_ix = AscReadLramByte(iop_base, 10590: (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TARGET_IX)); 10591: q_cntl = AscReadLramByte(iop_base, 10592: (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL)); 10593: tid_no = ASC_TIX_TO_TID(target_ix); 10594: target_id = (uchar) ASC_TID_TO_TARGET_ID(tid_no); 10595: if (asc_dvc->pci_fix_asyn_xfer & target_id) { 10596: 10597: asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB; 10598: } else { 10599: asyn_sdtr = 0; 10600: } 10601: if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) { 10602: if (asc_dvc->pci_fix_asyn_xfer & target_id) { 10603: AscSetChipSDTR(iop_base, 0, tid_no); 10604: boardp->sdtr_data[tid_no] = 0; 10605: } 10606: AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); 10607: return (0); 10608: } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) { 10609: if (asc_dvc->pci_fix_asyn_xfer & target_id) { 10610: AscSetChipSDTR(iop_base, asyn_sdtr, tid_no); 10611: boardp->sdtr_data[tid_no] = asyn_sdtr; 10612: } 10613: AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); 10614: return (0); 10615: } else if (int_halt_code == ASC_HALT_EXTMSG_IN) { 10616: 10617: AscMemWordCopyFromLram(iop_base, 10618: ASCV_MSGIN_BEG, 10619: (ushort *) & ext_msg, 10620: (ushort) (sizeof (EXT_MSG) >> 1)); 10621: 10622: if (ext_msg.msg_type == MS_EXTEND && 10623: ext_msg.msg_req == MS_SDTR_CODE && 10624: ext_msg.msg_len == MS_SDTR_LEN) { 10625: sdtr_accept = TRUE; 10626: if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) { 10627: 10628: sdtr_accept = FALSE; 10629: ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET; 10630: } 10631: if ((ext_msg.xfer_period < 10632: asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index]) || 10633: (ext_msg.xfer_period > 10634: asc_dvc->sdtr_period_tbl[asc_dvc->max_sdtr_index])) { 10635: sdtr_accept = FALSE; 10636: ext_msg.xfer_period = 10637: asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index]; 10638: } 10639: if (sdtr_accept) { 10640: sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period, 10641: ext_msg.req_ack_offset); 10642: if ((sdtr_data == 0xFF)) { 10643: 10644: q_cntl |= QC_MSG_OUT; 10645: asc_dvc->init_sdtr &= ~target_id; 10646: asc_dvc->sdtr_done &= ~target_id; 10647: AscSetChipSDTR(iop_base, asyn_sdtr, tid_no); 10648: boardp->sdtr_data[tid_no] = asyn_sdtr; 10649: } 10650: } 10651: if (ext_msg.req_ack_offset == 0) { 10652: 10653: q_cntl &= ~QC_MSG_OUT; 10654: asc_dvc->init_sdtr &= ~target_id; 10655: asc_dvc->sdtr_done &= ~target_id; 10656: AscSetChipSDTR(iop_base, asyn_sdtr, tid_no); 10657: } else { 10658: if (sdtr_accept && (q_cntl & QC_MSG_OUT)) { 10659: 10660: q_cntl &= ~QC_MSG_OUT; 10661: asc_dvc->sdtr_done |= target_id; 10662: asc_dvc->init_sdtr |= target_id; 10663: asc_dvc->pci_fix_asyn_xfer &= ~target_id; 10664: sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period, 10665: ext_msg.req_ack_offset); 10666: AscSetChipSDTR(iop_base, sdtr_data, tid_no); 10667: boardp->sdtr_data[tid_no] = sdtr_data; 10668: } else { 10669: 10670: q_cntl |= QC_MSG_OUT; 10671: AscMsgOutSDTR(asc_dvc, 10672: ext_msg.xfer_period, 10673: ext_msg.req_ack_offset); 10674: asc_dvc->pci_fix_asyn_xfer &= ~target_id; 10675: sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period, 10676: ext_msg.req_ack_offset); 10677: AscSetChipSDTR(iop_base, sdtr_data, tid_no); 10678: boardp->sdtr_data[tid_no] = sdtr_data; 10679: asc_dvc->sdtr_done |= target_id; 10680: asc_dvc->init_sdtr |= target_id; 10681: } 10682: } 10683: 10684: AscWriteLramByte(iop_base, 10685: (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL), 10686: q_cntl); 10687: AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); 10688: return (0); 10689: } else if (ext_msg.msg_type == MS_EXTEND && 10690: ext_msg.msg_req == MS_WDTR_CODE && 10691: ext_msg.msg_len == MS_WDTR_LEN) { 10692: 10693: ext_msg.wdtr_width = 0; 10694: AscMemWordCopyToLram(iop_base, 10695: ASCV_MSGOUT_BEG, 10696: (ushort *) & ext_msg, 10697: (ushort) (sizeof (EXT_MSG) >> 1)); 10698: q_cntl |= QC_MSG_OUT; 10699: AscWriteLramByte(iop_base, 10700: (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL), 10701: q_cntl); 10702: AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); 10703: return (0); 10704: } else { 10705: 10706: ext_msg.msg_type = M1_MSG_REJECT; 10707: AscMemWordCopyToLram(iop_base, 10708: ASCV_MSGOUT_BEG, 10709: (ushort *) & ext_msg, 10710: (ushort) (sizeof (EXT_MSG) >> 1)); 10711: q_cntl |= QC_MSG_OUT; 10712: AscWriteLramByte(iop_base, 10713: (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL), 10714: q_cntl); 10715: AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); 10716: return (0); 10717: } 10718: } else if (int_halt_code == ASC_HALT_CHK_CONDITION) { 10719: 10720: q_cntl |= QC_REQ_SENSE; 10721: 10722: if ((asc_dvc->init_sdtr & target_id) != 0) { 10723: 10724: asc_dvc->sdtr_done &= ~target_id; 10725: 10726: sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no); 10727: q_cntl |= QC_MSG_OUT; 10728: AscMsgOutSDTR(asc_dvc, 10729: asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) & 10730: (uchar) (asc_dvc->max_sdtr_index - 1)], 10731: (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET)); 10732: } 10733: 10734: AscWriteLramByte(iop_base, 10735: (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL), 10736: q_cntl); 10737: 10738: tag_code = AscReadLramByte(iop_base, 10739: (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE)); 10740: tag_code &= 0xDC; 10741: if ( 10742: (asc_dvc->pci_fix_asyn_xfer & target_id) 10743: && !(asc_dvc->pci_fix_asyn_xfer_always & target_id) 10744: ) { 10745: 10746: tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT 10747: | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX); 10748: 10749: } 10750: AscWriteLramByte(iop_base, 10751: (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE), 10752: tag_code); 10753: 10754: q_status = AscReadLramByte(iop_base, 10755: (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS)); 10756: q_status |= (QS_READY | QS_BUSY); 10757: AscWriteLramByte(iop_base, 10758: (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS), 10759: q_status); 10760: 10761: scsi_busy = AscReadLramByte(iop_base, 10762: (ushort) ASCV_SCSIBUSY_B); 10763: scsi_busy &= ~target_id; 10764: AscWriteLramByte(iop_base, (ushort) ASCV_SCSIBUSY_B, scsi_busy); 10765: 10766: AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); 10767: return (0); 10768: } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) { 10769: 10770: AscMemWordCopyFromLram(iop_base, 10771: ASCV_MSGOUT_BEG, 10772: (ushort *) & out_msg, 10773: (ushort) (sizeof (EXT_MSG) >> 1)); 10774: 10775: if ((out_msg.msg_type == MS_EXTEND) && 10776: (out_msg.msg_len == MS_SDTR_LEN) && 10777: (out_msg.msg_req == MS_SDTR_CODE)) { 10778: 10779: asc_dvc->init_sdtr &= ~target_id; 10780: asc_dvc->sdtr_done &= ~target_id; 10781: AscSetChipSDTR(iop_base, asyn_sdtr, tid_no); 10782: boardp->sdtr_data[tid_no] = asyn_sdtr; 10783: } 10784: q_cntl &= ~QC_MSG_OUT; 10785: AscWriteLramByte(iop_base, 10786: (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL), 10787: q_cntl); 10788: AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); 10789: return (0); 10790: } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) { 10791: 10792: scsi_status = AscReadLramByte(iop_base, 10793: (ushort) ((ushort) halt_q_addr + (ushort) ASC_SCSIQ_SCSI_STATUS)); 10794: cur_dvc_qng = AscReadLramByte(iop_base, 10795: (ushort) ((ushort) ASC_QADR_BEG + (ushort) target_ix)); 10796: if ((cur_dvc_qng > 0) && 10797: (asc_dvc->cur_dvc_qng[tid_no] > 0)) { 10798: 10799: scsi_busy = AscReadLramByte(iop_base, 10800: (ushort) ASCV_SCSIBUSY_B); 10801: scsi_busy |= target_id; 10802: AscWriteLramByte(iop_base, 10803: (ushort) ASCV_SCSIBUSY_B, scsi_busy); 10804: asc_dvc->queue_full_or_busy |= target_id; 10805: 10806: if (scsi_status == SS_QUEUE_FULL) { 10807: if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) { 10808: cur_dvc_qng -= 1; 10809: asc_dvc->max_dvc_qng[tid_no] = cur_dvc_qng; 10810: 10811: AscWriteLramByte(iop_base, 10812: (ushort) ((ushort) ASCV_MAX_DVC_QNG_BEG + 10813: (ushort) tid_no), 10814: cur_dvc_qng); 10815: 10816: /* 10817: * Set the device queue depth to the number of 10818: * active requests when the QUEUE FULL condition 10819: * was encountered. 10820: */ 10821: boardp->queue_full |= target_id; 10822: boardp->queue_full_cnt[tid_no] = cur_dvc_qng; 10823: #if ASC_QUEUE_FLOW_CONTROL 10824: if (boardp->device[tid_no] != NULL && 10825: boardp->device[tid_no]->queue_curr_depth > 10826: cur_dvc_qng) { 10827: boardp->device[tid_no]->queue_curr_depth = 10828: cur_dvc_qng; 10829: } 10830: #endif /* ASC_QUEUE_FLOW_CONTROL */ 10831: } 10832: } 10833: } 10834: AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); 10835: return (0); 10836: } 10837: return (0); 10838: } 10839: 10840: STATIC uchar 10841: _AscCopyLramScsiDoneQ( 10842: PortAddr iop_base, 10843: ushort q_addr, 10844: REG ASC_QDONE_INFO * scsiq, 10845: ulong max_dma_count 10846: ) 10847: { 10848: ushort _val; 10849: uchar sg_queue_cnt; 10850: 10851: DvcGetQinfo(iop_base, 10852: (ushort) (q_addr + (ushort) ASC_SCSIQ_DONE_INFO_BEG), 10853: (ushort *) scsiq, 10854: (ushort) ((sizeof (ASC_SCSIQ_2) + sizeof (ASC_SCSIQ_3)) / 2)); 10855: _val = AscReadLramWord(iop_base, 10856: (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS)); 10857: scsiq->q_status = (uchar) _val; 10858: scsiq->q_no = (uchar) (_val >> 8); 10859: _val = AscReadLramWord(iop_base, 10860: (ushort) (q_addr + (ushort) ASC_SCSIQ_B_CNTL)); 10861: scsiq->cntl = (uchar) _val; 10862: sg_queue_cnt = (uchar) (_val >> 8); 10863: _val = AscReadLramWord(iop_base, 10864: (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SENSE_LEN)); 10865: scsiq->sense_len = (uchar) _val; 10866: scsiq->extra_bytes = (uchar) (_val >> 8); 10867: scsiq->remain_bytes = AscReadLramWord(iop_base, 10868: (ushort) (q_addr + (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT)); 10869: scsiq->remain_bytes &= max_dma_count; 10870: return (sg_queue_cnt); 10871: } 10872: 10873: STATIC int 10874: AscIsrQDone( 10875: REG ASC_DVC_VAR asc_ptr_type * asc_dvc 10876: ) 10877: { 10878: uchar next_qp; 10879: uchar n_q_used; 10880: uchar sg_list_qp; 10881: uchar sg_queue_cnt; 10882: uchar q_cnt; 10883: uchar done_q_tail; 10884: uchar tid_no; 10885: ASC_SCSI_BIT_ID_TYPE scsi_busy; 10886: ASC_SCSI_BIT_ID_TYPE target_id; 10887: PortAddr iop_base; 10888: ushort q_addr; 10889: ushort sg_q_addr; 10890: uchar cur_target_qng; 10891: ASC_QDONE_INFO scsiq_buf; 10892: REG ASC_QDONE_INFO *scsiq; 10893: int false_overrun; 10894: ASC_ISR_CALLBACK asc_isr_callback; 10895: 10896: iop_base = asc_dvc->iop_base; 10897: asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback; 10898: n_q_used = 1; 10899: scsiq = (ASC_QDONE_INFO *) & scsiq_buf; 10900: done_q_tail = (uchar) AscGetVarDoneQTail(iop_base); 10901: q_addr = ASC_QNO_TO_QADDR(done_q_tail); 10902: next_qp = AscReadLramByte(iop_base, 10903: (ushort) (q_addr + (ushort) ASC_SCSIQ_B_FWD)); 10904: if (next_qp != ASC_QLINK_END) { 10905: AscPutVarDoneQTail(iop_base, next_qp); 10906: q_addr = ASC_QNO_TO_QADDR(next_qp); 10907: sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, 10908: asc_dvc->max_dma_count); 10909: AscWriteLramByte(iop_base, 10910: (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS), 10911: (uchar) (scsiq->q_status & (uchar) ~ (QS_READY | QS_ABORTED))); 10912: tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix); 10913: target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix); 10914: if ((scsiq->cntl & QC_SG_HEAD) != 0) { 10915: sg_q_addr = q_addr; 10916: sg_list_qp = next_qp; 10917: for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) { 10918: sg_list_qp = AscReadLramByte(iop_base, 10919: (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_FWD)); 10920: sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp); 10921: if (sg_list_qp == ASC_QLINK_END) { 10922: AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SG_Q_LINKS); 10923: scsiq->d3.done_stat = QD_WITH_ERROR; 10924: scsiq->d3.host_stat = QHSTA_D_QDONE_SG_LIST_CORRUPTED; 10925: goto FATAL_ERR_QDONE; 10926: } 10927: AscWriteLramByte(iop_base, 10928: (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_STATUS), 10929: QS_FREE); 10930: } 10931: n_q_used = sg_queue_cnt + 1; 10932: AscPutVarDoneQTail(iop_base, sg_list_qp); 10933: } 10934: if (asc_dvc->queue_full_or_busy & target_id) { 10935: cur_target_qng = AscReadLramByte(iop_base, 10936: (ushort) ((ushort) ASC_QADR_BEG + (ushort) scsiq->d2.target_ix)); 10937: if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) { 10938: scsi_busy = AscReadLramByte(iop_base, 10939: (ushort) ASCV_SCSIBUSY_B); 10940: scsi_busy &= ~target_id; 10941: AscWriteLramByte(iop_base, 10942: (ushort) ASCV_SCSIBUSY_B, scsi_busy); 10943: asc_dvc->queue_full_or_busy &= ~target_id; 10944: } 10945: } 10946: if (asc_dvc->cur_total_qng >= n_q_used) { 10947: asc_dvc->cur_total_qng -= n_q_used; 10948: if (asc_dvc->cur_dvc_qng[tid_no] != 0) { 10949: asc_dvc->cur_dvc_qng[tid_no]--; 10950: } 10951: } else { 10952: AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG); 10953: scsiq->d3.done_stat = QD_WITH_ERROR; 10954: goto FATAL_ERR_QDONE; 10955: } 10956: if ((scsiq->d2.srb_ptr == 0UL) || 10957: ((scsiq->q_status & QS_ABORTED) != 0)) { 10958: return (0x11); 10959: } else if (scsiq->q_status == QS_DONE) { 10960: false_overrun = FALSE; 10961: if (scsiq->extra_bytes != 0) { 10962: scsiq->remain_bytes += (ulong) scsiq->extra_bytes; 10963: } 10964: if (scsiq->d3.done_stat == QD_WITH_ERROR) { 10965: if (scsiq->d3.host_stat == QHSTA_M_DATA_OVER_RUN) { 10966: if ((scsiq->cntl & (QC_DATA_IN | QC_DATA_OUT)) == 0) { 10967: scsiq->d3.done_stat = QD_NO_ERROR; 10968: scsiq->d3.host_stat = QHSTA_NO_ERROR; 10969: } else if (false_overrun) { 10970: scsiq->d3.done_stat = QD_NO_ERROR; 10971: scsiq->d3.host_stat = QHSTA_NO_ERROR; 10972: } 10973: } else if (scsiq->d3.host_stat == 10974: QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) { 10975: AscStopChip(iop_base); 10976: AscSetChipControl(iop_base, 10977: (uchar) (CC_SCSI_RESET | CC_HALT)); 10978: DvcDelayNanoSecond(asc_dvc, 60000); 10979: AscSetChipControl(iop_base, CC_HALT); 10980: AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT); 10981: AscSetChipStatus(iop_base, 0); 10982: AscSetChipControl(iop_base, 0); 10983: } 10984: } 10985: if ((scsiq->cntl & QC_NO_CALLBACK) == 0) { 10986: (*asc_isr_callback) (asc_dvc, scsiq); 10987: } else { 10988: if ((AscReadLramByte(iop_base, 10989: (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG)) == 10990: SCSICMD_StartStopUnit)) { 10991: asc_dvc->unit_not_ready &= ~target_id; 10992: if (scsiq->d3.done_stat != QD_NO_ERROR) { 10993: asc_dvc->start_motor &= ~target_id; 10994: } 10995: } 10996: } 10997: return (1); 10998: } else { 10999: AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS); 11000: FATAL_ERR_QDONE: 11001: if ((scsiq->cntl & QC_NO_CALLBACK) == 0) { 11002: (*asc_isr_callback) (asc_dvc, scsiq); 11003: } 11004: return (0x80); 11005: } 11006: } 11007: return (0); 11008: } 11009: 11010: STATIC int 11011: AscISR( 11012: REG ASC_DVC_VAR asc_ptr_type * asc_dvc 11013: ) 11014: { 11015: ASC_CS_TYPE chipstat; 11016: PortAddr iop_base; 11017: ushort saved_ram_addr; 11018: uchar ctrl_reg; 11019: uchar saved_ctrl_reg; 11020: int int_pending; 11021: int status; 11022: uchar host_flag; 11023: 11024: iop_base = asc_dvc->iop_base; 11025: int_pending = FALSE; 11026: if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) 11027: || (asc_dvc->isr_callback == 0) 11028: ) { 11029: return (ERR); 11030: } 11031: if (asc_dvc->in_critical_cnt != 0) { 11032: AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL); 11033: return (ERR); 11034: } 11035: if (asc_dvc->is_in_int) { 11036: AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY); 11037: return (ERR); 11038: } 11039: asc_dvc->is_in_int = TRUE; 11040: ctrl_reg = AscGetChipControl(iop_base); 11041: saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET | 11042: CC_SINGLE_STEP | CC_DIAG | CC_TEST)); 11043: chipstat = AscGetChipStatus(iop_base); 11044: if (chipstat & CSW_SCSI_RESET_LATCH) { 11045: if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) { 11046: int_pending = TRUE; 11047: asc_dvc->sdtr_done = 0; 11048: saved_ctrl_reg &= (uchar) (~CC_HALT); 11049: while (AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) ; 11050: AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT)); 11051: AscSetChipControl(iop_base, CC_HALT); 11052: AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT); 11053: AscSetChipStatus(iop_base, 0); 11054: chipstat = AscGetChipStatus(iop_base); 11055: } 11056: } 11057: saved_ram_addr = AscGetChipLramAddr(iop_base); 11058: host_flag = AscReadLramByte(iop_base, 11059: ASCV_HOST_FLAG_B) & (uchar) (~ASC_HOST_FLAG_IN_ISR); 11060: AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, 11061: (uchar) (host_flag | (uchar) ASC_HOST_FLAG_IN_ISR)); 11062: if ((chipstat & CSW_INT_PENDING) 11063: || (int_pending) 11064: ) { 11065: AscAckInterrupt(iop_base); 11066: int_pending = TRUE; 11067: if ((chipstat & CSW_HALTED) && 11068: (ctrl_reg & CC_SINGLE_STEP)) { 11069: if (AscIsrChipHalted(asc_dvc) == ERR) { 11070: goto ISR_REPORT_QDONE_FATAL_ERROR; 11071: } else { 11072: saved_ctrl_reg &= (uchar) (~CC_HALT); 11073: } 11074: } else { 11075: ISR_REPORT_QDONE_FATAL_ERROR: 11076: if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) { 11077: while (((status = AscIsrQDone(asc_dvc)) & 0x01) != 0) { 11078: } 11079: } else { 11080: do { 11081: if ((status = AscIsrQDone(asc_dvc)) == 1) { 11082: break; 11083: } 11084: } while (status == 0x11); 11085: } 11086: if ((status & 0x80) != 0) 11087: int_pending = ERR; 11088: } 11089: } 11090: AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag); 11091: AscSetChipLramAddr(iop_base, saved_ram_addr); 11092: AscSetChipControl(iop_base, saved_ctrl_reg); 11093: asc_dvc->is_in_int = FALSE; 11094: return (int_pending); 11095: } 11096: 11097: STATIC uchar _asc_mcode_buf[] ASC_INITDATA = 11098: { 11099: 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11100: 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11101: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11102: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11103: 0x00, 0x00, 0x00, 0x00, 0x91, 0x10, 0x0A, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 11104: 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11105: 0x00, 0x00, 0x00, 0x23, 0x00, 0x24, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 11106: 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE2, 0x88, 0x00, 0x00, 0x00, 0x00, 11107: 0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40, 11108: 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2, 0xC2, 0x00, 0x92, 0x80, 11109: 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 11110: 0x4F, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62, 11111: 0x92, 0x80, 0x00, 0x46, 0x17, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8, 0xCD, 0x04, 0x4D, 0x00, 11112: 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1, 11113: 0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xE2, 0x01, 0xA6, 0x97, 0xCE, 0x81, 0x00, 0x33, 11114: 0x02, 0x00, 0xC0, 0x88, 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0x02, 0x01, 0x4F, 0x00, 11115: 0x84, 0x97, 0x07, 0xA6, 0x0C, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC0, 0x88, 0x03, 0x03, 0x03, 0xDE, 11116: 0x00, 0x33, 0x05, 0x00, 0xC0, 0x88, 0xCE, 0x00, 0x69, 0x60, 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 11117: 0x00, 0xA2, 0x80, 0x01, 0x80, 0x63, 0x07, 0xA6, 0x2C, 0x01, 0x80, 0x81, 0x03, 0x03, 0x80, 0x63, 11118: 0xE2, 0x00, 0x07, 0xA6, 0x3C, 0x01, 0x00, 0x33, 0x04, 0x00, 0xC0, 0x88, 0x03, 0x07, 0x02, 0x01, 11119: 0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04, 0x04, 0x85, 0x05, 0xD8, 0x0D, 0x23, 0x68, 0x98, 11120: 0xCD, 0x04, 0x15, 0x23, 0xF6, 0x88, 0xFB, 0x23, 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 11121: 0x06, 0xA3, 0x6A, 0x01, 0x00, 0x33, 0x0A, 0x00, 0xC0, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x76, 0x01, 11122: 0x00, 0x33, 0x0B, 0x00, 0xC0, 0x88, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1A, 0x00, 0xC0, 0x88, 11123: 0x50, 0x04, 0x90, 0x81, 0x06, 0xAB, 0x8A, 0x01, 0x90, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x9A, 0x01, 11124: 0x50, 0x00, 0x00, 0xA3, 0x44, 0x01, 0x00, 0x05, 0x84, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, 11125: 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, 0xC6, 0x81, 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 11126: 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xBC, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 11127: 0x00, 0x33, 0x1B, 0x00, 0xC0, 0x88, 0x06, 0x23, 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, 11128: 0x00, 0xA2, 0xDC, 0x01, 0x57, 0x60, 0x00, 0xA0, 0xE2, 0x01, 0xE6, 0x84, 0x80, 0x23, 0xA0, 0x01, 11129: 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x08, 0x02, 0x04, 0x01, 0x0C, 0xDE, 11130: 0x02, 0x01, 0x03, 0xCC, 0x4F, 0x00, 0x84, 0x97, 0x04, 0x82, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 11131: 0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80, 0xF0, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 11132: 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29, 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x67, 0xEB, 11133: 0x11, 0x23, 0xF6, 0x88, 0x04, 0x98, 0xF4, 0x80, 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x32, 0x02, 11134: 0x7C, 0x95, 0x06, 0xA6, 0x3C, 0x02, 0x03, 0xA6, 0x4C, 0x04, 0xC0, 0x88, 0x04, 0x01, 0x03, 0xD8, 11135: 0xB2, 0x98, 0x6A, 0x96, 0x4E, 0x82, 0xFE, 0x95, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 11136: 0x02, 0xA6, 0x78, 0x02, 0x07, 0xA6, 0x66, 0x02, 0x06, 0xA6, 0x6A, 0x02, 0x03, 0xA6, 0x6E, 0x02, 11137: 0x00, 0x33, 0x10, 0x00, 0xC0, 0x88, 0x7C, 0x95, 0x50, 0x82, 0x60, 0x96, 0x50, 0x82, 0x04, 0x23, 11138: 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC, 0xE0, 0x23, 0x25, 0x61, 11139: 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01, 0x6F, 0x00, 0xA5, 0x01, 0x03, 0x23, 0xA4, 0x01, 11140: 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xB6, 0x02, 0x07, 0xA6, 0x66, 0x02, 11141: 0x06, 0xA6, 0x6A, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xC0, 0x02, 0x00, 0xA6, 0xC0, 0x02, 11142: 0x00, 0x33, 0x12, 0x00, 0xC0, 0x88, 0x00, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x98, 0x02, 11143: 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01, 0x10, 0x31, 0x12, 0x35, 11144: 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xF6, 0x82, 0x18, 0x23, 0x04, 0x61, 11145: 0x18, 0xA0, 0xEE, 0x02, 0x04, 0x01, 0x9C, 0xC8, 0x00, 0x33, 0x1F, 0x00, 0xC0, 0x88, 0x08, 0x31, 11146: 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6, 0x20, 0x03, 0x00, 0xA6, 11147: 0x20, 0x03, 0x07, 0xA6, 0x18, 0x03, 0x06, 0xA6, 0x1C, 0x03, 0x03, 0xA6, 0x20, 0x04, 0x02, 0xA6, 11148: 0x78, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC0, 0x88, 0x7C, 0x95, 0xFA, 0x82, 0x60, 0x96, 0xFA, 0x82, 11149: 0x82, 0x98, 0x80, 0x42, 0x7E, 0x98, 0x60, 0xE4, 0x04, 0x01, 0x29, 0xC8, 0x31, 0x05, 0x07, 0x01, 11150: 0x00, 0xA2, 0x60, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98, 0x7E, 0x98, 0x00, 0xA6, 11151: 0x22, 0x03, 0x07, 0xA6, 0x58, 0x03, 0x03, 0xA6, 0x3C, 0x04, 0x06, 0xA6, 0x5C, 0x03, 0x01, 0xA6, 11152: 0x22, 0x03, 0x00, 0x33, 0x25, 0x00, 0xC0, 0x88, 0x7C, 0x95, 0x3E, 0x83, 0x60, 0x96, 0x3E, 0x83, 11153: 0x04, 0x01, 0x0C, 0xCE, 0x03, 0xC8, 0x00, 0x33, 0x42, 0x00, 0xC0, 0x88, 0x00, 0x01, 0x05, 0x05, 11154: 0xFF, 0xA2, 0x7E, 0x03, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x3A, 0x83, 0x05, 0x05, 0x15, 0x01, 11155: 0x00, 0xA2, 0x9E, 0x03, 0xEC, 0x00, 0x6E, 0x00, 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 11156: 0x01, 0xA6, 0x9A, 0x03, 0x00, 0xA6, 0x9A, 0x03, 0x12, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6, 11157: 0xA8, 0x03, 0x00, 0xA6, 0xC0, 0x03, 0x12, 0x84, 0xA6, 0x98, 0x80, 0x42, 0x01, 0xA6, 0xA8, 0x03, 11158: 0x07, 0xA6, 0xB6, 0x03, 0xD8, 0x83, 0x7C, 0x95, 0xAC, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC0, 0x88, 11159: 0xA6, 0x98, 0x80, 0x42, 0x00, 0xA6, 0xC0, 0x03, 0x07, 0xA6, 0xCE, 0x03, 0xD8, 0x83, 0x7C, 0x95, 11160: 0xC4, 0x83, 0x00, 0x33, 0x26, 0x00, 0xC0, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36, 0x04, 0x23, 11161: 0xA0, 0x01, 0x12, 0x23, 0xA1, 0x01, 0x12, 0x84, 0x06, 0xF0, 0x06, 0xA4, 0xF6, 0x03, 0x80, 0x6B, 11162: 0x05, 0x23, 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x10, 0x04, 0x07, 0xA6, 0x08, 0x04, 0x06, 0xA6, 11163: 0x0C, 0x04, 0x00, 0x33, 0x17, 0x00, 0xC0, 0x88, 0x7C, 0x95, 0xF6, 0x83, 0x60, 0x96, 0xF6, 0x83, 11164: 0x20, 0x84, 0x06, 0xF0, 0x06, 0xA4, 0x20, 0x04, 0x80, 0x6B, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63, 11165: 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6, 0x38, 0x04, 0x00, 0x33, 11166: 0x30, 0x00, 0xC0, 0x88, 0x7C, 0x95, 0x20, 0x84, 0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC, 11167: 0x00, 0x33, 0x00, 0x84, 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63, 11168: 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC0, 0x88, 0x03, 0x03, 0x80, 0x63, 0xA3, 0x01, 11169: 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, 0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00, 11170: 0x00, 0x33, 0x1D, 0x00, 0xC0, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00, 11171: 0xC0, 0x88, 0x42, 0x23, 0xF6, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04, 0x08, 0x23, 0x22, 0xA3, 11172: 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, 0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23, 11173: 0xF6, 0x88, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF6, 0x88, 0x04, 0x98, 11174: 0x00, 0xA2, 0xC0, 0x04, 0xB2, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20, 0x81, 0x62, 0xF0, 0x81, 11175: 0x47, 0x23, 0xF6, 0x88, 0x04, 0x01, 0x0B, 0xDE, 0x04, 0x98, 0xB2, 0x98, 0x00, 0x33, 0x00, 0x81, 11176: 0xC0, 0x20, 0x81, 0x62, 0x14, 0x01, 0x00, 0xA0, 0x08, 0x02, 0x43, 0x23, 0xF6, 0x88, 0x04, 0x23, 11177: 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3, 0xF4, 0x04, 0x00, 0x33, 11178: 0x27, 0x00, 0xC0, 0x88, 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01, 11179: 0x04, 0x98, 0x26, 0x95, 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05, 11180: 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85, 0x46, 0x97, 0xCD, 0x04, 11181: 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85, 11182: 0x02, 0x23, 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6, 11183: 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x49, 0x00, 0x81, 0x01, 11184: 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01, 11185: 0xC9, 0x00, 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00, 11186: 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63, 0x07, 0xA4, 0xF8, 0x05, 11187: 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, 0x00, 0x33, 0x2D, 0x00, 0xC0, 0x88, 0x04, 0xA0, 11188: 0xB8, 0x05, 0x80, 0x63, 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05, 11189: 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00, 0x62, 0x97, 0x04, 0x85, 11190: 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, 0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0, 11191: 0xC4, 0x05, 0xF4, 0x85, 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0, 11192: 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05, 0x80, 0x67, 0x80, 0x63, 11193: 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, 0x68, 0x98, 0x48, 0x23, 0xF6, 0x88, 0x07, 0x23, 11194: 0x80, 0x00, 0x06, 0x87, 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00, 11195: 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23, 0x07, 0x41, 0x83, 0x03, 11196: 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, 0x37, 0x00, 0xC0, 0x88, 0x1D, 0x01, 0x01, 0xD6, 11197: 0x20, 0x23, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05, 11198: 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00, 0x52, 0x00, 0x06, 0x61, 11199: 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01, 11200: 0x04, 0xCC, 0x00, 0x33, 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63, 11201: 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23, 0xDF, 0x00, 0x06, 0xA6, 11202: 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20, 11203: 0x81, 0x62, 0x00, 0x63, 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06, 11204: 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B, 0x40, 0x0E, 0x80, 0x63, 11205: 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43, 11206: 0x00, 0xA0, 0xA2, 0x06, 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E, 11207: 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x07, 0xA6, 0xD6, 0x06, 11208: 0x00, 0x33, 0x2A, 0x00, 0xC0, 0x88, 0x03, 0x03, 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6, 11209: 0xE8, 0x06, 0x00, 0x33, 0x29, 0x00, 0xC0, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E, 11210: 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20, 0x81, 0x62, 0x04, 0x01, 11211: 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33, 11212: 0x2C, 0x00, 0xC0, 0x88, 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 11213: 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC0, 0x88, 0x00, 0x00, 0x80, 0x67, 11214: 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61, 11215: 0x84, 0x01, 0xE6, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00, 11216: 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04, 0x80, 0x05, 0x81, 0x05, 11217: 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01, 11218: 0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01, 11219: 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01, 0xF1, 0x00, 0x70, 0x00, 11220: 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00, 11221: 0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01, 11222: 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1, 0xC4, 0x07, 0x00, 0x33, 11223: 0x07, 0x00, 0xC0, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01, 11224: 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07, 11225: 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x05, 0x05, 0x00, 0x63, 11226: 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02, 11227: 0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0, 11228: 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63, 0xF3, 0x04, 11229: 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08, 11230: 0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98, 11231: 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04, 0x5A, 0x88, 0x02, 0x01, 11232: 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, 0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08, 11233: 0x00, 0x05, 0x4E, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08, 11234: 0x00, 0x33, 0x3E, 0x00, 0xC0, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x38, 0x2B, 11235: 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, 0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09, 11236: 0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36, 11237: 0x80, 0x3A, 0x80, 0x3E, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32, 0x40, 0x36, 0x40, 0x3A, 0x40, 0x3E, 11238: 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0xB2, 0x08, 0x5D, 0x00, 0xFE, 0xC3, 0x00, 0x63, 11239: 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73, 0x13, 0x23, 11240: 0xF6, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01, 0xA1, 0x23, 0xA1, 0x01, 0x81, 0x62, 11241: 0xE0, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2, 0xF1, 0xC7, 11242: 0x41, 0x23, 0xF6, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84, 11243: }; 11244: 11245: STATIC ushort _asc_mcode_size ASC_INITDATA = sizeof(_asc_mcode_buf); 11246: STATIC ulong _asc_mcode_chksum ASC_INITDATA = 0x012B5442UL; 11247: 11248: #define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16 11249: STATIC uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = 11250: { 11251: SCSICMD_Inquiry, 11252: SCSICMD_RequestSense, 11253: SCSICMD_ReadCapacity, 11254: SCSICMD_ReadTOC, 11255: SCSICMD_ModeSelect6, 11256: SCSICMD_ModeSense6, 11257: SCSICMD_ModeSelect10, 11258: SCSICMD_ModeSense10, 11259: 0xFF, 11260: 0xFF, 11261: 0xFF, 11262: 0xFF, 11263: 0xFF, 11264: 0xFF, 11265: 0xFF, 11266: 0xFF 11267: }; 11268: 11269: STATIC int 11270: AscExeScsiQueue( 11271: REG ASC_DVC_VAR asc_ptr_type * asc_dvc, 11272: REG ASC_SCSI_Q * scsiq 11273: ) 11274: { 11275: PortAddr iop_base; 11276: int last_int_level; 11277: int sta; 11278: int n_q_required; 11279: int disable_syn_offset_one_fix; 11280: int i; 11281: ulong addr; 11282: ASC_EXE_CALLBACK asc_exe_callback; 11283: ushort sg_entry_cnt = 0; 11284: ushort sg_entry_cnt_minus_one = 0; 11285: uchar target_ix; 11286: uchar tid_no; 11287: uchar sdtr_data; 11288: uchar extra_bytes; 11289: uchar scsi_cmd; 11290: uchar disable_cmd; 11291: ASC_SG_HEAD *sg_head; 11292: ulong data_cnt; 11293: 11294: iop_base = asc_dvc->iop_base; 11295: sg_head = scsiq->sg_head; 11296: asc_exe_callback = (ASC_EXE_CALLBACK) asc_dvc->exe_callback; 11297: if (asc_dvc->err_code != 0) 11298: return (ERR); 11299: if (scsiq == (ASC_SCSI_Q *) 0L) { 11300: AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR); 11301: return (ERR); 11302: } 11303: scsiq->q1.q_no = 0; 11304: if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) { 11305: scsiq->q1.extra_bytes = 0; 11306: } 11307: sta = 0; 11308: target_ix = scsiq->q2.target_ix; 11309: tid_no = ASC_TIX_TO_TID(target_ix); 11310: n_q_required = 1; 11311: if (scsiq->cdbptr[0] == SCSICMD_RequestSense) { 11312: if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) { 11313: asc_dvc->sdtr_done &= ~scsiq->q1.target_id ; 11314: sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no); 11315: AscMsgOutSDTR(asc_dvc, 11316: asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) & 11317: (uchar) (asc_dvc->max_sdtr_index - 1)], 11318: (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET)); 11319: scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT); 11320: } 11321: } 11322: last_int_level = DvcEnterCritical(); 11323: if (asc_dvc->in_critical_cnt != 0) { 11324: DvcLeaveCritical(last_int_level); 11325: AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY); 11326: return (ERR); 11327: } 11328: asc_dvc->in_critical_cnt++; 11329: if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) { 11330: if ((sg_entry_cnt = sg_head->entry_cnt) == 0) { 11331: asc_dvc->in_critical_cnt--; 11332: DvcLeaveCritical(last_int_level); 11333: return (ERR); 11334: } 11335: if (sg_entry_cnt > ASC_MAX_SG_LIST) { 11336: return (ERR); 11337: } 11338: if (sg_entry_cnt == 1) { 11339: scsiq->q1.data_addr = sg_head->sg_list[0].addr; 11340: scsiq->q1.data_cnt = sg_head->sg_list[0].bytes; 11341: scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE); 11342: } 11343: sg_entry_cnt_minus_one = sg_entry_cnt - 1; 11344: } 11345: scsi_cmd = scsiq->cdbptr[0]; 11346: disable_syn_offset_one_fix = FALSE; 11347: if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) && 11348: !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) { 11349: if (scsiq->q1.cntl & QC_SG_HEAD) { 11350: data_cnt = 0; 11351: for (i = 0; i < sg_entry_cnt; i++) { 11352: data_cnt += sg_head->sg_list[i].bytes; 11353: } 11354: } else { 11355: data_cnt = scsiq->q1.data_cnt; 11356: } 11357: if (data_cnt != 0UL) { 11358: if (data_cnt < 512UL) { 11359: disable_syn_offset_one_fix = TRUE; 11360: } else { 11361: for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST; i++) { 11362: disable_cmd = _syn_offset_one_disable_cmd[i]; 11363: if (disable_cmd == 0xFF) { 11364: break; 11365: } 11366: if (scsi_cmd == disable_cmd) { 11367: disable_syn_offset_one_fix = TRUE; 11368: break; 11369: } 11370: } 11371: } 11372: } 11373: } 11374: if (disable_syn_offset_one_fix) { 11375: scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE; 11376: scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX | 11377: ASC_TAG_FLAG_DISABLE_DISCONNECT); 11378: } else { 11379: scsiq->q2.tag_code &= 0x23; 11380: } 11381: if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) { 11382: if (asc_dvc->bug_fix_cntl) { 11383: if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) { 11384: if ((scsi_cmd == SCSICMD_Read6) || 11385: (scsi_cmd == SCSICMD_Read10)) { 11386: addr = sg_head->sg_list[sg_entry_cnt_minus_one].addr + 11387: sg_head->sg_list[sg_entry_cnt_minus_one].bytes; 11388: extra_bytes = (uchar) ((ushort) addr & 0x0003); 11389: if ((extra_bytes != 0) && 11390: ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) 11391: == 0)) { 11392: scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES; 11393: scsiq->q1.extra_bytes = extra_bytes; 11394: sg_head->sg_list[sg_entry_cnt_minus_one].bytes -= 11395: (ulong) extra_bytes; 11396: } 11397: } 11398: } 11399: } 11400: sg_head->entry_to_copy = sg_head->entry_cnt; 11401: n_q_required = AscSgListToQueue(sg_entry_cnt); 11402: if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >= 11403: (uint) n_q_required) || ((scsiq->q1.cntl & QC_URGENT) != 0)) { 11404: if ((sta = AscSendScsiQueue(asc_dvc, scsiq, 11405: n_q_required)) == 1) { 11406: asc_dvc->in_critical_cnt--; 11407: if (asc_exe_callback != 0) { 11408: (*asc_exe_callback) (asc_dvc, scsiq); 11409: } 11410: DvcLeaveCritical(last_int_level); 11411: return (sta); 11412: } 11413: } 11414: } else { 11415: if (asc_dvc->bug_fix_cntl) { 11416: if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) { 11417: if ((scsi_cmd == SCSICMD_Read6) || 11418: (scsi_cmd == SCSICMD_Read10)) { 11419: addr = scsiq->q1.data_addr + scsiq->q1.data_cnt; 11420: extra_bytes = (uchar) ((ushort) addr & 0x0003); 11421: if ((extra_bytes != 0) && 11422: ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) 11423: == 0)) { 11424: if (((ushort) scsiq->q1.data_cnt & 0x01FF) == 0) { 11425: scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES; 11426: scsiq->q1.data_cnt -= (ulong) extra_bytes; 11427: scsiq->q1.extra_bytes = extra_bytes; 11428: } 11429: } 11430: } 11431: } 11432: } 11433: n_q_required = 1; 11434: if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) || 11435: ((scsiq->q1.cntl & QC_URGENT) != 0)) { 11436: if ((sta = AscSendScsiQueue(asc_dvc, scsiq, 11437: n_q_required)) == 1) { 11438: asc_dvc->in_critical_cnt--; 11439: if (asc_exe_callback != 0) { 11440: (*asc_exe_callback) (asc_dvc, scsiq); 11441: } 11442: DvcLeaveCritical(last_int_level); 11443: return (sta); 11444: } 11445: } 11446: } 11447: asc_dvc->in_critical_cnt--; 11448: DvcLeaveCritical(last_int_level); 11449: return (sta); 11450: } 11451: 11452: STATIC int 11453: AscSendScsiQueue( 11454: REG ASC_DVC_VAR asc_ptr_type * asc_dvc, 11455: REG ASC_SCSI_Q * scsiq, 11456: uchar n_q_required 11457: ) 11458: { 11459: PortAddr iop_base; 11460: uchar free_q_head; 11461: uchar next_qp; 11462: uchar tid_no; 11463: uchar target_ix; 11464: int sta; 11465: 11466: iop_base = asc_dvc->iop_base; 11467: target_ix = scsiq->q2.target_ix; 11468: tid_no = ASC_TIX_TO_TID(target_ix); 11469: sta = 0; 11470: free_q_head = (uchar) AscGetVarFreeQHead(iop_base); 11471: if (n_q_required > 1) { 11472: if ((next_qp = AscAllocMultipleFreeQueue(iop_base, 11473: free_q_head, (uchar) (n_q_required))) 11474: != (uchar) ASC_QLINK_END) { 11475: asc_dvc->last_q_shortage = 0; 11476: scsiq->sg_head->queue_cnt = n_q_required - 1; 11477: scsiq->q1.q_no = free_q_head; 11478: if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq, 11479: free_q_head)) == 1) { 11480: AscPutVarFreeQHead(iop_base, next_qp); 11481: asc_dvc->cur_total_qng += (uchar) (n_q_required); 11482: asc_dvc->cur_dvc_qng[tid_no]++; 11483: } 11484: return (sta); 11485: } 11486: } else if (n_q_required == 1) { 11487: if ((next_qp = AscAllocFreeQueue(iop_base, 11488: free_q_head)) != ASC_QLINK_END) { 11489: scsiq->q1.q_no = free_q_head; 11490: if ((sta = AscPutReadyQueue(asc_dvc, scsiq, 11491: free_q_head)) == 1) { 11492: AscPutVarFreeQHead(iop_base, next_qp); 11493: asc_dvc->cur_total_qng++; 11494: asc_dvc->cur_dvc_qng[tid_no]++; 11495: } 11496: return (sta); 11497: } 11498: } 11499: return (sta); 11500: } 11501: 11502: STATIC int 11503: AscSgListToQueue( 11504: int sg_list 11505: ) 11506: { 11507: int n_sg_list_qs; 11508: 11509: n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q); 11510: if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0) 11511: n_sg_list_qs++; 11512: return (n_sg_list_qs + 1); 11513: } 11514: 11515: 11516: STATIC uint 11517: AscGetNumOfFreeQueue( 11518: REG ASC_DVC_VAR asc_ptr_type * asc_dvc, 11519: uchar target_ix, 11520: uchar n_qs 11521: ) 11522: { 11523: uint cur_used_qs; 11524: uint cur_free_qs; 11525: ASC_SCSI_BIT_ID_TYPE target_id; 11526: uchar tid_no; 11527: 11528: target_id = ASC_TIX_TO_TARGET_ID(target_ix); 11529: tid_no = ASC_TIX_TO_TID(target_ix); 11530: if ((asc_dvc->unit_not_ready & target_id) || 11531: (asc_dvc->queue_full_or_busy & target_id)) { 11532: return (0); 11533: } 11534: if (n_qs == 1) { 11535: cur_used_qs = (uint) asc_dvc->cur_total_qng + 11536: (uint) asc_dvc->last_q_shortage + 11537: (uint) ASC_MIN_FREE_Q; 11538: } else { 11539: cur_used_qs = (uint) asc_dvc->cur_total_qng + 11540: (uint) ASC_MIN_FREE_Q; 11541: } 11542: if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) { 11543: cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs; 11544: if (asc_dvc->cur_dvc_qng[tid_no] >= 11545: asc_dvc->max_dvc_qng[tid_no]) { 11546: return (0); 11547: } 11548: return (cur_free_qs); 11549: } 11550: if (n_qs > 1) { 11551: if ((n_qs > asc_dvc->last_q_shortage) && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) { 11552: asc_dvc->last_q_shortage = n_qs; 11553: } 11554: } 11555: return (0); 11556: } 11557: 11558: STATIC int 11559: AscPutReadyQueue( 11560: REG ASC_DVC_VAR asc_ptr_type * asc_dvc, 11561: REG ASC_SCSI_Q * scsiq, 11562: uchar q_no 11563: ) 11564: { 11565: ushort q_addr; 11566: uchar tid_no; 11567: uchar sdtr_data; 11568: uchar syn_period_ix; 11569: uchar syn_offset; 11570: PortAddr iop_base; 11571: 11572: iop_base = asc_dvc->iop_base; 11573: if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) && 11574: ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) { 11575: tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix); 11576: sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no); 11577: syn_period_ix = (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1); 11578: syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET; 11579: AscMsgOutSDTR(asc_dvc, 11580: asc_dvc->sdtr_period_tbl[syn_period_ix], 11581: syn_offset); 11582: scsiq->q1.cntl |= QC_MSG_OUT; 11583: } 11584: q_addr = ASC_QNO_TO_QADDR(q_no); 11585: if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) { 11586: scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE; 11587: } 11588: scsiq->q1.status = QS_FREE; 11589: AscMemWordCopyToLram(iop_base, 11590: (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG), 11591: (ushort *) scsiq->cdbptr, 11592: (ushort) ((ushort) scsiq->q2.cdb_len >> 1)); 11593: DvcPutScsiQ(iop_base, 11594: (ushort) (q_addr + (ushort) ASC_SCSIQ_CPY_BEG), 11595: (ushort *) & scsiq->q1.cntl, 11596: (ushort) ((((sizeof (ASC_SCSIQ_1) + sizeof (ASC_SCSIQ_2)) / 2) - 1))); 11597: AscWriteLramWord(iop_base, 11598: (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS), 11599: (ushort) (((ushort) scsiq->q1.q_no << 8) | (ushort) QS_READY)); 11600: return (1); 11601: } 11602: 11603: STATIC int 11604: AscPutReadySgListQueue( 11605: REG ASC_DVC_VAR asc_ptr_type * asc_dvc, 11606: REG ASC_SCSI_Q * scsiq, 11607: uchar q_no 11608: ) 11609: { 11610: int sta; 11611: int i; 11612: ASC_SG_HEAD *sg_head; 11613: ASC_SG_LIST_Q scsi_sg_q; 11614: ulong saved_data_addr; 11615: ulong saved_data_cnt; 11616: PortAddr iop_base; 11617: ushort sg_list_dwords; 11618: ushort sg_index; 11619: ushort sg_entry_cnt; 11620: ushort q_addr; 11621: uchar next_qp; 11622: 11623: iop_base = asc_dvc->iop_base; 11624: sg_head = scsiq->sg_head; 11625: saved_data_addr = scsiq->q1.data_addr; 11626: saved_data_cnt = scsiq->q1.data_cnt; 11627: scsiq->q1.data_addr = sg_head->sg_list[0].addr; 11628: scsiq->q1.data_cnt = sg_head->sg_list[0].bytes; 11629: sg_entry_cnt = sg_head->entry_cnt - 1; 11630: if (sg_entry_cnt != 0) { 11631: scsiq->q1.cntl |= QC_SG_HEAD; 11632: q_addr = ASC_QNO_TO_QADDR(q_no); 11633: sg_index = 1; 11634: scsiq->q1.sg_queue_cnt = sg_head->queue_cnt; 11635: scsi_sg_q.sg_head_qp = q_no; 11636: scsi_sg_q.cntl = QCSG_SG_XFER_LIST; 11637: for (i = 0; i < sg_head->queue_cnt; i++) { 11638: scsi_sg_q.seq_no = i + 1; 11639: if (sg_entry_cnt > ASC_SG_LIST_PER_Q) { 11640: sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2); 11641: sg_entry_cnt -= ASC_SG_LIST_PER_Q; 11642: if (i == 0) { 11643: scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q; 11644: scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q; 11645: } else { 11646: scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1; 11647: scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1; 11648: } 11649: } else { 11650: scsi_sg_q.cntl |= QCSG_SG_XFER_END; 11651: sg_list_dwords = sg_entry_cnt << 1; 11652: if (i == 0) { 11653: scsi_sg_q.sg_list_cnt = sg_entry_cnt; 11654: scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt; 11655: } else { 11656: scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1; 11657: scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1; 11658: } 11659: sg_entry_cnt = 0; 11660: } 11661: next_qp = AscReadLramByte(iop_base, 11662: (ushort) (q_addr + ASC_SCSIQ_B_FWD)); 11663: scsi_sg_q.q_no = next_qp; 11664: q_addr = ASC_QNO_TO_QADDR(next_qp); 11665: AscMemWordCopyToLram(iop_base, 11666: (ushort) (q_addr + ASC_SCSIQ_SGHD_CPY_BEG), 11667: (ushort *) & scsi_sg_q, 11668: (ushort) (sizeof (ASC_SG_LIST_Q) >> 1)); 11669: AscMemDWordCopyToLram(iop_base, 11670: (ushort) (q_addr + ASC_SGQ_LIST_BEG), 11671: (ulong *) & sg_head->sg_list[sg_index], 11672: (ushort) sg_list_dwords); 11673: sg_index += ASC_SG_LIST_PER_Q; 11674: } 11675: } else { 11676: scsiq->q1.cntl &= ~QC_SG_HEAD; 11677: } 11678: sta = AscPutReadyQueue(asc_dvc, scsiq, q_no); 11679: scsiq->q1.data_addr = saved_data_addr; 11680: scsiq->q1.data_cnt = saved_data_cnt; 11681: return (sta); 11682: } 11683: 11684: STATIC int 11685: AscAbortSRB( 11686: REG ASC_DVC_VAR asc_ptr_type * asc_dvc, 11687: ulong srb_ptr 11688: ) 11689: { 11690: int sta; 11691: ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready; 11692: PortAddr iop_base; 11693: 11694: iop_base = asc_dvc->iop_base; 11695: sta = ERR; 11696: saved_unit_not_ready = asc_dvc->unit_not_ready; 11697: asc_dvc->unit_not_ready = 0xFF; 11698: AscWaitISRDone(asc_dvc); 11699: if (AscStopQueueExe(iop_base) == 1) { 11700: if (AscRiscHaltedAbortSRB(asc_dvc, srb_ptr) == 1) { 11701: sta = 1; 11702: AscCleanUpBusyQueue(iop_base); 11703: AscStartQueueExe(iop_base); 11704: } else { 11705: sta = 0; 11706: AscStartQueueExe(iop_base); 11707: } 11708: } 11709: asc_dvc->unit_not_ready = saved_unit_not_ready; 11710: return (sta); 11711: } 11712: 11713: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89) 11714: STATIC int 11715: AscResetDevice( 11716: REG ASC_DVC_VAR asc_ptr_type * asc_dvc, 11717: uchar target_ix 11718: ) 11719: { 11720: PortAddr iop_base; 11721: int sta; 11722: uchar tid_no; 11723: 11724: ASC_SCSI_BIT_ID_TYPE target_id; 11725: int i; 11726: ASC_SCSI_REQ_Q scsiq_buf; 11727: ASC_SCSI_REQ_Q *scsiq; 11728: uchar *buf; 11729: ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready; 11730: iop_base = asc_dvc->iop_base; 11731: tid_no = ASC_TIX_TO_TID(target_ix); 11732: target_id = ASC_TID_TO_TARGET_ID(tid_no); 11733: saved_unit_not_ready = asc_dvc->unit_not_ready; 11734: asc_dvc->unit_not_ready = target_id; 11735: sta = ERR; 11736: AscWaitTixISRDone(asc_dvc, target_ix); 11737: if (AscStopQueueExe(iop_base) == 1) { 11738: if (AscRiscHaltedAbortTIX(asc_dvc, target_ix) == 1) { 11739: AscCleanUpBusyQueue(iop_base); 11740: AscStartQueueExe(iop_base); 11741: AscWaitTixISRDone(asc_dvc, target_ix); 11742: sta = TRUE; 11743: scsiq = (ASC_SCSI_REQ_Q *) & scsiq_buf; 11744: buf = (uchar *) & scsiq_buf; 11745: for (i = 0; i < sizeof (ASC_SCSI_REQ_Q); i++) { 11746: *buf++ = 0x00; 11747: } 11748: scsiq->r1.status = (uchar) QS_READY; 11749: scsiq->r2.cdb_len = 6; 11750: scsiq->r2.tag_code = M2_QTAG_MSG_SIMPLE; 11751: scsiq->r1.target_id = target_id; 11752: scsiq->r2.target_ix = ASC_TIDLUN_TO_IX(tid_no, 0); 11753: scsiq->cdbptr = (uchar *) scsiq->cdb; 11754: scsiq->r1.cntl = QC_NO_CALLBACK | QC_MSG_OUT | QC_URGENT; 11755: AscWriteLramByte(asc_dvc->iop_base, ASCV_MSGOUT_BEG, 11756: M1_BUS_DVC_RESET); 11757: asc_dvc->unit_not_ready &= ~target_id; 11758: asc_dvc->sdtr_done |= target_id; 11759: if (AscExeScsiQueue(asc_dvc, (ASC_SCSI_Q *) scsiq) 11760: == 1) { 11761: asc_dvc->unit_not_ready = target_id; 11762: DvcSleepMilliSecond(1000); 11763: _AscWaitQDone(iop_base, (ASC_SCSI_Q *) scsiq); 11764: if (AscStopQueueExe(iop_base) == 1) { 11765: AscCleanUpDiscQueue(iop_base); 11766: AscStartQueueExe(iop_base); 11767: if (asc_dvc->pci_fix_asyn_xfer & target_id) { 11768: AscSetRunChipSynRegAtID(iop_base, tid_no, 11769: ASYN_SDTR_DATA_FIX_PCI_REV_AB); 11770: } 11771: AscWaitTixISRDone(asc_dvc, target_ix); 11772: } 11773: } else { 11774: sta = 0; 11775: } 11776: asc_dvc->sdtr_done &= ~target_id; 11777: } else { 11778: sta = ERR; 11779: AscStartQueueExe(iop_base); 11780: } 11781: } 11782: asc_dvc->unit_not_ready = saved_unit_not_ready; 11783: return (sta); 11784: } 11785: #endif /* version >= v1.3.89 */ 11786: 11787: STATIC int 11788: AscResetSB( 11789: REG ASC_DVC_VAR asc_ptr_type * asc_dvc 11790: ) 11791: { 11792: int sta; 11793: int i; 11794: PortAddr iop_base; 11795: 11796: iop_base = asc_dvc->iop_base; 11797: asc_dvc->unit_not_ready = 0xFF; 11798: sta = TRUE; 11799: AscWaitISRDone(asc_dvc); 11800: AscStopQueueExe(iop_base); 11801: asc_dvc->sdtr_done = 0; 11802: AscResetChipAndScsiBus(asc_dvc); 11803: DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000)); 11804: AscReInitLram(asc_dvc); 11805: for (i = 0; i <= ASC_MAX_TID; i++) { 11806: asc_dvc->cur_dvc_qng[i] = 0; 11807: if (asc_dvc->pci_fix_asyn_xfer & (ASC_SCSI_BIT_ID_TYPE) (0x01 << i)) { 11808: AscSetChipSynRegAtID(iop_base, i, ASYN_SDTR_DATA_FIX_PCI_REV_AB); 11809: } 11810: } 11811: asc_dvc->err_code = 0; 11812: AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR); 11813: if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) { 11814: sta = ERR; 11815: } 11816: if (AscStartChip(iop_base) == 0) { 11817: sta = ERR; 11818: } 11819: AscStartQueueExe(iop_base); 11820: asc_dvc->unit_not_ready = 0; 11821: asc_dvc->queue_full_or_busy = 0; 11822: return (sta); 11823: } 11824: 11825: STATIC int 11826: AscSetRunChipSynRegAtID( 11827: PortAddr iop_base, 11828: uchar tid_no, 11829: uchar sdtr_data 11830: ) 11831: { 11832: int sta = FALSE; 11833: 11834: if (AscHostReqRiscHalt(iop_base)) { 11835: sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data); 11836: AscStartChip(iop_base); 11837: return (sta); 11838: } 11839: return (sta); 11840: } 11841: 11842: STATIC int 11843: AscSetChipSynRegAtID( 11844: PortAddr iop_base, 11845: uchar id, 11846: uchar sdtr_data 11847: ) 11848: { 11849: ASC_SCSI_BIT_ID_TYPE org_id; 11850: int i; 11851: int sta = TRUE; 11852: 11853: AscSetBank(iop_base, 1); 11854: org_id = AscReadChipDvcID(iop_base); 11855: for (i = 0; i <= ASC_MAX_TID; i++) { 11856: if (org_id == (0x01 << i)) 11857: break; 11858: } 11859: org_id = i; 11860: AscWriteChipDvcID(iop_base, id); 11861: if (AscReadChipDvcID(iop_base) == (0x01 << id)) { 11862: AscSetBank(iop_base, 0); 11863: AscSetChipSyn(iop_base, sdtr_data); 11864: if (AscGetChipSyn(iop_base) != sdtr_data) { 11865: sta = FALSE; 11866: } 11867: } else { 11868: sta = FALSE; 11869: } 11870: AscSetBank(iop_base, 1); 11871: AscWriteChipDvcID(iop_base, org_id); 11872: AscSetBank(iop_base, 0); 11873: return (sta); 11874: } 11875: 11876: STATIC int 11877: AscReInitLram( 11878: REG ASC_DVC_VAR asc_ptr_type * asc_dvc 11879: ) 11880: { 11881: AscInitLram(asc_dvc); 11882: AscInitQLinkVar(asc_dvc); 11883: return (0); 11884: } 11885: 11886: STATIC ushort 11887: AscInitLram( 11888: REG ASC_DVC_VAR asc_ptr_type * asc_dvc 11889: ) 11890: { 11891: uchar i; 11892: ushort s_addr; 11893: PortAddr iop_base; 11894: ushort warn_code; 11895: 11896: iop_base = asc_dvc->iop_base; 11897: warn_code = 0; 11898: AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0, 11899: (ushort) (((int) (asc_dvc->max_total_qng + 2 + 1) * 64) >> 1) 11900: ); 11901: i = ASC_MIN_ACTIVE_QNO; 11902: s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE; 11903: AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD), 11904: (uchar) (i + 1)); 11905: AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD), 11906: (uchar) (asc_dvc->max_total_qng)); 11907: AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO), 11908: (uchar) i); 11909: i++; 11910: s_addr += ASC_QBLK_SIZE; 11911: for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) { 11912: AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD), 11913: (uchar) (i + 1)); 11914: AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD), 11915: (uchar) (i - 1)); 11916: AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO), 11917: (uchar) i); 11918: } 11919: AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD), 11920: (uchar) ASC_QLINK_END); 11921: AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD), 11922: (uchar) (asc_dvc->max_total_qng - 1)); 11923: AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO), 11924: (uchar) asc_dvc->max_total_qng); 11925: i++; 11926: s_addr += ASC_QBLK_SIZE; 11927: for (; i <= (uchar) (asc_dvc->max_total_qng + 3); 11928: i++, s_addr += ASC_QBLK_SIZE) { 11929: AscWriteLramByte(iop_base, 11930: (ushort) (s_addr + (ushort) ASC_SCSIQ_B_FWD), i); 11931: AscWriteLramByte(iop_base, 11932: (ushort) (s_addr + (ushort) ASC_SCSIQ_B_BWD), i); 11933: AscWriteLramByte(iop_base, 11934: (ushort) (s_addr + (ushort) ASC_SCSIQ_B_QNO), i); 11935: } 11936: return (warn_code); 11937: } 11938: 11939: STATIC ushort 11940: AscInitQLinkVar( 11941: REG ASC_DVC_VAR asc_ptr_type * asc_dvc 11942: ) 11943: { 11944: PortAddr iop_base; 11945: int i; 11946: ushort lram_addr; 11947: 11948: iop_base = asc_dvc->iop_base; 11949: AscPutRiscVarFreeQHead(iop_base, 1); 11950: AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng); 11951: AscPutVarFreeQHead(iop_base, 1); 11952: AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng); 11953: AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B, 11954: (uchar) ((int) asc_dvc->max_total_qng + 1)); 11955: AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B, 11956: (uchar) ((int) asc_dvc->max_total_qng + 2)); 11957: AscWriteLramByte(iop_base, (ushort) ASCV_TOTAL_READY_Q_B, 11958: asc_dvc->max_total_qng); 11959: AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0); 11960: AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); 11961: AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0); 11962: AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0); 11963: AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0); 11964: AscPutQDoneInProgress(iop_base, 0); 11965: lram_addr = ASC_QADR_BEG; 11966: for (i = 0; i < 32; i++, lram_addr += 2) { 11967: AscWriteLramWord(iop_base, lram_addr, 0); 11968: } 11969: return (0); 11970: } 11971: 11972: STATIC int 11973: AscSetLibErrorCode( 11974: REG ASC_DVC_VAR asc_ptr_type * asc_dvc, 11975: ushort err_code 11976: ) 11977: { 11978: if (asc_dvc->err_code == 0) { 11979: asc_dvc->err_code = err_code; 11980: AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W, 11981: err_code); 11982: } 11983: return (err_code); 11984: } 11985: 11986: 11987: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89) 11988: STATIC int 11989: _AscWaitQDone( 11990: PortAddr iop_base, 11991: REG ASC_SCSI_Q * scsiq 11992: ) 11993: { 11994: ushort q_addr; 11995: uchar q_status; 11996: int count = 0; 11997: 11998: while (scsiq->q1.q_no == 0) ; 11999: q_addr = ASC_QNO_TO_QADDR(scsiq->q1.q_no); 12000: do { 12001: q_status = AscReadLramByte(iop_base, q_addr + ASC_SCSIQ_B_STATUS); 12002: DvcSleepMilliSecond(100L); 12003: if (count++ > 30) { 12004: return (0); 12005: } 12006: } while ((q_status & QS_READY) != 0); 12007: return (1); 12008: } 12009: #endif /* version >= v1.3.89 */ 12010: 12011: STATIC uchar 12012: AscMsgOutSDTR( 12013: REG ASC_DVC_VAR asc_ptr_type * asc_dvc, 12014: uchar sdtr_period, 12015: uchar sdtr_offset 12016: ) 12017: { 12018: EXT_MSG sdtr_buf; 12019: uchar sdtr_period_index; 12020: PortAddr iop_base; 12021: 12022: iop_base = asc_dvc->iop_base; 12023: sdtr_buf.msg_type = MS_EXTEND; 12024: sdtr_buf.msg_len = MS_SDTR_LEN; 12025: sdtr_buf.msg_req = MS_SDTR_CODE; 12026: sdtr_buf.xfer_period = sdtr_period; 12027: sdtr_offset &= ASC_SYN_MAX_OFFSET; 12028: sdtr_buf.req_ack_offset = sdtr_offset; 12029: if ((sdtr_period_index = 12030: AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <= 12031: asc_dvc->max_sdtr_index) { 12032: AscMemWordCopyToLram(iop_base, 12033: ASCV_MSGOUT_BEG, 12034: (ushort *) & sdtr_buf, 12035: (ushort) (sizeof (EXT_MSG) >> 1)); 12036: return ((sdtr_period_index << 4) | sdtr_offset); 12037: } else { 12038: 12039: sdtr_buf.req_ack_offset = 0; 12040: AscMemWordCopyToLram(iop_base, 12041: ASCV_MSGOUT_BEG, 12042: (ushort *) & sdtr_buf, 12043: (ushort) (sizeof (EXT_MSG) >> 1)); 12044: return (0); 12045: } 12046: } 12047: 12048: STATIC uchar 12049: AscCalSDTRData( 12050: REG ASC_DVC_VAR asc_ptr_type * asc_dvc, 12051: uchar sdtr_period, 12052: uchar syn_offset 12053: ) 12054: { 12055: uchar byte; 12056: uchar sdtr_period_ix; 12057: 12058: sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period); 12059: if ( 12060: (sdtr_period_ix > asc_dvc->max_sdtr_index) 12061: ) { 12062: return (0xFF); 12063: } 12064: byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET); 12065: return (byte); 12066: } 12067: 12068: STATIC void 12069: AscSetChipSDTR( 12070: PortAddr iop_base, 12071: uchar sdtr_data, 12072: uchar tid_no 12073: ) 12074: { 12075: AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data); 12076: AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data); 12077: return; 12078: } 12079: 12080: STATIC uchar 12081: AscGetSynPeriodIndex( 12082: ASC_DVC_VAR asc_ptr_type * asc_dvc, 12083: ruchar syn_time 12084: ) 12085: { 12086: ruchar *period_table; 12087: int max_index; 12088: int min_index; 12089: int i; 12090: 12091: period_table = asc_dvc->sdtr_period_tbl; 12092: max_index = (int) asc_dvc->max_sdtr_index; 12093: min_index = (int)asc_dvc->host_init_sdtr_index ; 12094: if ((syn_time <= period_table[max_index])) { 12095: for (i = min_index; i < (max_index - 1); i++) { 12096: if (syn_time <= period_table[i]) { 12097: return ((uchar) i); 12098: } 12099: } 12100: return ((uchar) max_index); 12101: } else { 12102: return ((uchar) (max_index + 1)); 12103: } 12104: } 12105: 12106: STATIC uchar 12107: AscAllocFreeQueue( 12108: PortAddr iop_base, 12109: uchar free_q_head 12110: ) 12111: { 12112: ushort q_addr; 12113: uchar next_qp; 12114: uchar q_status; 12115: 12116: q_addr = ASC_QNO_TO_QADDR(free_q_head); 12117: q_status = (uchar) AscReadLramByte(iop_base, 12118: (ushort) (q_addr + ASC_SCSIQ_B_STATUS)); 12119: next_qp = AscReadLramByte(iop_base, 12120: (ushort) (q_addr + ASC_SCSIQ_B_FWD)); 12121: if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) { 12122: return (next_qp); 12123: } 12124: return (ASC_QLINK_END); 12125: } 12126: 12127: STATIC uchar 12128: AscAllocMultipleFreeQueue( 12129: PortAddr iop_base, 12130: uchar free_q_head, 12131: uchar n_free_q 12132: ) 12133: { 12134: uchar i; 12135: 12136: for (i = 0; i < n_free_q; i++) { 12137: if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head)) 12138: == ASC_QLINK_END) { 12139: return (ASC_QLINK_END); 12140: } 12141: } 12142: return (free_q_head); 12143: } 12144: 12145: STATIC int 12146: AscRiscHaltedAbortSRB( 12147: REG ASC_DVC_VAR asc_ptr_type * asc_dvc, 12148: ulong srb_ptr 12149: ) 12150: { 12151: PortAddr iop_base; 12152: ushort q_addr; 12153: uchar q_no; 12154: ASC_QDONE_INFO scsiq_buf; 12155: ASC_QDONE_INFO *scsiq; 12156: ASC_ISR_CALLBACK asc_isr_callback; 12157: int last_int_level; 12158: 12159: iop_base = asc_dvc->iop_base; 12160: asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback; 12161: last_int_level = DvcEnterCritical(); 12162: scsiq = (ASC_QDONE_INFO *) & scsiq_buf; 12163: for (q_no = ASC_MIN_ACTIVE_QNO; q_no <= asc_dvc->max_total_qng; 12164: q_no++) { 12165: q_addr = ASC_QNO_TO_QADDR(q_no); 12166: scsiq->d2.srb_ptr = AscReadLramDWord(iop_base, 12167: (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR)); 12168: if (scsiq->d2.srb_ptr == srb_ptr) { 12169: _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count); 12170: if (((scsiq->q_status & QS_READY) != 0) 12171: && ((scsiq->q_status & QS_ABORTED) == 0) 12172: && ((scsiq->cntl & QCSG_SG_XFER_LIST) == 0)) { 12173: scsiq->q_status |= QS_ABORTED; 12174: scsiq->d3.done_stat = QD_ABORTED_BY_HOST; 12175: AscWriteLramDWord(iop_base, 12176: (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR), 12177: 0L); 12178: AscWriteLramByte(iop_base, 12179: (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS), 12180: scsiq->q_status); 12181: (*asc_isr_callback) (asc_dvc, scsiq); 12182: return (1); 12183: } 12184: } 12185: } 12186: DvcLeaveCritical(last_int_level); 12187: return (0); 12188: } 12189: 12190: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89) 12191: STATIC int 12192: AscRiscHaltedAbortTIX( 12193: REG ASC_DVC_VAR asc_ptr_type * asc_dvc, 12194: uchar target_ix 12195: ) 12196: { 12197: PortAddr iop_base; 12198: ushort q_addr; 12199: uchar q_no; 12200: ASC_QDONE_INFO scsiq_buf; 12201: ASC_QDONE_INFO *scsiq; 12202: ASC_ISR_CALLBACK asc_isr_callback; 12203: int last_int_level; 12204: 12205: iop_base = asc_dvc->iop_base; 12206: asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback; 12207: last_int_level = DvcEnterCritical(); 12208: scsiq = (ASC_QDONE_INFO *) & scsiq_buf; 12209: for (q_no = ASC_MIN_ACTIVE_QNO; q_no <= asc_dvc->max_total_qng; 12210: q_no++) { 12211: q_addr = ASC_QNO_TO_QADDR(q_no); 12212: _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count); 12213: if (((scsiq->q_status & QS_READY) != 0) && 12214: ((scsiq->q_status & QS_ABORTED) == 0) && 12215: ((scsiq->cntl & QCSG_SG_XFER_LIST) == 0)) { 12216: if (scsiq->d2.target_ix == target_ix) { 12217: scsiq->q_status |= QS_ABORTED; 12218: scsiq->d3.done_stat = QD_ABORTED_BY_HOST; 12219: AscWriteLramDWord(iop_base, 12220: (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR), 12221: 0L); 12222: AscWriteLramByte(iop_base, 12223: (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS), 12224: scsiq->q_status); 12225: (*asc_isr_callback) (asc_dvc, scsiq); 12226: } 12227: } 12228: } 12229: DvcLeaveCritical(last_int_level); 12230: return (1); 12231: } 12232: #endif /* version >= v1.3.89 */ 12233: 12234: STATIC int 12235: AscHostReqRiscHalt( 12236: PortAddr iop_base 12237: ) 12238: { 12239: int count = 0; 12240: int sta = 0; 12241: uchar saved_stop_code; 12242: 12243: if (AscIsChipHalted(iop_base)) 12244: return (1); 12245: saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B); 12246: AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 12247: ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP 12248: ); 12249: do { 12250: if (AscIsChipHalted(iop_base)) { 12251: sta = 1; 12252: break; 12253: } 12254: DvcSleepMilliSecond(100); 12255: } while (count++ < 20); 12256: AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code); 12257: return (sta); 12258: } 12259: 12260: STATIC int 12261: AscStopQueueExe( 12262: PortAddr iop_base 12263: ) 12264: { 12265: int count = 0; 12266: 12267: if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) { 12268: AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 12269: ASC_STOP_REQ_RISC_STOP); 12270: do { 12271: if ( 12272: AscReadLramByte(iop_base, ASCV_STOP_CODE_B) & 12273: ASC_STOP_ACK_RISC_STOP) { 12274: return (1); 12275: } 12276: DvcSleepMilliSecond(100); 12277: } while (count++ < 20); 12278: } 12279: return (0); 12280: } 12281: 12282: STATIC int 12283: AscStartQueueExe( 12284: PortAddr iop_base 12285: ) 12286: { 12287: if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) { 12288: AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0); 12289: } 12290: return (1); 12291: } 12292: 12293: STATIC int 12294: AscCleanUpBusyQueue( 12295: PortAddr iop_base 12296: ) 12297: { 12298: int count; 12299: uchar stop_code; 12300: 12301: count = 0; 12302: if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) { 12303: AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 12304: ASC_STOP_CLEAN_UP_BUSY_Q); 12305: do { 12306: stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B); 12307: if ((stop_code & ASC_STOP_CLEAN_UP_BUSY_Q) == 0) 12308: break; 12309: DvcSleepMilliSecond(100); 12310: } while (count++ < 20); 12311: } 12312: return (1); 12313: } 12314: 12315: #if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89) 12316: STATIC int 12317: AscCleanUpDiscQueue( 12318: PortAddr iop_base 12319: ) 12320: { 12321: int count; 12322: uchar stop_code; 12323: 12324: count = 0; 12325: if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) { 12326: AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 12327: ASC_STOP_CLEAN_UP_DISC_Q); 12328: do { 12329: stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B); 12330: if ((stop_code & ASC_STOP_CLEAN_UP_DISC_Q) == 0) 12331: break; 12332: DvcSleepMilliSecond(100); 12333: } while (count++ < 20); 12334: } 12335: return (1); 12336: } 12337: #endif /* version >= v1.3.89 */ 12338: 12339: STATIC int 12340: AscWaitTixISRDone( 12341: ASC_DVC_VAR asc_ptr_type * asc_dvc, 12342: uchar target_ix 12343: ) 12344: { 12345: uchar cur_req; 12346: uchar tid_no; 12347: int i = 0; 12348: 12349: tid_no = ASC_TIX_TO_TID(target_ix); 12350: while (i++ < 10) { 12351: if ((cur_req = asc_dvc->cur_dvc_qng[tid_no]) == 0) { 12352: break; 12353: } 12354: DvcSleepMilliSecond(1000L); 12355: if (asc_dvc->cur_dvc_qng[tid_no] == cur_req) { 12356: break; 12357: } 12358: } 12359: return (1); 12360: } 12361: 12362: STATIC int 12363: AscWaitISRDone( 12364: REG ASC_DVC_VAR asc_ptr_type * asc_dvc 12365: ) 12366: { 12367: int tid; 12368: 12369: for (tid = 0; tid <= ASC_MAX_TID; tid++) { 12370: AscWaitTixISRDone(asc_dvc, ASC_TID_TO_TIX(tid)); 12371: } 12372: return (1); 12373: } 12374: 12375: STATIC ulong 12376: AscGetOnePhyAddr( 12377: REG ASC_DVC_VAR asc_ptr_type * asc_dvc, 12378: uchar * buf_addr, 12379: ulong buf_size 12380: ) 12381: { 12382: ASC_MIN_SG_HEAD sg_head; 12383: 12384: sg_head.entry_cnt = ASC_MIN_SG_LIST; 12385: if (DvcGetSGList(asc_dvc, (uchar *) buf_addr, 12386: buf_size, (ASC_SG_HEAD *) & sg_head) != buf_size) { 12387: return (0L); 12388: } 12389: if (sg_head.entry_cnt > 1) { 12390: return (0L); 12391: } 12392: return (sg_head.sg_list[0].addr); 12393: } 12394: 12395: STATIC void 12396: DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec) 12397: { 12398: udelay(micro_sec); 12399: } 12400: 12401: STATIC void 12402: DvcDelayNanoSecond(ASC_DVC_VAR asc_ptr_type * asc_dvc, ulong nano_sec) 12403: { 12404: udelay((nano_sec + 999)/1000); 12405: } 12406: 12407: ASC_INITFUNC( 12408: STATIC ulong 12409: AscGetEisaProductID( 12410: PortAddr iop_base 12411: ) 12412: ) 12413: { 12414: PortAddr eisa_iop; 12415: ushort product_id_high, product_id_low; 12416: ulong product_id; 12417: 12418: eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK; 12419: product_id_low = inpw(eisa_iop); 12420: product_id_high = inpw(eisa_iop + 2); 12421: product_id = ((ulong) product_id_high << 16) | (ulong) product_id_low; 12422: return (product_id); 12423: } 12424: 12425: ASC_INITFUNC( 12426: STATIC PortAddr 12427: AscSearchIOPortAddrEISA( 12428: PortAddr iop_base 12429: ) 12430: ) 12431: { 12432: ulong eisa_product_id; 12433: 12434: if (iop_base == 0) { 12435: iop_base = ASC_EISA_MIN_IOP_ADDR; 12436: } else { 12437: if (iop_base == ASC_EISA_MAX_IOP_ADDR) 12438: return (0); 12439: if ((iop_base & 0x0050) == 0x0050) { 12440: iop_base += ASC_EISA_BIG_IOP_GAP; 12441: } else { 12442: iop_base += ASC_EISA_SMALL_IOP_GAP; 12443: } 12444: } 12445: while (iop_base <= ASC_EISA_MAX_IOP_ADDR) { 12446: eisa_product_id = AscGetEisaProductID(iop_base); 12447: if ((eisa_product_id == ASC_EISA_ID_740) || 12448: (eisa_product_id == ASC_EISA_ID_750)) { 12449: if (AscFindSignature(iop_base)) { 12450: inpw(iop_base + 4); 12451: return (iop_base); 12452: } 12453: } 12454: if (iop_base == ASC_EISA_MAX_IOP_ADDR) 12455: return (0); 12456: if ((iop_base & 0x0050) == 0x0050) { 12457: iop_base += ASC_EISA_BIG_IOP_GAP; 12458: } else { 12459: iop_base += ASC_EISA_SMALL_IOP_GAP; 12460: } 12461: } 12462: return (0); 12463: } 12464: 12465: STATIC int 12466: AscStartChip( 12467: PortAddr iop_base 12468: ) 12469: { 12470: AscSetChipControl(iop_base, 0); 12471: if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) { 12472: return (0); 12473: } 12474: return (1); 12475: } 12476: 12477: STATIC int 12478: AscStopChip( 12479: PortAddr iop_base 12480: ) 12481: { 12482: uchar cc_val; 12483: 12484: cc_val = AscGetChipControl(iop_base) & (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG)); 12485: AscSetChipControl(iop_base, (uchar) (cc_val | CC_HALT)); 12486: AscSetChipIH(iop_base, INS_HALT); 12487: AscSetChipIH(iop_base, INS_RFLAG_WTM); 12488: if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) { 12489: return (0); 12490: } 12491: return (1); 12492: } 12493: 12494: STATIC int 12495: AscIsChipHalted( 12496: PortAddr iop_base 12497: ) 12498: { 12499: if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) { 12500: if ((AscGetChipControl(iop_base) & CC_HALT) != 0) { 12501: return (1); 12502: } 12503: } 12504: return (0); 12505: } 12506: 12507: STATIC void 12508: AscSetChipIH( 12509: PortAddr iop_base, 12510: ushort ins_code 12511: ) 12512: { 12513: AscSetBank(iop_base, 1); 12514: AscWriteChipIH(iop_base, ins_code); 12515: AscSetBank(iop_base, 0); 12516: return; 12517: } 12518: 12519: STATIC void 12520: AscAckInterrupt( 12521: PortAddr iop_base 12522: ) 12523: { 12524: uchar host_flag; 12525: uchar risc_flag; 12526: ushort loop; 12527: 12528: loop = 0; 12529: do { 12530: risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B); 12531: if (loop++ > 0x7FFF) { 12532: break; 12533: } 12534: } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0); 12535: host_flag = AscReadLramByte(iop_base, ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT); 12536: AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, 12537: (uchar) (host_flag | ASC_HOST_FLAG_ACK_INT)); 12538: AscSetChipStatus(iop_base, CIW_INT_ACK); 12539: loop = 0; 12540: while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) { 12541: AscSetChipStatus(iop_base, CIW_INT_ACK); 12542: if (loop++ > 3) { 12543: break; 12544: } 12545: } 12546: AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag); 12547: return; 12548: } 12549: 12550: STATIC void 12551: AscDisableInterrupt( 12552: PortAddr iop_base 12553: ) 12554: { 12555: ushort cfg; 12556: 12557: cfg = AscGetChipCfgLsw(iop_base); 12558: AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON)); 12559: return; 12560: } 12561: 12562: STATIC void 12563: AscEnableInterrupt( 12564: PortAddr iop_base 12565: ) 12566: { 12567: ushort cfg; 12568: 12569: cfg = AscGetChipCfgLsw(iop_base); 12570: AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON); 12571: return; 12572: } 12573: 12574: 12575: 12576: STATIC void 12577: AscSetBank( 12578: PortAddr iop_base, 12579: uchar bank 12580: ) 12581: { 12582: uchar val; 12583: 12584: val = AscGetChipControl(iop_base) & 12585: (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET | CC_CHIP_RESET)); 12586: if (bank == 1) { 12587: val |= CC_BANK_ONE; 12588: } else if (bank == 2) { 12589: val |= CC_DIAG | CC_BANK_ONE; 12590: } else { 12591: val &= ~CC_BANK_ONE; 12592: } 12593: AscSetChipControl(iop_base, val); 12594: return; 12595: } 12596: 12597: STATIC int 12598: AscResetChipAndScsiBus( 12599: ASC_DVC_VAR *asc_dvc 12600: ) 12601: { 12602: PortAddr iop_base; 12603: 12604: iop_base = asc_dvc->iop_base; 12605: while (AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) ; 12606: AscStopChip(iop_base); 12607: AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT); 12608: DvcDelayNanoSecond(asc_dvc, 60000); 12609: AscSetChipIH(iop_base, INS_RFLAG_WTM); 12610: AscSetChipIH(iop_base, INS_HALT); 12611: AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT); 12612: AscSetChipControl(iop_base, CC_HALT); 12613: DvcSleepMilliSecond(200); 12614: AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT); 12615: AscSetChipStatus(iop_base, 0); 12616: return (AscIsChipHalted(iop_base)); 12617: } 12618: 12619: ASC_INITFUNC( 12620: STATIC ulong 12621: AscGetMaxDmaCount( 12622: ushort bus_type 12623: ) 12624: ) 12625: { 12626: if (bus_type & ASC_IS_ISA) 12627: return (ASC_MAX_ISA_DMA_COUNT); 12628: else if (bus_type & (ASC_IS_EISA | ASC_IS_VL)) 12629: return (ASC_MAX_VL_DMA_COUNT); 12630: return (ASC_MAX_PCI_DMA_COUNT); 12631: } 12632: 12633: ASC_INITFUNC( 12634: STATIC ushort 12635: AscGetIsaDmaChannel( 12636: PortAddr iop_base 12637: ) 12638: ) 12639: { 12640: ushort channel; 12641: 12642: channel = AscGetChipCfgLsw(iop_base) & 0x0003; 12643: if (channel == 0x03) 12644: return (0); 12645: else if (channel == 0x00) 12646: return (7); 12647: return (channel + 4); 12648: } 12649: 12650: ASC_INITFUNC( 12651: STATIC ushort 12652: AscSetIsaDmaChannel( 12653: PortAddr iop_base, 12654: ushort dma_channel 12655: ) 12656: ) 12657: { 12658: ushort cfg_lsw; 12659: uchar value; 12660: 12661: if ((dma_channel >= 5) && (dma_channel <= 7)) { 12662: if (dma_channel == 7) 12663: value = 0x00; 12664: else 12665: value = dma_channel - 4; 12666: cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC; 12667: cfg_lsw |= value; 12668: AscSetChipCfgLsw(iop_base, cfg_lsw); 12669: return (AscGetIsaDmaChannel(iop_base)); 12670: } 12671: return (0); 12672: } 12673: 12674: ASC_INITFUNC( 12675: STATIC uchar 12676: AscSetIsaDmaSpeed( 12677: PortAddr iop_base, 12678: uchar speed_value 12679: ) 12680: ) 12681: { 12682: speed_value &= 0x07; 12683: AscSetBank(iop_base, 1); 12684: AscWriteChipDmaSpeed(iop_base, speed_value); 12685: AscSetBank(iop_base, 0); 12686: return (AscGetIsaDmaSpeed(iop_base)); 12687: } 12688: 12689: ASC_INITFUNC( 12690: STATIC uchar 12691: AscGetIsaDmaSpeed( 12692: PortAddr iop_base 12693: ) 12694: ) 12695: { 12696: uchar speed_value; 12697: 12698: AscSetBank(iop_base, 1); 12699: speed_value = AscReadChipDmaSpeed(iop_base); 12700: speed_value &= 0x07; 12701: AscSetBank(iop_base, 0); 12702: return (speed_value); 12703: } 12704: 12705: ASC_INITFUNC( 12706: STATIC ushort 12707: AscReadPCIConfigWord( 12708: ASC_DVC_VAR asc_ptr_type *asc_dvc, 12709: ushort pci_config_offset) 12710: ) 12711: { 12712: uchar lsb, msb; 12713: 12714: lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset); 12715: msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1); 12716: return ((ushort) ((msb << 8) | lsb)); 12717: } 12718: 12719: ASC_INITFUNC( 12720: STATIC ushort 12721: AscInitGetConfig( 12722: ASC_DVC_VAR asc_ptr_type * asc_dvc 12723: ) 12724: ) 12725: { 12726: ushort warn_code; 12727: PortAddr iop_base; 12728: ushort PCIDeviceID; 12729: ushort PCIVendorID; 12730: uchar PCIRevisionID; 12731: uchar prevCmdRegBits; 12732: 12733: warn_code = 0; 12734: iop_base = asc_dvc->iop_base; 12735: asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG; 12736: if (asc_dvc->err_code != 0) { 12737: return (UW_ERR); 12738: } 12739: if (asc_dvc->bus_type == ASC_IS_PCI) { 12740: PCIVendorID = AscReadPCIConfigWord(asc_dvc, 12741: AscPCIConfigVendorIDRegister); 12742: 12743: PCIDeviceID = AscReadPCIConfigWord(asc_dvc, 12744: AscPCIConfigDeviceIDRegister); 12745: 12746: PCIRevisionID = DvcReadPCIConfigByte(asc_dvc, 12747: AscPCIConfigRevisionIDRegister); 12748: 12749: if (PCIVendorID != ASC_PCI_VENDORID) { 12750: warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE; 12751: } 12752: prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc, 12753: AscPCIConfigCommandRegister); 12754: 12755: if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster) != 12756: AscPCICmdRegBits_IOMemBusMaster) { 12757: DvcWritePCIConfigByte(asc_dvc, 12758: AscPCIConfigCommandRegister, 12759: (prevCmdRegBits | 12760: AscPCICmdRegBits_IOMemBusMaster)); 12761: 12762: if ((DvcReadPCIConfigByte(asc_dvc, 12763: AscPCIConfigCommandRegister) 12764: & AscPCICmdRegBits_IOMemBusMaster) 12765: != AscPCICmdRegBits_IOMemBusMaster) { 12766: warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE; 12767: } 12768: } 12769: if ((PCIDeviceID == ASC_PCI_DEVICEID_1200A) || 12770: (PCIDeviceID == ASC_PCI_DEVICEID_1200B)) { 12771: DvcWritePCIConfigByte(asc_dvc, 12772: AscPCIConfigLatencyTimer, 0x00); 12773: if (DvcReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) 12774: != 0x00) { 12775: warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE; 12776: } 12777: } else if (PCIDeviceID == ASC_PCI_DEVICEID_ULTRA) { 12778: if (DvcReadPCIConfigByte(asc_dvc, 12779: AscPCIConfigLatencyTimer) < 0x20) { 12780: DvcWritePCIConfigByte(asc_dvc, 12781: AscPCIConfigLatencyTimer, 0x20); 12782: 12783: if (DvcReadPCIConfigByte(asc_dvc, 12784: AscPCIConfigLatencyTimer) < 0x20) { 12785: warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE; 12786: } 12787: } 12788: } 12789: } 12790: 12791: if (AscFindSignature(iop_base)) { 12792: warn_code |= AscInitAscDvcVar(asc_dvc); 12793: warn_code |= AscInitFromEEP(asc_dvc); 12794: asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG; 12795: if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) { 12796: asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT; 12797: } 12798: } else { 12799: asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; 12800: } 12801: return(warn_code); 12802: } 12803: 12804: ASC_INITFUNC( 12805: STATIC ushort 12806: AscInitSetConfig( 12807: ASC_DVC_VAR asc_ptr_type * asc_dvc 12808: ) 12809: ) 12810: { 12811: ushort warn_code = 0; 12812: 12813: asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG; 12814: if (asc_dvc->err_code != 0) 12815: return (UW_ERR); 12816: if (AscFindSignature(asc_dvc->iop_base)) { 12817: warn_code |= AscInitFromAscDvcVar(asc_dvc); 12818: asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG; 12819: } else { 12820: asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; 12821: } 12822: return (warn_code); 12823: } 12824: 12825: ASC_INITFUNC( 12826: STATIC ushort 12827: AscInitFromAscDvcVar( 12828: ASC_DVC_VAR asc_ptr_type * asc_dvc 12829: ) 12830: ) 12831: { 12832: PortAddr iop_base; 12833: ushort cfg_msw; 12834: ushort warn_code; 12835: ushort pci_device_id; 12836: 12837: iop_base = asc_dvc->iop_base; 12838: pci_device_id = asc_dvc->cfg->pci_device_id; 12839: warn_code = 0; 12840: cfg_msw = AscGetChipCfgMsw(iop_base); 12841: if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) { 12842: cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK)); 12843: warn_code |= ASC_WARN_CFG_MSW_RECOVER; 12844: AscSetChipCfgMsw(iop_base, cfg_msw); 12845: } 12846: if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) != 12847: asc_dvc->cfg->cmd_qng_enabled) { 12848: asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled; 12849: warn_code |= ASC_WARN_CMD_QNG_CONFLICT; 12850: } 12851: if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) { 12852: warn_code |= ASC_WARN_AUTO_CONFIG; 12853: } 12854: if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) { 12855: if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type) 12856: != asc_dvc->irq_no) { 12857: asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO; 12858: } 12859: } 12860: if (asc_dvc->bus_type & ASC_IS_PCI) { 12861: cfg_msw &= 0xFFC0; 12862: AscSetChipCfgMsw(iop_base, cfg_msw); 12863: if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) { 12864: } else { 12865: if ((pci_device_id == ASC_PCI_DEVICE_ID_REV_A) || 12866: (pci_device_id == ASC_PCI_DEVICE_ID_REV_B)) { 12867: asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB; 12868: asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN; 12869: } 12870: } 12871: } else if (asc_dvc->bus_type == ASC_IS_ISAPNP) { 12872: if (AscGetChipVersion(iop_base, asc_dvc->bus_type) 12873: == ASC_CHIP_VER_ASYN_BUG) { 12874: asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN; 12875: } 12876: } 12877: if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) != 12878: asc_dvc->cfg->chip_scsi_id) { 12879: asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID; 12880: } 12881: if (asc_dvc->bus_type & ASC_IS_ISA) { 12882: AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel); 12883: AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed); 12884: } 12885: return (warn_code); 12886: } 12887: 12888: ASC_INITFUNC( 12889: STATIC ushort 12890: AscInitAsc1000Driver( 12891: ASC_DVC_VAR asc_ptr_type * asc_dvc 12892: ) 12893: ) 12894: { 12895: ushort warn_code; 12896: PortAddr iop_base; 12897: extern ushort _asc_mcode_size; 12898: extern ulong _asc_mcode_chksum; 12899: extern uchar _asc_mcode_buf[]; 12900: 12901: iop_base = asc_dvc->iop_base; 12902: warn_code = 0; 12903: if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) && 12904: !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) { 12905: AscResetChipAndScsiBus(asc_dvc); 12906: DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000)); 12907: } 12908: asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC; 12909: if (asc_dvc->err_code != 0) 12910: return (UW_ERR); 12911: if (!AscFindSignature(asc_dvc->iop_base)) { 12912: asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; 12913: return (warn_code); 12914: } 12915: AscDisableInterrupt(iop_base); 12916: warn_code |= AscInitLram(asc_dvc); 12917: if (asc_dvc->err_code != 0) 12918: return (UW_ERR); 12919: if (AscLoadMicroCode(iop_base, 0, (ushort *) _asc_mcode_buf, 12920: _asc_mcode_size) != _asc_mcode_chksum) { 12921: asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; 12922: return (warn_code); 12923: } 12924: warn_code |= AscInitMicroCodeVar(asc_dvc); 12925: asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC; 12926: AscEnableInterrupt(iop_base); 12927: return (warn_code); 12928: } 12929: 12930: ASC_INITFUNC( 12931: STATIC ushort 12932: AscInitAscDvcVar( 12933: ASC_DVC_VAR asc_ptr_type * asc_dvc 12934: ) 12935: ) 12936: { 12937: int i; 12938: PortAddr iop_base; 12939: ushort warn_code; 12940: uchar chip_version; 12941: 12942: iop_base = asc_dvc->iop_base; 12943: warn_code = 0; 12944: asc_dvc->err_code = 0; 12945: if ((asc_dvc->bus_type & 12946: (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) { 12947: asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE; 12948: } 12949: AscSetChipControl(iop_base, CC_HALT); 12950: AscSetChipStatus(iop_base, 0); 12951: asc_dvc->bug_fix_cntl = 0; 12952: asc_dvc->pci_fix_asyn_xfer = 0; 12953: asc_dvc->pci_fix_asyn_xfer_always = 0; 12954: asc_dvc->init_state = 0; 12955: asc_dvc->sdtr_done = 0; 12956: asc_dvc->cur_total_qng = 0; 12957: asc_dvc->is_in_int = 0; 12958: asc_dvc->in_critical_cnt = 0; 12959: asc_dvc->last_q_shortage = 0; 12960: asc_dvc->use_tagged_qng = 0; 12961: asc_dvc->no_scam = 0; 12962: asc_dvc->unit_not_ready = 0; 12963: asc_dvc->queue_full_or_busy = 0; 12964: asc_dvc->redo_scam = 0 ; 12965: asc_dvc->res2 = 0 ; 12966: asc_dvc->host_init_sdtr_index = 0 ; 12967: asc_dvc->res7 = 0 ; 12968: asc_dvc->res8 = 0 ; 12969: asc_dvc->cfg->can_tagged_qng = 0 ; 12970: asc_dvc->cfg->cmd_qng_enabled = 0; 12971: asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL; 12972: asc_dvc->init_sdtr = 0; 12973: asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG; 12974: asc_dvc->scsi_reset_wait = 3; 12975: asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET; 12976: asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type); 12977: asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET; 12978: asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET; 12979: asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID; 12980: asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER; 12981: asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) | 12982: ASC_LIB_VERSION_MINOR; 12983: chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type); 12984: asc_dvc->cfg->chip_version = chip_version; 12985: asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0; 12986: asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1; 12987: asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2; 12988: asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3; 12989: asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4; 12990: asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5; 12991: asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6; 12992: asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7; 12993: asc_dvc->max_sdtr_index = 7; 12994: if ((asc_dvc->bus_type & ASC_IS_PCI) && 12995: (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) { 12996: asc_dvc->bus_type = ASC_IS_PCI_ULTRA; 12997: asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0; 12998: asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1; 12999: asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2; 13000: asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3; 13001: asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4; 13002: asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5; 13003: asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6; 13004: asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7; 13005: asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8; 13006: asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9; 13007: asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10; 13008: asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11; 13009: asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12; 13010: asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13; 13011: asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14; 13012: asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15; 13013: asc_dvc->max_sdtr_index = 15; 13014: if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) 13015: { 13016: AscSetExtraControl(iop_base, 13017: (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE)); 13018: } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) { 13019: AscSetExtraControl(iop_base, 13020: (SEC_ACTIVE_NEGATE | SEC_ENABLE_FILTER)); 13021: } 13022: } 13023: if (asc_dvc->bus_type == ASC_IS_PCI) { 13024: AscSetExtraControl(iop_base, (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE)); 13025: } 13026: 13027: asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED; 13028: if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) { 13029: AscSetChipIFC(iop_base, IFC_INIT_DEFAULT); 13030: asc_dvc->bus_type = ASC_IS_ISAPNP; 13031: } 13032: if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) { 13033: asc_dvc->cfg->isa_dma_channel = (uchar) AscGetIsaDmaChannel(iop_base); 13034: } 13035: for (i = 0; i <= ASC_MAX_TID; i++) { 13036: asc_dvc->cur_dvc_qng[i] = 0; 13037: asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG; 13038: asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *) 0L; 13039: asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *) 0L; 13040: asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG; 13041: } 13042: return (warn_code); 13043: } 13044: 13045: ASC_INITFUNC( 13046: STATIC ushort 13047: AscInitFromEEP( 13048: ASC_DVC_VAR asc_ptr_type * asc_dvc 13049: ) 13050: ) 13051: { 13052: ASCEEP_CONFIG eep_config_buf; 13053: ASCEEP_CONFIG *eep_config; 13054: PortAddr iop_base; 13055: ushort chksum; 13056: ushort warn_code; 13057: ushort cfg_msw, cfg_lsw; 13058: int i; 13059: int write_eep = 0; 13060: 13061: iop_base = asc_dvc->iop_base; 13062: warn_code = 0; 13063: AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE); 13064: AscStopQueueExe(iop_base); 13065: if ((AscStopChip(iop_base) == FALSE) || 13066: (AscGetChipScsiCtrl(iop_base) != 0)) { 13067: asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE; 13068: AscResetChipAndScsiBus(asc_dvc); 13069: DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000)); 13070: } 13071: if (AscIsChipHalted(iop_base) == FALSE) { 13072: asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP; 13073: return (warn_code); 13074: } 13075: AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR); 13076: if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) { 13077: asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR; 13078: return (warn_code); 13079: } 13080: eep_config = (ASCEEP_CONFIG *) & eep_config_buf; 13081: cfg_msw = AscGetChipCfgMsw(iop_base); 13082: cfg_lsw = AscGetChipCfgLsw(iop_base); 13083: if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) { 13084: cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK)); 13085: warn_code |= ASC_WARN_CFG_MSW_RECOVER; 13086: AscSetChipCfgMsw(iop_base, cfg_msw); 13087: } 13088: chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type); 13089: if (chksum == 0) { 13090: chksum = 0xaa55; 13091: } 13092: if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) { 13093: warn_code |= ASC_WARN_AUTO_CONFIG; 13094: if (asc_dvc->cfg->chip_version == 3) { 13095: if (eep_config->cfg_lsw != cfg_lsw) { 13096: warn_code |= ASC_WARN_EEPROM_RECOVER; 13097: eep_config->cfg_lsw = AscGetChipCfgLsw(iop_base); 13098: } 13099: if (eep_config->cfg_msw != cfg_msw) { 13100: warn_code |= ASC_WARN_EEPROM_RECOVER; 13101: eep_config->cfg_msw = AscGetChipCfgMsw(iop_base); 13102: } 13103: } 13104: } 13105: eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK; 13106: eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON; 13107: if (chksum != eep_config->chksum) { 13108: if (AscGetChipVersion(iop_base, asc_dvc->bus_type) == 13109: ASC_CHIP_VER_PCI_ULTRA_3050 ) 13110: { 13111: eep_config->init_sdtr = 0xFF; 13112: eep_config->disc_enable = 0xFF; 13113: eep_config->start_motor = 0xFF; 13114: eep_config->use_cmd_qng = 0; 13115: eep_config->max_total_qng = 0xF0; 13116: eep_config->max_tag_qng = 0x20; 13117: eep_config->cntl = 0xBFFF; 13118: eep_config->chip_scsi_id = 7; 13119: eep_config->no_scam = 0; 13120: eep_config->adapter_info[0] = 0; 13121: eep_config->adapter_info[1] = 0; 13122: eep_config->adapter_info[2] = 0; 13123: eep_config->adapter_info[3] = 0; 13124: eep_config->adapter_info[4] = 0; 13125: /* Indicate EEPROM-less board. */ 13126: eep_config->adapter_info[5] = 0xBB; 13127: } else { 13128: write_eep = 1 ; 13129: warn_code |= ASC_WARN_EEPROM_CHKSUM ; 13130: } 13131: } 13132: asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr ; 13133: asc_dvc->cfg->disc_enable = eep_config->disc_enable; 13134: asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng; 13135: asc_dvc->cfg->isa_dma_speed = eep_config->isa_dma_speed; 13136: asc_dvc->start_motor = eep_config->start_motor; 13137: asc_dvc->dvc_cntl = eep_config->cntl; 13138: asc_dvc->no_scam = eep_config->no_scam; 13139: asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0]; 13140: asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1]; 13141: asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2]; 13142: asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3]; 13143: asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4]; 13144: asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5]; 13145: if (!AscTestExternalLram(asc_dvc)) { 13146: if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA)) { 13147: eep_config->max_total_qng = ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG; 13148: eep_config->max_tag_qng = ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG; 13149: } else { 13150: eep_config->cfg_msw |= 0x0800; 13151: cfg_msw |= 0x0800; 13152: AscSetChipCfgMsw(iop_base, cfg_msw); 13153: eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG; 13154: eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG; 13155: } 13156: } else { 13157: } 13158: if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) { 13159: eep_config->max_total_qng = ASC_MIN_TOTAL_QNG; 13160: } 13161: if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) { 13162: eep_config->max_total_qng = ASC_MAX_TOTAL_QNG; 13163: } 13164: if (eep_config->max_tag_qng > eep_config->max_total_qng) { 13165: eep_config->max_tag_qng = eep_config->max_total_qng; 13166: } 13167: if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) { 13168: eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC; 13169: } 13170: asc_dvc->max_total_qng = eep_config->max_total_qng; 13171: if ((eep_config->use_cmd_qng & eep_config->disc_enable) != 13172: eep_config->use_cmd_qng) { 13173: eep_config->disc_enable = eep_config->use_cmd_qng; 13174: warn_code |= ASC_WARN_CMD_QNG_CONFLICT; 13175: } 13176: if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) { 13177: asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type); 13178: } 13179: eep_config->chip_scsi_id &= ASC_MAX_TID; 13180: asc_dvc->cfg->chip_scsi_id = eep_config->chip_scsi_id; 13181: if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) && 13182: !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) { 13183: asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX; 13184: } 13185: 13186: for (i = 0; i <= ASC_MAX_TID; i++) { 13187: asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i]; 13188: asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng; 13189: asc_dvc->cfg->sdtr_period_offset[i] = 13190: (uchar) (ASC_DEF_SDTR_OFFSET | 13191: (asc_dvc->host_init_sdtr_index << 4)); 13192: } 13193: eep_config->cfg_msw = AscGetChipCfgMsw(iop_base); 13194: if (write_eep) { 13195: (void) AscSetEEPConfig(iop_base, eep_config, asc_dvc->bus_type); 13196: } 13197: return (warn_code); 13198: } 13199: 13200: ASC_INITFUNC( 13201: STATIC ushort 13202: AscInitMicroCodeVar( 13203: ASC_DVC_VAR asc_ptr_type * asc_dvc 13204: ) 13205: ) 13206: { 13207: int i; 13208: ushort warn_code; 13209: PortAddr iop_base; 13210: ulong phy_addr; 13211: 13212: iop_base = asc_dvc->iop_base; 13213: warn_code = 0; 13214: for (i = 0; i <= ASC_MAX_TID; i++) { 13215: AscPutMCodeInitSDTRAtID(iop_base, i, 13216: asc_dvc->cfg->sdtr_period_offset[i] 13217: ); 13218: } 13219: AscInitQLinkVar(asc_dvc); 13220: AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B, 13221: asc_dvc->cfg->disc_enable); 13222: AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B, 13223: ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id)); 13224: if ((phy_addr = AscGetOnePhyAddr(asc_dvc, 13225: (uchar *) asc_dvc->cfg->overrun_buf, 13226: ASC_OVERRUN_BSIZE)) == 0L) { 13227: asc_dvc->err_code |= ASC_IERR_GET_PHY_ADDR; 13228: } else { 13229: phy_addr = (phy_addr & 0xFFFFFFF8UL) + 8; 13230: AscWriteLramDWord(iop_base, ASCV_OVERRUN_PADDR_D, phy_addr); 13231: AscWriteLramDWord(iop_base, ASCV_OVERRUN_BSIZE_D, 13232: ASC_OVERRUN_BSIZE - 8); 13233: } 13234: asc_dvc->cfg->mcode_date = AscReadLramWord(iop_base, 13235: (ushort) ASCV_MC_DATE_W); 13236: asc_dvc->cfg->mcode_version = AscReadLramWord(iop_base, 13237: (ushort) ASCV_MC_VER_W); 13238: AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR); 13239: if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) { 13240: asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR; 13241: return (warn_code); 13242: } 13243: if (AscStartChip(iop_base) != 1) { 13244: asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP; 13245: return (warn_code); 13246: } 13247: return (warn_code); 13248: } 13249: 13250: ASC_INITFUNC( 13251: STATIC int 13252: AscTestExternalLram( 13253: ASC_DVC_VAR asc_ptr_type * asc_dvc 13254: ) 13255: ) 13256: { 13257: PortAddr iop_base; 13258: ushort q_addr; 13259: ushort saved_word; 13260: int sta; 13261: 13262: iop_base = asc_dvc->iop_base; 13263: sta = 0; 13264: q_addr = ASC_QNO_TO_QADDR(241); 13265: saved_word = AscReadLramWord(iop_base, q_addr); 13266: AscSetChipLramAddr(iop_base, q_addr); 13267: AscSetChipLramData(iop_base, 0x55AA); 13268: DvcSleepMilliSecond(10); 13269: AscSetChipLramAddr(iop_base, q_addr); 13270: if (AscGetChipLramData(iop_base) == 0x55AA) { 13271: sta = 1; 13272: AscWriteLramWord(iop_base, q_addr, saved_word); 13273: } 13274: return (sta); 13275: } 13276: 13277: ASC_INITFUNC( 13278: STATIC int 13279: AscWriteEEPCmdReg( 13280: PortAddr iop_base, 13281: uchar cmd_reg 13282: ) 13283: ) 13284: { 13285: uchar read_back; 13286: int retry; 13287: 13288: retry = 0; 13289: while (TRUE) { 13290: AscSetChipEEPCmd(iop_base, cmd_reg); 13291: DvcSleepMilliSecond(1); 13292: read_back = AscGetChipEEPCmd(iop_base); 13293: if (read_back == cmd_reg) { 13294: return (1); 13295: } 13296: if (retry++ > ASC_EEP_MAX_RETRY) { 13297: return (0); 13298: } 13299: } 13300: } 13301: 13302: ASC_INITFUNC( 13303: STATIC int 13304: AscWriteEEPDataReg( 13305: PortAddr iop_base, 13306: ushort data_reg 13307: ) 13308: ) 13309: { 13310: ushort read_back; 13311: int retry; 13312: 13313: retry = 0; 13314: while (TRUE) { 13315: AscSetChipEEPData(iop_base, data_reg); 13316: DvcSleepMilliSecond(1); 13317: read_back = AscGetChipEEPData(iop_base); 13318: if (read_back == data_reg) { 13319: return (1); 13320: } 13321: if (retry++ > ASC_EEP_MAX_RETRY) { 13322: return (0); 13323: } 13324: } 13325: } 13326: 13327: ASC_INITFUNC( 13328: STATIC void 13329: AscWaitEEPRead( 13330: void 13331: ) 13332: ) 13333: { 13334: DvcSleepMilliSecond(1); 13335: return; 13336: } 13337: 13338: ASC_INITFUNC( 13339: STATIC void 13340: AscWaitEEPWrite( 13341: void 13342: ) 13343: ) 13344: { 13345: DvcSleepMilliSecond(20); 13346: return; 13347: } 13348: 13349: ASC_INITFUNC( 13350: STATIC ushort 13351: AscReadEEPWord( 13352: PortAddr iop_base, 13353: uchar addr 13354: ) 13355: ) 13356: { 13357: ushort read_wval; 13358: uchar cmd_reg; 13359: 13360: AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE); 13361: AscWaitEEPRead(); 13362: cmd_reg = addr | ASC_EEP_CMD_READ; 13363: AscWriteEEPCmdReg(iop_base, cmd_reg); 13364: AscWaitEEPRead(); 13365: read_wval = AscGetChipEEPData(iop_base); 13366: AscWaitEEPRead(); 13367: return (read_wval); 13368: } 13369: 13370: ASC_INITFUNC( 13371: STATIC ushort 13372: AscWriteEEPWord( 13373: PortAddr iop_base, 13374: uchar addr, 13375: ushort word_val 13376: ) 13377: ) 13378: { 13379: ushort read_wval; 13380: 13381: read_wval = AscReadEEPWord(iop_base, addr); 13382: if (read_wval != word_val) { 13383: AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE); 13384: AscWaitEEPRead(); 13385: AscWriteEEPDataReg(iop_base, word_val); 13386: AscWaitEEPRead(); 13387: AscWriteEEPCmdReg(iop_base, 13388: (uchar) ((uchar) ASC_EEP_CMD_WRITE | addr)); 13389: AscWaitEEPWrite(); 13390: AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE); 13391: AscWaitEEPRead(); 13392: return (AscReadEEPWord(iop_base, addr)); 13393: } 13394: return (read_wval); 13395: } 13396: 13397: ASC_INITFUNC( 13398: STATIC ushort 13399: AscGetEEPConfig( 13400: PortAddr iop_base, 13401: ASCEEP_CONFIG * cfg_buf, ushort bus_type 13402: ) 13403: ) 13404: { 13405: ushort wval; 13406: ushort sum; 13407: ushort *wbuf; 13408: int cfg_beg; 13409: int cfg_end; 13410: int s_addr; 13411: int isa_pnp_wsize; 13412: 13413: wbuf = (ushort *) cfg_buf; 13414: sum = 0; 13415: isa_pnp_wsize = 0; 13416: for (s_addr = 0; s_addr < (2 + isa_pnp_wsize); s_addr++, wbuf++) { 13417: wval = AscReadEEPWord(iop_base, (uchar) s_addr); 13418: sum += wval; 13419: *wbuf = wval; 13420: } 13421: if (bus_type & ASC_IS_VL) { 13422: cfg_beg = ASC_EEP_DVC_CFG_BEG_VL; 13423: cfg_end = ASC_EEP_MAX_DVC_ADDR_VL; 13424: } else { 13425: cfg_beg = ASC_EEP_DVC_CFG_BEG; 13426: cfg_end = ASC_EEP_MAX_DVC_ADDR; 13427: } 13428: for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); 13429: s_addr++, wbuf++) { 13430: wval = AscReadEEPWord(iop_base, (uchar) s_addr); 13431: sum += wval; 13432: *wbuf = wval; 13433: } 13434: *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr); 13435: return (sum); 13436: } 13437: 13438: ASC_INITFUNC( 13439: STATIC int 13440: AscSetEEPConfigOnce( 13441: PortAddr iop_base, 13442: ASCEEP_CONFIG * cfg_buf, ushort bus_type 13443: ) 13444: ) 13445: { 13446: int n_error; 13447: ushort *wbuf; 13448: ushort sum; 13449: int s_addr; 13450: int cfg_beg; 13451: int cfg_end; 13452: 13453: wbuf = (ushort *) cfg_buf; 13454: n_error = 0; 13455: sum = 0; 13456: for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) { 13457: sum += *wbuf; 13458: if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) { 13459: n_error++; 13460: } 13461: } 13462: if (bus_type & ASC_IS_VL) { 13463: cfg_beg = ASC_EEP_DVC_CFG_BEG_VL; 13464: cfg_end = ASC_EEP_MAX_DVC_ADDR_VL; 13465: } else { 13466: cfg_beg = ASC_EEP_DVC_CFG_BEG; 13467: cfg_end = ASC_EEP_MAX_DVC_ADDR; 13468: } 13469: for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); 13470: s_addr++, wbuf++) { 13471: sum += *wbuf; 13472: if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) { 13473: n_error++; 13474: } 13475: } 13476: *wbuf = sum; 13477: if (sum != AscWriteEEPWord(iop_base, (uchar) s_addr, sum)) { 13478: n_error++; 13479: } 13480: wbuf = (ushort *) cfg_buf; 13481: for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) { 13482: if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) { 13483: n_error++; 13484: } 13485: } 13486: for (s_addr = cfg_beg; s_addr <= cfg_end; 13487: s_addr++, wbuf++) { 13488: if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) { 13489: n_error++; 13490: } 13491: } 13492: return (n_error); 13493: } 13494: 13495: ASC_INITFUNC( 13496: STATIC int 13497: AscSetEEPConfig( 13498: PortAddr iop_base, 13499: ASCEEP_CONFIG * cfg_buf, ushort bus_type 13500: ) 13501: ) 13502: { 13503: int retry; 13504: int n_error; 13505: 13506: retry = 0; 13507: while (TRUE) { 13508: if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf, 13509: bus_type)) == 0) { 13510: break; 13511: } 13512: if (++retry > ASC_EEP_MAX_RETRY) { 13513: break; 13514: } 13515: } 13516: return (n_error); 13517: } 13518: 13519: STATIC void 13520: AscAsyncFix( 13521: ASC_DVC_VAR asc_ptr_type *asc_dvc, 13522: uchar tid_no, 13523: ASC_SCSI_INQUIRY *inq) 13524: { 13525: uchar dvc_type; 13526: ASC_SCSI_BIT_ID_TYPE tid_bits; 13527: 13528: dvc_type = inq->byte0.peri_dvc_type; 13529: tid_bits = ASC_TIX_TO_TARGET_ID(tid_no); 13530: 13531: if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) { 13532: if (!(asc_dvc->init_sdtr & tid_bits)) { 13533: if ((dvc_type == SCSI_TYPE_CDROM) && 13534: (AscCompareString((uchar *) inq->vendor_id, 13535: (uchar *) "HP ", 3) == 0)) { 13536: asc_dvc->pci_fix_asyn_xfer_always |= tid_bits; 13537: } 13538: asc_dvc->pci_fix_asyn_xfer |= tid_bits; 13539: if ((dvc_type == SCSI_TYPE_PROC) || 13540: (dvc_type == SCSI_TYPE_SCANNER)) { 13541: asc_dvc->pci_fix_asyn_xfer &= ~tid_bits; 13542: } 13543: if ((dvc_type == SCSI_TYPE_SASD) && 13544: (AscCompareString((uchar *) inq->vendor_id, 13545: (uchar *) "TANDBERG", 8) == 0) && 13546: (AscCompareString((uchar *) inq->product_id, 13547: (uchar *) " TDC 36", 7) == 0)) { 13548: asc_dvc->pci_fix_asyn_xfer &= ~tid_bits; 13549: } 13550: if ((dvc_type == SCSI_TYPE_SASD) && 13551: (AscCompareString((uchar *) inq->vendor_id, 13552: (uchar *) "WANGTEK ", 8) == 0)) { 13553: asc_dvc->pci_fix_asyn_xfer &= ~tid_bits; 13554: } 13555: 13556: if ((dvc_type == SCSI_TYPE_CDROM) && 13557: (AscCompareString((uchar *) inq->vendor_id, 13558: (uchar *) "NEC ", 8) == 0) && 13559: (AscCompareString((uchar *) inq->product_id, 13560: (uchar *) "CD-ROM DRIVE ", 16) == 0)) { 13561: asc_dvc->pci_fix_asyn_xfer &= ~tid_bits; 13562: } 13563: 13564: if ((dvc_type == SCSI_TYPE_CDROM) && 13565: (AscCompareString((uchar *) inq->vendor_id, 13566: (uchar *) "YAMAHA", 6) == 0) && 13567: (AscCompareString((uchar *) inq->product_id, 13568: (uchar *) "CDR400", 6) == 0)) { 13569: asc_dvc->pci_fix_asyn_xfer &= ~tid_bits; 13570: } 13571: if (asc_dvc->pci_fix_asyn_xfer & tid_bits) { 13572: AscSetRunChipSynRegAtID(asc_dvc->iop_base, tid_no, 13573: ASYN_SDTR_DATA_FIX_PCI_REV_AB); 13574: } 13575: } 13576: } 13577: return; 13578: } 13579: 13580: STATIC int 13581: AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq) 13582: { 13583: if ((inq->add_len >= 32) && 13584: (AscCompareString((uchar *) inq->vendor_id, 13585: (uchar *) "QUANTUM XP34301", 15) == 0) && 13586: (AscCompareString((uchar *) inq->product_rev_level, 13587: (uchar *) "1071", 4) == 0)) 13588: { 13589: return 0; 13590: } 13591: return 1; 13592: } 13593: 13594: STATIC void 13595: AscInquiryHandling(ASC_DVC_VAR asc_ptr_type *asc_dvc, 13596: uchar tid_no, ASC_SCSI_INQUIRY *inq) 13597: { 13598: ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no); 13599: ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng; 13600: 13601: orig_init_sdtr = asc_dvc->init_sdtr; 13602: orig_use_tagged_qng = asc_dvc->use_tagged_qng; 13603: 13604: asc_dvc->init_sdtr &= ~tid_bit; 13605: asc_dvc->cfg->can_tagged_qng &= ~tid_bit; 13606: asc_dvc->use_tagged_qng &= ~tid_bit; 13607: 13608: if (inq->byte3.rsp_data_fmt >= 2 || inq->byte2.ansi_apr_ver >= 2) { 13609: if ((asc_dvc->cfg->sdtr_enable & tid_bit) && inq->byte7.Sync) { 13610: asc_dvc->init_sdtr |= tid_bit; 13611: } 13612: if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) && inq->byte7.CmdQue) { 13613: if (AscTagQueuingSafe(inq)) { 13614: asc_dvc->use_tagged_qng |= tid_bit; 13615: asc_dvc->cfg->can_tagged_qng |= tid_bit; 13616: } 13617: } 13618: } 13619: if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) { 13620: AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B, 13621: asc_dvc->cfg->disc_enable); 13622: AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B, 13623: asc_dvc->use_tagged_qng); 13624: AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B, 13625: asc_dvc->cfg->can_tagged_qng); 13626: 13627: asc_dvc->max_dvc_qng[tid_no] = 13628: asc_dvc->cfg->max_tag_qng[tid_no]; 13629: AscWriteLramByte(asc_dvc->iop_base, 13630: (ushort) (ASCV_MAX_DVC_QNG_BEG + tid_no), 13631: asc_dvc->max_dvc_qng[tid_no]); 13632: } 13633: if (orig_init_sdtr != asc_dvc->init_sdtr) { 13634: AscAsyncFix(asc_dvc, tid_no, inq); 13635: } 13636: return; 13637: } 13638: 13639: STATIC int 13640: AscCompareString( 13641: ruchar * str1, 13642: ruchar * str2, 13643: int len 13644: ) 13645: { 13646: int i; 13647: int diff; 13648: 13649: for (i = 0; i < len; i++) { 13650: diff = (int) (str1[i] - str2[i]); 13651: if (diff != 0) 13652: return (diff); 13653: } 13654: return (0); 13655: } 13656: 13657: STATIC uchar 13658: AscReadLramByte( 13659: PortAddr iop_base, 13660: ushort addr 13661: ) 13662: { 13663: uchar byte_data; 13664: ushort word_data; 13665: 13666: if (isodd_word(addr)) { 13667: AscSetChipLramAddr(iop_base, addr - 1); 13668: word_data = AscGetChipLramData(iop_base); 13669: byte_data = (uchar) ((word_data >> 8) & 0xFF); 13670: } else { 13671: AscSetChipLramAddr(iop_base, addr); 13672: word_data = AscGetChipLramData(iop_base); 13673: byte_data = (uchar) (word_data & 0xFF); 13674: } 13675: return (byte_data); 13676: } 13677: 13678: STATIC ushort 13679: AscReadLramWord( 13680: PortAddr iop_base, 13681: ushort addr 13682: ) 13683: { 13684: ushort word_data; 13685: 13686: AscSetChipLramAddr(iop_base, addr); 13687: word_data = AscGetChipLramData(iop_base); 13688: return (word_data); 13689: } 13690: 13691: STATIC ulong 13692: AscReadLramDWord( 13693: PortAddr iop_base, 13694: ushort addr 13695: ) 13696: { 13697: ushort val_low, val_high; 13698: ulong dword_data; 13699: 13700: AscSetChipLramAddr(iop_base, addr); 13701: val_low = AscGetChipLramData(iop_base); 13702: val_high = AscGetChipLramData(iop_base); 13703: dword_data = ((ulong) val_high << 16) | (ulong) val_low; 13704: return (dword_data); 13705: } 13706: 13707: STATIC void 13708: AscWriteLramWord( 13709: PortAddr iop_base, 13710: ushort addr, 13711: ushort word_val 13712: ) 13713: { 13714: AscSetChipLramAddr(iop_base, addr); 13715: AscSetChipLramData(iop_base, word_val); 13716: return; 13717: } 13718: 13719: STATIC void 13720: AscWriteLramDWord( 13721: PortAddr iop_base, 13722: ushort addr, 13723: ulong dword_val 13724: ) 13725: { 13726: ushort word_val; 13727: 13728: AscSetChipLramAddr(iop_base, addr); 13729: word_val = (ushort) dword_val; 13730: AscSetChipLramData(iop_base, word_val); 13731: word_val = (ushort) (dword_val >> 16); 13732: AscSetChipLramData(iop_base, word_val); 13733: return; 13734: } 13735: 13736: STATIC void 13737: AscWriteLramByte( 13738: PortAddr iop_base, 13739: ushort addr, 13740: uchar byte_val 13741: ) 13742: { 13743: ushort word_data; 13744: 13745: if (isodd_word(addr)) { 13746: addr--; 13747: word_data = AscReadLramWord(iop_base, addr); 13748: word_data &= 0x00FF; 13749: word_data |= (((ushort) byte_val << 8) & 0xFF00); 13750: } else { 13751: word_data = AscReadLramWord(iop_base, addr); 13752: word_data &= 0xFF00; 13753: word_data |= ((ushort) byte_val & 0x00FF); 13754: } 13755: AscWriteLramWord(iop_base, addr, word_data); 13756: return; 13757: } 13758: 13759: STATIC void 13760: AscMemWordCopyToLram( 13761: PortAddr iop_base, 13762: ushort s_addr, 13763: ushort * s_buffer, 13764: int words 13765: ) 13766: { 13767: AscSetChipLramAddr(iop_base, s_addr); 13768: DvcOutPortWords(iop_base + IOP_RAM_DATA, s_buffer, words); 13769: return; 13770: } 13771: 13772: STATIC void 13773: AscMemDWordCopyToLram( 13774: PortAddr iop_base, 13775: ushort s_addr, 13776: ulong * s_buffer, 13777: int dwords 13778: ) 13779: { 13780: AscSetChipLramAddr(iop_base, s_addr); 13781: DvcOutPortDWords(iop_base + IOP_RAM_DATA, s_buffer, dwords); 13782: return; 13783: } 13784: 13785: STATIC void 13786: AscMemWordCopyFromLram( 13787: PortAddr iop_base, 13788: ushort s_addr, 13789: ushort * d_buffer, 13790: int words 13791: ) 13792: { 13793: AscSetChipLramAddr(iop_base, s_addr); 13794: DvcInPortWords(iop_base + IOP_RAM_DATA, d_buffer, words); 13795: return; 13796: } 13797: 13798: STATIC ulong 13799: AscMemSumLramWord( 13800: PortAddr iop_base, 13801: ushort s_addr, 13802: rint words 13803: ) 13804: { 13805: ulong sum; 13806: int i; 13807: 13808: sum = 0L; 13809: for (i = 0; i < words; i++, s_addr += 2) { 13810: sum += AscReadLramWord(iop_base, s_addr); 13811: } 13812: return (sum); 13813: } 13814: 13815: STATIC void 13816: AscMemWordSetLram( 13817: PortAddr iop_base, 13818: ushort s_addr, 13819: ushort set_wval, 13820: rint words 13821: ) 13822: { 13823: rint i; 13824: 13825: AscSetChipLramAddr(iop_base, s_addr); 13826: for (i = 0; i < words; i++) { 13827: AscSetChipLramData(iop_base, set_wval); 13828: } 13829: return; 13830: } 13831: 13832: 13833: /* 13834: * --- Adv Library Functions 13835: */ 13836: 13837: /* a_qswap.h */ 13838: STATIC unsigned char _adv_mcode_buf[] ASC_INITDATA = { 13839: 0x9C, 0xF0, 0x80, 0x01, 0x00, 0xF0, 0x44, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13840: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13841: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x01, 0xD6, 0x11, 0x00, 0x00, 0x70, 0x01, 13842: 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x10, 0x2D, 0x03, 0x00, 0x00, 0x00, 0x00, 13843: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13844: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13845: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13846: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13847: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13848: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13849: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13850: 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13851: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13852: 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 13853: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13854: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13855: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13856: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13857: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x56, 0x34, 0x12, 13858: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13859: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13860: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13861: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13862: 0x00, 0x00, 0x04, 0xF7, 0x70, 0x01, 0x0C, 0x1C, 0x06, 0xF7, 0x02, 0x00, 0x00, 0xF2, 0xD6, 0x0A, 13863: 0x04, 0xF7, 0x70, 0x01, 0x06, 0xF7, 0x02, 0x00, 0x3E, 0x57, 0x3C, 0x56, 0x0C, 0x1C, 0x00, 0xFC, 13864: 0xA6, 0x00, 0x01, 0x58, 0xAA, 0x13, 0x20, 0xF0, 0xA6, 0x03, 0x06, 0xEC, 0xB9, 0x00, 0x0E, 0x47, 13865: 0x03, 0xE6, 0x10, 0x00, 0xCE, 0x45, 0x02, 0x13, 0x3E, 0x57, 0x06, 0xEA, 0xB9, 0x00, 0x47, 0x4B, 13866: 0x03, 0xF6, 0xE0, 0x00, 0x00, 0xF2, 0x68, 0x0A, 0x01, 0x48, 0x4E, 0x12, 0x03, 0xF6, 0xC0, 0x00, 13867: 0x00, 0xF2, 0x68, 0x0A, 0x41, 0x58, 0x03, 0xF6, 0xD0, 0x00, 0x00, 0xF2, 0x68, 0x0A, 0x49, 0x44, 13868: 0x59, 0xF0, 0x0A, 0x02, 0x03, 0xF6, 0xE0, 0x00, 0x00, 0xF2, 0x68, 0x0A, 0x44, 0x58, 0x00, 0xF2, 13869: 0xE2, 0x0D, 0x02, 0xCC, 0x4A, 0xE4, 0x01, 0x00, 0x55, 0xF0, 0x08, 0x03, 0x45, 0xF4, 0x02, 0x00, 13870: 0x83, 0x5A, 0x04, 0xCC, 0x01, 0x4A, 0x12, 0x12, 0x00, 0xF2, 0xE2, 0x0D, 0x00, 0xCD, 0x48, 0xE4, 13871: 0x01, 0x00, 0xE9, 0x13, 0x00, 0xF2, 0xC6, 0x0F, 0xFA, 0x10, 0x0E, 0x47, 0x03, 0xE6, 0x10, 0x00, 13872: 0xCE, 0x45, 0x02, 0x13, 0x3E, 0x57, 0xCE, 0x47, 0x97, 0x13, 0x04, 0xEC, 0xB4, 0x00, 0x00, 0xF2, 13873: 0xE2, 0x0D, 0x00, 0xCD, 0x48, 0xE4, 0x00, 0x00, 0x12, 0x12, 0x3E, 0x57, 0x06, 0xCC, 0x45, 0xF4, 13874: 0x02, 0x00, 0x83, 0x5A, 0x00, 0xCC, 0x00, 0xEA, 0xB4, 0x00, 0x92, 0x10, 0x00, 0xF0, 0x8C, 0x01, 13875: 0x43, 0xF0, 0x5C, 0x02, 0x44, 0xF0, 0x60, 0x02, 0x45, 0xF0, 0x64, 0x02, 0x46, 0xF0, 0x68, 0x02, 13876: 0x47, 0xF0, 0x6E, 0x02, 0x48, 0xF0, 0x9E, 0x02, 0xB9, 0x54, 0x62, 0x10, 0x00, 0x1C, 0x5A, 0x10, 13877: 0x02, 0x1C, 0x56, 0x10, 0x1E, 0x1C, 0x52, 0x10, 0x00, 0xF2, 0x1E, 0x11, 0x50, 0x10, 0x06, 0xFC, 13878: 0xA8, 0x00, 0x03, 0xF6, 0xBE, 0x00, 0x00, 0xF2, 0x4E, 0x0A, 0x8C, 0x10, 0x01, 0xF6, 0x01, 0x00, 13879: 0x01, 0xFA, 0xA8, 0x00, 0x00, 0xF2, 0x2C, 0x0B, 0x06, 0x10, 0xB9, 0x54, 0x01, 0xFA, 0xA8, 0x00, 13880: 0x03, 0xF6, 0xBE, 0x00, 0x00, 0xF2, 0x58, 0x0A, 0x01, 0xFC, 0xA8, 0x00, 0x20, 0x10, 0x58, 0x1C, 13881: 0x00, 0xF2, 0x1C, 0x0B, 0x5A, 0x1C, 0x01, 0xF6, 0x01, 0x00, 0x38, 0x54, 0x00, 0xFA, 0xA6, 0x00, 13882: 0x01, 0xFA, 0xA8, 0x00, 0x20, 0x1C, 0x00, 0xF0, 0x72, 0x01, 0x01, 0xF6, 0x01, 0x00, 0x38, 0x54, 13883: 0x00, 0xFA, 0xA6, 0x00, 0x01, 0xFA, 0xA8, 0x00, 0x20, 0x1C, 0x00, 0xF0, 0x80, 0x01, 0x03, 0xF6, 13884: 0xE0, 0x00, 0x00, 0xF2, 0x68, 0x0A, 0x01, 0x48, 0x0A, 0x13, 0x00, 0xF2, 0x38, 0x10, 0x00, 0xF2, 13885: 0x54, 0x0F, 0x24, 0x10, 0x03, 0xF6, 0xC0, 0x00, 0x00, 0xF2, 0x68, 0x0A, 0x02, 0xF6, 0xD0, 0x00, 13886: 0x02, 0x57, 0x03, 0x59, 0x01, 0xCC, 0x49, 0x44, 0x5B, 0xF0, 0x04, 0x03, 0x00, 0xF2, 0x9C, 0x0F, 13887: 0x00, 0xF0, 0x80, 0x01, 0x00, 0xF2, 0x14, 0x10, 0x0C, 0x1C, 0x02, 0x4B, 0xBF, 0x57, 0x9E, 0x43, 13888: 0x77, 0x57, 0x07, 0x4B, 0x20, 0xF0, 0xA6, 0x03, 0x40, 0x1C, 0x1E, 0xF0, 0x30, 0x03, 0x26, 0xF0, 13889: 0x2C, 0x03, 0xA0, 0xF0, 0x1A, 0x03, 0x11, 0xF0, 0xA6, 0x03, 0x12, 0x10, 0x9F, 0xF0, 0x3E, 0x03, 13890: 0x46, 0x1C, 0x82, 0xE7, 0x05, 0x00, 0x9E, 0xE7, 0x11, 0x00, 0x00, 0xF0, 0x06, 0x0A, 0x0C, 0x1C, 13891: 0x48, 0x1C, 0x46, 0x1C, 0x38, 0x54, 0x00, 0xEC, 0xBA, 0x00, 0x08, 0x44, 0x00, 0xEA, 0xBA, 0x00, 13892: 0x03, 0xF6, 0xC0, 0x00, 0x00, 0xF2, 0x68, 0x0A, 0x08, 0x44, 0x00, 0x4C, 0x82, 0xE7, 0x02, 0x00, 13893: 0x00, 0xF2, 0x12, 0x11, 0x00, 0xF2, 0x12, 0x11, 0x85, 0xF0, 0x70, 0x03, 0x00, 0xF2, 0x60, 0x0B, 13894: 0x06, 0xF0, 0x80, 0x03, 0x09, 0xF0, 0x24, 0x09, 0x1E, 0xF0, 0xFC, 0x09, 0x00, 0xF0, 0x02, 0x0A, 13895: 0x00, 0xFC, 0xBE, 0x00, 0x98, 0x57, 0x55, 0xF0, 0xAC, 0x04, 0x01, 0xE6, 0x0C, 0x00, 0x00, 0xF2, 13896: 0x4E, 0x0D, 0x00, 0xF2, 0x12, 0x11, 0x00, 0xF2, 0xBC, 0x11, 0x00, 0xF2, 0xC8, 0x11, 0x01, 0xF0, 13897: 0x7C, 0x02, 0x00, 0xF0, 0x8A, 0x02, 0x46, 0x1C, 0x0C, 0x1C, 0x67, 0x1B, 0xBF, 0x57, 0x77, 0x57, 13898: 0x02, 0x4B, 0x48, 0x1C, 0x32, 0x1C, 0x00, 0xF2, 0x92, 0x0D, 0x30, 0x1C, 0x96, 0xF0, 0xBC, 0x03, 13899: 0xB1, 0xF0, 0xC0, 0x03, 0x1E, 0xF0, 0xFC, 0x09, 0x85, 0xF0, 0x02, 0x0A, 0x00, 0xFC, 0xBE, 0x00, 13900: 0x98, 0x57, 0x14, 0x12, 0x01, 0xE6, 0x0C, 0x00, 0x00, 0xF2, 0x4E, 0x0D, 0x00, 0xF2, 0x12, 0x11, 13901: 0x01, 0xF0, 0x7C, 0x02, 0x00, 0xF0, 0x8A, 0x02, 0x03, 0xF6, 0xE0, 0x00, 0x00, 0xF2, 0x68, 0x0A, 13902: 0x01, 0x48, 0x55, 0xF0, 0x98, 0x04, 0x03, 0x82, 0x03, 0xFC, 0xA0, 0x00, 0x9B, 0x57, 0x40, 0x12, 13903: 0x69, 0x18, 0x00, 0xF2, 0x12, 0x11, 0x85, 0xF0, 0x42, 0x04, 0x69, 0x08, 0x00, 0xF2, 0x12, 0x11, 13904: 0x85, 0xF0, 0x02, 0x0A, 0x68, 0x08, 0x4C, 0x44, 0x28, 0x12, 0x44, 0x48, 0x03, 0xF6, 0xE0, 0x00, 13905: 0x00, 0xF2, 0x68, 0x0A, 0x45, 0x58, 0x00, 0xF2, 0xF6, 0x0D, 0x00, 0xCC, 0x01, 0x48, 0x55, 0xF0, 13906: 0x98, 0x04, 0x4C, 0x44, 0xEF, 0x13, 0x00, 0xF2, 0xC6, 0x0F, 0x00, 0xF2, 0x14, 0x10, 0x08, 0x10, 13907: 0x68, 0x18, 0x45, 0x5A, 0x00, 0xF2, 0xF6, 0x0D, 0x04, 0x80, 0x18, 0xE4, 0x10, 0x00, 0x28, 0x12, 13908: 0x01, 0xE6, 0x06, 0x00, 0x04, 0x80, 0x18, 0xE4, 0x01, 0x00, 0x04, 0x12, 0x01, 0xE6, 0x0D, 0x00, 13909: 0x00, 0xF2, 0x4E, 0x0D, 0x00, 0xF2, 0x12, 0x11, 0x04, 0xE6, 0x02, 0x00, 0x9E, 0xE7, 0x15, 0x00, 13910: 0x01, 0xF0, 0x1C, 0x0A, 0x00, 0xF0, 0x02, 0x0A, 0x69, 0x08, 0x05, 0x80, 0x48, 0xE4, 0x00, 0x00, 13911: 0x0C, 0x12, 0x00, 0xE6, 0x11, 0x00, 0x00, 0xEA, 0xB8, 0x00, 0x00, 0xF2, 0xB6, 0x10, 0x82, 0xE7, 13912: 0x02, 0x00, 0x1C, 0x90, 0x40, 0x5C, 0x00, 0x16, 0x01, 0xE6, 0x06, 0x00, 0x00, 0xF2, 0x4E, 0x0D, 13913: 0x01, 0xF0, 0x80, 0x01, 0x1E, 0xF0, 0x80, 0x01, 0x00, 0xF0, 0xA0, 0x04, 0x42, 0x5B, 0x06, 0xF7, 13914: 0x03, 0x00, 0x46, 0x59, 0xBF, 0x57, 0x77, 0x57, 0x01, 0xE6, 0x80, 0x00, 0x07, 0x80, 0x31, 0x44, 13915: 0x04, 0x80, 0x18, 0xE4, 0x20, 0x00, 0x56, 0x13, 0x20, 0x80, 0x48, 0xE4, 0x03, 0x00, 0x4E, 0x12, 13916: 0x00, 0xFC, 0xA2, 0x00, 0x98, 0x57, 0x55, 0xF0, 0x1C, 0x05, 0x31, 0xE4, 0x40, 0x00, 0x00, 0xFC, 13917: 0xA0, 0x00, 0x98, 0x57, 0x36, 0x12, 0x4C, 0x1C, 0x00, 0xF2, 0x12, 0x11, 0x89, 0x48, 0x00, 0xF2, 13918: 0x12, 0x11, 0x86, 0xF0, 0x2E, 0x05, 0x82, 0xE7, 0x06, 0x00, 0x1B, 0x80, 0x48, 0xE4, 0x22, 0x00, 13919: 0x5B, 0xF0, 0x0C, 0x05, 0x48, 0xE4, 0x20, 0x00, 0x59, 0xF0, 0x10, 0x05, 0x00, 0xE6, 0x20, 0x00, 13920: 0x09, 0x48, 0x00, 0xF2, 0x12, 0x11, 0x86, 0xF0, 0x2E, 0x05, 0x83, 0x80, 0x04, 0x10, 0x00, 0xF2, 13921: 0xA2, 0x0D, 0x00, 0xE6, 0x01, 0x00, 0x00, 0xEA, 0x26, 0x01, 0x01, 0xEA, 0x27, 0x01, 0x04, 0x80, 13922: 0x18, 0xE4, 0x10, 0x00, 0x36, 0x12, 0xB9, 0x54, 0x00, 0xF2, 0xF6, 0x0E, 0x01, 0xE6, 0x06, 0x00, 13923: 0x04, 0x80, 0x18, 0xE4, 0x01, 0x00, 0x04, 0x12, 0x01, 0xE6, 0x0D, 0x00, 0x00, 0xF2, 0x4E, 0x0D, 13924: 0x00, 0xF2, 0x12, 0x11, 0x00, 0xF2, 0xBC, 0x11, 0x00, 0xF2, 0xC8, 0x11, 0x04, 0xE6, 0x02, 0x00, 13925: 0x9E, 0xE7, 0x15, 0x00, 0x01, 0xF0, 0x1C, 0x0A, 0x00, 0xF0, 0x02, 0x0A, 0x00, 0xFC, 0x20, 0x01, 13926: 0x98, 0x57, 0x34, 0x12, 0x00, 0xFC, 0x24, 0x01, 0x98, 0x57, 0x2C, 0x13, 0xB9, 0x54, 0x00, 0xF2, 13927: 0xF6, 0x0E, 0x86, 0xF0, 0xA8, 0x05, 0x03, 0xF6, 0x01, 0x00, 0x00, 0xF2, 0x8C, 0x0E, 0x85, 0xF0, 13928: 0x9E, 0x05, 0x82, 0xE7, 0x03, 0x00, 0x00, 0xF2, 0x60, 0x0B, 0x82, 0xE7, 0x02, 0x00, 0x00, 0xFC, 13929: 0x24, 0x01, 0xB0, 0x57, 0x00, 0xFA, 0x24, 0x01, 0x00, 0xFC, 0x9E, 0x00, 0x98, 0x57, 0x5A, 0x12, 13930: 0x00, 0xFC, 0xB6, 0x00, 0x98, 0x57, 0x52, 0x13, 0x03, 0xE6, 0x0C, 0x00, 0x00, 0xFC, 0x9C, 0x00, 13931: 0x98, 0x57, 0x04, 0x13, 0x03, 0xE6, 0x19, 0x00, 0x05, 0xE6, 0x08, 0x00, 0x00, 0xF6, 0x00, 0x01, 13932: 0x00, 0x57, 0x00, 0x57, 0x03, 0x58, 0x00, 0xDC, 0x18, 0xF4, 0x00, 0x80, 0x04, 0x13, 0x05, 0xE6, 13933: 0x0F, 0x00, 0xB9, 0x54, 0x00, 0xF2, 0xF6, 0x0E, 0x86, 0xF0, 0x0A, 0x06, 0x00, 0xF2, 0xBA, 0x0E, 13934: 0x85, 0xF0, 0x00, 0x06, 0x82, 0xE7, 0x03, 0x00, 0x00, 0xF2, 0x60, 0x0B, 0x82, 0xE7, 0x02, 0x00, 13935: 0x00, 0xFC, 0xB6, 0x00, 0xB0, 0x57, 0x00, 0xFA, 0xB6, 0x00, 0x01, 0xF6, 0x01, 0x00, 0x00, 0xF2, 13936: 0xF6, 0x0E, 0x9C, 0x32, 0x4E, 0x1C, 0x32, 0x1C, 0x00, 0xF2, 0x92, 0x0D, 0x30, 0x1C, 0x82, 0xE7, 13937: 0x04, 0x00, 0xB1, 0xF0, 0x22, 0x06, 0x0A, 0xF0, 0x3E, 0x06, 0x05, 0xF0, 0xD6, 0x06, 0x06, 0xF0, 13938: 0xDC, 0x06, 0x09, 0xF0, 0x24, 0x09, 0x1E, 0xF0, 0xFC, 0x09, 0x00, 0xF0, 0x02, 0x0A, 0x04, 0x80, 13939: 0x18, 0xE4, 0x20, 0x00, 0x30, 0x12, 0x09, 0xE7, 0x03, 0x00, 0x00, 0xF2, 0x12, 0x11, 0x21, 0x80, 13940: 0x18, 0xE4, 0xE0, 0x00, 0x09, 0x48, 0x00, 0xF2, 0x12, 0x11, 0x09, 0xE7, 0x00, 0x00, 0x00, 0xF2, 13941: 0x12, 0x11, 0x09, 0xE7, 0x00, 0x00, 0x00, 0xF2, 0x12, 0x11, 0x99, 0xA4, 0x00, 0xF2, 0x12, 0x11, 13942: 0x09, 0xE7, 0x00, 0x00, 0x9A, 0x10, 0x04, 0x80, 0x18, 0xE4, 0x02, 0x00, 0x34, 0x12, 0x09, 0xE7, 13943: 0x1B, 0x00, 0x00, 0xF2, 0x12, 0x11, 0x21, 0x80, 0x18, 0xE4, 0xE0, 0x00, 0x09, 0x48, 0x00, 0xF2, 13944: 0x12, 0x11, 0x09, 0xE7, 0x00, 0x00, 0x00, 0xF2, 0x12, 0x11, 0x09, 0xE7, 0x00, 0x00, 0x00, 0xF2, 13945: 0x12, 0x11, 0x09, 0xE7, 0x01, 0x00, 0x00, 0xF2, 0x12, 0x11, 0x09, 0xE7, 0x00, 0x00, 0x00, 0xF0, 13946: 0x0C, 0x09, 0xBB, 0x55, 0x9A, 0x81, 0x03, 0xF7, 0x20, 0x00, 0x09, 0x6F, 0x93, 0x45, 0x55, 0xF0, 13947: 0xE2, 0x06, 0xB1, 0xF0, 0xC2, 0x06, 0x0A, 0xF0, 0xBA, 0x06, 0x09, 0xF0, 0x24, 0x09, 0x1E, 0xF0, 13948: 0xFC, 0x09, 0x00, 0xF0, 0x02, 0x0A, 0x00, 0xF2, 0x60, 0x0B, 0x47, 0x10, 0x09, 0xE7, 0x08, 0x00, 13949: 0x41, 0x10, 0x05, 0x80, 0x48, 0xE4, 0x00, 0x00, 0x1E, 0x12, 0x00, 0xE6, 0x11, 0x00, 0x00, 0xEA, 13950: 0xB8, 0x00, 0x00, 0xF2, 0xB6, 0x10, 0x2C, 0x90, 0xAE, 0x90, 0x08, 0x50, 0x8A, 0x50, 0x38, 0x54, 13951: 0x1F, 0x40, 0x00, 0xF2, 0xB4, 0x0D, 0x08, 0x10, 0x08, 0x90, 0x8A, 0x90, 0x30, 0x50, 0xB2, 0x50, 13952: 0x9C, 0x32, 0x0C, 0x92, 0x8E, 0x92, 0x38, 0x54, 0x04, 0x80, 0x30, 0xE4, 0x08, 0x00, 0x04, 0x40, 13953: 0x0C, 0x1C, 0x00, 0xF6, 0x03, 0x00, 0xB1, 0xF0, 0x26, 0x07, 0x9E, 0xF0, 0x3A, 0x07, 0x01, 0x48, 13954: 0x55, 0xF0, 0xFC, 0x09, 0x0C, 0x1C, 0x10, 0x44, 0xED, 0x10, 0x0B, 0xF0, 0x5E, 0x07, 0x0C, 0xF0, 13955: 0x62, 0x07, 0x05, 0xF0, 0x52, 0x07, 0x06, 0xF0, 0x58, 0x07, 0x09, 0xF0, 0x24, 0x09, 0x00, 0xF0, 13956: 0x02, 0x0A, 0x00, 0xF2, 0x60, 0x0B, 0xCF, 0x10, 0x09, 0xE7, 0x08, 0x00, 0xC9, 0x10, 0x2E, 0x1C, 13957: 0x02, 0x10, 0x2C, 0x1C, 0xAA, 0xF0, 0x64, 0x07, 0xAC, 0xF0, 0x72, 0x07, 0x40, 0x10, 0x34, 0x1C, 13958: 0xF3, 0x10, 0xAD, 0xF0, 0x7C, 0x07, 0xC8, 0x10, 0x36, 0x1C, 0xE9, 0x10, 0x2B, 0xF0, 0x82, 0x08, 13959: 0x6B, 0x18, 0x18, 0xF4, 0x00, 0xFE, 0x20, 0x12, 0x01, 0x58, 0xD2, 0xF0, 0x82, 0x08, 0x76, 0x18, 13960: 0x18, 0xF4, 0x03, 0x00, 0xEC, 0x12, 0x00, 0xFC, 0x22, 0x01, 0x18, 0xF4, 0x01, 0x00, 0xE2, 0x12, 13961: 0x0B, 0xF0, 0x64, 0x07, 0x0C, 0xF0, 0x64, 0x07, 0x36, 0x1C, 0x34, 0x1C, 0xB7, 0x10, 0x38, 0x54, 13962: 0xB9, 0x54, 0x84, 0x80, 0x19, 0xE4, 0x20, 0x00, 0xB2, 0x13, 0x85, 0x80, 0x81, 0x48, 0x66, 0x12, 13963: 0x04, 0x80, 0x18, 0xE4, 0x08, 0x00, 0x58, 0x13, 0x1F, 0x80, 0x08, 0x44, 0xC8, 0x44, 0x9F, 0x12, 13964: 0x1F, 0x40, 0x34, 0x91, 0xB6, 0x91, 0x44, 0x55, 0xE5, 0x55, 0x02, 0xEC, 0xB8, 0x00, 0x02, 0x49, 13965: 0xBB, 0x55, 0x82, 0x81, 0xC0, 0x55, 0x48, 0xF4, 0x0F, 0x00, 0x5A, 0xF0, 0x1A, 0x08, 0x4A, 0xE4, 13966: 0x17, 0x00, 0xD5, 0xF0, 0xFA, 0x07, 0x02, 0xF6, 0x0F, 0x00, 0x02, 0xF4, 0x02, 0x00, 0x02, 0xEA, 13967: 0xB8, 0x00, 0x04, 0x91, 0x86, 0x91, 0x02, 0x4B, 0x2C, 0x90, 0x08, 0x50, 0x2E, 0x90, 0x0A, 0x50, 13968: 0x2C, 0x51, 0xAE, 0x51, 0x00, 0xF2, 0xB6, 0x10, 0x38, 0x54, 0x00, 0xF2, 0xB4, 0x0D, 0x56, 0x10, 13969: 0x34, 0x91, 0xB6, 0x91, 0x0C, 0x10, 0x04, 0x80, 0x18, 0xE4, 0x08, 0x00, 0x41, 0x12, 0x0C, 0x91, 13970: 0x8E, 0x91, 0x04, 0x80, 0x18, 0xE4, 0xF7, 0x00, 0x04, 0x40, 0x30, 0x90, 0xB2, 0x90, 0x36, 0x10, 13971: 0x02, 0x80, 0x48, 0xE4, 0x10, 0x00, 0x31, 0x12, 0x82, 0xE7, 0x10, 0x00, 0x84, 0x80, 0x19, 0xE4, 13972: 0x20, 0x00, 0x10, 0x13, 0x0C, 0x90, 0x8E, 0x90, 0x5D, 0xF0, 0x78, 0x07, 0x0C, 0x58, 0x8D, 0x58, 13973: 0x00, 0xF0, 0x64, 0x07, 0x38, 0x54, 0xB9, 0x54, 0x19, 0x80, 0xF1, 0x10, 0x3A, 0x55, 0x19, 0x81, 13974: 0xBB, 0x55, 0x10, 0x90, 0x92, 0x90, 0x10, 0x58, 0x91, 0x58, 0x14, 0x59, 0x95, 0x59, 0x00, 0xF0, 13975: 0x64, 0x07, 0x04, 0x80, 0x18, 0xE4, 0x20, 0x00, 0x06, 0x12, 0x6C, 0x19, 0x19, 0x41, 0x7C, 0x10, 13976: 0x6C, 0x19, 0x0C, 0x51, 0xED, 0x19, 0x8E, 0x51, 0x6B, 0x18, 0x18, 0xF4, 0x00, 0xFF, 0x02, 0x13, 13977: 0x6A, 0x10, 0x01, 0x58, 0xD2, 0xF0, 0xC0, 0x08, 0x76, 0x18, 0x18, 0xF4, 0x03, 0x00, 0x0A, 0x12, 13978: 0x00, 0xFC, 0x22, 0x01, 0x18, 0xF4, 0x01, 0x00, 0x06, 0x13, 0x9E, 0xE7, 0x16, 0x00, 0x4C, 0x10, 13979: 0xD1, 0xF0, 0xCA, 0x08, 0x9E, 0xE7, 0x17, 0x00, 0x42, 0x10, 0xD0, 0xF0, 0xD4, 0x08, 0x9E, 0xE7, 13980: 0x19, 0x00, 0x38, 0x10, 0xCF, 0xF0, 0xDE, 0x08, 0x9E, 0xE7, 0x20, 0x00, 0x2E, 0x10, 0xCE, 0xF0, 13981: 0xE8, 0x08, 0x9E, 0xE7, 0x21, 0x00, 0x24, 0x10, 0xCD, 0xF0, 0xF2, 0x08, 0x9E, 0xE7, 0x22, 0x00, 13982: 0x1A, 0x10, 0xCC, 0xF0, 0x04, 0x09, 0x84, 0x80, 0x19, 0xE4, 0x04, 0x00, 0x06, 0x12, 0x9E, 0xE7, 13983: 0x12, 0x00, 0x08, 0x10, 0xCB, 0xF0, 0x0C, 0x09, 0x9E, 0xE7, 0x24, 0x00, 0xB1, 0xF0, 0x0C, 0x09, 13984: 0x05, 0xF0, 0x1E, 0x09, 0x09, 0xF0, 0x24, 0x09, 0x1E, 0xF0, 0xFC, 0x09, 0xE4, 0x10, 0x00, 0xF2, 13985: 0x60, 0x0B, 0xE9, 0x10, 0x9C, 0x32, 0x82, 0xE7, 0x20, 0x00, 0x32, 0x1C, 0xE9, 0x09, 0x00, 0xF2, 13986: 0x12, 0x11, 0x85, 0xF0, 0x02, 0x0A, 0x69, 0x08, 0x01, 0xF0, 0x44, 0x09, 0x1E, 0xF0, 0xFC, 0x09, 13987: 0x00, 0xF0, 0x38, 0x09, 0x30, 0x44, 0x06, 0x12, 0x9E, 0xE7, 0x42, 0x00, 0xB8, 0x10, 0x04, 0xF6, 13988: 0x01, 0x00, 0xB3, 0x45, 0x74, 0x12, 0x04, 0x80, 0x18, 0xE4, 0x20, 0x00, 0x22, 0x13, 0x4B, 0xE4, 13989: 0x02, 0x00, 0x36, 0x12, 0x4B, 0xE4, 0x28, 0x00, 0xAC, 0x13, 0x00, 0xF2, 0xBC, 0x11, 0x00, 0xF2, 13990: 0xC8, 0x11, 0x03, 0xF6, 0xD0, 0x00, 0xFA, 0x14, 0x82, 0xE7, 0x01, 0x00, 0x00, 0xF0, 0x80, 0x01, 13991: 0x9E, 0xE7, 0x44, 0x00, 0x4B, 0xE4, 0x02, 0x00, 0x06, 0x12, 0x03, 0xE6, 0x02, 0x00, 0x76, 0x10, 13992: 0x00, 0xF2, 0xA2, 0x0D, 0x03, 0xE6, 0x02, 0x00, 0x6C, 0x10, 0x00, 0xF2, 0xA2, 0x0D, 0x19, 0x82, 13993: 0x34, 0x46, 0x0A, 0x13, 0x03, 0xE6, 0x02, 0x00, 0x9E, 0xE7, 0x43, 0x00, 0x68, 0x10, 0x04, 0x80, 13994: 0x30, 0xE4, 0x20, 0x00, 0x04, 0x40, 0x00, 0xF2, 0xBC, 0x11, 0x00, 0xF2, 0xC8, 0x11, 0x82, 0xE7, 13995: 0x01, 0x00, 0x06, 0xF7, 0x02, 0x00, 0x00, 0xF0, 0x08, 0x03, 0x04, 0x80, 0x18, 0xE4, 0x20, 0x00, 13996: 0x06, 0x12, 0x03, 0xE6, 0x02, 0x00, 0x3E, 0x10, 0x04, 0x80, 0x18, 0xE4, 0x02, 0x00, 0x3A, 0x12, 13997: 0x04, 0x80, 0x18, 0xE4, 0xFD, 0x00, 0x04, 0x40, 0x1C, 0x1C, 0x9D, 0xF0, 0xEA, 0x09, 0x1C, 0x1C, 13998: 0x9D, 0xF0, 0xF0, 0x09, 0xC1, 0x10, 0x9E, 0xE7, 0x13, 0x00, 0x0A, 0x10, 0x9E, 0xE7, 0x41, 0x00, 13999: 0x04, 0x10, 0x9E, 0xE7, 0x24, 0x00, 0x00, 0xFC, 0xBE, 0x00, 0x98, 0x57, 0xD5, 0xF0, 0x8A, 0x02, 14000: 0x04, 0xE6, 0x04, 0x00, 0x06, 0x10, 0x04, 0xE6, 0x04, 0x00, 0x9D, 0x41, 0x1C, 0x42, 0x9F, 0xE7, 14001: 0x00, 0x00, 0x06, 0xF7, 0x02, 0x00, 0x03, 0xF6, 0xE0, 0x00, 0x3C, 0x14, 0x44, 0x58, 0x45, 0x58, 14002: 0x00, 0xF2, 0xF6, 0x0D, 0x00, 0xF2, 0x7E, 0x10, 0x00, 0xF2, 0xC6, 0x0F, 0x3C, 0x14, 0x1E, 0x1C, 14003: 0x00, 0xF0, 0x80, 0x01, 0x12, 0x1C, 0x22, 0x1C, 0xD2, 0x14, 0x00, 0xF0, 0x72, 0x01, 0x83, 0x59, 14004: 0x03, 0xDC, 0x73, 0x57, 0x80, 0x5D, 0x00, 0x16, 0x83, 0x59, 0x03, 0xDC, 0x38, 0x54, 0x70, 0x57, 14005: 0x33, 0x54, 0x3B, 0x54, 0x80, 0x5D, 0x00, 0x16, 0x03, 0x57, 0x83, 0x59, 0x38, 0x54, 0x00, 0xCC, 14006: 0x00, 0x16, 0x03, 0x57, 0x83, 0x59, 0x00, 0x4C, 0x00, 0x16, 0x02, 0x80, 0x48, 0xE4, 0x01, 0x00, 14007: 0x0E, 0x12, 0x48, 0xE4, 0x05, 0x00, 0x08, 0x12, 0x00, 0xF2, 0xBC, 0x11, 0x00, 0xF2, 0xC8, 0x11, 14008: 0xC1, 0x5A, 0x3A, 0x55, 0x02, 0xEC, 0xB5, 0x00, 0x45, 0x59, 0x00, 0xF2, 0xF6, 0x0D, 0x83, 0x58, 14009: 0x30, 0xE7, 0x00, 0x00, 0x10, 0x4D, 0x30, 0xE7, 0x40, 0x00, 0x10, 0x4F, 0x38, 0x90, 0xBA, 0x90, 14010: 0x10, 0x5C, 0x80, 0x5C, 0x83, 0x5A, 0x10, 0x4E, 0x04, 0xEA, 0xB5, 0x00, 0x43, 0x5B, 0x03, 0xF4, 14011: 0xE0, 0x00, 0x83, 0x59, 0x04, 0xCC, 0x01, 0x4A, 0x0A, 0x12, 0x45, 0x5A, 0x00, 0xF2, 0xF6, 0x0D, 14012: 0x00, 0xF2, 0x38, 0x10, 0x00, 0x16, 0x08, 0x1C, 0x00, 0xFC, 0xAC, 0x00, 0x06, 0x58, 0x67, 0x18, 14013: 0x18, 0xF4, 0x8F, 0xE1, 0x01, 0xFC, 0xAE, 0x00, 0x19, 0xF4, 0x70, 0x1E, 0xB0, 0x54, 0x07, 0x58, 14014: 0x00, 0xFC, 0xB0, 0x00, 0x08, 0x58, 0x00, 0xFC, 0xB2, 0x00, 0x09, 0x58, 0x0A, 0x1C, 0x00, 0xE6, 14015: 0x0F, 0x00, 0x00, 0xEA, 0xB9, 0x00, 0x38, 0x54, 0x00, 0xFA, 0x24, 0x01, 0x00, 0xFA, 0xB6, 0x00, 14016: 0x18, 0x1C, 0x14, 0x1C, 0x10, 0x1C, 0x32, 0x1C, 0x12, 0x1C, 0x00, 0x16, 0x3E, 0x57, 0x0C, 0x14, 14017: 0x0E, 0x47, 0x07, 0xE6, 0x10, 0x00, 0xCE, 0x47, 0xF5, 0x13, 0x00, 0x16, 0x00, 0xF2, 0xA2, 0x0D, 14018: 0x02, 0x4B, 0x03, 0xF6, 0xE0, 0x00, 0x00, 0xF2, 0x68, 0x0A, 0x01, 0x48, 0x20, 0x12, 0x44, 0x58, 14019: 0x45, 0x58, 0x9E, 0xE7, 0x15, 0x00, 0x9C, 0xE7, 0x04, 0x00, 0x00, 0xF2, 0xF6, 0x0D, 0x00, 0xF2, 14020: 0x7E, 0x10, 0x00, 0xF2, 0xC6, 0x0F, 0x00, 0xF2, 0x7A, 0x0A, 0x1E, 0x1C, 0xD5, 0x10, 0x00, 0x16, 14021: 0x69, 0x08, 0x48, 0xE4, 0x04, 0x00, 0x64, 0x12, 0x48, 0xE4, 0x02, 0x00, 0x20, 0x12, 0x48, 0xE4, 14022: 0x03, 0x00, 0x1A, 0x12, 0x48, 0xE4, 0x08, 0x00, 0x14, 0x12, 0x48, 0xE4, 0x01, 0x00, 0xF0, 0x12, 14023: 0x48, 0xE4, 0x07, 0x00, 0x12, 0x12, 0x01, 0xE6, 0x07, 0x00, 0x00, 0xF2, 0x4E, 0x0D, 0x00, 0xF2, 14024: 0x12, 0x11, 0x05, 0xF0, 0x60, 0x0B, 0x00, 0x16, 0x00, 0xE6, 0x01, 0x00, 0x00, 0xEA, 0x99, 0x00, 14025: 0x02, 0x80, 0x48, 0xE4, 0x03, 0x00, 0xE7, 0x12, 0x48, 0xE4, 0x06, 0x00, 0xE1, 0x12, 0x01, 0xE6, 14026: 0x06, 0x00, 0x00, 0xF2, 0x4E, 0x0D, 0x00, 0xF2, 0x12, 0x11, 0x04, 0xE6, 0x02, 0x00, 0x9E, 0xE7, 14027: 0x15, 0x00, 0x01, 0xF0, 0x1C, 0x0A, 0x00, 0xF0, 0x02, 0x0A, 0x00, 0x16, 0x02, 0x80, 0x48, 0xE4, 14028: 0x10, 0x00, 0x1C, 0x12, 0x82, 0xE7, 0x08, 0x00, 0x3C, 0x56, 0x03, 0x82, 0x00, 0xF2, 0xE2, 0x0D, 14029: 0x30, 0xE7, 0x08, 0x00, 0x04, 0xF7, 0x70, 0x01, 0x06, 0xF7, 0x02, 0x00, 0x00, 0xF0, 0x80, 0x01, 14030: 0x6C, 0x19, 0xED, 0x19, 0x5D, 0xF0, 0xD4, 0x0B, 0x44, 0x55, 0xE5, 0x55, 0x59, 0xF0, 0x52, 0x0C, 14031: 0x04, 0x55, 0xA5, 0x55, 0x1F, 0x80, 0x01, 0xEC, 0xB8, 0x00, 0x82, 0x48, 0x82, 0x80, 0x49, 0x44, 14032: 0x2E, 0x13, 0x01, 0xEC, 0xB8, 0x00, 0x41, 0xE4, 0x02, 0x00, 0x01, 0xEA, 0xB8, 0x00, 0x49, 0xE4, 14033: 0x11, 0x00, 0x59, 0xF0, 0x2E, 0x0C, 0x01, 0xE6, 0x17, 0x00, 0x01, 0xEA, 0xB8, 0x00, 0x02, 0x4B, 14034: 0x88, 0x90, 0xAC, 0x50, 0x8A, 0x90, 0xAE, 0x50, 0x01, 0xEC, 0xB8, 0x00, 0x82, 0x48, 0x82, 0x80, 14035: 0x10, 0x44, 0x02, 0x4B, 0x1F, 0x40, 0xC0, 0x44, 0x00, 0xF2, 0xB4, 0x0D, 0x04, 0x55, 0xA5, 0x55, 14036: 0x9F, 0x10, 0x0C, 0x51, 0x8E, 0x51, 0x30, 0x90, 0xB2, 0x90, 0x00, 0x56, 0xA1, 0x56, 0x30, 0x50, 14037: 0xB2, 0x50, 0x34, 0x90, 0xB6, 0x90, 0x40, 0x56, 0xE1, 0x56, 0x34, 0x50, 0xB6, 0x50, 0x65, 0x10, 14038: 0xB1, 0xF0, 0x70, 0x0C, 0x85, 0xF0, 0xCA, 0x0B, 0xE9, 0x09, 0x4B, 0xE4, 0x03, 0x00, 0x78, 0x12, 14039: 0x4B, 0xE4, 0x02, 0x00, 0x01, 0x13, 0xB1, 0xF0, 0x86, 0x0C, 0x85, 0xF0, 0xCA, 0x0B, 0x69, 0x08, 14040: 0x48, 0xE4, 0x03, 0x00, 0xD5, 0xF0, 0x86, 0x0B, 0x00, 0xF2, 0x12, 0x11, 0x85, 0xF0, 0xCA, 0x0B, 14041: 0xE8, 0x09, 0x3C, 0x56, 0x00, 0xFC, 0x20, 0x01, 0x98, 0x57, 0x02, 0x13, 0xBB, 0x45, 0x4B, 0xE4, 14042: 0x00, 0x00, 0x08, 0x12, 0x03, 0xE6, 0x01, 0x00, 0x04, 0xF6, 0x00, 0x80, 0xA8, 0x14, 0xD2, 0x14, 14043: 0x30, 0x1C, 0x02, 0x80, 0x48, 0xE4, 0x03, 0x00, 0x10, 0x13, 0x00, 0xFC, 0xB6, 0x00, 0x98, 0x57, 14044: 0x02, 0x13, 0x4C, 0x1C, 0x3E, 0x1C, 0x00, 0xF0, 0x8E, 0x0B, 0x00, 0xFC, 0x24, 0x01, 0xB0, 0x57, 14045: 0x00, 0xFA, 0x24, 0x01, 0x4C, 0x1C, 0x3E, 0x1C, 0x00, 0xF2, 0x12, 0x11, 0x86, 0xF0, 0x8E, 0x0B, 14046: 0x00, 0xF2, 0x8C, 0x0E, 0x00, 0xF0, 0x8E, 0x0B, 0xB1, 0xF0, 0xF8, 0x0C, 0x85, 0xF0, 0x86, 0x0B, 14047: 0x69, 0x08, 0x48, 0xE4, 0x01, 0x00, 0xD5, 0xF0, 0x86, 0x0B, 0xFC, 0x14, 0x42, 0x58, 0x6C, 0x14, 14048: 0x80, 0x14, 0x30, 0x1C, 0x4A, 0xF4, 0x02, 0x00, 0x55, 0xF0, 0x86, 0x0B, 0x4A, 0xF4, 0x01, 0x00, 14049: 0x0E, 0x12, 0x02, 0x80, 0x48, 0xE4, 0x03, 0x00, 0x06, 0x13, 0x3E, 0x1C, 0x00, 0xF0, 0x8E, 0x0B, 14050: 0x00, 0xFC, 0xB6, 0x00, 0xB0, 0x57, 0x00, 0xFA, 0xB6, 0x00, 0x4C, 0x1C, 0x3E, 0x1C, 0x00, 0xF2, 14051: 0x12, 0x11, 0x86, 0xF0, 0x8E, 0x0B, 0x00, 0xF2, 0xBA, 0x0E, 0x00, 0xF0, 0x8E, 0x0B, 0x4C, 0x1C, 14052: 0xB1, 0xF0, 0x50, 0x0D, 0x85, 0xF0, 0x5C, 0x0D, 0x69, 0x08, 0xF3, 0x10, 0x86, 0xF0, 0x64, 0x0D, 14053: 0x4E, 0x1C, 0x89, 0x48, 0x00, 0x16, 0x00, 0xF6, 0x00, 0x01, 0x00, 0x57, 0x00, 0x57, 0x03, 0x58, 14054: 0x00, 0xDC, 0x18, 0xF4, 0xFF, 0x7F, 0x30, 0x56, 0x00, 0x5C, 0x00, 0x16, 0x00, 0xF6, 0x00, 0x01, 14055: 0x00, 0x57, 0x00, 0x57, 0x03, 0x58, 0x00, 0xDC, 0x18, 0xF4, 0x00, 0x80, 0x30, 0x56, 0x00, 0x5C, 14056: 0x00, 0x16, 0x00, 0xF6, 0x00, 0x01, 0x00, 0x57, 0x00, 0x57, 0x03, 0x58, 0x00, 0xDC, 0x0B, 0x58, 14057: 0x00, 0x16, 0x03, 0xF6, 0x24, 0x01, 0x00, 0xF2, 0x58, 0x0A, 0x03, 0xF6, 0xB6, 0x00, 0x00, 0xF2, 14058: 0x58, 0x0A, 0x00, 0x16, 0x02, 0xEC, 0xB8, 0x00, 0x02, 0x49, 0x18, 0xF4, 0xFF, 0x00, 0x00, 0x54, 14059: 0x00, 0x54, 0x00, 0x54, 0x00, 0xF4, 0x08, 0x00, 0xE1, 0x18, 0x80, 0x54, 0x03, 0x58, 0x00, 0xDD, 14060: 0x01, 0xDD, 0x02, 0xDD, 0x03, 0xDC, 0x02, 0x4B, 0x30, 0x50, 0xB2, 0x50, 0x34, 0x51, 0xB6, 0x51, 14061: 0x00, 0x16, 0x45, 0x5A, 0x1D, 0xF4, 0xFF, 0x00, 0x85, 0x56, 0x85, 0x56, 0x85, 0x56, 0x05, 0xF4, 14062: 0x02, 0x12, 0x83, 0x5A, 0x00, 0x16, 0x1D, 0xF4, 0xFF, 0x00, 0x85, 0x56, 0x85, 0x56, 0x85, 0x56, 14063: 0x05, 0xF4, 0x00, 0x12, 0x83, 0x5A, 0x00, 0x16, 0x38, 0x54, 0xBB, 0x55, 0x3C, 0x56, 0xBD, 0x56, 14064: 0x00, 0xF2, 0x12, 0x11, 0x85, 0xF0, 0x82, 0x0E, 0xE9, 0x09, 0xC1, 0x59, 0x00, 0xF2, 0x12, 0x11, 14065: 0x85, 0xF0, 0x82, 0x0E, 0xE8, 0x0A, 0x83, 0x55, 0x83, 0x55, 0x4B, 0xF4, 0x90, 0x01, 0x5C, 0xF0, 14066: 0x36, 0x0E, 0xBD, 0x56, 0x40, 0x10, 0x4B, 0xF4, 0x30, 0x00, 0x59, 0xF0, 0x48, 0x0E, 0x01, 0xF6, 14067: 0x0C, 0x00, 0x00, 0xF6, 0x01, 0x00, 0x2E, 0x10, 0x02, 0xFC, 0x9C, 0x00, 0x9A, 0x57, 0x14, 0x13, 14068: 0x4B, 0xF4, 0x64, 0x00, 0x59, 0xF0, 0x64, 0x0E, 0x03, 0xF6, 0x64, 0x00, 0x01, 0xF6, 0x19, 0x00, 14069: 0x00, 0xF6, 0x01, 0x00, 0x43, 0xF4, 0x33, 0x00, 0x56, 0xF0, 0x76, 0x0E, 0x04, 0xF4, 0x00, 0x01, 14070: 0x43, 0xF4, 0x19, 0x00, 0xF3, 0x10, 0xB4, 0x56, 0xC3, 0x58, 0x02, 0xFC, 0x9E, 0x00, 0x9A, 0x57, 14071: 0x08, 0x13, 0x3C, 0x56, 0x00, 0xF6, 0x02, 0x00, 0x00, 0x16, 0x00, 0x16, 0x09, 0xE7, 0x01, 0x00, 14072: 0x00, 0xF2, 0x12, 0x11, 0x86, 0xF0, 0xB8, 0x0E, 0x09, 0xE7, 0x02, 0x00, 0x00, 0xF2, 0x12, 0x11, 14073: 0x86, 0xF0, 0xB8, 0x0E, 0x09, 0xE7, 0x03, 0x00, 0x00, 0xF2, 0x12, 0x11, 0x86, 0xF0, 0xB8, 0x0E, 14074: 0x4E, 0x1C, 0x89, 0x49, 0x00, 0xF2, 0x12, 0x11, 0x00, 0x16, 0x09, 0xE7, 0x01, 0x00, 0x00, 0xF2, 14075: 0x12, 0x11, 0x86, 0xF0, 0xF2, 0x0E, 0x09, 0xE7, 0x03, 0x00, 0x00, 0xF2, 0x12, 0x11, 0x86, 0xF0, 14076: 0xF2, 0x0E, 0x09, 0xE7, 0x01, 0x00, 0x00, 0xF2, 0x12, 0x11, 0x86, 0xF0, 0xF2, 0x0E, 0x89, 0x49, 14077: 0x00, 0xF2, 0x12, 0x11, 0x86, 0xF0, 0xF2, 0x0E, 0x4E, 0x1C, 0x89, 0x4A, 0x00, 0xF2, 0x12, 0x11, 14078: 0x00, 0x16, 0x3C, 0x56, 0x00, 0x16, 0x00, 0xEC, 0x26, 0x01, 0x48, 0xE4, 0x01, 0x00, 0x1E, 0x13, 14079: 0x38, 0x44, 0x00, 0xEA, 0x26, 0x01, 0x49, 0xF4, 0x00, 0x00, 0x04, 0x12, 0x4E, 0x1C, 0x02, 0x10, 14080: 0x4C, 0x1C, 0x01, 0xEC, 0x27, 0x01, 0x89, 0x48, 0x00, 0xF2, 0x12, 0x11, 0x02, 0x14, 0x00, 0x16, 14081: 0x85, 0xF0, 0x52, 0x0F, 0x38, 0x54, 0x00, 0xEA, 0x99, 0x00, 0x00, 0xF2, 0x60, 0x0B, 0x02, 0x80, 14082: 0x48, 0xE4, 0x06, 0x00, 0x1C, 0x13, 0x00, 0xEC, 0x99, 0x00, 0x48, 0xE4, 0x01, 0x00, 0x0A, 0x12, 14083: 0x04, 0x80, 0x30, 0xE4, 0x01, 0x00, 0x04, 0x40, 0x08, 0x10, 0x04, 0x80, 0x18, 0xE4, 0xFE, 0x00, 14084: 0x04, 0x40, 0x00, 0x16, 0x02, 0xF6, 0xE0, 0x00, 0x02, 0x57, 0x03, 0x59, 0x01, 0xCC, 0x81, 0x48, 14085: 0x22, 0x12, 0x00, 0x4E, 0x83, 0x5A, 0x90, 0x4C, 0x20, 0xE7, 0x00, 0x00, 0xC3, 0x58, 0x1B, 0xF4, 14086: 0xFF, 0x00, 0x83, 0x55, 0x83, 0x55, 0x83, 0x55, 0x03, 0xF4, 0x00, 0x12, 0x8B, 0x55, 0x83, 0x59, 14087: 0x00, 0x4E, 0x00, 0x16, 0x00, 0x4E, 0x02, 0xF6, 0xF0, 0x00, 0x02, 0x57, 0x03, 0x59, 0x00, 0x4E, 14088: 0x83, 0x5A, 0x30, 0xE7, 0x00, 0x00, 0x20, 0xE7, 0x00, 0x00, 0x00, 0x16, 0x02, 0xF6, 0xF0, 0x00, 14089: 0x02, 0x57, 0x03, 0x59, 0x01, 0xCC, 0x00, 0x4E, 0x83, 0x5A, 0x30, 0xE7, 0x00, 0x00, 0x80, 0x4C, 14090: 0xC3, 0x58, 0x1B, 0xF4, 0xFF, 0x00, 0x83, 0x55, 0x83, 0x55, 0x83, 0x55, 0x03, 0xF4, 0x00, 0x12, 14091: 0x83, 0x59, 0x00, 0x4E, 0x00, 0x16, 0x03, 0xF6, 0xE0, 0x00, 0x03, 0x57, 0x83, 0x59, 0x3A, 0x55, 14092: 0x02, 0xCC, 0x45, 0x5A, 0x00, 0xF2, 0xF6, 0x0D, 0xC0, 0x5A, 0x40, 0x5C, 0x38, 0x54, 0x00, 0xCD, 14093: 0x01, 0xCC, 0x4A, 0x46, 0x0A, 0x13, 0x83, 0x59, 0x00, 0x4C, 0x01, 0x48, 0x16, 0x13, 0x0C, 0x10, 14094: 0xC5, 0x58, 0x00, 0xF2, 0xF6, 0x0D, 0x00, 0x4C, 0x01, 0x48, 0x08, 0x13, 0x05, 0xF6, 0xF0, 0x00, 14095: 0x05, 0x57, 0x08, 0x10, 0x45, 0x58, 0x00, 0xF2, 0xF6, 0x0D, 0x8D, 0x56, 0x83, 0x5A, 0x80, 0x4C, 14096: 0x05, 0x17, 0x00, 0x16, 0x02, 0x4B, 0x06, 0xF7, 0x04, 0x00, 0x62, 0x0B, 0x03, 0x82, 0x00, 0xF2, 14097: 0xE2, 0x0D, 0x02, 0x80, 0x00, 0x4C, 0x45, 0xF4, 0x02, 0x00, 0x52, 0x14, 0x06, 0xF7, 0x02, 0x00, 14098: 0x06, 0x14, 0x00, 0xF2, 0x54, 0x0F, 0x00, 0x16, 0x02, 0x4B, 0x01, 0xF6, 0xFF, 0x00, 0x38, 0x1C, 14099: 0x05, 0xF4, 0x04, 0x00, 0x83, 0x5A, 0x18, 0xDF, 0x19, 0xDF, 0x1D, 0xF7, 0x3C, 0x00, 0xB8, 0xF0, 14100: 0x4E, 0x10, 0x9C, 0x14, 0x01, 0x48, 0x1C, 0x13, 0x0E, 0xF7, 0x3C, 0x00, 0x03, 0xF7, 0x04, 0x00, 14101: 0xAF, 0x19, 0x03, 0x42, 0x45, 0xF4, 0x02, 0x00, 0x83, 0x5A, 0x02, 0xCC, 0x02, 0x41, 0x45, 0xF4, 14102: 0x02, 0x00, 0x00, 0x16, 0x91, 0x44, 0xD5, 0xF0, 0x3E, 0x10, 0x00, 0xF0, 0x9E, 0x02, 0x01, 0xF6, 14103: 0xFF, 0x00, 0x38, 0x1C, 0x05, 0xF4, 0x04, 0x00, 0x83, 0x5A, 0x18, 0xDF, 0x19, 0xDF, 0x0E, 0xF7, 14104: 0x3C, 0x00, 0x03, 0xF7, 0x04, 0x00, 0x0F, 0x79, 0x1C, 0xF7, 0x3C, 0x00, 0xB8, 0xF0, 0x9C, 0x10, 14105: 0x4E, 0x14, 0x01, 0x48, 0x06, 0x13, 0x45, 0xF4, 0x04, 0x00, 0x00, 0x16, 0x91, 0x44, 0xD5, 0xF0, 14106: 0x82, 0x10, 0x00, 0xF0, 0x9E, 0x02, 0x02, 0xF6, 0xFF, 0x00, 0x38, 0x1C, 0x2C, 0xBC, 0xAE, 0xBC, 14107: 0xE2, 0x08, 0x00, 0xEC, 0xB8, 0x00, 0x02, 0x48, 0x1D, 0xF7, 0x80, 0x00, 0xB8, 0xF0, 0xCC, 0x10, 14108: 0x1E, 0x14, 0x01, 0x48, 0x0E, 0x13, 0x0E, 0xF7, 0x80, 0x00, 0x38, 0x54, 0x03, 0x58, 0xAF, 0x19, 14109: 0x82, 0x48, 0x00, 0x16, 0x82, 0x48, 0x12, 0x45, 0xD5, 0xF0, 0xBA, 0x10, 0x00, 0xF0, 0x9E, 0x02, 14110: 0x39, 0xF0, 0xF8, 0x10, 0x38, 0x44, 0x00, 0x16, 0x7E, 0x18, 0x18, 0xF4, 0x03, 0x00, 0x04, 0x13, 14111: 0x61, 0x18, 0x00, 0x16, 0x38, 0x1C, 0x00, 0xFC, 0x22, 0x01, 0x18, 0xF4, 0x01, 0x00, 0xF1, 0x12, 14112: 0xE3, 0x10, 0x30, 0x44, 0x30, 0x44, 0x30, 0x44, 0xB1, 0xF0, 0x18, 0x11, 0x00, 0x16, 0x3E, 0x57, 14113: 0x03, 0xF6, 0xE0, 0x00, 0x03, 0x57, 0x83, 0x59, 0x04, 0xCC, 0x01, 0x4A, 0x6A, 0x12, 0x45, 0x5A, 14114: 0x00, 0xF2, 0xF6, 0x0D, 0x02, 0x4B, 0x70, 0x14, 0x34, 0x13, 0x02, 0x80, 0x48, 0xE4, 0x08, 0x00, 14115: 0x18, 0x12, 0x9C, 0xE7, 0x02, 0x00, 0x9E, 0xE7, 0x15, 0x00, 0x00, 0xF2, 0xC6, 0x0F, 0x00, 0xF2, 14116: 0x7A, 0x0A, 0x1E, 0x1C, 0x01, 0xF6, 0x01, 0x00, 0x00, 0x16, 0x30, 0xE4, 0x10, 0x00, 0x04, 0x40, 14117: 0x00, 0xF2, 0xE2, 0x0D, 0x20, 0xE7, 0x01, 0x00, 0x01, 0xF6, 0x01, 0x00, 0x00, 0x16, 0x04, 0xDC, 14118: 0x01, 0x4A, 0x24, 0x12, 0x45, 0x5A, 0x00, 0xF2, 0xF6, 0x0D, 0x43, 0x5B, 0x06, 0xEC, 0x98, 0x00, 14119: 0x00, 0xF2, 0x38, 0x10, 0xC6, 0x59, 0x20, 0x14, 0x0A, 0x13, 0x00, 0xF2, 0xC6, 0x0F, 0x00, 0xF2, 14120: 0x14, 0x10, 0xA7, 0x10, 0x83, 0x5A, 0xD7, 0x10, 0x0E, 0x47, 0x07, 0xE6, 0x10, 0x00, 0xCE, 0x47, 14121: 0x5A, 0xF0, 0x20, 0x11, 0xB9, 0x54, 0x00, 0x16, 0x14, 0x90, 0x96, 0x90, 0x02, 0xFC, 0xA8, 0x00, 14122: 0x03, 0xFC, 0xAA, 0x00, 0x48, 0x55, 0x02, 0x13, 0xC9, 0x55, 0x00, 0x16, 0x00, 0xEC, 0xBA, 0x00, 14123: 0x10, 0x44, 0x00, 0xEA, 0xBA, 0x00, 0x00, 0x16, 0x03, 0xF6, 0xC0, 0x00, 0x00, 0xF2, 0x68, 0x0A, 14124: 0x10, 0x44, 0x00, 0x4C, 0x00, 0x16 14125: }; 14126: 14127: unsigned short _adv_mcode_size ASC_INITDATA = 14128: sizeof(_adv_mcode_buf); /* 0x11D6 */ 14129: unsigned long _adv_mcode_chksum ASC_INITDATA = 0x03494981UL; 14130: 14131: /* a_init.c */ 14132: /* 14133: * EEPROM Configuration. 14134: * 14135: * All drivers should use this structure to set the default EEPROM 14136: * configuration. The BIOS now uses this structure when it is built. 14137: * Additional structure information can be found in a_condor.h where 14138: * the structure is defined. 14139: */ 14140: STATIC ADVEEP_CONFIG 14141: Default_EEPROM_Config ASC_INITDATA = { 14142: ADV_EEPROM_BIOS_ENABLE, /* cfg_msw */ 14143: 0x0000, /* cfg_lsw */ 14144: 0xFFFF, /* disc_enable */ 14145: 0xFFFF, /* wdtr_able */ 14146: 0xFFFF, /* sdtr_able */ 14147: 0xFFFF, /* start_motor */ 14148: 0xFFFF, /* tagqng_able */ 14149: 0xFFFF, /* bios_scan */ 14150: 0, /* scam_tolerant */ 14151: 7, /* adapter_scsi_id */ 14152: 0, /* bios_boot_delay */ 14153: 3, /* scsi_reset_delay */ 14154: 0, /* bios_id_lun */ 14155: 0, /* termination */ 14156: 0, /* reserved1 */ 14157: 0xFFEF, /* bios_ctrl */ 14158: 0xFFFF, /* ultra_able */ 14159: 0, /* reserved2 */ 14160: ASC_DEF_MAX_HOST_QNG, /* max_host_qng */ 14161: ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */ 14162: 0, /* dvc_cntl */ 14163: 0, /* bug_fix */ 14164: 0, /* serial_number_word1 */ 14165: 0, /* serial_number_word2 */ 14166: 0, /* serial_number_word3 */ 14167: 0, /* check_sum */ 14168: { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* oem_name[16] */ 14169: 0, /* dvc_err_code */ 14170: 0, /* adv_err_code */ 14171: 0, /* adv_err_addr */ 14172: 0, /* saved_dvc_err_code */ 14173: 0, /* saved_adv_err_code */ 14174: 0, /* saved_adv_err_addr */ 14175: 0 /* num_of_err */ 14176: }; 14177: 14178: /* 14179: * Initialize the ADV_DVC_VAR structure. 14180: * 14181: * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR. 14182: * 14183: * For a non-fatal error return a warning code. If there are no warnings 14184: * then 0 is returned. 14185: */ 14186: ASC_INITFUNC( 14187: int 14188: AdvInitGetConfig(ADV_DVC_VAR *asc_dvc) 14189: ) 14190: { 14191: ushort warn_code; 14192: AdvPortAddr iop_base; 14193: uchar pci_cmd_reg; 14194: int status; 14195: 14196: warn_code = 0; 14197: asc_dvc->err_code = 0; 14198: iop_base = asc_dvc->iop_base; 14199: 14200: /* 14201: * PCI Command Register 14202: */ 14203: 14204: if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc, 14205: AscPCIConfigCommandRegister)) 14206: & AscPCICmdRegBits_BusMastering) 14207: != AscPCICmdRegBits_BusMastering) 14208: { 14209: pci_cmd_reg |= AscPCICmdRegBits_BusMastering; 14210: 14211: DvcAdvWritePCIConfigByte(asc_dvc, 14212: AscPCIConfigCommandRegister, pci_cmd_reg); 14213: 14214: if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister)) 14215: & AscPCICmdRegBits_BusMastering) 14216: != AscPCICmdRegBits_BusMastering) 14217: { 14218: warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE; 14219: } 14220: } 14221: 14222: /* 14223: * PCI Latency Timer 14224: * 14225: * If the "latency timer" register is 0x20 or above, then we don't need 14226: * to change it. Otherwise, set it to 0x20 (i.e. set it to 0x20 if it 14227: * comes up less than 0x20). 14228: */ 14229: if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) { 14230: DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer, 0x20); 14231: if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) 14232: { 14233: warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE; 14234: } 14235: } 14236: 14237: /* 14238: * Save the state of the PCI Configuration Command Register 14239: * "Parity Error Response Control" Bit. If the bit is clear (0), 14240: * in AdvInitAsc3550Driver() tell the microcode to ignore DMA 14241: * parity errors. 14242: */ 14243: asc_dvc->cfg->control_flag = 0; 14244: if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister) 14245: & AscPCICmdRegBits_ParErrRespCtrl)) == 0) 14246: { 14247: asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR; 14248: } 14249: 14250: asc_dvc->cur_host_qng = 0; 14251: 14252: asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) | 14253: ADV_LIB_VERSION_MINOR; 14254: asc_dvc->cfg->chip_version = 14255: AdvGetChipVersion(iop_base, asc_dvc->bus_type); 14256: 14257: /* 14258: * Reset the chip to start and allow register writes. 14259: */ 14260: if (AdvFindSignature(iop_base) == 0) 14261: { 14262: asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; 14263: return ADV_ERROR; 14264: } 14265: else { 14266: 14267: AdvResetChip(asc_dvc); 14268: 14269: if ((status = AdvInitFromEEP(asc_dvc)) == ADV_ERROR) 14270: { 14271: return ADV_ERROR; 14272: } 14273: warn_code |= status; 14274: 14275: /* 14276: * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus 14277: * Resets should be performed. 14278: */ 14279: if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) 14280: { 14281: AdvResetSCSIBus(asc_dvc); 14282: } 14283: } 14284: 14285: return warn_code; 14286: } 14287: 14288: /* 14289: * Initialize the ASC3550. 14290: * 14291: * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR. 14292: * 14293: * For a non-fatal error return a warning code. If there are no warnings 14294: * then 0 is returned. 14295: */ 14296: ASC_INITFUNC( 14297: int 14298: AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc) 14299: ) 14300: { 14301: AdvPortAddr iop_base; 14302: ushort warn_code; 14303: ulong sum; 14304: int begin_addr; 14305: int end_addr; 14306: int code_sum; 14307: int word; 14308: int rql_addr; /* RISC Queue List address */ 14309: int i; 14310: ushort scsi_cfg1; 14311: uchar biosmem[ASC_MC_BIOSLEN]; /* BIOS RISC Memory 0x40-0x8F. */ 14312: 14313: /* If there is already an error, don't continue. */ 14314: if (asc_dvc->err_code != 0) 14315: { 14316: return ADV_ERROR; 14317: } 14318: 14319: warn_code = 0; 14320: iop_base = asc_dvc->iop_base; 14321: 14322: /* 14323: * Save the RISC memory BIOS region before writing the microcode. 14324: * The BIOS may already be loaded and using its RISC LRAM region 14325: * so its region must be saved and restored. 14326: * 14327: * Note: This code makes the assumption, which is currently true, 14328: * that a chip reset does not clear RISC LRAM. 14329: */ 14330: for (i = 0; i < ASC_MC_BIOSLEN; i++) 14331: { 14332: AdvReadByteLram(iop_base, ASC_MC_BIOSMEM + i, biosmem[i]); 14333: } 14334: 14335: /* 14336: * Load the Microcode 14337: * 14338: * Write the microcode image to RISC memory starting at address 0. 14339: */ 14340: AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); 14341: for (word = 0; word < _adv_mcode_size; word += 2) 14342: { 14343: AdvWriteWordAutoIncLram(iop_base, 14344: *((ushort *) (&_adv_mcode_buf[word]))); 14345: } 14346: 14347: /* 14348: * Clear the rest of Condor's Internal RAM (8KB). 14349: */ 14350: for (; word < ADV_CONDOR_MEMSIZE; word += 2) 14351: { 14352: AdvWriteWordAutoIncLram(iop_base, 0); 14353: } 14354: 14355: /* 14356: * Verify the microcode checksum. 14357: */ 14358: sum = 0; 14359: AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); 14360: for (word = 0; word < _adv_mcode_size; word += 2) 14361: { 14362: sum += AdvReadWordAutoIncLram(iop_base); 14363: } 14364: 14365: if (sum != _adv_mcode_chksum) 14366: { 14367: asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; 14368: return ADV_ERROR; 14369: } 14370: 14371: /* 14372: * Restore the RISC memory BIOS region. 14373: */ 14374: for (i = 0; i < ASC_MC_BIOSLEN; i++) 14375: { 14376: AdvWriteByteLram(iop_base, ASC_MC_BIOSMEM + i, biosmem[i]); 14377: } 14378: 14379: /* 14380: * Calculate and write the microcode code checksum to the microcode 14381: * code checksum location ASC_MC_CODE_CHK_SUM (0x2C). 14382: */ 14383: AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr); 14384: AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr); 14385: code_sum = 0; 14386: for (word = begin_addr; word < end_addr; word += 2) 14387: { 14388: code_sum += *((ushort *) (&_adv_mcode_buf[word])); 14389: } 14390: AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum); 14391: 14392: /* 14393: * Read microcode version and date. 14394: */ 14395: AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date); 14396: AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version); 14397: 14398: /* 14399: * Initialize microcode operating variables 14400: */ 14401: AdvWriteWordLram(iop_base, ASC_MC_ADAPTER_SCSI_ID, 14402: asc_dvc->chip_scsi_id); 14403: 14404: /* 14405: * If the PCI Configuration Command Register "Parity Error Response 14406: * Control" Bit was clear (0), then set the microcode variable 14407: * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode 14408: * to ignore DMA parity errors. 14409: */ 14410: if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) 14411: { 14412: /* 14413: * Note: Don't remove the use of a temporary variable in 14414: * the following code, otherwise the Microsoft C compiler 14415: * will turn the following lines into a no-op. 14416: */ 14417: AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); 14418: word |= CONTROL_FLAG_IGNORE_PERR; 14419: AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); 14420: } 14421: 14422: /* 14423: * Set default microcode operating variables for WDTR, SDTR, and 14424: * command tag queuing based on the EEPROM configuration values. 14425: * 14426: * These ADV_DVC_VAR fields and the microcode variables will be 14427: * changed in AdvInquiryHandling() if it is found a device is 14428: * incapable of a particular feature. 14429: */ 14430: 14431: /* 14432: * Set the microcode ULTRA target mask from EEPROM value. The 14433: * SDTR target mask overrides the ULTRA target mask in the 14434: * microcode so it is safe to set this value without determining 14435: * whether the device supports SDTR. 14436: * 14437: * Note: There is no way to know whether a device supports ULTRA 14438: * speed without attempting a SDTR ULTRA speed negotiation with 14439: * the device. The device will reject the speed if it does not 14440: * support it by responding with an SDTR message containing a 14441: * slower speed. 14442: */ 14443: AdvWriteWordLram(iop_base, ASC_MC_ULTRA_ABLE, asc_dvc->ultra_able); 14444: AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable); 14445: 14446: 14447: /* 14448: * Set SCSI_CFG0 Microcode Default Value. 14449: * 14450: * The microcode will set the SCSI_CFG0 register using this value 14451: * after it is started below. 14452: */ 14453: AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0, 14454: PARITY_EN | SEL_TMO_LONG | OUR_ID_EN | asc_dvc->chip_scsi_id); 14455: 14456: /* 14457: * Determine SCSI_CFG1 Microcode Default Value. 14458: * 14459: * The microcode will set the SCSI_CFG1 register using this value 14460: * after it is started below. 14461: */ 14462: 14463: /* Read current SCSI_CFG1 Register value. */ 14464: scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); 14465: 14466: /* 14467: * If all three connectors are in use, return an error. 14468: */ 14469: if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 || 14470: (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) 14471: { 14472: asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION; 14473: return ADV_ERROR; 14474: } 14475: 14476: /* 14477: * If the internal narrow cable is reversed all of the SCSI_CTRL 14478: * register signals will be set. Check for and return an error if 14479: * this condition is found. 14480: */ 14481: if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) 14482: { 14483: asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE; 14484: return ADV_ERROR; 14485: } 14486: 14487: /* 14488: * If this is a differential board and a single-ended device 14489: * is attached to one of the connectors, return an error. 14490: */ 14491: if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) 14492: { 14493: asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE; 14494: return ADV_ERROR; 14495: } 14496: 14497: /* 14498: * If automatic termination control is enabled, then set the 14499: * termination value based on a table listed in a_condor.h. 14500: * 14501: * If manual termination was specified with an EEPROM setting 14502: * then 'termination' was set-up in AdvInitFromEEP() and 14503: * is ready to be 'ored' into SCSI_CFG1. 14504: */ 14505: if (asc_dvc->cfg->termination == 0) 14506: { 14507: /* 14508: * The software always controls termination by setting TERM_CTL_SEL. 14509: * If TERM_CTL_SEL were set to 0, the hardware would set termination. 14510: */ 14511: asc_dvc->cfg->termination |= TERM_CTL_SEL; 14512: 14513: switch(scsi_cfg1 & CABLE_DETECT) 14514: { 14515: /* TERM_CTL_H: on, TERM_CTL_L: on */ 14516: case 0x3: case 0x7: case 0xB: case 0xD: case 0xE: case 0xF: 14517: asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L); 14518: break; 14519: 14520: /* TERM_CTL_H: on, TERM_CTL_L: off */ 14521: case 0x1: case 0x5: case 0x9: case 0xA: case 0xC: 14522: asc_dvc->cfg->termination |= TERM_CTL_H; 14523: break; 14524: 14525: /* TERM_CTL_H: off, TERM_CTL_L: off */ 14526: case 0x2: case 0x6: 14527: break; 14528: } 14529: } 14530: 14531: /* 14532: * Clear any set TERM_CTL_H and TERM_CTL_L bits. 14533: */ 14534: scsi_cfg1 &= ~TERM_CTL; 14535: 14536: /* 14537: * Invert the TERM_CTL_H and TERM_CTL_L bits and then 14538: * set 'scsi_cfg1'. The TERM_POL bit does not need to be 14539: * referenced, because the hardware internally inverts 14540: * the Termination High and Low bits if TERM_POL is set. 14541: */ 14542: scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL)); 14543: 14544: /* 14545: * Set SCSI_CFG1 Microcode Default Value 14546: * 14547: * Set filter value and possibly modified termination control 14548: * bits in the Microcode SCSI_CFG1 Register Value. 14549: * 14550: * The microcode will set the SCSI_CFG1 register using this value 14551: * after it is started below. 14552: */ 14553: AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, 14554: FLTR_11_TO_20NS | scsi_cfg1); 14555: 14556: /* 14557: * Set SEL_MASK Microcode Default Value 14558: * 14559: * The microcode will set the SEL_MASK register using this value 14560: * after it is started below. 14561: */ 14562: AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK, 14563: ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id)); 14564: 14565: /* 14566: * Link all the RISC Queue Lists together in a doubly-linked 14567: * NULL terminated list. 14568: * 14569: * Skip the NULL (0) queue which is not used. 14570: */ 14571: for (i = 1, rql_addr = ASC_MC_RISC_Q_LIST_BASE + ASC_MC_RISC_Q_LIST_SIZE; 14572: i < ASC_MC_RISC_Q_TOTAL_CNT; 14573: i++, rql_addr += ASC_MC_RISC_Q_LIST_SIZE) 14574: { 14575: /* 14576: * Set the current RISC Queue List's RQL_FWD and RQL_BWD pointers 14577: * in a one word write and set the state (RQL_STATE) to free. 14578: */ 14579: AdvWriteWordLram(iop_base, rql_addr, ((i + 1) + ((i - 1) << 8))); 14580: AdvWriteByteLram(iop_base, rql_addr + RQL_STATE, ASC_MC_QS_FREE); 14581: } 14582: 14583: /* 14584: * Set the Host and RISC Queue List pointers. 14585: * 14586: * Both sets of pointers are initialized with the same values: 14587: * ASC_MC_RISC_Q_FIRST(0x01) and ASC_MC_RISC_Q_LAST (0xFF). 14588: */ 14589: AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_READY, ASC_MC_RISC_Q_FIRST); 14590: AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_DONE, ASC_MC_RISC_Q_LAST); 14591: 14592: AdvWriteByteLram(iop_base, ASC_MC_RISC_NEXT_READY, ASC_MC_RISC_Q_FIRST); 14593: AdvWriteByteLram(iop_base, ASC_MC_RISC_NEXT_DONE, ASC_MC_RISC_Q_LAST); 14594: 14595: /* 14596: * Finally, set up the last RISC Queue List (255) with 14597: * a NULL forward pointer. 14598: */ 14599: AdvWriteWordLram(iop_base, rql_addr, (ASC_MC_NULL_Q + ((i - 1) << 8))); 14600: AdvWriteByteLram(iop_base, rql_addr + RQL_STATE, ASC_MC_QS_FREE); 14601: 14602: AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES, 14603: (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR)); 14604: 14605: /* 14606: * Note: Don't remove the use of a temporary variable in 14607: * the following code, otherwise the Microsoft C compiler 14608: * will turn the following lines into a no-op. 14609: */ 14610: AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word); 14611: AdvWriteWordRegister(iop_base, IOPW_PC, word); 14612: 14613: /* finally, finally, gentlemen, start your engine */ 14614: AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN); 14615: 14616: return warn_code; 14617: } 14618: 14619: /* 14620: * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and 14621: * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while 14622: * all of this is done. 14623: * 14624: * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR. 14625: * 14626: * For a non-fatal error return a warning code. If there are no warnings 14627: * then 0 is returned. 14628: * 14629: * Note: Chip is stopped on entry. 14630: */ 14631: ASC_INITFUNC( 14632: STATIC int 14633: AdvInitFromEEP(ADV_DVC_VAR *asc_dvc) 14634: ) 14635: { 14636: AdvPortAddr iop_base; 14637: ushort warn_code; 14638: ADVEEP_CONFIG eep_config; 14639: int i; 14640: 14641: iop_base = asc_dvc->iop_base; 14642: 14643: warn_code = 0; 14644: 14645: /* 14646: * Read the board's EEPROM configuration. 14647: * 14648: * Set default values if a bad checksum is found. 14649: */ 14650: if (AdvGetEEPConfig(iop_base, &eep_config) != eep_config.check_sum) 14651: { 14652: warn_code |= ASC_WARN_EEPROM_CHKSUM; 14653: 14654: /* 14655: * Set EEPROM default values. 14656: */ 14657: for (i = 0; i < sizeof(ADVEEP_CONFIG); i++) 14658: { 14659: *((uchar *) &eep_config + i) = 14660: *((uchar *) &Default_EEPROM_Config + i); 14661: } 14662: 14663: /* 14664: * Assume the 6 byte board serial number that was read 14665: * from EEPROM is correct even if the EEPROM checksum 14666: * failed. 14667: */ 14668: eep_config.serial_number_word3 = 14669: AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 1); 14670: eep_config.serial_number_word2 = 14671: AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 2); 14672: eep_config.serial_number_word1 = 14673: AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 3); 14674: AdvSetEEPConfig(iop_base, &eep_config); 14675: } 14676: 14677: /* 14678: * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the 14679: * EEPROM configuration that was read. 14680: * 14681: * This is the mapping of EEPROM fields to Adv Library fields. 14682: */ 14683: asc_dvc->wdtr_able = eep_config.wdtr_able; 14684: asc_dvc->sdtr_able = eep_config.sdtr_able; 14685: asc_dvc->ultra_able = eep_config.ultra_able; 14686: asc_dvc->tagqng_able = eep_config.tagqng_able; 14687: asc_dvc->cfg->disc_enable = eep_config.disc_enable; 14688: asc_dvc->max_host_qng = eep_config.max_host_qng; 14689: asc_dvc->max_dvc_qng = eep_config.max_dvc_qng; 14690: asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID); 14691: asc_dvc->start_motor = eep_config.start_motor; 14692: asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay; 14693: asc_dvc->cfg->bios_boot_wait = eep_config.bios_boot_delay; 14694: asc_dvc->bios_ctrl = eep_config.bios_ctrl; 14695: asc_dvc->no_scam = eep_config.scam_tolerant; 14696: asc_dvc->cfg->serial1 = eep_config.serial_number_word1; 14697: asc_dvc->cfg->serial2 = eep_config.serial_number_word2; 14698: asc_dvc->cfg->serial3 = eep_config.serial_number_word3; 14699: 14700: /* 14701: * Set the host maximum queuing (max. 253, min. 16) and the per device 14702: * maximum queuing (max. 63, min. 4). 14703: */ 14704: if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) 14705: { 14706: eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG; 14707: } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) 14708: { 14709: /* If the value is zero, assume it is uninitialized. */ 14710: if (eep_config.max_host_qng == 0) 14711: { 14712: eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG; 14713: } else 14714: { 14715: eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG; 14716: } 14717: } 14718: 14719: if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) 14720: { 14721: eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG; 14722: } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) 14723: { 14724: /* If the value is zero, assume it is uninitialized. */ 14725: if (eep_config.max_dvc_qng == 0) 14726: { 14727: eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG; 14728: } else 14729: { 14730: eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG; 14731: } 14732: } 14733: 14734: /* 14735: * If 'max_dvc_qng' is greater than 'max_host_qng', then 14736: * set 'max_dvc_qng' to 'max_host_qng'. 14737: */ 14738: if (eep_config.max_dvc_qng > eep_config.max_host_qng) 14739: { 14740: eep_config.max_dvc_qng = eep_config.max_host_qng; 14741: } 14742: 14743: /* 14744: * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_CFG 'max_dvc_qng' 14745: * values based on possibly adjusted EEPROM values. 14746: */ 14747: asc_dvc->max_host_qng = eep_config.max_host_qng; 14748: asc_dvc->max_dvc_qng = eep_config.max_dvc_qng; 14749: 14750: 14751: /* 14752: * If the EEPROM 'termination' field is set to automatic (0), then set 14753: * the ADV_DVC_CFG 'termination' field to automatic also. 14754: * 14755: * If the termination is specified with a non-zero 'termination' 14756: * value check that a legal value is set and set the ADV_DVC_CFG 14757: * 'termination' field appropriately. 14758: */ 14759: if (eep_config.termination == 0) 14760: { 14761: asc_dvc->cfg->termination = 0; /* auto termination */ 14762: } else 14763: { 14764: /* Enable manual control with low off / high off. */ 14765: if (eep_config.termination == 1) 14766: { 14767: asc_dvc->cfg->termination = TERM_CTL_SEL; 14768: 14769: /* Enable manual control with low off / high on. */ 14770: } else if (eep_config.termination == 2) 14771: { 14772: asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H; 14773: 14774: /* Enable manual control with low on / high on. */ 14775: } else if (eep_config.termination == 3) 14776: { 14777: asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L; 14778: } else 14779: { 14780: /* 14781: * The EEPROM 'termination' field contains a bad value. Use 14782: * automatic termination instead. 14783: */ 14784: asc_dvc->cfg->termination = 0; 14785: warn_code |= ASC_WARN_EEPROM_TERMINATION; 14786: } 14787: } 14788: 14789: return warn_code; 14790: } 14791: 14792: /* 14793: * Read EEPROM configuration into the specified buffer. 14794: * 14795: * Return a checksum based on the EEPROM configuration read. 14796: */ 14797: ASC_INITFUNC( 14798: STATIC ushort 14799: AdvGetEEPConfig(AdvPortAddr iop_base, ADVEEP_CONFIG *cfg_buf) 14800: ) 14801: { 14802: ushort wval, chksum; 14803: ushort *wbuf; 14804: int eep_addr; 14805: 14806: wbuf = (ushort *) cfg_buf; 14807: chksum = 0; 14808: 14809: for (eep_addr = ASC_EEP_DVC_CFG_BEGIN; 14810: eep_addr < ASC_EEP_DVC_CFG_END; 14811: eep_addr++, wbuf++) 14812: { 14813: wval = AdvReadEEPWord(iop_base, eep_addr); 14814: chksum += wval; 14815: *wbuf = wval; 14816: } 14817: *wbuf = AdvReadEEPWord(iop_base, eep_addr); 14818: wbuf++; 14819: for (eep_addr = ASC_EEP_DVC_CTL_BEGIN; 14820: eep_addr < ASC_EEP_MAX_WORD_ADDR; 14821: eep_addr++, wbuf++) 14822: { 14823: *wbuf = AdvReadEEPWord(iop_base, eep_addr); 14824: } 14825: return chksum; 14826: } 14827: 14828: /* 14829: * Read the EEPROM from specified location 14830: */ 14831: ASC_INITFUNC( 14832: STATIC ushort 14833: AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr) 14834: ) 14835: { 14836: AdvWriteWordRegister(iop_base, IOPW_EE_CMD, 14837: ASC_EEP_CMD_READ | eep_word_addr); 14838: AdvWaitEEPCmd(iop_base); 14839: return AdvReadWordRegister(iop_base, IOPW_EE_DATA); 14840: } 14841: 14842: /* 14843: * Wait for EEPROM command to complete 14844: */ 14845: ASC_INITFUNC( 14846: STATIC void 14847: AdvWaitEEPCmd(AdvPortAddr iop_base) 14848: ) 14849: { 14850: int eep_delay_ms; 14851: 14852: for (eep_delay_ms = 0; eep_delay_ms < ASC_EEP_DELAY_MS; eep_delay_ms++) 14853: { 14854: if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) 14855: { 14856: break; 14857: } 14858: DvcSleepMilliSecond(1); 14859: } 14860: if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) == 0) 14861: { 14862: ADV_ASSERT(0); 14863: } 14864: return; 14865: } 14866: 14867: /* 14868: * Write the EEPROM from 'cfg_buf'. 14869: */ 14870: ASC_INITFUNC( 14871: STATIC void 14872: AdvSetEEPConfig(AdvPortAddr iop_base, ADVEEP_CONFIG *cfg_buf) 14873: ) 14874: { 14875: ushort *wbuf; 14876: ushort addr, chksum; 14877: 14878: wbuf = (ushort *) cfg_buf; 14879: chksum = 0; 14880: 14881: AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE); 14882: AdvWaitEEPCmd(iop_base); 14883: 14884: /* 14885: * Write EEPROM from word 0 to word 15 14886: */ 14887: for (addr = ASC_EEP_DVC_CFG_BEGIN; 14888: addr < ASC_EEP_DVC_CFG_END; addr++, wbuf++) 14889: { 14890: chksum += *wbuf; 14891: AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf); 14892: AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); 14893: AdvWaitEEPCmd(iop_base); 14894: DvcSleepMilliSecond(ASC_EEP_DELAY_MS); 14895: } 14896: 14897: /* 14898: * Write EEPROM checksum at word 18 14899: */ 14900: AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum); 14901: AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); 14902: AdvWaitEEPCmd(iop_base); 14903: wbuf++; /* skip over check_sum */ 14904: 14905: /* 14906: * Write EEPROM OEM name at words 19 to 26 14907: */ 14908: for (addr = ASC_EEP_DVC_CTL_BEGIN; 14909: addr < ASC_EEP_MAX_WORD_ADDR; addr++, wbuf++) 14910: { 14911: AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf); 14912: AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); 14913: AdvWaitEEPCmd(iop_base); 14914: } 14915: AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE); 14916: AdvWaitEEPCmd(iop_base); 14917: return; 14918: } 14919: 14920: /* 14921: * This function resets the chip and SCSI bus 14922: * 14923: * It is up to the caller to add a delay to let the bus settle after 14924: * calling this function. 14925: * 14926: * The SCSI_CFG0, SCSI_CFG1, and MEM_CFG registers are set-up in 14927: * AdvInitAsc3550Driver(). Here when doing a write to one of these 14928: * registers read first and then write. 14929: * 14930: * Note: A SCSI Bus Reset can not be done until after the EEPROM 14931: * configuration is read to determine whether SCSI Bus Resets 14932: * should be performed. 14933: */ 14934: ASC_INITFUNC( 14935: STATIC void 14936: AdvResetChip(ADV_DVC_VAR *asc_dvc) 14937: ) 14938: { 14939: AdvPortAddr iop_base; 14940: ushort word; 14941: uchar byte; 14942: 14943: iop_base = asc_dvc->iop_base; 14944: 14945: /* 14946: * Reset Chip. 14947: */ 14948: AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET); 14949: DvcSleepMilliSecond(100); 14950: AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_WR_IO_REG); 14951: 14952: /* 14953: * Initialize Chip registers. 14954: * 14955: * Note: Don't remove the use of a temporary variable in the following 14956: * code, otherwise the Microsoft C compiler will turn the following lines 14957: * into a no-op. 14958: */ 14959: byte = AdvReadByteRegister(iop_base, IOPB_MEM_CFG); 14960: byte |= RAM_SZ_8KB; 14961: AdvWriteByteRegister(iop_base, IOPB_MEM_CFG, byte); 14962: 14963: word = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); 14964: word &= ~BIG_ENDIAN; 14965: AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, word); 14966: 14967: /* 14968: * Setting the START_CTL_EMFU 3:2 bits sets a FIFO threshold 14969: * of 128 bytes. This register is only accessible to the host. 14970: */ 14971: AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0, 14972: START_CTL_EMFU | READ_CMD_MRM); 14973: } 14974: 14975: /* a_advlib.c */ 14976: /* 14977: * Description: 14978: * Send a SCSI request to the ASC3550 chip 14979: * 14980: * If there is no SG list for the request, set 'sg_entry_cnt' to 0. 14981: * 14982: * If 'sg_real_addr' is non-zero on entry, AscGetSGList() will not be 14983: * called. It is assumed the caller has already initialized 'sg_real_addr'. 14984: * 14985: * Return: 14986: * ADV_SUCCESS(1) - the request is in the mailbox 14987: * ADV_BUSY(0) - total request count > 253, try later 14988: * ADV_ERROR(-1) - invalid scsi request Q 14989: */ 14990: STATIC int 14991: AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, 14992: ADV_SCSI_REQ_Q *scsiq) 14993: { 14994: if (scsiq == (ADV_SCSI_REQ_Q *) 0L) 14995: { 14996: /* 'scsiq' should never be NULL. */ 14997: ADV_ASSERT(0); 14998: return ADV_ERROR; 14999: } 15000: 15001: return AdvSendScsiCmd(asc_dvc, scsiq); 15002: } 15003: 15004: /* 15005: * Reset SCSI Bus and purge all outstanding requests. 15006: * 15007: * Return Value: 15008: * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset. 15009: * 15010: * Note: Should always return ADV_TRUE. 15011: */ 15012: STATIC int 15013: AdvResetSB(ADV_DVC_VAR *asc_dvc) 15014: { 15015: int status; 15016: 15017: status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET, 0L, 0); 15018: 15019: AdvResetSCSIBus(asc_dvc); 15020: 15021: return status; 15022: } 15023: 15024: /* 15025: * Reset SCSI Bus and delay. 15026: */ 15027: STATIC void 15028: AdvResetSCSIBus(ADV_DVC_VAR *asc_dvc) 15029: { 15030: AdvPortAddr iop_base; 15031: ushort scsi_ctrl; 15032: 15033: iop_base = asc_dvc->iop_base; 15034: 15035: /* 15036: * The microcode currently sets the SCSI Bus Reset signal while 15037: * handling the AscSendIdleCmd() IDLE_CMD_SCSI_RESET command above. 15038: * But the SCSI Bus Reset Hold Time in the microcode is not deterministic 15039: * (it may in fact be for less than the SCSI Spec. minimum of 25 us). 15040: * Therefore on return the Adv Library sets the SCSI Bus Reset signal 15041: * for ASC_SCSI_RESET_HOLD_TIME_US, which is defined to be greater 15042: * than 25 us. 15043: */ 15044: scsi_ctrl = AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL); 15045: AdvWriteWordRegister(iop_base, IOPW_SCSI_CTRL, 15046: scsi_ctrl | ADV_SCSI_CTRL_RSTOUT); 15047: DvcDelayMicroSecond(asc_dvc, (ushort) ASC_SCSI_RESET_HOLD_TIME_US); 15048: AdvWriteWordRegister(iop_base, IOPW_SCSI_CTRL, 15049: scsi_ctrl & ~ADV_SCSI_CTRL_RSTOUT); 15050: 15051: DvcSleepMilliSecond((ulong) asc_dvc->scsi_reset_wait * 1000); 15052: } 15053: 15054: 15055: /* 15056: * Adv Library Interrupt Service Routine 15057: * 15058: * This function is called by a driver's interrupt service routine. 15059: * The function disables and re-enables interrupts. 15060: * 15061: * When a microcode idle command is completed, the ADV_DVC_VAR 15062: * 'idle_cmd_done' field is set to ADV_TRUE. 15063: * 15064: * Note: AdvISR() can be called when interrupts are disabled or even 15065: * when there is no hardware interrupt condition present. It will 15066: * always check for completed idle commands and microcode requests. 15067: * This is an important feature that shouldn't be changed because it 15068: * allows commands to be completed from polling mode loops. 15069: * 15070: * Return: 15071: * ADV_TRUE(1) - interrupt was pending 15072: * ADV_FALSE(0) - no interrupt was pending 15073: */ 15074: STATIC int 15075: AdvISR(ADV_DVC_VAR *asc_dvc) 15076: { 15077: AdvPortAddr iop_base; 15078: uchar int_stat; 15079: ushort next_done_loc, target_bit; 15080: int completed_q; 1.1.1.2 ! root 15081: long flags; 1.1 root 15082: ADV_SCSI_REQ_Q *scsiq; 15083: ASC_REQ_SENSE *sense_data; 15084: int ret; 15085: 15086: flags = DvcEnterCritical(); 15087: iop_base = asc_dvc->iop_base; 15088: 15089: if (AdvIsIntPending(iop_base)) 15090: { 15091: ret = ADV_TRUE; 15092: } else 15093: { 15094: ret = ADV_FALSE; 15095: } 15096: 15097: /* Reading the register clears the interrupt. */ 15098: int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG); 15099: 15100: if (int_stat & ADV_INTR_STATUS_INTRB) 15101: { 15102: asc_dvc->idle_cmd_done = ADV_TRUE; 15103: } 15104: 15105: /* 15106: * Notify the driver of a hardware detected SCSI Bus Reset. 15107: */ 15108: if (int_stat & ADV_INTR_STATUS_INTRC) 15109: { 15110: if (asc_dvc->sbreset_callback != 0) 15111: { 15112: (*(ADV_SBRESET_CALLBACK) asc_dvc->sbreset_callback)(asc_dvc); 15113: } 15114: } 15115: 15116: /* 15117: * ASC_MC_HOST_NEXT_DONE (0x129) is actually the last completed RISC 15118: * Queue List request. Its forward pointer (RQL_FWD) points to the 15119: * current completed RISC Queue List request. 15120: */ 15121: AdvReadByteLram(iop_base, ASC_MC_HOST_NEXT_DONE, next_done_loc); 15122: next_done_loc = ASC_MC_RISC_Q_LIST_BASE + 15123: (next_done_loc * ASC_MC_RISC_Q_LIST_SIZE) + RQL_FWD; 15124: 15125: AdvReadByteLram(iop_base, next_done_loc, completed_q); 15126: 15127: /* Loop until all completed Q's are processed. */ 15128: while (completed_q != ASC_MC_NULL_Q) 15129: { 15130: AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_DONE, completed_q); 15131: 15132: next_done_loc = ASC_MC_RISC_Q_LIST_BASE + 15133: (completed_q * ASC_MC_RISC_Q_LIST_SIZE); 15134: 15135: /* 15136: * Read the ADV_SCSI_REQ_Q virtual address pointer from 15137: * the RISC list entry. The microcode has changed the 15138: * ADV_SCSI_REQ_Q physical address to its virtual address. 15139: * 15140: * Refer to comments at the end of AdvSendScsiCmd() for 15141: * more information on the RISC list structure. 15142: */ 15143: { 15144: ushort lsw, msw; 15145: AdvReadWordLram(iop_base, next_done_loc + RQL_PHYADDR, lsw); 15146: AdvReadWordLram(iop_base, next_done_loc + RQL_PHYADDR + 2, msw); 15147: 15148: scsiq = (ADV_SCSI_REQ_Q *) (((ulong) msw << 16) | lsw); 15149: } 15150: ADV_ASSERT(scsiq != NULL); 15151: 15152: target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id); 15153: 15154: /* 15155: * Clear request microcode control flag. 15156: */ 15157: scsiq->cntl = 0; 15158: 15159: /* 15160: * Check Condition handling 15161: */ 15162: if ((scsiq->done_status == QD_WITH_ERROR) && 15163: (scsiq->scsi_status == SS_CHK_CONDITION) && 15164: (sense_data = (ASC_REQ_SENSE *) scsiq->vsense_addr) != 0 && 15165: (scsiq->orig_sense_len - scsiq->sense_len) >= ASC_MIN_SENSE_LEN) 15166: { 15167: /* 15168: * Command returned with a check condition and valid 15169: * sense data. 15170: */ 15171: } 15172: /* 15173: * If the command that completed was a SCSI INQUIRY and 15174: * LUN 0 was sent the command, then process the INQUIRY 15175: * command information for the device. 15176: */ 15177: else if (scsiq->done_status == QD_NO_ERROR && 15178: scsiq->cdb[0] == SCSICMD_Inquiry && 15179: scsiq->target_lun == 0) 15180: { 15181: AdvInquiryHandling(asc_dvc, scsiq); 15182: } 15183: 15184: 15185: /* Change the RISC Queue List state to free. */ 15186: AdvWriteByteLram(iop_base, next_done_loc + RQL_STATE, ASC_MC_QS_FREE); 15187: 15188: /* Get the RISC Queue List forward pointer. */ 15189: AdvReadByteLram(iop_base, next_done_loc + RQL_FWD, completed_q); 15190: 15191: /* 15192: * Notify the driver of the completed request by passing 15193: * the ADV_SCSI_REQ_Q pointer to its callback function. 15194: */ 15195: ADV_ASSERT(asc_dvc->cur_host_qng > 0); 15196: asc_dvc->cur_host_qng--; 15197: scsiq->a_flag |= ADV_SCSIQ_DONE; 15198: (*(ADV_ISR_CALLBACK) asc_dvc->isr_callback)(asc_dvc, scsiq); 15199: /* 15200: * Note: After the driver callback function is called, 'scsiq' 15201: * can no longer be referenced. 15202: * 15203: * Fall through and continue processing other completed 15204: * requests... 15205: */ 15206: 15207: /* 15208: * Disable interrupts again in case the driver inadvertently 15209: * enabled interrupts in its callback function. 15210: * 15211: * The DvcEnterCritical() return value is ignored, because 15212: * the 'flags' saved when AdvISR() was first entered will be 15213: * used to restore the interrupt flag on exit. 15214: */ 15215: (void) DvcEnterCritical(); 15216: } 15217: DvcLeaveCritical(flags); 15218: return ret; 15219: } 15220: 15221: /* 15222: * Send an idle command to the chip and wait for completion. 15223: * 15224: * Interrupts do not have to be enabled on entry. 15225: * 15226: * Return Values: 15227: * ADV_TRUE - command completed successfully 15228: * ADV_FALSE - command failed 15229: */ 15230: STATIC int 15231: AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc, 15232: ushort idle_cmd, 15233: ulong idle_cmd_parameter, 15234: int flags) 15235: { 15236: int last_int_level; 15237: ulong i; 15238: AdvPortAddr iop_base; 15239: int ret; 15240: 15241: asc_dvc->idle_cmd_done = 0; 15242: 15243: last_int_level = DvcEnterCritical(); 15244: iop_base = asc_dvc->iop_base; 15245: 15246: /* 15247: * Write the idle command value after the idle command parameter 15248: * has been written to avoid a race condition. If the order is not 15249: * followed, the microcode may process the idle command before the 15250: * parameters have been written to LRAM. 15251: */ 15252: AdvWriteDWordLram(iop_base, ASC_MC_IDLE_PARA_STAT, idle_cmd_parameter); 15253: AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd); 15254: DvcLeaveCritical(last_int_level); 15255: 15256: /* 15257: * If the 'flags' argument contains the ADV_NOWAIT flag, then 15258: * return with success. 15259: */ 15260: if (flags & ADV_NOWAIT) 15261: { 15262: return ADV_TRUE; 15263: } 15264: 15265: for (i = 0; i < SCSI_WAIT_10_SEC * SCSI_MS_PER_SEC; i++) 15266: { 15267: /* 15268: * 'idle_cmd_done' is set by AdvISR(). 15269: */ 15270: if (asc_dvc->idle_cmd_done) 15271: { 15272: break; 15273: } 15274: DvcSleepMilliSecond(1); 15275: 15276: /* 15277: * If interrupts were disabled on entry to AdvSendIdleCmd(), 15278: * then they will still be disabled here. Call AdvISR() to 15279: * check for the idle command completion. 15280: */ 15281: (void) AdvISR(asc_dvc); 15282: } 15283: 15284: last_int_level = DvcEnterCritical(); 15285: 15286: if (asc_dvc->idle_cmd_done == ADV_FALSE) 15287: { 15288: ADV_ASSERT(0); /* The idle command should never timeout. */ 15289: return ADV_FALSE; 15290: } else 15291: { 15292: AdvReadWordLram(iop_base, ASC_MC_IDLE_PARA_STAT, ret); 15293: return ret; 15294: } 15295: } 15296: 15297: /* 15298: * Send the SCSI request block to the adapter 15299: * 15300: * Each of the 255 Adv Library/Microcode RISC Lists or mailboxes has the 15301: * following structure: 15302: * 15303: * 0: RQL_FWD - RISC list forward pointer (1 byte) 15304: * 1: RQL_BWD - RISC list backward pointer (1 byte) 15305: * 2: RQL_STATE - RISC list state byte - free, ready, done, aborted (1 byte) 15306: * 3: RQL_TID - request target id (1 byte) 15307: * 4: RQL_PHYADDR - ADV_SCSI_REQ_Q physical pointer (4 bytes) 15308: * 15309: * Return: 15310: * ADV_SUCCESS(1) - the request is in the mailbox 15311: * ADV_BUSY(0) - total request count > 253, try later 15312: */ 15313: STATIC int 15314: AdvSendScsiCmd( 15315: ADV_DVC_VAR *asc_dvc, 15316: ADV_SCSI_REQ_Q *scsiq) 15317: { 15318: ushort next_ready_loc; 15319: uchar next_ready_loc_fwd; 15320: int last_int_level; 15321: AdvPortAddr iop_base; 15322: long req_size; 15323: ulong q_phy_addr; 15324: 15325: /* 15326: * The ADV_SCSI_REQ_Q 'target_id' field should never be equal 15327: * to the host adapter ID or exceed ADV_MAX_TID. 15328: */ 15329: if (scsiq->target_id == asc_dvc->chip_scsi_id || 15330: scsiq->target_id > ADV_MAX_TID) 15331: { 15332: scsiq->host_status = QHSTA_M_INVALID_DEVICE; 15333: scsiq->done_status = QD_WITH_ERROR; 15334: return ADV_ERROR; 15335: } 15336: 15337: iop_base = asc_dvc->iop_base; 15338: 15339: last_int_level = DvcEnterCritical(); 15340: 15341: if (asc_dvc->cur_host_qng >= asc_dvc->max_host_qng) 15342: { 15343: DvcLeaveCritical(last_int_level); 15344: return ADV_BUSY; 15345: } else 15346: { 15347: ADV_ASSERT(asc_dvc->cur_host_qng < ASC_MC_RISC_Q_TOTAL_CNT); 15348: asc_dvc->cur_host_qng++; 15349: } 15350: 15351: /* 15352: * Clear the ADV_SCSI_REQ_Q done flag. 15353: */ 15354: scsiq->a_flag &= ~ADV_SCSIQ_DONE; 15355: 15356: /* 15357: * Save the original sense buffer length. 15358: * 15359: * After the request completes 'sense_len' will be set to the residual 15360: * byte count of the Auto-Request Sense if a command returns CHECK 15361: * CONDITION and the Sense Data is valid indicated by 'host_status' not 15362: * being set to QHSTA_M_AUTO_REQ_SENSE_FAIL. To determine the valid 15363: * Sense Data Length subtract 'sense_len' from 'orig_sense_len'. 15364: */ 15365: scsiq->orig_sense_len = scsiq->sense_len; 15366: 15367: AdvReadByteLram(iop_base, ASC_MC_HOST_NEXT_READY, next_ready_loc); 15368: next_ready_loc = ASC_MC_RISC_Q_LIST_BASE + 15369: (next_ready_loc * ASC_MC_RISC_Q_LIST_SIZE); 15370: 15371: /* 15372: * Write the physical address of the Q to the mailbox. 15373: * We need to skip the first four bytes, because the microcode 15374: * uses them internally for linking Q's together. 15375: */ 15376: req_size = sizeof(ADV_SCSI_REQ_Q); 15377: q_phy_addr = DvcGetPhyAddr(asc_dvc, scsiq, 15378: (uchar *) scsiq, &req_size, 15379: ADV_IS_SCSIQ_FLAG); 15380: ADV_ASSERT(ADV_DWALIGN(q_phy_addr) == q_phy_addr); 15381: ADV_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q)); 15382: 15383: scsiq->scsiq_ptr = (ADV_SCSI_REQ_Q *) scsiq; 15384: 15385: /* 15386: * The RISC list structure, which 'next_ready_loc' is a pointer 15387: * to in microcode LRAM, has the format detailed in the comment 15388: * header for this function. 15389: * 15390: * Write the ADV_SCSI_REQ_Q physical pointer to 'next_ready_loc' request. 15391: */ 15392: AdvWriteDWordLram(iop_base, next_ready_loc + RQL_PHYADDR, q_phy_addr); 15393: 15394: /* Write target_id to 'next_ready_loc' request. */ 15395: AdvWriteByteLram(iop_base, next_ready_loc + RQL_TID, scsiq->target_id); 15396: 15397: /* 15398: * Set the ASC_MC_HOST_NEXT_READY (0x128) microcode variable to 15399: * the 'next_ready_loc' request forward pointer. 15400: * 15401: * Do this *before* changing the 'next_ready_loc' queue to QS_READY. 15402: * After the state is changed to QS_READY 'RQL_FWD' will be changed 15403: * by the microcode. 15404: * 15405: * NOTE: The temporary variable 'next_ready_loc_fwd' is required to 15406: * prevent some compilers from optimizing out 'AdvReadByteLram()' if 15407: * it were used as the 3rd argument to 'AdvWriteByteLram()'. 15408: */ 15409: AdvReadByteLram(iop_base, next_ready_loc + RQL_FWD, next_ready_loc_fwd); 15410: AdvWriteByteLram(iop_base, ASC_MC_HOST_NEXT_READY, next_ready_loc_fwd); 15411: 15412: /* 15413: * Change the state of 'next_ready_loc' request from QS_FREE to 15414: * QS_READY which will cause the microcode to pick it up and 15415: * execute it. 15416: * 15417: * Can't reference 'next_ready_loc' after changing the request 15418: * state to QS_READY. The microcode now owns the request. 15419: */ 15420: AdvWriteByteLram(iop_base, next_ready_loc + RQL_STATE, ASC_MC_QS_READY); 15421: 15422: DvcLeaveCritical(last_int_level); 15423: return ADV_SUCCESS; 15424: } 15425: 15426: /* 15427: * Inquiry Information Byte 7 Handling 15428: * 15429: * Handle SCSI Inquiry Command information for a device by setting 15430: * microcode operating variables that affect WDTR, SDTR, and Tag 15431: * Queuing. 15432: */ 15433: STATIC void 15434: AdvInquiryHandling( 15435: ADV_DVC_VAR *asc_dvc, 15436: ADV_SCSI_REQ_Q *scsiq) 15437: { 15438: AdvPortAddr iop_base; 15439: uchar tid; 15440: ASC_SCSI_INQUIRY *inq; 15441: ushort tidmask; 15442: ushort cfg_word; 15443: 15444: /* 15445: * AdvInquiryHandling() requires up to INQUIRY information Byte 7 15446: * to be available. 15447: * 15448: * If less than 8 bytes of INQUIRY information were requested or less 15449: * than 8 bytes were transferred, then return. cdb[4] is the request 15450: * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the 15451: * microcode to the transfer residual count. 15452: */ 15453: if (scsiq->cdb[4] < 8 || (scsiq->cdb[4] - scsiq->data_cnt) < 8) 15454: { 15455: return; 15456: } 15457: 15458: iop_base = asc_dvc->iop_base; 15459: tid = scsiq->target_id; 15460: inq = (ASC_SCSI_INQUIRY *) scsiq->vdata_addr; 15461: 15462: /* 15463: * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices. 15464: */ 15465: if (inq->byte3.rsp_data_fmt < 2 && inq->byte2.ansi_apr_ver < 2) 15466: { 15467: return; 15468: } else 15469: { 15470: /* 15471: * INQUIRY Byte 7 Handling 15472: * 15473: * Use a device's INQUIRY byte 7 to determine whether it 15474: * supports WDTR, SDTR, and Tag Queuing. If the feature 15475: * is enabled in the EEPROM and the device supports the 15476: * feature, then enable it in the microcode. 15477: */ 15478: 15479: tidmask = ADV_TID_TO_TIDMASK(tid); 15480: 15481: /* 15482: * Wide Transfers 15483: * 15484: * If the EEPROM enabled WDTR for the device and the device 15485: * supports wide bus (16 bit) transfers, then turn on the 15486: * device's 'wdtr_able' bit and write the new value to the 15487: * microcode. 15488: */ 15489: if ((asc_dvc->wdtr_able & tidmask) && inq->byte7.WBus16) 15490: { 15491: AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word); 15492: if ((cfg_word & tidmask) == 0) 15493: { 15494: cfg_word |= tidmask; 15495: AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word); 15496: 15497: /* 15498: * Clear the microcode "WDTR negotiation" done indicator 15499: * for the target to cause it to negotiate with the new 15500: * setting set above. 15501: */ 15502: AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word); 15503: cfg_word &= ~tidmask; 15504: AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word); 15505: } 15506: } 15507: 15508: /* 15509: * Synchronous Transfers 15510: * 15511: * If the EEPROM enabled SDTR for the device and the device 15512: * supports synchronous transfers, then turn on the device's 15513: * 'sdtr_able' bit. Write the new value to the microcode. 15514: */ 15515: if ((asc_dvc->sdtr_able & tidmask) && inq->byte7.Sync) 15516: { 15517: AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word); 15518: if ((cfg_word & tidmask) == 0) 15519: { 15520: cfg_word |= tidmask; 15521: AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word); 15522: 15523: /* 15524: * Clear the microcode "SDTR negotiation" done indicator 15525: * for the target to cause it to negotiate with the new 15526: * setting set above. 15527: */ 15528: AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word); 15529: cfg_word &= ~tidmask; 15530: AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word); 15531: } 15532: } 15533: 15534: /* 15535: * If the EEPROM enabled Tag Queuing for device and the 15536: * device supports Tag Queuing, then turn on the device's 15537: * 'tagqng_enable' bit in the microcode and set the microcode 15538: * maximum command count to the ADV_DVC_VAR 'max_dvc_qng' 15539: * value. 15540: * 15541: * Tag Queuing is disabled for the BIOS which runs in polled 15542: * mode and would see no benefit from Tag Queuing. Also by 15543: * disabling Tag Queuing in the BIOS devices with Tag Queuing 15544: * bugs will at least work with the BIOS. 15545: */ 15546: if ((asc_dvc->tagqng_able & tidmask) && inq->byte7.CmdQue) 15547: { 15548: AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word); 15549: cfg_word |= tidmask; 15550: AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word); 15551: AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, 15552: asc_dvc->max_dvc_qng); 15553: } 15554: } 15555: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.