linux-bk/drivers/scsi/advansys.c
<<
>>
Prefs
   1#define ASC_VERSION "3.3GJ"    /* AdvanSys Driver Version */
   2
   3/*
   4 * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
   5 *
   6 * Copyright (c) 1995-2000 Advanced System Products, Inc.
   7 * Copyright (c) 2000-2001 ConnectCom Solutions, 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 * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
  16 * changed its name to ConnectCom Solutions, Inc.
  17 *
  18 * There is an AdvanSys Linux WWW page at:
  19 *  http://www.connectcom.net/downloads/software/os/linux.html
  20 *  http://www.advansys.com/linux.html
  21 *
  22 * The latest released version of the AdvanSys driver is available at:
  23 *  ftp://ftp.advansys.com/pub/linux/linux.tgz
  24 *  ftp://ftp.connectcom.net/pub/linux/linux.tgz
  25 *
  26 * Please send questions, comments, bug reports to:
  27 *  support@connectcom.net
  28 */
  29
  30/*
  31
  32  Documentation for the AdvanSys Driver
  33
  34  A. Linux Kernels Supported by this Driver
  35  B. Adapters Supported by this Driver
  36  C. Linux source files modified by AdvanSys Driver
  37  D. Source Comments
  38  E. Driver Compile Time Options and Debugging
  39  F. Driver LILO Option
  40  G. Tests to run before releasing new driver
  41  H. Release History
  42  I. Known Problems/Fix List
  43  J. Credits (Chronological Order)
  44  K. ConnectCom (AdvanSys) Contact Information
  45
  46  A. Linux Kernels Supported by this Driver
  47
  48     This driver has been tested in the following Linux kernels: v2.2.18
  49     v2.4.0. The driver is supported on v2.2 and v2.4 kernels and on x86,
  50     alpha, and PowerPC platforms.
  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     Laptop Products:
  68        ABP-480 - Bus-Master CardBus (16 CDB) (2.4 kernel and greater)
  69
  70     Connectivity Products:
  71        ABP510/5150 - Bus-Master ISA (240 CDB)
  72        ABP5140 - Bus-Master ISA PnP (16 CDB)
  73        ABP5142 - Bus-Master ISA PnP with floppy (16 CDB)
  74        ABP902/3902 - Bus-Master PCI (16 CDB)
  75        ABP3905 - Bus-Master PCI (16 CDB)
  76        ABP915 - Bus-Master PCI (16 CDB)
  77        ABP920 - Bus-Master PCI (16 CDB)
  78        ABP3922 - Bus-Master PCI (16 CDB)
  79        ABP3925 - Bus-Master PCI (16 CDB)
  80        ABP930 - Bus-Master PCI (16 CDB)
  81        ABP930U - Bus-Master PCI Ultra (16 CDB)
  82        ABP930UA - Bus-Master PCI Ultra (16 CDB)
  83        ABP960 - Bus-Master PCI MAC/PC (16 CDB)
  84        ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB)
  85
  86     Single Channel Products:
  87        ABP542 - Bus-Master ISA with floppy (240 CDB)
  88        ABP742 - Bus-Master EISA (240 CDB)
  89        ABP842 - Bus-Master VL (240 CDB)
  90        ABP940 - Bus-Master PCI (240 CDB)
  91        ABP940U - Bus-Master PCI Ultra (240 CDB)
  92        ABP940UA/3940UA - Bus-Master PCI Ultra (240 CDB)
  93        ABP970 - Bus-Master PCI MAC/PC (240 CDB)
  94        ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB)
  95        ABP3960UA - Bus-Master PCI MAC/PC Ultra (240 CDB)
  96        ABP940UW/3940UW - Bus-Master PCI Ultra-Wide (253 CDB)
  97        ABP970UW - Bus-Master PCI MAC/PC Ultra-Wide (253 CDB)
  98        ABP3940U2W - Bus-Master PCI LVD/Ultra2-Wide (253 CDB)
  99
 100     Multi-Channel Products:
 101        ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel)
 102        ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel)
 103        ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel)
 104        ABP950UW - Dual Channel Bus-Master PCI Ultra-Wide (253 CDB Per Channel)
 105        ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel)
 106        ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel)
 107        ABP980UA/3980UA - Four Channel Bus-Master PCI Ultra (16 CDB Per Chan.)
 108        ABP3950U2W - Bus-Master PCI LVD/Ultra2-Wide and Ultra-Wide (253 CDB)
 109        ABP3950U3W - Bus-Master PCI Dual LVD2/Ultra3-Wide (253 CDB)
 110
 111  C. Linux source files modified by AdvanSys Driver
 112
 113     This section for historical purposes documents the changes
 114     originally made to the Linux kernel source to add the advansys
 115     driver. As Linux has changed some of these files have also
 116     been modified.
 117
 118     1. linux/arch/i386/config.in:
 119
 120          bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y
 121
 122     2. linux/drivers/scsi/hosts.c:
 123
 124          #ifdef CONFIG_SCSI_ADVANSYS
 125          #include "advansys.h"
 126          #endif
 127
 128        and after "static Scsi_Host_Template builtin_scsi_hosts[] =":
 129
 130          #ifdef CONFIG_SCSI_ADVANSYS
 131          ADVANSYS,
 132          #endif
 133
 134     3. linux/drivers/scsi/Makefile:
 135
 136          ifdef CONFIG_SCSI_ADVANSYS
 137          SCSI_SRCS := $(SCSI_SRCS) advansys.c
 138          SCSI_OBJS := $(SCSI_OBJS) advansys.o
 139          else
 140          SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o
 141          endif
 142
 143     4. linux/init/main.c:
 144
 145          extern void advansys_setup(char *str, int *ints);
 146
 147        and add the following lines to the bootsetups[] array.
 148
 149          #ifdef CONFIG_SCSI_ADVANSYS
 150             { "advansys=", advansys_setup },
 151          #endif
 152
 153  D. Source Comments
 154
 155     1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'.
 156
 157     2. This driver should be maintained in multiple files. But to make
 158        it easier to include with Linux and to follow Linux conventions,
 159        the whole driver is maintained in the source files advansys.h and
 160        advansys.c. In this file logical sections of the driver begin with
 161        a comment that contains '---'. The following are the logical sections
 162        of the driver below.
 163
 164           --- Linux Version
 165           --- Linux Include File
 166           --- Driver Options
 167           --- Debugging Header
 168           --- Asc Library Constants and Macros
 169           --- Adv Library Constants and Macros
 170           --- Driver Constants and Macros
 171           --- Driver Structures
 172           --- Driver Data
 173           --- Driver Function Prototypes
 174           --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
 175           --- Loadable Driver Support
 176           --- Miscellaneous Driver Functions
 177           --- Functions Required by the Asc Library
 178           --- Functions Required by the Adv Library
 179           --- Tracing and Debugging Functions
 180           --- Asc Library Functions
 181           --- Adv Library Functions
 182
 183     3. The string 'XXX' is used to flag code that needs to be re-written
 184        or that contains a problem that needs to be addressed.
 185
 186     4. I have stripped comments from and reformatted the source for the
 187        Asc Library and Adv Library to reduce the size of this file. This
 188        source can be found under the following headings. The Asc Library
 189        is used to support Narrow Boards. The Adv Library is used to
 190        support Wide Boards.
 191
 192           --- Asc Library Constants and Macros
 193           --- Adv Library Constants and Macros
 194           --- Asc Library Functions
 195           --- Adv Library Functions
 196
 197  E. Driver Compile Time Options and Debugging
 198
 199     In this source file the following constants can be defined. They are
 200     defined in the source below. Both of these options are enabled by
 201     default.
 202
 203     1. ADVANSYS_ASSERT - Enable driver assertions (Def: Enabled)
 204
 205        Enabling this option adds assertion logic statements to the
 206        driver. If an assertion fails a message will be displayed to
 207        the console, but the system will continue to operate. Any
 208        assertions encountered should be reported to the person
 209        responsible for the driver. Assertion statements may proactively
 210        detect problems with the driver and facilitate fixing these
 211        problems. Enabling assertions will add a small overhead to the
 212        execution of the driver.
 213
 214     2. ADVANSYS_DEBUG - Enable driver debugging (Def: Disabled)
 215
 216        Enabling this option adds tracing functions to the driver and
 217        the ability to set a driver tracing level at boot time. This
 218        option will also export symbols not required outside the driver to
 219        the kernel name space. This option is very useful for debugging
 220        the driver, but it will add to the size of the driver execution
 221        image and add overhead to the execution of the driver.
 222
 223        The amount of debugging output can be controlled with the global
 224        variable 'asc_dbglvl'. The higher the number the more output. By
 225        default the debug level is 0.
 226
 227        If the driver is loaded at boot time and the LILO Driver Option
 228        is included in the system, the debug level can be changed by
 229        specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The
 230        first three hex digits of the pseudo I/O Port must be set to
 231        'deb' and the fourth hex digit specifies the debug level: 0 - F.
 232        The following command line will look for an adapter at 0x330
 233        and set the debug level to 2.
 234
 235           linux advansys=0x330,0,0,0,0xdeb2
 236
 237        If the driver is built as a loadable module this variable can be
 238        defined when the driver is loaded. The following insmod command
 239        will set the debug level to one.
 240
 241           insmod advansys.o asc_dbglvl=1
 242
 243        Debugging Message Levels:
 244           0: Errors Only
 245           1: High-Level Tracing
 246           2-N: Verbose Tracing
 247
 248        To enable debug output to console, please make sure that:
 249
 250        a. System and kernel logging is enabled (syslogd, klogd running).
 251        b. Kernel messages are routed to console output. Check
 252           /etc/syslog.conf for an entry similar to this:
 253
 254                kern.*                  /dev/console
 255
 256        c. klogd is started with the appropriate -c parameter
 257           (e.g. klogd -c 8)
 258
 259        This will cause printk() messages to be be displayed on the
 260        current console. Refer to the klogd(8) and syslogd(8) man pages
 261        for details.
 262
 263        Alternatively you can enable printk() to console with this
 264        program. However, this is not the 'official' way to do this.
 265        Debug output is logged in /var/log/messages.
 266
 267          main()
 268          {
 269                  syscall(103, 7, 0, 0);
 270          }
 271
 272        Increasing LOG_BUF_LEN in kernel/printk.c to something like
 273        40960 allows more debug messages to be buffered in the kernel
 274        and written to the console or log file.
 275
 276     3. ADVANSYS_STATS - Enable statistics (Def: Enabled >= v1.3.0)
 277
 278        Enabling this option adds statistics collection and display
 279        through /proc to the driver. The information is useful for
 280        monitoring driver and device performance. It will add to the
 281        size of the driver execution image and add minor overhead to
 282        the execution of the driver.
 283
 284        Statistics are maintained on a per adapter basis. Driver entry
 285        point call counts and transfer size counts are maintained.
 286        Statistics are only available for kernels greater than or equal
 287        to v1.3.0 with the CONFIG_PROC_FS (/proc) file system configured.
 288
 289        AdvanSys SCSI adapter files have the following path name format:
 290
 291           /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
 292
 293        This information can be displayed with cat. For example:
 294
 295           cat /proc/scsi/advansys/0
 296
 297        When ADVANSYS_STATS is not defined the AdvanSys /proc files only
 298        contain adapter and device configuration information.
 299
 300  F. Driver LILO Option
 301
 302     If init/main.c is modified as described in the 'Directions for Adding
 303     the AdvanSys Driver to Linux' section (B.4.) above, the driver will
 304     recognize the 'advansys' LILO command line and /etc/lilo.conf option.
 305     This option can be used to either disable I/O port scanning or to limit
 306     scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and
 307     PCI boards will still be searched for and detected. This option only
 308     affects searching for ISA and VL boards.
 309
 310     Examples:
 311       1. Eliminate I/O port scanning:
 312            boot: linux advansys=
 313              or
 314            boot: linux advansys=0x0
 315       2. Limit I/O port scanning to one I/O port:
 316            boot: linux advansys=0x110
 317       3. Limit I/O port scanning to four I/O ports:
 318            boot: linux advansys=0x110,0x210,0x230,0x330
 319
 320     For a loadable module the same effect can be achieved by setting
 321     the 'asc_iopflag' variable and 'asc_ioport' array when loading
 322     the driver, e.g.
 323
 324           insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330
 325
 326     If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_IOPORT_PROBE + 1)
 327     I/O Port may be added to specify the driver debug level. Refer to
 328     the 'Driver Compile Time Options and Debugging' section above for
 329     more information.
 330
 331  G. Tests to run before releasing new driver
 332
 333     1. In the supported kernels verify there are no warning or compile
 334        errors when the kernel is built as both a driver and as a module
 335        and with the following options:
 336
 337        ADVANSYS_DEBUG - enabled and disabled
 338        CONFIG_SMP - enabled and disabled
 339        CONFIG_PROC_FS - enabled and disabled
 340
 341     2. Run tests on an x86, alpha, and PowerPC with at least one narrow
 342        card and one wide card attached to a hard disk and CD-ROM drive:
 343        fdisk, mkfs, fsck, bonnie, copy/compare test from the
 344        CD-ROM to the hard drive.
 345
 346  H. Release History
 347
 348     BETA-1.0 (12/23/95):
 349         First Release
 350
 351     BETA-1.1 (12/28/95):
 352         1. Prevent advansys_detect() from being called twice.
 353         2. Add LILO 0xdeb[0-f] option to set 'asc_dbglvl'.
 354
 355     1.2 (1/12/96):
 356         1. Prevent re-entrancy in the interrupt handler which
 357            resulted in the driver hanging Linux.
 358         2. Fix problem that prevented ABP-940 cards from being
 359            recognized on some PCI motherboards.
 360         3. Add support for the ABP-5140 PnP ISA card.
 361         4. Fix check condition return status.
 362         5. Add conditionally compiled code for Linux v1.3.X.
 363
 364     1.3 (2/23/96):
 365         1. Fix problem in advansys_biosparam() that resulted in the
 366            wrong drive geometry being returned for drives > 1GB with
 367            extended translation enabled.
 368         2. Add additional tracing during device initialization.
 369         3. Change code that only applies to ISA PnP adapter.
 370         4. Eliminate 'make dep' warning.
 371         5. Try to fix problem with handling resets by increasing their
 372            timeout value.
 373
 374     1.4 (5/8/96):
 375         1. Change definitions to eliminate conflicts with other subsystems.
 376         2. Add versioning code for the shared interrupt changes.
 377         3. Eliminate problem in asc_rmqueue() with iterating after removing
 378            a request.
 379         4. Remove reset request loop problem from the "Known Problems or
 380            Issues" section. This problem was isolated and fixed in the
 381            mid-level SCSI driver.
 382
 383     1.5 (8/8/96):
 384         1. Add support for ABP-940U (PCI Ultra) adapter.
 385         2. Add support for IRQ sharing by setting the SA_SHIRQ flag for
 386            request_irq and supplying a dev_id pointer to both request_irq()
 387            and free_irq().
 388         3. In AscSearchIOPortAddr11() restore a call to check_region() which
 389            should be used before I/O port probing.
 390         4. Fix bug in asc_prt_hex() which resulted in the displaying
 391            the wrong data.
 392         5. Incorporate miscellaneous Asc Library bug fixes and new microcode.
 393         6. Change driver versioning to be specific to each Linux sub-level.
 394         7. Change statistics gathering to be per adapter instead of global
 395            to the driver.
 396         8. Add more information and statistics to the adapter /proc file:
 397            /proc/scsi/advansys[0...].
 398         9. Remove 'cmd_per_lun' from the "Known Problems or Issues" list.
 399            This problem has been addressed with the SCSI mid-level changes
 400            made in v1.3.89. The advansys_select_queue_depths() function
 401            was added for the v1.3.89 changes.
 402
 403     1.6 (9/10/96):
 404         1. Incorporate miscellaneous Asc Library bug fixes and new microcode.
 405
 406     1.7 (9/25/96):
 407         1. Enable clustering and optimize the setting of the maximum number
 408            of scatter gather elements for any particular board. Clustering
 409            increases CPU utilization, but results in a relatively larger
 410            increase in I/O throughput.
 411         2. Improve the performance of the request queuing functions by
 412            adding a last pointer to the queue structure.
 413         3. Correct problems with reset and abort request handling that
 414            could have hung or crashed Linux.
 415         4. Add more information to the adapter /proc file:
 416            /proc/scsi/advansys[0...].
 417         5. Remove the request timeout issue form the driver issues list.
 418         6. Miscellaneous documentation additions and changes.
 419
 420     1.8 (10/4/96):
 421         1. Make changes to handle the new v2.1.0 kernel memory mapping
 422            in which a kernel virtual address may not be equivalent to its
 423            bus or DMA memory address.
 424         2. Change abort and reset request handling to make it yet even
 425            more robust.
 426         3. Try to mitigate request starvation by sending ordered requests
 427            to heavily loaded, tag queuing enabled devices.
 428         4. Maintain statistics on request response time.
 429         5. Add request response time statistics and other information to
 430            the adapter /proc file: /proc/scsi/advansys[0...].
 431
 432     1.9 (10/21/96):
 433         1. Add conditionally compiled code (ASC_QUEUE_FLOW_CONTROL) to
 434            make use of mid-level SCSI driver device queue depth flow
 435            control mechanism. This will eliminate aborts caused by a
 436            device being unable to keep up with requests and eliminate
 437            repeat busy or QUEUE FULL status returned by a device.
 438         2. Incorporate miscellaneous Asc Library bug fixes.
 439         3. To allow the driver to work in kernels with broken module
 440            support set 'cmd_per_lun' if the driver is compiled as a
 441            module. This change affects kernels v1.3.89 to present.
 442         4. Remove PCI BIOS address from the driver banner. The PCI BIOS
 443            is relocated by the motherboard BIOS and its new address can
 444            not be determined by the driver.
 445         5. Add mid-level SCSI queue depth information to the adapter
 446            /proc file: /proc/scsi/advansys[0...].
 447
 448     2.0 (11/14/96):
 449         1. Change allocation of global structures used for device
 450            initialization to guarantee they are in DMA-able memory.
 451            Previously when the driver was loaded as a module these
 452            structures might not have been in DMA-able memory, causing
 453            device initialization to fail.
 454
 455     2.1 (12/30/96):
 456         1. In advansys_reset(), if the request is a synchronous reset
 457            request, even if the request serial number has changed, then
 458            complete the request.
 459         2. Add Asc Library bug fixes including new microcode.
 460         3. Clear inquiry buffer before using it.
 461         4. Correct ifdef typo.
 462
 463     2.2 (1/15/97):
 464         1. Add Asc Library bug fixes including new microcode.
 465         2. Add synchronous data transfer rate information to the
 466            adapter /proc file: /proc/scsi/advansys[0...].
 467         3. Change ADVANSYS_DEBUG to be disabled by default. This
 468            will reduce the size of the driver image, eliminate execution
 469            overhead, and remove unneeded symbols from the kernel symbol
 470            space that were previously added by the driver.
 471         4. Add new compile-time option ADVANSYS_ASSERT for assertion
 472            code that used to be defined within ADVANSYS_DEBUG. This
 473            option is enabled by default.
 474
 475     2.8 (5/26/97):
 476         1. Change version number to 2.8 to synchronize the Linux driver
 477            version numbering with other AdvanSys drivers.
 478         2. Reformat source files without tabs to present the same view
 479            of the file to everyone regardless of the editor tab setting
 480            being used.
 481         3. Add Asc Library bug fixes.
 482
 483     3.1A (1/8/98):
 484         1. Change version number to 3.1 to indicate that support for
 485            Ultra-Wide adapters (ABP-940UW) is included in this release.
 486         2. Add Asc Library (Narrow Board) bug fixes.
 487         3. Report an underrun condition with the host status byte set
 488            to DID_UNDERRUN. Currently DID_UNDERRUN is defined to 0 which
 489            causes the underrun condition to be ignored. When Linux defines
 490            its own DID_UNDERRUN the constant defined in this file can be
 491            removed.
 492         4. Add patch to AscWaitTixISRDone().
 493         5. Add support for up to 16 different AdvanSys host adapter SCSI
 494            channels in one system. This allows four cards with four channels
 495            to be used in one system.
 496
 497     3.1B (1/9/98):
 498         1. Handle that PCI register base addresses are not always page
 499            aligned even though ioremap() requires that the address argument
 500            be page aligned.
 501
 502     3.1C (1/10/98):
 503         1. Update latest BIOS version checked for from the /proc file.
 504         2. Don't set microcode SDTR variable at initialization. Instead
 505            wait until device capabilities have been detected from an Inquiry
 506            command.
 507
 508     3.1D (1/21/98):
 509         1. Improve performance when the driver is compiled as module by
 510            allowing up to 64 scatter-gather elements instead of 8.
 511
 512     3.1E (5/1/98):
 513         1. Set time delay in AscWaitTixISRDone() to 1000 ms.
 514         2. Include SMP locking changes.
 515         3. For v2.1.93 and newer kernels use CONFIG_PCI and new PCI BIOS
 516            access functions.
 517         4. Update board serial number printing.
 518         5. Try allocating an IRQ both with and without the SA_INTERRUPT
 519            flag set to allow IRQ sharing with drivers that do not set
 520            the SA_INTERRUPT flag. Also display a more descriptive error
 521            message if request_irq() fails.
 522         6. Update to latest Asc and Adv Libraries.
 523
 524     3.2A (7/22/99):
 525         1. Update Adv Library to 4.16 which includes support for
 526            the ASC38C0800 (Ultra2/LVD) IC.
 527
 528     3.2B (8/23/99):
 529         1. Correct PCI compile time option for v2.1.93 and greater
 530            kernels, advansys_info() string, and debug compile time
 531            option.
 532         2. Correct DvcSleepMilliSecond() for v2.1.0 and greater
 533            kernels. This caused an LVD detection/BIST problem problem
 534            among other things.
 535         3. Sort PCI cards by PCI Bus, Slot, Function ascending order
 536            to be consistent with the BIOS.
 537         4. Update to Asc Library S121 and Adv Library 5.2.
 538
 539     3.2C (8/24/99):
 540         1. Correct PCI card detection bug introduced in 3.2B that
 541            prevented PCI cards from being detected in kernels older
 542            than v2.1.93.
 543
 544     3.2D (8/26/99):
 545         1. Correct /proc device synchronous speed information display.
 546            Also when re-negotiation is pending for a target device
 547            note this condition with an * and footnote.
 548         2. Correct initialization problem with Ultra-Wide cards that
 549            have a pre-3.2 BIOS. A microcode variable changed locations
 550            in 3.2 and greater BIOSes which caused WDTR to be attempted
 551            erroneously with drives that don't support WDTR.
 552
 553     3.2E (8/30/99):
 554         1. Fix compile error caused by v2.3.13 PCI structure change.
 555         2. Remove field from ASCEEP_CONFIG that resulted in an EEPROM
 556            checksum error for ISA cards.
 557         3. Remove ASC_QUEUE_FLOW_CONTROL conditional code. The mid-level
 558            SCSI changes that it depended on were never included in Linux.
 559
 560     3.2F (9/3/99):
 561         1. Handle new initial function code added in v2.3.16 for all
 562            driver versions.
 563
 564     3.2G (9/8/99):
 565         1. Fix PCI board detection in v2.3.13 and greater kernels.
 566         2. Fix comiple errors in v2.3.X with debugging enabled.
 567
 568     3.2H (9/13/99):
 569         1. Add 64-bit address, long support for Alpha and UltraSPARC.
 570            The driver has been verified to work on an Alpha system.
 571         2. Add partial byte order handling support for Power PC and
 572            other big-endian platforms. This support has not yet been
 573            completed or verified.
 574         3. For wide boards replace block zeroing of request and
 575            scatter-gather structures with individual field initialization
 576            to improve performance.
 577         4. Correct and clarify ROM BIOS version detection.
 578
 579     3.2I (10/8/99):
 580         1. Update to Adv Library 5.4.
 581         2. Add v2.3.19 underrun reporting to asc_isr_callback() and
 582            adv_isr_callback().  Remove DID_UNDERRUN constant and other
 583            no longer needed code that previously documented the lack
 584            of underrun handling.
 585
 586     3.2J (10/14/99):
 587         1. Eliminate compile errors for v2.0 and earlier kernels.
 588
 589     3.2K (11/15/99):
 590         1. Correct debug compile error in asc_prt_adv_scsi_req_q().
 591         2. Update Adv Library to 5.5.
 592         3. Add ifdef handling for /proc changes added in v2.3.28.
 593         4. Increase Wide board scatter-gather list maximum length to
 594            255 when the driver is compiled into the kernel.
 595
 596     3.2L (11/18/99):
 597         1. Fix bug in adv_get_sglist() that caused an assertion failure
 598            at line 7475. The reqp->sgblkp pointer must be initialized
 599            to NULL in adv_get_sglist().
 600
 601     3.2M (11/29/99):
 602         1. Really fix bug in adv_get_sglist().
 603         2. Incorporate v2.3.29 changes into driver.
 604
 605     3.2N (4/1/00):
 606         1. Add CONFIG_ISA ifdef code.
 607         2. Include advansys_interrupts_enabled name change patch.
 608         3. For >= v2.3.28 use new SCSI error handling with new function
 609            advansys_eh_bus_reset(). Don't include an abort function
 610            because of base library limitations.
 611         4. For >= v2.3.28 use per board lock instead of io_request_lock.
 612         5. For >= v2.3.28 eliminate advansys_command() and
 613            advansys_command_done().
 614         6. Add some changes for PowerPC (Big Endian) support, but it isn't
 615            working yet.
 616         7. Fix "nonexistent resource free" problem that occurred on a module
 617            unload for boards with an I/O space >= 255. The 'n_io_port' field
 618            is only one byte and can not be used to hold an ioport length more
 619            than 255.
 620
 621     3.3A (4/4/00):
 622         1. Update to Adv Library 5.8.
 623         2. For wide cards add support for CDBs up to 16 bytes.
 624         3. Eliminate warnings when CONFIG_PROC_FS is not defined.
 625
 626     3.3B (5/1/00):
 627         1. Support for PowerPC (Big Endian) wide cards. Narrow cards
 628            still need work.
 629         2. Change bitfields to shift and mask access for endian
 630            portability.
 631
 632     3.3C (10/13/00):
 633         1. Update for latest 2.4 kernel.
 634         2. Test ABP-480 CardBus support in 2.4 kernel - works!
 635         3. Update to Asc Library S123.
 636         4. Update to Adv Library 5.12.
 637
 638     3.3D (11/22/00):
 639         1. Update for latest 2.4 kernel.
 640         2. Create patches for 2.2 and 2.4 kernels.
 641
 642     3.3E (1/9/01):
 643         1. Now that 2.4 is released remove ifdef code for kernel versions
 644            less than 2.2. The driver is now only supported in kernels 2.2,
 645            2.4, and greater.
 646         2. Add code to release and acquire the io_request_lock in
 647            the driver entrypoint functions: advansys_detect and
 648            advansys_queuecommand. In kernel 2.4 the SCSI mid-level driver
 649            still holds the io_request_lock on entry to SCSI low-level drivers.
 650            This was supposed to be removed before 2.4 was released but never
 651            happened. When the mid-level SCSI driver is changed all references
 652            to the io_request_lock should be removed from the driver.
 653         3. Simplify error handling by removing advansys_abort(),
 654            AscAbortSRB(), AscResetDevice(). SCSI bus reset requests are
 655            now handled by resetting the SCSI bus and fully re-initializing
 656            the chip. This simple method of error recovery has proven to work
 657            most reliably after attempts at different methods. Also now only
 658            support the "new" error handling method and remove the obsolete
 659            error handling interface.
 660         4. Fix debug build errors.
 661
 662     3.3F (1/24/01):
 663         1. Merge with ConnectCom version from Andy Kellner which
 664            updates Adv Library to 5.14.
 665         2. Make PowerPC (Big Endian) work for narrow cards and
 666            fix problems writing EEPROM for wide cards.
 667         3. Remove interrupts_enabled assertion function.
 668
 669     3.3G (2/16/01):
 670         1. Return an error from narrow boards if passed a 16 byte
 671            CDB. The wide board can already handle 16 byte CDBs.
 672
 673     3.3GJ (4/15/02):
 674         1. hacks for lk 2.5 series (D. Gilbert)
 675
 676     3.3GJD (10/14/02):
 677         1. change select_queue_depths to slave_configure
 678         2. make cmd_per_lun be sane again
 679
 680  I. Known Problems/Fix List (XXX)
 681
 682     1. Need to add memory mapping workaround. Test the memory mapping.
 683        If it doesn't work revert to I/O port access. Can a test be done
 684        safely?
 685     2. Handle an interrupt not working. Keep an interrupt counter in
 686        the interrupt handler. In the timeout function if the interrupt
 687        has not occurred then print a message and run in polled mode.
 688     3. Allow bus type scanning order to be changed.
 689     4. Need to add support for target mode commands, cf. CAM XPT.
 690
 691  J. Credits (Chronological Order)
 692
 693     Bob Frey <bfrey@turbolinux.com.cn> wrote the AdvanSys SCSI driver
 694     and maintained it up to 3.3F. He continues to answer questions
 695     and help maintain the driver.
 696
 697     Nathan Hartwell <mage@cdc3.cdc.net> provided the directions and
 698     basis for the Linux v1.3.X changes which were included in the
 699     1.2 release.
 700
 701     Thomas E Zerucha <zerucha@shell.portal.com> pointed out a bug
 702     in advansys_biosparam() which was fixed in the 1.3 release.
 703
 704     Erik Ratcliffe <erik@caldera.com> has done testing of the
 705     AdvanSys driver in the Caldera releases.
 706
 707     Rik van Riel <H.H.vanRiel@fys.ruu.nl> provided a patch to
 708     AscWaitTixISRDone() which he found necessary to make the
 709     driver work with a SCSI-1 disk.
 710
 711     Mark Moran <mmoran@mmoran.com> has helped test Ultra-Wide
 712     support in the 3.1A driver.
 713
 714     Doug Gilbert <dgilbert@interlog.com> has made changes and
 715     suggestions to improve the driver and done a lot of testing.
 716
 717     Ken Mort <ken@mort.net> reported a DEBUG compile bug fixed
 718     in 3.2K.
 719
 720     Tom Rini <trini@kernel.crashing.org> provided the CONFIG_ISA
 721     patch and helped with PowerPC wide and narrow board support.
 722
 723     Philip Blundell <philip.blundell@pobox.com> provided an
 724     advansys_interrupts_enabled patch.
 725
 726     Dave Jones <dave@denial.force9.co.uk> reported the compiler
 727     warnings generated when CONFIG_PROC_FS was not defined in
 728     the 3.2M driver.
 729
 730     Jerry Quinn <jlquinn@us.ibm.com> fixed PowerPC support (endian
 731     problems) for wide cards.
 732
 733     Bryan Henderson <bryanh@giraffe-data.com> helped debug narrow
 734     card error handling.
 735
 736     Manuel Veloso <veloso@pobox.com> worked hard on PowerPC narrow
 737     board support and fixed a bug in AscGetEEPConfig().
 738
 739     Arnaldo Carvalho de Melo <acme@conectiva.com.br> made
 740     save_flags/restore_flags changes.
 741
 742     Andy Kellner <AKellner@connectcom.net> continues the Advansys SCSI
 743     driver development for ConnectCom (Version > 3.3F).
 744
 745  K. ConnectCom (AdvanSys) Contact Information
 746
 747     Mail:                   ConnectCom Solutions, Inc.
 748                             1150 Ringwood Court
 749                             San Jose, CA 95131
 750     Operator/Sales:         1-408-383-9400
 751     FAX:                    1-408-383-9612
 752     Tech Support:           1-408-467-2930
 753     Tech Support E-Mail:    linux@connectcom.net
 754     FTP Site:               ftp.connectcom.net (login: anonymous)
 755     Web Site:               http://www.connectcom.net
 756
 757*/
 758
 759
 760/*
 761 * --- Linux Version
 762 */
 763
 764#ifndef LINUX_VERSION_CODE
 765#include <linux/version.h>
 766#endif /* LINUX_VERSION_CODE */
 767
 768/* Convert Linux Version, Patch-level, Sub-level to LINUX_VERSION_CODE. */
 769#define ASC_LINUX_VERSION(V, P, S)    (((V) * 65536) + ((P) * 256) + (S))
 770#define ASC_LINUX_KERNEL22 (LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,4,0))
 771#define ASC_LINUX_KERNEL24 (LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,4,0))
 772
 773/* Driver supported only in version 2.2 and version >= 2.4. */
 774#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,2,0) || \
 775    (LINUX_VERSION_CODE > ASC_LINUX_VERSION(2,3,0) && \
 776     LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,4,0))
 777#error "AdvanSys driver supported only in 2.2 and 2.4 or greater kernels."
 778#endif
 779
 780/*
 781 * --- Linux Include Files
 782 */
 783
 784#include <linux/config.h>
 785#include <linux/module.h>
 786
 787#if defined(CONFIG_X86) && !defined(CONFIG_ISA)
 788#define CONFIG_ISA
 789#endif /* CONFIG_X86 && !CONFIG_ISA */
 790
 791#include <linux/string.h>
 792#include <linux/kernel.h>
 793#include <linux/types.h>
 794#include <linux/ioport.h>
 795#include <linux/interrupt.h>
 796#include <linux/delay.h>
 797#include <linux/slab.h>
 798#include <linux/mm.h>
 799#include <linux/proc_fs.h>
 800#include <linux/init.h>
 801#include <linux/blkdev.h>
 802#include <linux/stat.h>
 803#include <linux/spinlock.h>
 804
 805#include <asm/io.h>
 806#include <asm/system.h>
 807#include <asm/dma.h>
 808
 809#include "scsi.h"
 810#include "hosts.h"
 811#include "advansys.h"
 812#ifdef CONFIG_PCI
 813#include <linux/pci.h>
 814#endif /* CONFIG_PCI */
 815
 816
 817/*
 818 * --- Driver Options
 819 */
 820
 821/* Enable driver assertions. */
 822#define ADVANSYS_ASSERT
 823
 824/* Enable driver /proc statistics. */
 825#define ADVANSYS_STATS
 826
 827/* Enable driver tracing. */
 828/* #define ADVANSYS_DEBUG */
 829
 830
 831/*
 832 * --- Debugging Header
 833 */
 834
 835#ifdef ADVANSYS_DEBUG
 836#define STATIC
 837#else /* ADVANSYS_DEBUG */
 838#define STATIC static
 839#endif /* ADVANSYS_DEBUG */
 840
 841
 842/*
 843 * --- Asc Library Constants and Macros
 844 */
 845
 846#define ASC_LIB_VERSION_MAJOR  1
 847#define ASC_LIB_VERSION_MINOR  24
 848#define ASC_LIB_SERIAL_NUMBER  123
 849
 850/*
 851 * Portable Data Types
 852 *
 853 * Any instance where a 32-bit long or pointer type is assumed
 854 * for precision or HW defined structures, the following define
 855 * types must be used. In Linux the char, short, and int types
 856 * are all consistent at 8, 16, and 32 bits respectively. Pointers
 857 * and long types are 64 bits on Alpha and UltraSPARC.
 858 */
 859#define ASC_PADDR __u32         /* Physical/Bus address data type. */
 860#define ASC_VADDR __u32         /* Virtual address data type. */
 861#define ASC_DCNT  __u32         /* Unsigned Data count type. */
 862#define ASC_SDCNT __s32         /* Signed Data count type. */
 863
 864/*
 865 * These macros are used to convert a virtual address to a
 866 * 32-bit value. This currently can be used on Linux Alpha
 867 * which uses 64-bit virtual address but a 32-bit bus address.
 868 * This is likely to break in the future, but doing this now
 869 * will give us time to change the HW and FW to handle 64-bit
 870 * addresses.
 871 */
 872#define ASC_VADDR_TO_U32   virt_to_bus
 873#define ASC_U32_TO_VADDR   bus_to_virt
 874
 875typedef unsigned char uchar;
 876
 877#ifndef NULL
 878#define NULL     (0)
 879#endif
 880#ifndef TRUE
 881#define TRUE     (1)
 882#endif
 883#ifndef FALSE
 884#define FALSE    (0)
 885#endif
 886
 887#define EOF      (-1)
 888#define ERR      (-1)
 889#define UW_ERR   (uint)(0xFFFF)
 890#define isodd_word(val)   ((((uint)val) & (uint)0x0001) != 0)
 891#define AscPCIConfigVendorIDRegister      0x0000
 892#define AscPCIConfigDeviceIDRegister      0x0002
 893#define AscPCIConfigCommandRegister       0x0004
 894#define AscPCIConfigStatusRegister        0x0006
 895#define AscPCIConfigRevisionIDRegister    0x0008
 896#define AscPCIConfigCacheSize             0x000C
 897#define AscPCIConfigLatencyTimer          0x000D
 898#define AscPCIIOBaseRegister              0x0010
 899#define AscPCICmdRegBits_IOMemBusMaster   0x0007
 900#define ASC_PCI_ID2BUS(id)    ((id) & 0xFF)
 901#define ASC_PCI_ID2DEV(id)    (((id) >> 11) & 0x1F)
 902#define ASC_PCI_ID2FUNC(id)   (((id) >> 8) & 0x7)
 903#define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF))
 904#define ASC_PCI_VENDORID                  0x10CD
 905#define ASC_PCI_DEVICEID_1200A            0x1100
 906#define ASC_PCI_DEVICEID_1200B            0x1200
 907#define ASC_PCI_DEVICEID_ULTRA            0x1300
 908#define ASC_PCI_REVISION_3150             0x02
 909#define ASC_PCI_REVISION_3050             0x03
 910
 911#define  ASC_DVCLIB_CALL_DONE     (1)
 912#define  ASC_DVCLIB_CALL_FAILED   (0)
 913#define  ASC_DVCLIB_CALL_ERROR    (-1)
 914
 915/*
 916 * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
 917 * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
 918 * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
 919 * SRB structure.
 920 */
 921#define CC_VERY_LONG_SG_LIST 0
 922#define ASC_SRB2SCSIQ(srb_ptr)  (srb_ptr)
 923
 924#define PortAddr                 unsigned short    /* port address size  */
 925#define inp(port)                inb(port)
 926#define outp(port, byte)         outb((byte), (port))
 927
 928#define inpw(port)               inw(port)
 929#define outpw(port, word)        outw((word), (port))
 930
 931#define ASC_MAX_SG_QUEUE    7
 932#define ASC_MAX_SG_LIST     255
 933
 934#define ASC_CS_TYPE  unsigned short
 935
 936#define ASC_IS_ISA          (0x0001)
 937#define ASC_IS_ISAPNP       (0x0081)
 938#define ASC_IS_EISA         (0x0002)
 939#define ASC_IS_PCI          (0x0004)
 940#define ASC_IS_PCI_ULTRA    (0x0104)
 941#define ASC_IS_PCMCIA       (0x0008)
 942#define ASC_IS_MCA          (0x0020)
 943#define ASC_IS_VL           (0x0040)
 944#define ASC_ISA_PNP_PORT_ADDR  (0x279)
 945#define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
 946#define ASC_IS_WIDESCSI_16  (0x0100)
 947#define ASC_IS_WIDESCSI_32  (0x0200)
 948#define ASC_IS_BIG_ENDIAN   (0x8000)
 949#define ASC_CHIP_MIN_VER_VL      (0x01)
 950#define ASC_CHIP_MAX_VER_VL      (0x07)
 951#define ASC_CHIP_MIN_VER_PCI     (0x09)
 952#define ASC_CHIP_MAX_VER_PCI     (0x0F)
 953#define ASC_CHIP_VER_PCI_BIT     (0x08)
 954#define ASC_CHIP_MIN_VER_ISA     (0x11)
 955#define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
 956#define ASC_CHIP_MAX_VER_ISA     (0x27)
 957#define ASC_CHIP_VER_ISA_BIT     (0x30)
 958#define ASC_CHIP_VER_ISAPNP_BIT  (0x20)
 959#define ASC_CHIP_VER_ASYN_BUG    (0x21)
 960#define ASC_CHIP_VER_PCI             0x08
 961#define ASC_CHIP_VER_PCI_ULTRA_3150  (ASC_CHIP_VER_PCI | 0x02)
 962#define ASC_CHIP_VER_PCI_ULTRA_3050  (ASC_CHIP_VER_PCI | 0x03)
 963#define ASC_CHIP_MIN_VER_EISA (0x41)
 964#define ASC_CHIP_MAX_VER_EISA (0x47)
 965#define ASC_CHIP_VER_EISA_BIT (0x40)
 966#define ASC_CHIP_LATEST_VER_EISA   ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
 967#define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER   0x21
 968#define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER   0x0A
 969#define ASC_MAX_VL_DMA_ADDR     (0x07FFFFFFL)
 970#define ASC_MAX_VL_DMA_COUNT    (0x07FFFFFFL)
 971#define ASC_MAX_PCI_DMA_ADDR    (0xFFFFFFFFL)
 972#define ASC_MAX_PCI_DMA_COUNT   (0xFFFFFFFFL)
 973#define ASC_MAX_ISA_DMA_ADDR    (0x00FFFFFFL)
 974#define ASC_MAX_ISA_DMA_COUNT   (0x00FFFFFFL)
 975#define ASC_MAX_EISA_DMA_ADDR   (0x07FFFFFFL)
 976#define ASC_MAX_EISA_DMA_COUNT  (0x07FFFFFFL)
 977
 978#define ASC_SCSI_ID_BITS  3
 979#define ASC_SCSI_TIX_TYPE     uchar
 980#define ASC_ALL_DEVICE_BIT_SET  0xFF
 981#define ASC_SCSI_BIT_ID_TYPE  uchar
 982#define ASC_MAX_TID       7
 983#define ASC_MAX_LUN       7
 984#define ASC_SCSI_WIDTH_BIT_SET  0xFF
 985#define ASC_MAX_SENSE_LEN   32
 986#define ASC_MIN_SENSE_LEN   14
 987#define ASC_MAX_CDB_LEN     12
 988#define ASC_SCSI_RESET_HOLD_TIME_US  60
 989#define SCSICMD_TestUnitReady     0x00
 990#define SCSICMD_Rewind            0x01
 991#define SCSICMD_Rezero            0x01
 992#define SCSICMD_RequestSense      0x03
 993#define SCSICMD_Format            0x04
 994#define SCSICMD_FormatUnit        0x04
 995#define SCSICMD_Read6             0x08
 996#define SCSICMD_Write6            0x0A
 997#define SCSICMD_Seek6             0x0B
 998#define SCSICMD_Inquiry           0x12
 999#define SCSICMD_Verify6           0x13
1000#define SCSICMD_ModeSelect6       0x15
1001#define SCSICMD_ModeSense6        0x1A
1002#define SCSICMD_StartStopUnit     0x1B
1003#define SCSICMD_LoadUnloadTape    0x1B
1004#define SCSICMD_ReadCapacity      0x25
1005#define SCSICMD_Read10            0x28
1006#define SCSICMD_Write10           0x2A
1007#define SCSICMD_Seek10            0x2B
1008#define SCSICMD_Erase10           0x2C
1009#define SCSICMD_WriteAndVerify10  0x2E
1010#define SCSICMD_Verify10          0x2F
1011#define SCSICMD_WriteBuffer       0x3B
1012#define SCSICMD_ReadBuffer        0x3C
1013#define SCSICMD_ReadLong          0x3E
1014#define SCSICMD_WriteLong         0x3F
1015#define SCSICMD_ReadTOC           0x43
1016#define SCSICMD_ReadHeader        0x44
1017#define SCSICMD_ModeSelect10      0x55
1018#define SCSICMD_ModeSense10       0x5A
1019
1020/* Inquiry Data Peripheral Device Types */
1021#define SCSI_TYPE_DASD     0x00
1022#define SCSI_TYPE_SASD     0x01
1023#define SCSI_TYPE_PRN      0x02
1024#define SCSI_TYPE_PROC     0x03
1025#define SCSI_TYPE_WORM     0x04
1026#define SCSI_TYPE_CDROM    0x05
1027#define SCSI_TYPE_SCANNER  0x06
1028#define SCSI_TYPE_OPTMEM   0x07
1029#define SCSI_TYPE_MED_CHG  0x08
1030#define SCSI_TYPE_COMM     0x09
1031#define SCSI_TYPE_UNKNOWN  0x1F
1032
1033#define ADV_INQ_CLOCKING_ST_ONLY    0x0
1034#define ADV_INQ_CLOCKING_DT_ONLY    0x1
1035#define ADV_INQ_CLOCKING_ST_AND_DT  0x3
1036
1037/*
1038 * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
1039 * and CmdDt (Command Support Data) field bit definitions.
1040 */
1041#define ADV_INQ_RTN_VPD_AND_CMDDT           0x3
1042#define ADV_INQ_RTN_CMDDT_FOR_OP_CODE       0x2
1043#define ADV_INQ_RTN_VPD_FOR_PG_CODE         0x1
1044#define ADV_INQ_RTN_STD_INQUIRY_DATA        0x0
1045
1046#define ASC_SCSIDIR_NOCHK    0x00
1047#define ASC_SCSIDIR_T2H      0x08
1048#define ASC_SCSIDIR_H2T      0x10
1049#define ASC_SCSIDIR_NODATA   0x18
1050#define SCSI_SENKEY_NO_SENSE      0x00
1051#define SCSI_SENKEY_UNDEFINED     0x01
1052#define SCSI_SENKEY_NOT_READY     0x02
1053#define SCSI_SENKEY_MEDIUM_ERR    0x03
1054#define SCSI_SENKEY_HW_ERR        0x04
1055#define SCSI_SENKEY_ILLEGAL       0x05
1056#define SCSI_SENKEY_ATTENTION     0x06
1057#define SCSI_SENKEY_PROTECTED     0x07
1058#define SCSI_SENKEY_BLANK         0x08
1059#define SCSI_SENKEY_V_UNIQUE      0x09
1060#define SCSI_SENKEY_CPY_ABORT     0x0A
1061#define SCSI_SENKEY_ABORT         0x0B
1062#define SCSI_SENKEY_EQUAL         0x0C
1063#define SCSI_SENKEY_VOL_OVERFLOW  0x0D
1064#define SCSI_SENKEY_MISCOMP       0x0E
1065#define SCSI_SENKEY_RESERVED      0x0F
1066#define SCSI_ASC_NOMEDIA          0x3A
1067#define ASC_SRB_HOST(x)  ((uchar)((uchar)(x) >> 4))
1068#define ASC_SRB_TID(x)   ((uchar)((uchar)(x) & (uchar)0x0F))
1069#define ASC_SRB_LUN(x)   ((uchar)((uint)(x) >> 13))
1070#define PUT_CDB1(x)   ((uchar)((uint)(x) >> 8))
1071#define SS_GOOD              0x00
1072#define SS_CHK_CONDITION     0x02
1073#define SS_CONDITION_MET     0x04
1074#define SS_TARGET_BUSY       0x08
1075#define SS_INTERMID          0x10
1076#define SS_INTERMID_COND_MET 0x14
1077#define SS_RSERV_CONFLICT    0x18
1078#define SS_CMD_TERMINATED    0x22
1079#define SS_QUEUE_FULL        0x28
1080#define MS_CMD_DONE    0x00
1081#define MS_EXTEND      0x01
1082#define MS_SDTR_LEN    0x03
1083#define MS_SDTR_CODE   0x01
1084#define MS_WDTR_LEN    0x02
1085#define MS_WDTR_CODE   0x03
1086#define MS_MDP_LEN    0x05
1087#define MS_MDP_CODE   0x00
1088#define M1_SAVE_DATA_PTR        0x02
1089#define M1_RESTORE_PTRS         0x03
1090#define M1_DISCONNECT           0x04
1091#define M1_INIT_DETECTED_ERR    0x05
1092#define M1_ABORT                0x06
1093#define M1_MSG_REJECT           0x07
1094#define M1_NO_OP                0x08
1095#define M1_MSG_PARITY_ERR       0x09
1096#define M1_LINK_CMD_DONE        0x0A
1097#define M1_LINK_CMD_DONE_WFLAG  0x0B
1098#define M1_BUS_DVC_RESET        0x0C
1099#define M1_ABORT_TAG            0x0D
1100#define M1_CLR_QUEUE            0x0E
1101#define M1_INIT_RECOVERY        0x0F
1102#define M1_RELEASE_RECOVERY     0x10
1103#define M1_KILL_IO_PROC         0x11
1104#define M2_QTAG_MSG_SIMPLE      0x20
1105#define M2_QTAG_MSG_HEAD        0x21
1106#define M2_QTAG_MSG_ORDERED     0x22
1107#define M2_IGNORE_WIDE_RESIDUE  0x23
1108
1109/*
1110 * Inquiry data structure and bitfield macros
1111 *
1112 * Only quantities of more than 1 bit are shifted, since the others are
1113 * just tested for true or false. C bitfields aren't portable between big
1114 * and little-endian platforms so they are not used.
1115 */
1116
1117#define ASC_INQ_DVC_TYPE(inq)       ((inq)->periph & 0x1f)
1118#define ASC_INQ_QUALIFIER(inq)      (((inq)->periph & 0xe0) >> 5)
1119#define ASC_INQ_DVC_TYPE_MOD(inq)   ((inq)->devtype & 0x7f)
1120#define ASC_INQ_REMOVABLE(inq)      ((inq)->devtype & 0x80)
1121#define ASC_INQ_ANSI_VER(inq)       ((inq)->ver & 0x07)
1122#define ASC_INQ_ECMA_VER(inq)       (((inq)->ver & 0x38) >> 3)
1123#define ASC_INQ_ISO_VER(inq)        (((inq)->ver & 0xc0) >> 6)
1124#define ASC_INQ_RESPONSE_FMT(inq)   ((inq)->byte3 & 0x0f)
1125#define ASC_INQ_TERM_IO(inq)        ((inq)->byte3 & 0x40)
1126#define ASC_INQ_ASYNC_NOTIF(inq)    ((inq)->byte3 & 0x80)
1127#define ASC_INQ_SOFT_RESET(inq)     ((inq)->flags & 0x01)
1128#define ASC_INQ_CMD_QUEUE(inq)      ((inq)->flags & 0x02)
1129#define ASC_INQ_LINK_CMD(inq)       ((inq)->flags & 0x08)
1130#define ASC_INQ_SYNC(inq)           ((inq)->flags & 0x10)
1131#define ASC_INQ_WIDE16(inq)         ((inq)->flags & 0x20)
1132#define ASC_INQ_WIDE32(inq)         ((inq)->flags & 0x40)
1133#define ASC_INQ_REL_ADDR(inq)       ((inq)->flags & 0x80)
1134#define ASC_INQ_INFO_UNIT(inq)      ((inq)->info & 0x01)
1135#define ASC_INQ_QUICK_ARB(inq)      ((inq)->info & 0x02)
1136#define ASC_INQ_CLOCKING(inq)       (((inq)->info & 0x0c) >> 2)
1137
1138typedef struct {
1139    uchar               periph;
1140    uchar               devtype;
1141    uchar               ver;
1142    uchar               byte3;
1143    uchar               add_len;
1144    uchar               res1;
1145    uchar               res2;
1146    uchar               flags;
1147    uchar               vendor_id[8];
1148    uchar               product_id[16];
1149    uchar               product_rev_level[4];
1150} ASC_SCSI_INQUIRY;
1151
1152#define ASC_SG_LIST_PER_Q   7
1153#define QS_FREE        0x00
1154#define QS_READY       0x01
1155#define QS_DISC1       0x02
1156#define QS_DISC2       0x04
1157#define QS_BUSY        0x08
1158#define QS_ABORTED     0x40
1159#define QS_DONE        0x80
1160#define QC_NO_CALLBACK   0x01
1161#define QC_SG_SWAP_QUEUE 0x02
1162#define QC_SG_HEAD       0x04
1163#define QC_DATA_IN       0x08
1164#define QC_DATA_OUT      0x10
1165#define QC_URGENT        0x20
1166#define QC_MSG_OUT       0x40
1167#define QC_REQ_SENSE     0x80
1168#define QCSG_SG_XFER_LIST  0x02
1169#define QCSG_SG_XFER_MORE  0x04
1170#define QCSG_SG_XFER_END   0x08
1171#define QD_IN_PROGRESS       0x00
1172#define QD_NO_ERROR          0x01
1173#define QD_ABORTED_BY_HOST   0x02
1174#define QD_WITH_ERROR        0x04
1175#define QD_INVALID_REQUEST   0x80
1176#define QD_INVALID_HOST_NUM  0x81
1177#define QD_INVALID_DEVICE    0x82
1178#define QD_ERR_INTERNAL      0xFF
1179#define QHSTA_NO_ERROR               0x00
1180#define QHSTA_M_SEL_TIMEOUT          0x11
1181#define QHSTA_M_DATA_OVER_RUN        0x12
1182#define QHSTA_M_DATA_UNDER_RUN       0x12
1183#define QHSTA_M_UNEXPECTED_BUS_FREE  0x13
1184#define QHSTA_M_BAD_BUS_PHASE_SEQ    0x14
1185#define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
1186#define QHSTA_D_ASC_DVC_ERROR_CODE_SET  0x22
1187#define QHSTA_D_HOST_ABORT_FAILED       0x23
1188#define QHSTA_D_EXE_SCSI_Q_FAILED       0x24
1189#define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
1190#define QHSTA_D_ASPI_NO_BUF_POOL        0x26
1191#define QHSTA_M_WTM_TIMEOUT         0x41
1192#define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
1193#define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
1194#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
1195#define QHSTA_M_TARGET_STATUS_BUSY  0x45
1196#define QHSTA_M_BAD_TAG_CODE        0x46
1197#define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY  0x47
1198#define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
1199#define QHSTA_D_LRAM_CMP_ERROR        0x81
1200#define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
1201#define ASC_FLAG_SCSIQ_REQ        0x01
1202#define ASC_FLAG_BIOS_SCSIQ_REQ   0x02
1203#define ASC_FLAG_BIOS_ASYNC_IO    0x04
1204#define ASC_FLAG_SRB_LINEAR_ADDR  0x08
1205#define ASC_FLAG_WIN16            0x10
1206#define ASC_FLAG_WIN32            0x20
1207#define ASC_FLAG_ISA_OVER_16MB    0x40
1208#define ASC_FLAG_DOS_VM_CALLBACK  0x80
1209#define ASC_TAG_FLAG_EXTRA_BYTES               0x10
1210#define ASC_TAG_FLAG_DISABLE_DISCONNECT        0x04
1211#define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX  0x08
1212#define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
1213#define ASC_SCSIQ_CPY_BEG              4
1214#define ASC_SCSIQ_SGHD_CPY_BEG         2
1215#define ASC_SCSIQ_B_FWD                0
1216#define ASC_SCSIQ_B_BWD                1
1217#define ASC_SCSIQ_B_STATUS             2
1218#define ASC_SCSIQ_B_QNO                3
1219#define ASC_SCSIQ_B_CNTL               4
1220#define ASC_SCSIQ_B_SG_QUEUE_CNT       5
1221#define ASC_SCSIQ_D_DATA_ADDR          8
1222#define ASC_SCSIQ_D_DATA_CNT          12
1223#define ASC_SCSIQ_B_SENSE_LEN         20
1224#define ASC_SCSIQ_DONE_INFO_BEG       22
1225#define ASC_SCSIQ_D_SRBPTR            22
1226#define ASC_SCSIQ_B_TARGET_IX         26
1227#define ASC_SCSIQ_B_CDB_LEN           28
1228#define ASC_SCSIQ_B_TAG_CODE          29
1229#define ASC_SCSIQ_W_VM_ID             30
1230#define ASC_SCSIQ_DONE_STATUS         32
1231#define ASC_SCSIQ_HOST_STATUS         33
1232#define ASC_SCSIQ_SCSI_STATUS         34
1233#define ASC_SCSIQ_CDB_BEG             36
1234#define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
1235#define ASC_SCSIQ_DW_REMAIN_XFER_CNT  60
1236#define ASC_SCSIQ_B_FIRST_SG_WK_QP    48
1237#define ASC_SCSIQ_B_SG_WK_QP          49
1238#define ASC_SCSIQ_B_SG_WK_IX          50
1239#define ASC_SCSIQ_W_ALT_DC1           52
1240#define ASC_SCSIQ_B_LIST_CNT          6
1241#define ASC_SCSIQ_B_CUR_LIST_CNT      7
1242#define ASC_SGQ_B_SG_CNTL             4
1243#define ASC_SGQ_B_SG_HEAD_QP          5
1244#define ASC_SGQ_B_SG_LIST_CNT         6
1245#define ASC_SGQ_B_SG_CUR_LIST_CNT     7
1246#define ASC_SGQ_LIST_BEG              8
1247#define ASC_DEF_SCSI1_QNG    4
1248#define ASC_MAX_SCSI1_QNG    4
1249#define ASC_DEF_SCSI2_QNG    16
1250#define ASC_MAX_SCSI2_QNG    32
1251#define ASC_TAG_CODE_MASK    0x23
1252#define ASC_STOP_REQ_RISC_STOP      0x01
1253#define ASC_STOP_ACK_RISC_STOP      0x03
1254#define ASC_STOP_CLEAN_UP_BUSY_Q    0x10
1255#define ASC_STOP_CLEAN_UP_DISC_Q    0x20
1256#define ASC_STOP_HOST_REQ_RISC_HALT 0x40
1257#define ASC_TIDLUN_TO_IX(tid, lun)  (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
1258#define ASC_TID_TO_TARGET_ID(tid)   (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
1259#define ASC_TIX_TO_TARGET_ID(tix)   (0x01 << ((tix) & ASC_MAX_TID))
1260#define ASC_TIX_TO_TID(tix)         ((tix) & ASC_MAX_TID)
1261#define ASC_TID_TO_TIX(tid)         ((tid) & ASC_MAX_TID)
1262#define ASC_TIX_TO_LUN(tix)         (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
1263#define ASC_QNO_TO_QADDR(q_no)      ((ASC_QADR_BEG)+((int)(q_no) << 6))
1264
1265typedef struct asc_scsiq_1 {
1266    uchar               status;
1267    uchar               q_no;
1268    uchar               cntl;
1269    uchar               sg_queue_cnt;
1270    uchar               target_id;
1271    uchar               target_lun;
1272    ASC_PADDR           data_addr;
1273    ASC_DCNT            data_cnt;
1274    ASC_PADDR           sense_addr;
1275    uchar               sense_len;
1276    uchar               extra_bytes;
1277} ASC_SCSIQ_1;
1278
1279typedef struct asc_scsiq_2 {
1280    ASC_VADDR           srb_ptr;
1281    uchar               target_ix;
1282    uchar               flag;
1283    uchar               cdb_len;
1284    uchar               tag_code;
1285    ushort              vm_id;
1286} ASC_SCSIQ_2;
1287
1288typedef struct asc_scsiq_3 {
1289    uchar               done_stat;
1290    uchar               host_stat;
1291    uchar               scsi_stat;
1292    uchar               scsi_msg;
1293} ASC_SCSIQ_3;
1294
1295typedef struct asc_scsiq_4 {
1296    uchar               cdb[ASC_MAX_CDB_LEN];
1297    uchar               y_first_sg_list_qp;
1298    uchar               y_working_sg_qp;
1299    uchar               y_working_sg_ix;
1300    uchar               y_res;
1301    ushort              x_req_count;
1302    ushort              x_reconnect_rtn;
1303    ASC_PADDR           x_saved_data_addr;
1304    ASC_DCNT            x_saved_data_cnt;
1305} ASC_SCSIQ_4;
1306
1307typedef struct asc_q_done_info {
1308    ASC_SCSIQ_2         d2;
1309    ASC_SCSIQ_3         d3;
1310    uchar               q_status;
1311    uchar               q_no;
1312    uchar               cntl;
1313    uchar               sense_len;
1314    uchar               extra_bytes;
1315    uchar               res;
1316    ASC_DCNT            remain_bytes;
1317} ASC_QDONE_INFO;
1318
1319typedef struct asc_sg_list {
1320    ASC_PADDR           addr;
1321    ASC_DCNT            bytes;
1322} ASC_SG_LIST;
1323
1324typedef struct asc_sg_head {
1325    ushort              entry_cnt;
1326    ushort              queue_cnt;
1327    ushort              entry_to_copy;
1328    ushort              res;
1329    ASC_SG_LIST         sg_list[ASC_MAX_SG_LIST];
1330} ASC_SG_HEAD;
1331
1332#define ASC_MIN_SG_LIST   2
1333
1334typedef struct asc_min_sg_head {
1335    ushort              entry_cnt;
1336    ushort              queue_cnt;
1337    ushort              entry_to_copy;
1338    ushort              res;
1339    ASC_SG_LIST         sg_list[ASC_MIN_SG_LIST];
1340} ASC_MIN_SG_HEAD;
1341
1342#define QCX_SORT        (0x0001)
1343#define QCX_COALEASE    (0x0002)
1344
1345typedef struct asc_scsi_q {
1346    ASC_SCSIQ_1         q1;
1347    ASC_SCSIQ_2         q2;
1348    uchar               *cdbptr;
1349    ASC_SG_HEAD         *sg_head;
1350    ushort              remain_sg_entry_cnt;
1351    ushort              next_sg_index;
1352} ASC_SCSI_Q;
1353
1354typedef struct asc_scsi_req_q {
1355    ASC_SCSIQ_1         r1;
1356    ASC_SCSIQ_2         r2;
1357    uchar               *cdbptr;
1358    ASC_SG_HEAD         *sg_head;
1359    uchar               *sense_ptr;
1360    ASC_SCSIQ_3         r3;
1361    uchar               cdb[ASC_MAX_CDB_LEN];
1362    uchar               sense[ASC_MIN_SENSE_LEN];
1363} ASC_SCSI_REQ_Q;
1364
1365typedef struct asc_scsi_bios_req_q {
1366    ASC_SCSIQ_1         r1;
1367    ASC_SCSIQ_2         r2;
1368    uchar               *cdbptr;
1369    ASC_SG_HEAD         *sg_head;
1370    uchar               *sense_ptr;
1371    ASC_SCSIQ_3         r3;
1372    uchar               cdb[ASC_MAX_CDB_LEN];
1373    uchar               sense[ASC_MIN_SENSE_LEN];
1374} ASC_SCSI_BIOS_REQ_Q;
1375
1376typedef struct asc_risc_q {
1377    uchar               fwd;
1378    uchar               bwd;
1379    ASC_SCSIQ_1         i1;
1380    ASC_SCSIQ_2         i2;
1381    ASC_SCSIQ_3         i3;
1382    ASC_SCSIQ_4         i4;
1383} ASC_RISC_Q;
1384
1385typedef struct asc_sg_list_q {
1386    uchar               seq_no;
1387    uchar               q_no;
1388    uchar               cntl;
1389    uchar               sg_head_qp;
1390    uchar               sg_list_cnt;
1391    uchar               sg_cur_list_cnt;
1392} ASC_SG_LIST_Q;
1393
1394typedef struct asc_risc_sg_list_q {
1395    uchar               fwd;
1396    uchar               bwd;
1397    ASC_SG_LIST_Q       sg;
1398    ASC_SG_LIST         sg_list[7];
1399} ASC_RISC_SG_LIST_Q;
1400
1401#define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP  0x1000000UL
1402#define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP  1024
1403#define ASCQ_ERR_NO_ERROR             0
1404#define ASCQ_ERR_IO_NOT_FOUND         1
1405#define ASCQ_ERR_LOCAL_MEM            2
1406#define ASCQ_ERR_CHKSUM               3
1407#define ASCQ_ERR_START_CHIP           4
1408#define ASCQ_ERR_INT_TARGET_ID        5
1409#define ASCQ_ERR_INT_LOCAL_MEM        6
1410#define ASCQ_ERR_HALT_RISC            7
1411#define ASCQ_ERR_GET_ASPI_ENTRY       8
1412#define ASCQ_ERR_CLOSE_ASPI           9
1413#define ASCQ_ERR_HOST_INQUIRY         0x0A
1414#define ASCQ_ERR_SAVED_SRB_BAD        0x0B
1415#define ASCQ_ERR_QCNTL_SG_LIST        0x0C
1416#define ASCQ_ERR_Q_STATUS             0x0D
1417#define ASCQ_ERR_WR_SCSIQ             0x0E
1418#define ASCQ_ERR_PC_ADDR              0x0F
1419#define ASCQ_ERR_SYN_OFFSET           0x10
1420#define ASCQ_ERR_SYN_XFER_TIME        0x11
1421#define ASCQ_ERR_LOCK_DMA             0x12
1422#define ASCQ_ERR_UNLOCK_DMA           0x13
1423#define ASCQ_ERR_VDS_CHK_INSTALL      0x14
1424#define ASCQ_ERR_MICRO_CODE_HALT      0x15
1425#define ASCQ_ERR_SET_LRAM_ADDR        0x16
1426#define ASCQ_ERR_CUR_QNG              0x17
1427#define ASCQ_ERR_SG_Q_LINKS           0x18
1428#define ASCQ_ERR_SCSIQ_PTR            0x19
1429#define ASCQ_ERR_ISR_RE_ENTRY         0x1A
1430#define ASCQ_ERR_CRITICAL_RE_ENTRY    0x1B
1431#define ASCQ_ERR_ISR_ON_CRITICAL      0x1C
1432#define ASCQ_ERR_SG_LIST_ODD_ADDRESS  0x1D
1433#define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
1434#define ASCQ_ERR_SCSIQ_NULL_PTR       0x1F
1435#define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR   0x20
1436#define ASCQ_ERR_GET_NUM_OF_FREE_Q    0x21
1437#define ASCQ_ERR_SEND_SCSI_Q          0x22
1438#define ASCQ_ERR_HOST_REQ_RISC_HALT   0x23
1439#define ASCQ_ERR_RESET_SDTR           0x24
1440
1441/*
1442 * Warning code values are set in ASC_DVC_VAR  'warn_code'.
1443 */
1444#define ASC_WARN_NO_ERROR             0x0000
1445#define ASC_WARN_IO_PORT_ROTATE       0x0001
1446#define ASC_WARN_EEPROM_CHKSUM        0x0002
1447#define ASC_WARN_IRQ_MODIFIED         0x0004
1448#define ASC_WARN_AUTO_CONFIG          0x0008
1449#define ASC_WARN_CMD_QNG_CONFLICT     0x0010
1450#define ASC_WARN_EEPROM_RECOVER       0x0020
1451#define ASC_WARN_CFG_MSW_RECOVER      0x0040
1452#define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
1453
1454/*
1455 * Error code values are set in ASC_DVC_VAR  'err_code'.
1456 */
1457#define ASC_IERR_WRITE_EEPROM         0x0001
1458#define ASC_IERR_MCODE_CHKSUM         0x0002
1459#define ASC_IERR_SET_PC_ADDR          0x0004
1460#define ASC_IERR_START_STOP_CHIP      0x0008
1461#define ASC_IERR_IRQ_NO               0x0010
1462#define ASC_IERR_SET_IRQ_NO           0x0020
1463#define ASC_IERR_CHIP_VERSION         0x0040
1464#define ASC_IERR_SET_SCSI_ID          0x0080
1465#define ASC_IERR_GET_PHY_ADDR         0x0100
1466#define ASC_IERR_BAD_SIGNATURE        0x0200
1467#define ASC_IERR_NO_BUS_TYPE          0x0400
1468#define ASC_IERR_SCAM                 0x0800
1469#define ASC_IERR_SET_SDTR             0x1000
1470#define ASC_IERR_RW_LRAM              0x8000
1471
1472#define ASC_DEF_IRQ_NO  10
1473#define ASC_MAX_IRQ_NO  15
1474#define ASC_MIN_IRQ_NO  10
1475#define ASC_MIN_REMAIN_Q        (0x02)
1476#define ASC_DEF_MAX_TOTAL_QNG   (0xF0)
1477#define ASC_MIN_TAG_Q_PER_DVC   (0x04)
1478#define ASC_DEF_TAG_Q_PER_DVC   (0x04)
1479#define ASC_MIN_FREE_Q        ASC_MIN_REMAIN_Q
1480#define ASC_MIN_TOTAL_QNG     ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
1481#define ASC_MAX_TOTAL_QNG 240
1482#define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
1483#define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG   8
1484#define ASC_MAX_PCI_INRAM_TOTAL_QNG  20
1485#define ASC_MAX_INRAM_TAG_QNG   16
1486#define ASC_IOADR_TABLE_MAX_IX  11
1487#define ASC_IOADR_GAP   0x10
1488#define ASC_SEARCH_IOP_GAP 0x10
1489#define ASC_MIN_IOP_ADDR   (PortAddr)0x0100
1490#define ASC_MAX_IOP_ADDR   (PortAddr)0x3F0
1491#define ASC_IOADR_1     (PortAddr)0x0110
1492#define ASC_IOADR_2     (PortAddr)0x0130
1493#define ASC_IOADR_3     (PortAddr)0x0150
1494#define ASC_IOADR_4     (PortAddr)0x0190
1495#define ASC_IOADR_5     (PortAddr)0x0210
1496#define ASC_IOADR_6     (PortAddr)0x0230
1497#define ASC_IOADR_7     (PortAddr)0x0250
1498#define ASC_IOADR_8     (PortAddr)0x0330
1499#define ASC_IOADR_DEF   ASC_IOADR_8
1500#define ASC_LIB_SCSIQ_WK_SP        256
1501#define ASC_MAX_SYN_XFER_NO        16
1502#define ASC_SYN_MAX_OFFSET         0x0F
1503#define ASC_DEF_SDTR_OFFSET        0x0F
1504#define ASC_DEF_SDTR_INDEX         0x00
1505#define ASC_SDTR_ULTRA_PCI_10MB_INDEX  0x02
1506#define SYN_XFER_NS_0  25
1507#define SYN_XFER_NS_1  30
1508#define SYN_XFER_NS_2  35
1509#define SYN_XFER_NS_3  40
1510#define SYN_XFER_NS_4  50
1511#define SYN_XFER_NS_5  60
1512#define SYN_XFER_NS_6  70
1513#define SYN_XFER_NS_7  85
1514#define SYN_ULTRA_XFER_NS_0    12
1515#define SYN_ULTRA_XFER_NS_1    19
1516#define SYN_ULTRA_XFER_NS_2    25
1517#define SYN_ULTRA_XFER_NS_3    32
1518#define SYN_ULTRA_XFER_NS_4    38
1519#define SYN_ULTRA_XFER_NS_5    44
1520#define SYN_ULTRA_XFER_NS_6    50
1521#define SYN_ULTRA_XFER_NS_7    57
1522#define SYN_ULTRA_XFER_NS_8    63
1523#define SYN_ULTRA_XFER_NS_9    69
1524#define SYN_ULTRA_XFER_NS_10   75
1525#define SYN_ULTRA_XFER_NS_11   82
1526#define SYN_ULTRA_XFER_NS_12   88
1527#define SYN_ULTRA_XFER_NS_13   94
1528#define SYN_ULTRA_XFER_NS_14  100
1529#define SYN_ULTRA_XFER_NS_15  107
1530
1531typedef struct ext_msg {
1532    uchar               msg_type;
1533    uchar               msg_len;
1534    uchar               msg_req;
1535    union {
1536        struct {
1537            uchar               sdtr_xfer_period;
1538            uchar               sdtr_req_ack_offset;
1539        } sdtr;
1540        struct {
1541            uchar               wdtr_width;
1542        } wdtr;
1543        struct {
1544            uchar               mdp_b3;
1545            uchar               mdp_b2;
1546            uchar               mdp_b1;
1547            uchar               mdp_b0;
1548        } mdp;
1549    } u_ext_msg;
1550    uchar               res;
1551} EXT_MSG;
1552
1553#define xfer_period     u_ext_msg.sdtr.sdtr_xfer_period
1554#define req_ack_offset  u_ext_msg.sdtr.sdtr_req_ack_offset
1555#define wdtr_width      u_ext_msg.wdtr.wdtr_width
1556#define mdp_b3          u_ext_msg.mdp_b3
1557#define mdp_b2          u_ext_msg.mdp_b2
1558#define mdp_b1          u_ext_msg.mdp_b1
1559#define mdp_b0          u_ext_msg.mdp_b0
1560
1561typedef struct asc_dvc_cfg {
1562    ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
1563    ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
1564    ASC_SCSI_BIT_ID_TYPE disc_enable;
1565    ASC_SCSI_BIT_ID_TYPE sdtr_enable;
1566    uchar               chip_scsi_id;
1567    uchar               isa_dma_speed;
1568    uchar               isa_dma_channel;
1569    uchar               chip_version;
1570    ushort              lib_serial_no;
1571    ushort              lib_version;
1572    ushort              mcode_date;
1573    ushort              mcode_version;
1574    uchar               max_tag_qng[ASC_MAX_TID + 1];
1575    uchar               *overrun_buf;
1576    uchar               sdtr_period_offset[ASC_MAX_TID + 1];
1577    ushort              pci_slot_info;
1578    uchar               adapter_info[6];
1579    struct pci_dev      *pci_dev;
1580} ASC_DVC_CFG;
1581
1582#define ASC_DEF_DVC_CNTL       0xFFFF
1583#define ASC_DEF_CHIP_SCSI_ID   7
1584#define ASC_DEF_ISA_DMA_SPEED  4
1585#define ASC_INIT_STATE_NULL          0x0000
1586#define ASC_INIT_STATE_BEG_GET_CFG   0x0001
1587#define ASC_INIT_STATE_END_GET_CFG   0x0002
1588#define ASC_INIT_STATE_BEG_SET_CFG   0x0004
1589#define ASC_INIT_STATE_END_SET_CFG   0x0008
1590#define ASC_INIT_STATE_BEG_LOAD_MC   0x0010
1591#define ASC_INIT_STATE_END_LOAD_MC   0x0020
1592#define ASC_INIT_STATE_BEG_INQUIRY   0x0040
1593#define ASC_INIT_STATE_END_INQUIRY   0x0080
1594#define ASC_INIT_RESET_SCSI_DONE     0x0100
1595#define ASC_INIT_STATE_WITHOUT_EEP   0x8000
1596#define ASC_PCI_DEVICE_ID_REV_A      0x1100
1597#define ASC_PCI_DEVICE_ID_REV_B      0x1200
1598#define ASC_BUG_FIX_IF_NOT_DWB       0x0001
1599#define ASC_BUG_FIX_ASYN_USE_SYN     0x0002
1600#define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
1601#define ASC_MIN_TAGGED_CMD  7
1602#define ASC_MAX_SCSI_RESET_WAIT      30
1603
1604struct asc_dvc_var;     /* Forward Declaration. */
1605
1606typedef void (* ASC_ISR_CALLBACK)(struct asc_dvc_var *, ASC_QDONE_INFO *);
1607typedef int (* ASC_EXE_CALLBACK)(struct asc_dvc_var *, ASC_SCSI_Q *);
1608
1609typedef struct asc_dvc_var {
1610    PortAddr            iop_base;
1611    ushort              err_code;
1612    ushort              dvc_cntl;
1613    ushort              bug_fix_cntl;
1614    ushort              bus_type;
1615    ASC_ISR_CALLBACK    isr_callback;
1616    ASC_EXE_CALLBACK    exe_callback;
1617    ASC_SCSI_BIT_ID_TYPE init_sdtr;
1618    ASC_SCSI_BIT_ID_TYPE sdtr_done;
1619    ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
1620    ASC_SCSI_BIT_ID_TYPE unit_not_ready;
1621    ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
1622    ASC_SCSI_BIT_ID_TYPE start_motor;
1623    uchar               scsi_reset_wait;
1624    uchar               chip_no;
1625    char                is_in_int;
1626    uchar               max_total_qng;
1627    uchar               cur_total_qng;
1628    uchar               in_critical_cnt;
1629    uchar               irq_no;
1630    uchar               last_q_shortage;
1631    ushort              init_state;
1632    uchar               cur_dvc_qng[ASC_MAX_TID + 1];
1633    uchar               max_dvc_qng[ASC_MAX_TID + 1];
1634    ASC_SCSI_Q  *scsiq_busy_head[ASC_MAX_TID + 1];
1635    ASC_SCSI_Q  *scsiq_busy_tail[ASC_MAX_TID + 1];
1636    uchar               sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
1637    ASC_DVC_CFG *cfg;
1638    ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
1639    char                redo_scam;
1640    ushort              res2;
1641    uchar               dos_int13_table[ASC_MAX_TID + 1];
1642    ASC_DCNT            max_dma_count;
1643    ASC_SCSI_BIT_ID_TYPE no_scam;
1644    ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
1645    uchar               max_sdtr_index;
1646    uchar               host_init_sdtr_index;
1647    struct asc_board    *drv_ptr;
1648    ASC_DCNT            uc_break;
1649} ASC_DVC_VAR;
1650
1651typedef struct asc_dvc_inq_info {
1652    uchar               type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1653} ASC_DVC_INQ_INFO;
1654
1655typedef struct asc_cap_info {
1656    ASC_DCNT            lba;
1657    ASC_DCNT            blk_size;
1658} ASC_CAP_INFO;
1659
1660typedef struct asc_cap_info_array {
1661    ASC_CAP_INFO        cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1662} ASC_CAP_INFO_ARRAY;
1663
1664#define ASC_MCNTL_NO_SEL_TIMEOUT  (ushort)0x0001
1665#define ASC_MCNTL_NULL_TARGET     (ushort)0x0002
1666#define ASC_CNTL_INITIATOR         (ushort)0x0001
1667#define ASC_CNTL_BIOS_GT_1GB       (ushort)0x0002
1668#define ASC_CNTL_BIOS_GT_2_DISK    (ushort)0x0004
1669#define ASC_CNTL_BIOS_REMOVABLE    (ushort)0x0008
1670#define ASC_CNTL_NO_SCAM           (ushort)0x0010
1671#define ASC_CNTL_INT_MULTI_Q       (ushort)0x0080
1672#define ASC_CNTL_NO_LUN_SUPPORT    (ushort)0x0040
1673#define ASC_CNTL_NO_VERIFY_COPY    (ushort)0x0100
1674#define ASC_CNTL_RESET_SCSI        (ushort)0x0200
1675#define ASC_CNTL_INIT_INQUIRY      (ushort)0x0400
1676#define ASC_CNTL_INIT_VERBOSE      (ushort)0x0800
1677#define ASC_CNTL_SCSI_PARITY       (ushort)0x1000
1678#define ASC_CNTL_BURST_MODE        (ushort)0x2000
1679#define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
1680#define ASC_EEP_DVC_CFG_BEG_VL    2
1681#define ASC_EEP_MAX_DVC_ADDR_VL   15
1682#define ASC_EEP_DVC_CFG_BEG      32
1683#define ASC_EEP_MAX_DVC_ADDR     45
1684#define ASC_EEP_DEFINED_WORDS    10
1685#define ASC_EEP_MAX_ADDR         63
1686#define ASC_EEP_RES_WORDS         0
1687#define ASC_EEP_MAX_RETRY        20
1688#define ASC_MAX_INIT_BUSY_RETRY   8
1689#define ASC_EEP_ISA_PNP_WSIZE    16
1690
1691/*
1692 * These macros keep the chip SCSI id and ISA DMA speed
1693 * bitfields in board order. C bitfields aren't portable
1694 * between big and little-endian platforms so they are
1695 * not used.
1696 */
1697
1698#define ASC_EEP_GET_CHIP_ID(cfg)    ((cfg)->id_speed & 0x0f)
1699#define ASC_EEP_GET_DMA_SPD(cfg)    (((cfg)->id_speed & 0xf0) >> 4)
1700#define ASC_EEP_SET_CHIP_ID(cfg, sid) \
1701   ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
1702#define ASC_EEP_SET_DMA_SPD(cfg, spd) \
1703   ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
1704
1705typedef struct asceep_config {
1706    ushort              cfg_lsw;
1707    ushort              cfg_msw;
1708    uchar               init_sdtr;
1709    uchar               disc_enable;
1710    uchar               use_cmd_qng;
1711    uchar               start_motor;
1712    uchar               max_total_qng;
1713    uchar               max_tag_qng;
1714    uchar               bios_scan;
1715    uchar               power_up_wait;
1716    uchar               no_scam;
1717    uchar               id_speed; /* low order 4 bits is chip scsi id */
1718                                  /* high order 4 bits is isa dma speed */
1719    uchar               dos_int13_table[ASC_MAX_TID + 1];
1720    uchar               adapter_info[6];
1721    ushort              cntl;
1722    ushort              chksum;
1723} ASCEEP_CONFIG;
1724
1725#define ASC_PCI_CFG_LSW_SCSI_PARITY  0x0800
1726#define ASC_PCI_CFG_LSW_BURST_MODE   0x0080
1727#define ASC_PCI_CFG_LSW_INTR_ABLE    0x0020
1728
1729#define ASC_EEP_CMD_READ          0x80
1730#define ASC_EEP_CMD_WRITE         0x40
1731#define ASC_EEP_CMD_WRITE_ABLE    0x30
1732#define ASC_EEP_CMD_WRITE_DISABLE 0x00
1733#define ASC_OVERRUN_BSIZE  0x00000048UL
1734#define ASC_CTRL_BREAK_ONCE        0x0001
1735#define ASC_CTRL_BREAK_STAY_IDLE   0x0002
1736#define ASCV_MSGOUT_BEG         0x0000
1737#define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
1738#define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
1739#define ASCV_BREAK_SAVED_CODE   (ushort)0x0006
1740#define ASCV_MSGIN_BEG          (ASCV_MSGOUT_BEG+8)
1741#define ASCV_MSGIN_SDTR_PERIOD  (ASCV_MSGIN_BEG+3)
1742#define ASCV_MSGIN_SDTR_OFFSET  (ASCV_MSGIN_BEG+4)
1743#define ASCV_SDTR_DATA_BEG      (ASCV_MSGIN_BEG+8)
1744#define ASCV_SDTR_DONE_BEG      (ASCV_SDTR_DATA_BEG+8)
1745#define ASCV_MAX_DVC_QNG_BEG    (ushort)0x0020
1746#define ASCV_BREAK_ADDR           (ushort)0x0028
1747#define ASCV_BREAK_NOTIFY_COUNT   (ushort)0x002A
1748#define ASCV_BREAK_CONTROL        (ushort)0x002C
1749#define ASCV_BREAK_HIT_COUNT      (ushort)0x002E
1750
1751#define ASCV_ASCDVC_ERR_CODE_W  (ushort)0x0030
1752#define ASCV_MCODE_CHKSUM_W   (ushort)0x0032
1753#define ASCV_MCODE_SIZE_W     (ushort)0x0034
1754#define ASCV_STOP_CODE_B      (ushort)0x0036
1755#define ASCV_DVC_ERR_CODE_B   (ushort)0x0037
1756#define ASCV_OVERRUN_PADDR_D  (ushort)0x0038
1757#define ASCV_OVERRUN_BSIZE_D  (ushort)0x003C
1758#define ASCV_HALTCODE_W       (ushort)0x0040
1759#define ASCV_CHKSUM_W         (ushort)0x0042
1760#define ASCV_MC_DATE_W        (ushort)0x0044
1761#define ASCV_MC_VER_W         (ushort)0x0046
1762#define ASCV_NEXTRDY_B        (ushort)0x0048
1763#define ASCV_DONENEXT_B       (ushort)0x0049
1764#define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
1765#define ASCV_SCSIBUSY_B       (ushort)0x004B
1766#define ASCV_Q_DONE_IN_PROGRESS_B  (ushort)0x004C
1767#define ASCV_CURCDB_B         (ushort)0x004D
1768#define ASCV_RCLUN_B          (ushort)0x004E
1769#define ASCV_BUSY_QHEAD_B     (ushort)0x004F
1770#define ASCV_DISC1_QHEAD_B    (ushort)0x0050
1771#define ASCV_DISC_ENABLE_B    (ushort)0x0052
1772#define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
1773#define ASCV_HOSTSCSI_ID_B    (ushort)0x0055
1774#define ASCV_MCODE_CNTL_B     (ushort)0x0056
1775#define ASCV_NULL_TARGET_B    (ushort)0x0057
1776#define ASCV_FREE_Q_HEAD_W    (ushort)0x0058
1777#define ASCV_DONE_Q_TAIL_W    (ushort)0x005A
1778#define ASCV_FREE_Q_HEAD_B    (ushort)(ASCV_FREE_Q_HEAD_W+1)
1779#define ASCV_DONE_Q_TAIL_B    (ushort)(ASCV_DONE_Q_TAIL_W+1)
1780#define ASCV_HOST_FLAG_B      (ushort)0x005D
1781#define ASCV_TOTAL_READY_Q_B  (ushort)0x0064
1782#define ASCV_VER_SERIAL_B     (ushort)0x0065
1783#define ASCV_HALTCODE_SAVED_W (ushort)0x0066
1784#define ASCV_WTM_FLAG_B       (ushort)0x0068
1785#define ASCV_RISC_FLAG_B      (ushort)0x006A
1786#define ASCV_REQ_SG_LIST_QP   (ushort)0x006B
1787#define ASC_HOST_FLAG_IN_ISR        0x01
1788#define ASC_HOST_FLAG_ACK_INT       0x02
1789#define ASC_RISC_FLAG_GEN_INT      0x01
1790#define ASC_RISC_FLAG_REQ_SG_LIST  0x02
1791#define IOP_CTRL         (0x0F)
1792#define IOP_STATUS       (0x0E)
1793#define IOP_INT_ACK      IOP_STATUS
1794#define IOP_REG_IFC      (0x0D)
1795#define IOP_SYN_OFFSET    (0x0B)
1796#define IOP_EXTRA_CONTROL (0x0D)
1797#define IOP_REG_PC        (0x0C)
1798#define IOP_RAM_ADDR      (0x0A)
1799#define IOP_RAM_DATA      (0x08)
1800#define IOP_EEP_DATA      (0x06)
1801#define IOP_EEP_CMD       (0x07)
1802#define IOP_VERSION       (0x03)
1803#define IOP_CONFIG_HIGH   (0x04)
1804#define IOP_CONFIG_LOW    (0x02)
1805#define IOP_SIG_BYTE      (0x01)
1806#define IOP_SIG_WORD      (0x00)
1807#define IOP_REG_DC1      (0x0E)
1808#define IOP_REG_DC0      (0x0C)
1809#define IOP_REG_SB       (0x0B)
1810#define IOP_REG_DA1      (0x0A)
1811#define IOP_REG_DA0      (0x08)
1812#define IOP_REG_SC       (0x09)
1813#define IOP_DMA_SPEED    (0x07)
1814#define IOP_REG_FLAG     (0x07)
1815#define IOP_FIFO_H       (0x06)
1816#define IOP_FIFO_L       (0x04)
1817#define IOP_REG_ID       (0x05)
1818#define IOP_REG_QP       (0x03)
1819#define IOP_REG_IH       (0x02)
1820#define IOP_REG_IX       (0x01)
1821#define IOP_REG_AX       (0x00)
1822#define IFC_REG_LOCK      (0x00)
1823#define IFC_REG_UNLOCK    (0x09)
1824#define IFC_WR_EN_FILTER  (0x10)
1825#define IFC_RD_NO_EEPROM  (0x10)
1826#define IFC_SLEW_RATE     (0x20)
1827#define IFC_ACT_NEG       (0x40)
1828#define IFC_INP_FILTER    (0x80)
1829#define IFC_INIT_DEFAULT  (IFC_ACT_NEG | IFC_REG_UNLOCK)
1830#define SC_SEL   (uchar)(0x80)
1831#define SC_BSY   (uchar)(0x40)
1832#define SC_ACK   (uchar)(0x20)
1833#define SC_REQ   (uchar)(0x10)
1834#define SC_ATN   (uchar)(0x08)
1835#define SC_IO    (uchar)(0x04)
1836#define SC_CD    (uchar)(0x02)
1837#define SC_MSG   (uchar)(0x01)
1838#define SEC_SCSI_CTL         (uchar)(0x80)
1839#define SEC_ACTIVE_NEGATE    (uchar)(0x40)
1840#define SEC_SLEW_RATE        (uchar)(0x20)
1841#define SEC_ENABLE_FILTER    (uchar)(0x10)
1842#define ASC_HALT_EXTMSG_IN     (ushort)0x8000
1843#define ASC_HALT_CHK_CONDITION (ushort)0x8100
1844#define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
1845#define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX  (ushort)0x8300
1846#define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX   (ushort)0x8400
1847#define ASC_HALT_SDTR_REJECTED (ushort)0x4000
1848#define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
1849#define ASC_MAX_QNO        0xF8
1850#define ASC_DATA_SEC_BEG   (ushort)0x0080
1851#define ASC_DATA_SEC_END   (ushort)0x0080
1852#define ASC_CODE_SEC_BEG   (ushort)0x0080
1853#define ASC_CODE_SEC_END   (ushort)0x0080
1854#define ASC_QADR_BEG       (0x4000)
1855#define ASC_QADR_USED      (ushort)(ASC_MAX_QNO * 64)
1856#define ASC_QADR_END       (ushort)0x7FFF
1857#define ASC_QLAST_ADR      (ushort)0x7FC0
1858#define ASC_QBLK_SIZE      0x40
1859#define ASC_BIOS_DATA_QBEG 0xF8
1860#define ASC_MIN_ACTIVE_QNO 0x01
1861#define ASC_QLINK_END      0xFF
1862#define ASC_EEPROM_WORDS   0x10
1863#define ASC_MAX_MGS_LEN    0x10
1864#define ASC_BIOS_ADDR_DEF  0xDC00
1865#define ASC_BIOS_SIZE      0x3800
1866#define ASC_BIOS_RAM_OFF   0x3800
1867#define ASC_BIOS_RAM_SIZE  0x800
1868#define ASC_BIOS_MIN_ADDR  0xC000
1869#define ASC_BIOS_MAX_ADDR  0xEC00
1870#define ASC_BIOS_BANK_SIZE 0x0400
1871#define ASC_MCODE_START_ADDR  0x0080
1872#define ASC_CFG0_HOST_INT_ON    0x0020
1873#define ASC_CFG0_BIOS_ON        0x0040
1874#define ASC_CFG0_VERA_BURST_ON  0x0080
1875#define ASC_CFG0_SCSI_PARITY_ON 0x0800
1876#define ASC_CFG1_SCSI_TARGET_ON 0x0080
1877#define ASC_CFG1_LRAM_8BITS_ON  0x0800
1878#define ASC_CFG_MSW_CLR_MASK    0x3080
1879#define CSW_TEST1             (ASC_CS_TYPE)0x8000
1880#define CSW_AUTO_CONFIG       (ASC_CS_TYPE)0x4000
1881#define CSW_RESERVED1         (ASC_CS_TYPE)0x2000
1882#define CSW_IRQ_WRITTEN       (ASC_CS_TYPE)0x1000
1883#define CSW_33MHZ_SELECTED    (ASC_CS_TYPE)0x0800
1884#define CSW_TEST2             (ASC_CS_TYPE)0x0400
1885#define CSW_TEST3             (ASC_CS_TYPE)0x0200
1886#define CSW_RESERVED2         (ASC_CS_TYPE)0x0100
1887#define CSW_DMA_DONE          (ASC_CS_TYPE)0x0080
1888#define CSW_FIFO_RDY          (ASC_CS_TYPE)0x0040
1889#define CSW_EEP_READ_DONE     (ASC_CS_TYPE)0x0020
1890#define CSW_HALTED            (ASC_CS_TYPE)0x0010
1891#define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
1892#define CSW_PARITY_ERR        (ASC_CS_TYPE)0x0004
1893#define CSW_SCSI_RESET_LATCH  (ASC_CS_TYPE)0x0002
1894#define CSW_INT_PENDING       (ASC_CS_TYPE)0x0001
1895#define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
1896#define CIW_INT_ACK      (ASC_CS_TYPE)0x0100
1897#define CIW_TEST1        (ASC_CS_TYPE)0x0200
1898#define CIW_TEST2        (ASC_CS_TYPE)0x0400
1899#define CIW_SEL_33MHZ    (ASC_CS_TYPE)0x0800
1900#define CIW_IRQ_ACT      (ASC_CS_TYPE)0x1000
1901#define CC_CHIP_RESET   (uchar)0x80
1902#define CC_SCSI_RESET   (uchar)0x40
1903#define CC_HALT         (uchar)0x20
1904#define CC_SINGLE_STEP  (uchar)0x10
1905#define CC_DMA_ABLE     (uchar)0x08
1906#define CC_TEST         (uchar)0x04
1907#define CC_BANK_ONE     (uchar)0x02
1908#define CC_DIAG         (uchar)0x01
1909#define ASC_1000_ID0W      0x04C1
1910#define ASC_1000_ID0W_FIX  0x00C1
1911#define ASC_1000_ID1B      0x25
1912#define ASC_EISA_BIG_IOP_GAP   (0x1C30-0x0C50)
1913#define ASC_EISA_SMALL_IOP_GAP (0x0020)
1914#define ASC_EISA_MIN_IOP_ADDR  (0x0C30)
1915#define ASC_EISA_MAX_IOP_ADDR  (0xFC50)
1916#define ASC_EISA_REV_IOP_MASK  (0x0C83)
1917#define ASC_EISA_PID_IOP_MASK  (0x0C80)
1918#define ASC_EISA_CFG_IOP_MASK  (0x0C86)
1919#define ASC_GET_EISA_SLOT(iop)  (PortAddr)((iop) & 0xF000)
1920#define ASC_EISA_ID_740    0x01745004UL
1921#define ASC_EISA_ID_750    0x01755004UL
1922#define INS_HALTINT        (ushort)0x6281
1923#define INS_HALT           (ushort)0x6280
1924#define INS_SINT           (ushort)0x6200
1925#define INS_RFLAG_WTM      (ushort)0x7380
1926#define ASC_MC_SAVE_CODE_WSIZE  0x500
1927#define ASC_MC_SAVE_DATA_WSIZE  0x40
1928
1929typedef struct asc_mc_saved {
1930    ushort              data[ASC_MC_SAVE_DATA_WSIZE];
1931    ushort              code[ASC_MC_SAVE_CODE_WSIZE];
1932} ASC_MC_SAVED;
1933
1934#define AscGetQDoneInProgress(port)         AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
1935#define AscPutQDoneInProgress(port, val)    AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
1936#define AscGetVarFreeQHead(port)            AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
1937#define AscGetVarDoneQTail(port)            AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
1938#define AscPutVarFreeQHead(port, val)       AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
1939#define AscPutVarDoneQTail(port, val)       AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
1940#define AscGetRiscVarFreeQHead(port)        AscReadLramByte((port), ASCV_NEXTRDY_B)
1941#define AscGetRiscVarDoneQTail(port)        AscReadLramByte((port), ASCV_DONENEXT_B)
1942#define AscPutRiscVarFreeQHead(port, val)   AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
1943#define AscPutRiscVarDoneQTail(port, val)   AscWriteLramByte((port), ASCV_DONENEXT_B, val)
1944#define AscPutMCodeSDTRDoneAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
1945#define AscGetMCodeSDTRDoneAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
1946#define AscPutMCodeInitSDTRAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
1947#define AscGetMCodeInitSDTRAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
1948#define AscSynIndexToPeriod(index)        (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1949#define AscGetChipSignatureByte(port)     (uchar)inp((port)+IOP_SIG_BYTE)
1950#define AscGetChipSignatureWord(port)     (ushort)inpw((port)+IOP_SIG_WORD)
1951#define AscGetChipVerNo(port)             (uchar)inp((port)+IOP_VERSION)
1952#define AscGetChipCfgLsw(port)            (ushort)inpw((port)+IOP_CONFIG_LOW)
1953#define AscGetChipCfgMsw(port)            (ushort)inpw((port)+IOP_CONFIG_HIGH)
1954#define AscSetChipCfgLsw(port, data)      outpw((port)+IOP_CONFIG_LOW, data)
1955#define AscSetChipCfgMsw(port, data)      outpw((port)+IOP_CONFIG_HIGH, data)
1956#define AscGetChipEEPCmd(port)            (uchar)inp((port)+IOP_EEP_CMD)
1957#define AscSetChipEEPCmd(port, data)      outp((port)+IOP_EEP_CMD, data)
1958#define AscGetChipEEPData(port)           (ushort)inpw((port)+IOP_EEP_DATA)
1959#define AscSetChipEEPData(port, data)     outpw((port)+IOP_EEP_DATA, data)
1960#define AscGetChipLramAddr(port)          (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1961#define AscSetChipLramAddr(port, addr)    outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1962#define AscGetChipLramData(port)          (ushort)inpw((port)+IOP_RAM_DATA)
1963#define AscSetChipLramData(port, data)    outpw((port)+IOP_RAM_DATA, data)
1964#define AscGetChipIFC(port)               (uchar)inp((port)+IOP_REG_IFC)
1965#define AscSetChipIFC(port, data)          outp((port)+IOP_REG_IFC, data)
1966#define AscGetChipStatus(port)            (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1967#define AscSetChipStatus(port, cs_val)    outpw((port)+IOP_STATUS, cs_val)
1968#define AscGetChipControl(port)           (uchar)inp((port)+IOP_CTRL)
1969#define AscSetChipControl(port, cc_val)   outp((port)+IOP_CTRL, cc_val)
1970#define AscGetChipSyn(port)               (uchar)inp((port)+IOP_SYN_OFFSET)
1971#define AscSetChipSyn(port, data)         outp((port)+IOP_SYN_OFFSET, data)
1972#define AscSetPCAddr(port, data)          outpw((port)+IOP_REG_PC, data)
1973#define AscGetPCAddr(port)                (ushort)inpw((port)+IOP_REG_PC)
1974#define AscIsIntPending(port)             (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1975#define AscGetChipScsiID(port)            ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1976#define AscGetExtraControl(port)          (uchar)inp((port)+IOP_EXTRA_CONTROL)
1977#define AscSetExtraControl(port, data)    outp((port)+IOP_EXTRA_CONTROL, data)
1978#define AscReadChipAX(port)               (ushort)inpw((port)+IOP_REG_AX)
1979#define AscWriteChipAX(port, data)        outpw((port)+IOP_REG_AX, data)
1980#define AscReadChipIX(port)               (uchar)inp((port)+IOP_REG_IX)
1981#define AscWriteChipIX(port, data)        outp((port)+IOP_REG_IX, data)
1982#define AscReadChipIH(port)               (ushort)inpw((port)+IOP_REG_IH)
1983#define AscWriteChipIH(port, data)        outpw((port)+IOP_REG_IH, data)
1984#define AscReadChipQP(port)               (uchar)inp((port)+IOP_REG_QP)
1985#define AscWriteChipQP(port, data)        outp((port)+IOP_REG_QP, data)
1986#define AscReadChipFIFO_L(port)           (ushort)inpw((port)+IOP_REG_FIFO_L)
1987#define AscWriteChipFIFO_L(port, data)    outpw((port)+IOP_REG_FIFO_L, data)
1988#define AscReadChipFIFO_H(port)           (ushort)inpw((port)+IOP_REG_FIFO_H)
1989#define AscWriteChipFIFO_H(port, data)    outpw((port)+IOP_REG_FIFO_H, data)
1990#define AscReadChipDmaSpeed(port)         (uchar)inp((port)+IOP_DMA_SPEED)
1991#define AscWriteChipDmaSpeed(port, data)  outp((port)+IOP_DMA_SPEED, data)
1992#define AscReadChipDA0(port)              (ushort)inpw((port)+IOP_REG_DA0)
1993#define AscWriteChipDA0(port)             outpw((port)+IOP_REG_DA0, data)
1994#define AscReadChipDA1(port)              (ushort)inpw((port)+IOP_REG_DA1)
1995#define AscWriteChipDA1(port)             outpw((port)+IOP_REG_DA1, data)
1996#define AscReadChipDC0(port)              (ushort)inpw((port)+IOP_REG_DC0)
1997#define AscWriteChipDC0(port)             outpw((port)+IOP_REG_DC0, data)
1998#define AscReadChipDC1(port)              (ushort)inpw((port)+IOP_REG_DC1)
1999#define AscWriteChipDC1(port)             outpw((port)+IOP_REG_DC1, data)
2000#define AscReadChipDvcID(port)            (uchar)inp((port)+IOP_REG_ID)
2001#define AscWriteChipDvcID(port, data)     outp((port)+IOP_REG_ID, data)
2002
2003STATIC int       AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
2004STATIC int       AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
2005STATIC void      AscWaitEEPRead(void);
2006STATIC void      AscWaitEEPWrite(void);
2007STATIC ushort    AscReadEEPWord(PortAddr, uchar);
2008STATIC ushort    AscWriteEEPWord(PortAddr, uchar, ushort);
2009STATIC ushort    AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
2010STATIC int       AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
2011STATIC int       AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
2012STATIC int       AscStartChip(PortAddr);
2013STATIC int       AscStopChip(PortAddr);
2014STATIC void      AscSetChipIH(PortAddr, ushort);
2015STATIC int       AscIsChipHalted(PortAddr);
2016STATIC void      AscAckInterrupt(PortAddr);
2017STATIC void      AscDisableInterrupt(PortAddr);
2018STATIC void      AscEnableInterrupt(PortAddr);
2019STATIC void      AscSetBank(PortAddr, uchar);
2020STATIC int       AscResetChipAndScsiBus(ASC_DVC_VAR *);
2021#ifdef CONFIG_ISA
2022STATIC ushort    AscGetIsaDmaChannel(PortAddr);
2023STATIC ushort    AscSetIsaDmaChannel(PortAddr, ushort);
2024STATIC uchar     AscSetIsaDmaSpeed(PortAddr, uchar);
2025STATIC uchar     AscGetIsaDmaSpeed(PortAddr);
2026#endif /* CONFIG_ISA */
2027STATIC uchar     AscReadLramByte(PortAddr, ushort);
2028STATIC ushort    AscReadLramWord(PortAddr, ushort);
2029#if CC_VERY_LONG_SG_LIST
2030STATIC ASC_DCNT  AscReadLramDWord(PortAddr, ushort);
2031#endif /* CC_VERY_LONG_SG_LIST */
2032STATIC void      AscWriteLramWord(PortAddr, ushort, ushort);
2033STATIC void      AscWriteLramByte(PortAddr, ushort, uchar);
2034STATIC ASC_DCNT  AscMemSumLramWord(PortAddr, ushort, int);
2035STATIC void      AscMemWordSetLram(PortAddr, ushort, ushort, int);
2036STATIC void      AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
2037STATIC void      AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
2038STATIC void      AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
2039STATIC ushort    AscInitAscDvcVar(ASC_DVC_VAR *);
2040STATIC ushort    AscInitFromEEP(ASC_DVC_VAR *);
2041STATIC ushort    AscInitFromAscDvcVar(ASC_DVC_VAR *);
2042STATIC ushort    AscInitMicroCodeVar(ASC_DVC_VAR *);
2043STATIC int       AscTestExternalLram(ASC_DVC_VAR *);
2044STATIC uchar     AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
2045STATIC uchar     AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
2046STATIC void      AscSetChipSDTR(PortAddr, uchar, uchar);
2047STATIC uchar     AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
2048STATIC uchar     AscAllocFreeQueue(PortAddr, uchar);
2049STATIC uchar     AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
2050STATIC int       AscHostReqRiscHalt(PortAddr);
2051STATIC int       AscStopQueueExe(PortAddr);
2052STATIC int       AscSendScsiQueue(ASC_DVC_VAR *,
2053                    ASC_SCSI_Q * scsiq,
2054                    uchar n_q_required);
2055STATIC int       AscPutReadyQueue(ASC_DVC_VAR *,
2056                    ASC_SCSI_Q *, uchar);
2057STATIC int       AscPutReadySgListQueue(ASC_DVC_VAR *,
2058                    ASC_SCSI_Q *, uchar);
2059STATIC int       AscSetChipSynRegAtID(PortAddr, uchar, uchar);
2060STATIC int       AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
2061STATIC ushort    AscInitLram(ASC_DVC_VAR *);
2062STATIC ushort    AscInitQLinkVar(ASC_DVC_VAR *);
2063STATIC int       AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
2064STATIC int       AscIsrChipHalted(ASC_DVC_VAR *);
2065STATIC uchar     _AscCopyLramScsiDoneQ(PortAddr, ushort,
2066                    ASC_QDONE_INFO *, ASC_DCNT);
2067STATIC int       AscIsrQDone(ASC_DVC_VAR *);
2068STATIC int       AscCompareString(uchar *, uchar *, int);
2069#ifdef CONFIG_ISA
2070STATIC ushort    AscGetEisaChipCfg(PortAddr);
2071STATIC ASC_DCNT  AscGetEisaProductID(PortAddr);
2072STATIC PortAddr  AscSearchIOPortAddrEISA(PortAddr);
2073STATIC PortAddr  AscSearchIOPortAddr11(PortAddr);
2074STATIC PortAddr  AscSearchIOPortAddr(PortAddr, ushort);
2075STATIC void      AscSetISAPNPWaitForKey(void);
2076#endif /* CONFIG_ISA */
2077STATIC uchar     AscGetChipScsiCtrl(PortAddr);
2078STATIC uchar     AscSetChipScsiID(PortAddr, uchar);
2079STATIC uchar     AscGetChipVersion(PortAddr, ushort);
2080STATIC ushort    AscGetChipBusType(PortAddr);
2081STATIC ASC_DCNT  AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
2082STATIC int       AscFindSignature(PortAddr);
2083STATIC void      AscToggleIRQAct(PortAddr);
2084STATIC uchar     AscGetChipIRQ(PortAddr, ushort);
2085STATIC uchar     AscSetChipIRQ(PortAddr, uchar, ushort);
2086STATIC ushort    AscGetChipBiosAddress(PortAddr, ushort);
2087STATIC inline ulong DvcEnterCritical(void);
2088STATIC inline void DvcLeaveCritical(ulong);
2089#ifdef CONFIG_PCI
2090STATIC uchar     DvcReadPCIConfigByte(ASC_DVC_VAR *, ushort);
2091STATIC void      DvcWritePCIConfigByte(ASC_DVC_VAR *,
2092                    ushort, uchar);
2093#endif /* CONFIG_PCI */
2094STATIC ushort      AscGetChipBiosAddress(PortAddr, ushort);
2095STATIC void      DvcSleepMilliSecond(ASC_DCNT);
2096STATIC void      DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
2097STATIC void      DvcPutScsiQ(PortAddr, ushort, uchar *, int);
2098STATIC void      DvcGetQinfo(PortAddr, ushort, uchar *, int);
2099STATIC ushort    AscInitGetConfig(ASC_DVC_VAR *);
2100STATIC ushort    AscInitSetConfig(ASC_DVC_VAR *);
2101STATIC ushort    AscInitAsc1000Driver(ASC_DVC_VAR *);
2102STATIC void      AscAsyncFix(ASC_DVC_VAR *, uchar,
2103                    ASC_SCSI_INQUIRY *);
2104STATIC int       AscTagQueuingSafe(ASC_SCSI_INQUIRY *);
2105STATIC void      AscInquiryHandling(ASC_DVC_VAR *,
2106                    uchar, ASC_SCSI_INQUIRY *);
2107STATIC int       AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
2108STATIC int       AscISR(ASC_DVC_VAR *);
2109STATIC uint      AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar,
2110                    uchar);
2111STATIC int       AscSgListToQueue(int);
2112#ifdef CONFIG_ISA
2113STATIC void      AscEnableIsaDma(uchar);
2114#endif /* CONFIG_ISA */
2115STATIC ASC_DCNT  AscGetMaxDmaCount(ushort);
2116
2117
2118/*
2119 * --- Adv Library Constants and Macros
2120 */
2121
2122#define ADV_LIB_VERSION_MAJOR  5
2123#define ADV_LIB_VERSION_MINOR  14
2124
2125/* d_os_dep.h */
2126#define ADV_OS_LINUX
2127
2128/*
2129 * Define Adv Library required special types.
2130 */
2131
2132/*
2133 * Portable Data Types
2134 *
2135 * Any instance where a 32-bit long or pointer type is assumed
2136 * for precision or HW defined structures, the following define
2137 * types must be used. In Linux the char, short, and int types
2138 * are all consistent at 8, 16, and 32 bits respectively. Pointers
2139 * and long types are 64 bits on Alpha and UltraSPARC.
2140 */
2141#define ADV_PADDR __u32         /* Physical address data type. */
2142#define ADV_VADDR __u32         /* Virtual address data type. */
2143#define ADV_DCNT  __u32         /* Unsigned Data count type. */
2144#define ADV_SDCNT __s32         /* Signed Data count type. */
2145
2146/*
2147 * These macros are used to convert a virtual address to a
2148 * 32-bit value. This currently can be used on Linux Alpha
2149 * which uses 64-bit virtual address but a 32-bit bus address.
2150 * This is likely to break in the future, but doing this now
2151 * will give us time to change the HW and FW to handle 64-bit
2152 * addresses.
2153 */
2154#define ADV_VADDR_TO_U32   virt_to_bus
2155#define ADV_U32_TO_VADDR   bus_to_virt
2156
2157#define AdvPortAddr  ulong              /* Virtual memory address size */
2158
2159/*
2160 * Define Adv Library required memory access macros.
2161 */
2162#define ADV_MEM_READB(addr) readb(addr)
2163#define ADV_MEM_READW(addr) readw(addr)
2164#define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
2165#define ADV_MEM_WRITEW(addr, word) writew(word, addr)
2166#define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
2167
2168#define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
2169
2170/*
2171 * For wide  boards a CDB length maximum of 16 bytes
2172 * is supported.
2173 */
2174#define ADV_MAX_CDB_LEN     16
2175
2176/*
2177 * Define total number of simultaneous maximum element scatter-gather
2178 * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
2179 * maximum number of outstanding commands per wide host adapter. Each
2180 * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
2181 * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
2182 * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
2183 * structures or 255 scatter-gather elements.
2184 *
2185 */
2186#define ADV_TOT_SG_BLOCK        ASC_DEF_MAX_HOST_QNG
2187
2188/*
2189 * Define Adv Library required maximum number of scatter-gather
2190 * elements per request.
2191 */
2192#define ADV_MAX_SG_LIST         255
2193
2194/* Number of SG blocks needed. */
2195#define ADV_NUM_SG_BLOCK \
2196    ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
2197
2198/* Total contiguous memory needed for SG blocks. */
2199#define ADV_SG_TOTAL_MEM_SIZE \
2200    (sizeof(ADV_SG_BLOCK) *  ADV_NUM_SG_BLOCK)
2201
2202#define ADV_PAGE_SIZE PAGE_SIZE
2203
2204#define ADV_NUM_PAGE_CROSSING \
2205    ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2206
2207/* a_condor.h */
2208#define ADV_PCI_VENDOR_ID               0x10CD
2209#define ADV_PCI_DEVICE_ID_REV_A         0x2300
2210#define ADV_PCI_DEVID_38C0800_REV1      0x2500
2211#define ADV_PCI_DEVID_38C1600_REV1      0x2700
2212
2213#define ADV_EEP_DVC_CFG_BEGIN           (0x00)
2214#define ADV_EEP_DVC_CFG_END             (0x15)
2215#define ADV_EEP_DVC_CTL_BEGIN           (0x16)  /* location of OEM name */
2216#define ADV_EEP_MAX_WORD_ADDR           (0x1E)
2217
2218#define ADV_EEP_DELAY_MS                100
2219
2220#define ADV_EEPROM_BIG_ENDIAN          0x8000   /* EEPROM Bit 15 */
2221#define ADV_EEPROM_BIOS_ENABLE         0x4000   /* EEPROM Bit 14 */
2222/*
2223 * For the ASC3550 Bit 13 is Termination Polarity control bit.
2224 * For later ICs Bit 13 controls whether the CIS (Card Information
2225 * Service Section) is loaded from EEPROM.
2226 */
2227#define ADV_EEPROM_TERM_POL            0x2000   /* EEPROM Bit 13 */
2228#define ADV_EEPROM_CIS_LD              0x2000   /* EEPROM Bit 13 */
2229/*
2230 * ASC38C1600 Bit 11
2231 *
2232 * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
2233 * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
2234 * Function 0 will specify INT B.
2235 *
2236 * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
2237 * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
2238 * Function 1 will specify INT A.
2239 */
2240#define ADV_EEPROM_INTAB               0x0800   /* EEPROM Bit 11 */
2241
2242typedef struct adveep_3550_config
2243{
2244                                /* Word Offset, Description */
2245
2246  ushort cfg_lsw;               /* 00 power up initialization */
2247                                /*  bit 13 set - Term Polarity Control */
2248                                /*  bit 14 set - BIOS Enable */
2249                                /*  bit 15 set - Big Endian Mode */
2250  ushort cfg_msw;               /* 01 unused      */
2251  ushort disc_enable;           /* 02 disconnect enable */
2252  ushort wdtr_able;             /* 03 Wide DTR able */
2253  ushort sdtr_able;             /* 04 Synchronous DTR able */
2254  ushort start_motor;           /* 05 send start up motor */
2255  ushort tagqng_able;           /* 06 tag queuing able */
2256  ushort bios_scan;             /* 07 BIOS device control */
2257  ushort scam_tolerant;         /* 08 no scam */
2258
2259  uchar  adapter_scsi_id;       /* 09 Host Adapter ID */
2260  uchar  bios_boot_delay;       /*    power up wait */
2261
2262  uchar  scsi_reset_delay;      /* 10 reset delay */
2263  uchar  bios_id_lun;           /*    first boot device scsi id & lun */
2264                                /*    high nibble is lun */
2265                                /*    low nibble is scsi id */
2266
2267  uchar  termination;           /* 11 0 - automatic */
2268                                /*    1 - low off / high off */
2269                                /*    2 - low off / high on */
2270                                /*    3 - low on  / high on */
2271                                /*    There is no low on  / high off */
2272
2273  uchar  reserved1;             /*    reserved byte (not used) */
2274
2275  ushort bios_ctrl;             /* 12 BIOS control bits */
2276                                /*  bit 0  BIOS don't act as initiator. */
2277                                /*  bit 1  BIOS > 1 GB support */
2278                                /*  bit 2  BIOS > 2 Disk Support */
2279                                /*  bit 3  BIOS don't support removables */
2280                                /*  bit 4  BIOS support bootable CD */
2281                                /*  bit 5  BIOS scan enabled */
2282                                /*  bit 6  BIOS support multiple LUNs */
2283                                /*  bit 7  BIOS display of message */
2284                                /*  bit 8  SCAM disabled */
2285                                /*  bit 9  Reset SCSI bus during init. */
2286                                /*  bit 10 */
2287                                /*  bit 11 No verbose initialization. */
2288                                /*  bit 12 SCSI parity enabled */
2289                                /*  bit 13 */
2290                                /*  bit 14 */
2291                                /*  bit 15 */
2292  ushort  ultra_able;           /* 13 ULTRA speed able */
2293  ushort  reserved2;            /* 14 reserved */
2294  uchar   max_host_qng;         /* 15 maximum host queuing */
2295  uchar   max_dvc_qng;          /*    maximum per device queuing */
2296  ushort  dvc_cntl;             /* 16 control bit for driver */
2297  ushort  bug_fix;              /* 17 control bit for bug fix */
2298  ushort  serial_number_word1;  /* 18 Board serial number word 1 */
2299  ushort  serial_number_word2;  /* 19 Board serial number word 2 */
2300  ushort  serial_number_word3;  /* 20 Board serial number word 3 */
2301  ushort  check_sum;            /* 21 EEP check sum */
2302  uchar   oem_name[16];         /* 22 OEM name */
2303  ushort  dvc_err_code;         /* 30 last device driver error code */
2304  ushort  adv_err_code;         /* 31 last uc and Adv Lib error code */
2305  ushort  adv_err_addr;         /* 32 last uc error address */
2306  ushort  saved_dvc_err_code;   /* 33 saved last dev. driver error code   */
2307  ushort  saved_adv_err_code;   /* 34 saved last uc and Adv Lib error code */
2308  ushort  saved_adv_err_addr;   /* 35 saved last uc error address         */
2309  ushort  num_of_err;           /* 36 number of error */
2310} ADVEEP_3550_CONFIG;
2311
2312typedef struct adveep_38C0800_config
2313{
2314                                /* Word Offset, Description */
2315
2316  ushort cfg_lsw;               /* 00 power up initialization */
2317                                /*  bit 13 set - Load CIS */
2318                                /*  bit 14 set - BIOS Enable */
2319                                /*  bit 15 set - Big Endian Mode */
2320  ushort cfg_msw;               /* 01 unused      */
2321  ushort disc_enable;           /* 02 disconnect enable */
2322  ushort wdtr_able;             /* 03 Wide DTR able */
2323  ushort sdtr_speed1;           /* 04 SDTR Speed TID 0-3 */
2324  ushort start_motor;           /* 05 send start up motor */
2325  ushort tagqng_able;           /* 06 tag queuing able */
2326  ushort bios_scan;             /* 07 BIOS device control */
2327  ushort scam_tolerant;         /* 08 no scam */
2328
2329  uchar  adapter_scsi_id;       /* 09 Host Adapter ID */
2330  uchar  bios_boot_delay;       /*    power up wait */
2331
2332  uchar  scsi_reset_delay;      /* 10 reset delay */
2333  uchar  bios_id_lun;           /*    first boot device scsi id & lun */
2334                                /*    high nibble is lun */
2335                                /*    low nibble is scsi id */
2336
2337  uchar  termination_se;        /* 11 0 - automatic */
2338                                /*    1 - low off / high off */
2339                                /*    2 - low off / high on */
2340                                /*    3 - low on  / high on */
2341                                /*    There is no low on  / high off */
2342
2343  uchar  termination_lvd;       /* 11 0 - automatic */
2344                                /*    1 - low off / high off */
2345                                /*    2 - low off / high on */
2346                                /*    3 - low on  / high on */
2347                                /*    There is no low on  / high off */
2348
2349  ushort bios_ctrl;             /* 12 BIOS control bits */
2350                                /*  bit 0  BIOS don't act as initiator. */
2351                                /*  bit 1  BIOS > 1 GB support */
2352                                /*  bit 2  BIOS > 2 Disk Support */
2353                                /*  bit 3  BIOS don't support removables */
2354                                /*  bit 4  BIOS support bootable CD */
2355                                /*  bit 5  BIOS scan enabled */
2356                                /*  bit 6  BIOS support multiple LUNs */
2357                                /*  bit 7  BIOS display of message */
2358                                /*  bit 8  SCAM disabled */
2359                                /*  bit 9  Reset SCSI bus during init. */
2360                                /*  bit 10 */
2361                                /*  bit 11 No verbose initialization. */
2362                                /*  bit 12 SCSI parity enabled */
2363                                /*  bit 13 */
2364                                /*  bit 14 */
2365                                /*  bit 15 */
2366  ushort  sdtr_speed2;          /* 13 SDTR speed TID 4-7 */
2367  ushort  sdtr_speed3;          /* 14 SDTR speed TID 8-11 */
2368  uchar   max_host_qng;         /* 15 maximum host queueing */
2369  uchar   max_dvc_qng;          /*    maximum per device queuing */
2370  ushort  dvc_cntl;             /* 16 control bit for driver */
2371  ushort  sdtr_speed4;          /* 17 SDTR speed 4 TID 12-15 */
2372  ushort  serial_number_word1;  /* 18 Board serial number word 1 */
2373  ushort  serial_number_word2;  /* 19 Board serial number word 2 */
2374  ushort  serial_number_word3;  /* 20 Board serial number word 3 */
2375  ushort  check_sum;            /* 21 EEP check sum */
2376  uchar   oem_name[16];         /* 22 OEM name */
2377  ushort  dvc_err_code;         /* 30 last device driver error code */
2378  ushort  adv_err_code;         /* 31 last uc and Adv Lib error code */
2379  ushort  adv_err_addr;         /* 32 last uc error address */
2380  ushort  saved_dvc_err_code;   /* 33 saved last dev. driver error code   */
2381  ushort  saved_adv_err_code;   /* 34 saved last uc and Adv Lib error code */
2382  ushort  saved_adv_err_addr;   /* 35 saved last uc error address         */
2383  ushort  reserved36;           /* 36 reserved */
2384  ushort  reserved37;           /* 37 reserved */
2385  ushort  reserved38;           /* 38 reserved */
2386  ushort  reserved39;           /* 39 reserved */
2387  ushort  reserved40;           /* 40 reserved */
2388  ushort  reserved41;           /* 41 reserved */
2389  ushort  reserved42;           /* 42 reserved */
2390  ushort  reserved43;           /* 43 reserved */
2391  ushort  reserved44;           /* 44 reserved */
2392  ushort  reserved45;           /* 45 reserved */
2393  ushort  reserved46;           /* 46 reserved */
2394  ushort  reserved47;           /* 47 reserved */
2395  ushort  reserved48;           /* 48 reserved */
2396  ushort  reserved49;           /* 49 reserved */
2397  ushort  reserved50;           /* 50 reserved */
2398  ushort  reserved51;           /* 51 reserved */
2399  ushort  reserved52;           /* 52 reserved */
2400  ushort  reserved53;           /* 53 reserved */
2401  ushort  reserved54;           /* 54 reserved */
2402  ushort  reserved55;           /* 55 reserved */
2403  ushort  cisptr_lsw;           /* 56 CIS PTR LSW */
2404  ushort  cisprt_msw;           /* 57 CIS PTR MSW */
2405  ushort  subsysvid;            /* 58 SubSystem Vendor ID */
2406  ushort  subsysid;             /* 59 SubSystem ID */
2407  ushort  reserved60;           /* 60 reserved */
2408  ushort  reserved61;           /* 61 reserved */
2409  ushort  reserved62;           /* 62 reserved */
2410  ushort  reserved63;           /* 63 reserved */
2411} ADVEEP_38C0800_CONFIG;
2412
2413typedef struct adveep_38C1600_config
2414{
2415                                /* Word Offset, Description */
2416
2417  ushort cfg_lsw;               /* 00 power up initialization */
2418                                /*  bit 11 set - Func. 0 INTB, Func. 1 INTA */
2419                                /*       clear - Func. 0 INTA, Func. 1 INTB */
2420                                /*  bit 13 set - Load CIS */
2421                                /*  bit 14 set - BIOS Enable */
2422                                /*  bit 15 set - Big Endian Mode */
2423  ushort cfg_msw;               /* 01 unused */
2424  ushort disc_enable;           /* 02 disconnect enable */
2425  ushort wdtr_able;             /* 03 Wide DTR able */
2426  ushort sdtr_speed1;           /* 04 SDTR Speed TID 0-3 */
2427  ushort start_motor;           /* 05 send start up motor */
2428  ushort tagqng_able;           /* 06 tag queuing able */
2429  ushort bios_scan;             /* 07 BIOS device control */
2430  ushort scam_tolerant;         /* 08 no scam */
2431
2432  uchar  adapter_scsi_id;       /* 09 Host Adapter ID */
2433  uchar  bios_boot_delay;       /*    power up wait */
2434
2435  uchar  scsi_reset_delay;      /* 10 reset delay */
2436  uchar  bios_id_lun;           /*    first boot device scsi id & lun */
2437                                /*    high nibble is lun */
2438                                /*    low nibble is scsi id */
2439
2440  uchar  termination_se;        /* 11 0 - automatic */
2441                                /*    1 - low off / high off */
2442                                /*    2 - low off / high on */
2443                                /*    3 - low on  / high on */
2444                                /*    There is no low on  / high off */
2445
2446  uchar  termination_lvd;       /* 11 0 - automatic */
2447                                /*    1 - low off / high off */
2448                                /*    2 - low off / high on */
2449                                /*    3 - low on  / high on */
2450                                /*    There is no low on  / high off */
2451
2452  ushort bios_ctrl;             /* 12 BIOS control bits */
2453                                /*  bit 0  BIOS don't act as initiator. */
2454                                /*  bit 1  BIOS > 1 GB support */
2455                                /*  bit 2  BIOS > 2 Disk Support */
2456                                /*  bit 3  BIOS don't support removables */
2457                                /*  bit 4  BIOS support bootable CD */
2458                                /*  bit 5  BIOS scan enabled */
2459                                /*  bit 6  BIOS support multiple LUNs */
2460                                /*  bit 7  BIOS display of message */
2461                                /*  bit 8  SCAM disabled */
2462                                /*  bit 9  Reset SCSI bus during init. */
2463                                /*  bit 10 Basic Integrity Checking disabled */
2464                                /*  bit 11 No verbose initialization. */
2465                                /*  bit 12 SCSI parity enabled */
2466                                /*  bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
2467                                /*  bit 14 */
2468                                /*  bit 15 */
2469  ushort  sdtr_speed2;          /* 13 SDTR speed TID 4-7 */
2470  ushort  sdtr_speed3;          /* 14 SDTR speed TID 8-11 */
2471  uchar   max_host_qng;         /* 15 maximum host queueing */
2472  uchar   max_dvc_qng;          /*    maximum per device queuing */
2473  ushort  dvc_cntl;             /* 16 control bit for driver */
2474  ushort  sdtr_speed4;          /* 17 SDTR speed 4 TID 12-15 */
2475  ushort  serial_number_word1;  /* 18 Board serial number word 1 */
2476  ushort  serial_number_word2;  /* 19 Board serial number word 2 */
2477  ushort  serial_number_word3;  /* 20 Board serial number word 3 */
2478  ushort  check_sum;            /* 21 EEP check sum */
2479  uchar   oem_name[16];         /* 22 OEM name */
2480  ushort  dvc_err_code;         /* 30 last device driver error code */
2481  ushort  adv_err_code;         /* 31 last uc and Adv Lib error code */
2482  ushort  adv_err_addr;         /* 32 last uc error address */
2483  ushort  saved_dvc_err_code;   /* 33 saved last dev. driver error code   */
2484  ushort  saved_adv_err_code;   /* 34 saved last uc and Adv Lib error code */
2485  ushort  saved_adv_err_addr;   /* 35 saved last uc error address         */
2486  ushort  reserved36;           /* 36 reserved */
2487  ushort  reserved37;           /* 37 reserved */
2488  ushort  reserved38;           /* 38 reserved */
2489  ushort  reserved39;           /* 39 reserved */
2490  ushort  reserved40;           /* 40 reserved */
2491  ushort  reserved41;           /* 41 reserved */
2492  ushort  reserved42;           /* 42 reserved */
2493  ushort  reserved43;           /* 43 reserved */
2494  ushort  reserved44;           /* 44 reserved */
2495  ushort  reserved45;           /* 45 reserved */
2496  ushort  reserved46;           /* 46 reserved */
2497  ushort  reserved47;           /* 47 reserved */
2498  ushort  reserved48;           /* 48 reserved */
2499  ushort  reserved49;           /* 49 reserved */
2500  ushort  reserved50;           /* 50 reserved */
2501  ushort  reserved51;           /* 51 reserved */
2502  ushort  reserved52;           /* 52 reserved */
2503  ushort  reserved53;           /* 53 reserved */
2504  ushort  reserved54;           /* 54 reserved */
2505  ushort  reserved55;           /* 55 reserved */
2506  ushort  cisptr_lsw;           /* 56 CIS PTR LSW */
2507  ushort  cisprt_msw;           /* 57 CIS PTR MSW */
2508  ushort  subsysvid;            /* 58 SubSystem Vendor ID */
2509  ushort  subsysid;             /* 59 SubSystem ID */
2510  ushort  reserved60;           /* 60 reserved */
2511  ushort  reserved61;           /* 61 reserved */
2512  ushort  reserved62;           /* 62 reserved */
2513  ushort  reserved63;           /* 63 reserved */
2514} ADVEEP_38C1600_CONFIG;
2515
2516/*
2517 * EEPROM Commands
2518 */
2519#define ASC_EEP_CMD_DONE             0x0200
2520#define ASC_EEP_CMD_DONE_ERR         0x0001
2521
2522/* cfg_word */
2523#define EEP_CFG_WORD_BIG_ENDIAN      0x8000
2524
2525/* bios_ctrl */
2526#define BIOS_CTRL_BIOS               0x0001
2527#define BIOS_CTRL_EXTENDED_XLAT      0x0002
2528#define BIOS_CTRL_GT_2_DISK          0x0004
2529#define BIOS_CTRL_BIOS_REMOVABLE     0x0008
2530#define BIOS_CTRL_BOOTABLE_CD        0x0010
2531#define BIOS_CTRL_MULTIPLE_LUN       0x0040
2532#define BIOS_CTRL_DISPLAY_MSG        0x0080
2533#define BIOS_CTRL_NO_SCAM            0x0100
2534#define BIOS_CTRL_RESET_SCSI_BUS     0x0200
2535#define BIOS_CTRL_INIT_VERBOSE       0x0800
2536#define BIOS_CTRL_SCSI_PARITY        0x1000
2537#define BIOS_CTRL_AIPP_DIS           0x2000
2538
2539#define ADV_3550_MEMSIZE   0x2000       /* 8 KB Internal Memory */
2540#define ADV_3550_IOLEN     0x40         /* I/O Port Range in bytes */
2541
2542#define ADV_38C0800_MEMSIZE  0x4000     /* 16 KB Internal Memory */
2543#define ADV_38C0800_IOLEN    0x100      /* I/O Port Range in bytes */
2544
2545/*
2546 * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
2547 * a special 16K Adv Library and Microcode version. After the issue is
2548 * resolved, should restore 32K support.
2549 *
2550 * #define ADV_38C1600_MEMSIZE  0x8000L   * 32 KB Internal Memory *
2551 */
2552#define ADV_38C1600_MEMSIZE  0x4000   /* 16 KB Internal Memory */
2553#define ADV_38C1600_IOLEN    0x100     /* I/O Port Range 256 bytes */
2554#define ADV_38C1600_MEMLEN   0x1000    /* Memory Range 4KB bytes */
2555
2556/*
2557 * Byte I/O register address from base of 'iop_base'.
2558 */
2559#define IOPB_INTR_STATUS_REG    0x00
2560#define IOPB_CHIP_ID_1          0x01
2561#define IOPB_INTR_ENABLES       0x02
2562#define IOPB_CHIP_TYPE_REV      0x03
2563#define IOPB_RES_ADDR_4         0x04
2564#define IOPB_RES_ADDR_5         0x05
2565#define IOPB_RAM_DATA           0x06
2566#define IOPB_RES_ADDR_7         0x07
2567#define IOPB_FLAG_REG           0x08
2568#define IOPB_RES_ADDR_9         0x09
2569#define IOPB_RISC_CSR           0x0A
2570#define IOPB_RES_ADDR_B         0x0B
2571#define IOPB_RES_ADDR_C         0x0C
2572#define IOPB_RES_ADDR_D         0x0D
2573#define IOPB_SOFT_OVER_WR       0x0E
2574#define IOPB_RES_ADDR_F         0x0F
2575#define IOPB_MEM_CFG            0x10
2576#define IOPB_RES_ADDR_11        0x11
2577#define IOPB_GPIO_DATA          0x12
2578#define IOPB_RES_ADDR_13        0x13
2579#define IOPB_FLASH_PAGE         0x14
2580#define IOPB_RES_ADDR_15        0x15
2581#define IOPB_GPIO_CNTL          0x16
2582#define IOPB_RES_ADDR_17        0x17
2583#define IOPB_FLASH_DATA         0x18
2584#define IOPB_RES_ADDR_19        0x19
2585#define IOPB_RES_ADDR_1A        0x1A
2586#define IOPB_RES_ADDR_1B        0x1B
2587#define IOPB_RES_ADDR_1C        0x1C
2588#define IOPB_RES_ADDR_1D        0x1D
2589#define IOPB_RES_ADDR_1E        0x1E
2590#define IOPB_RES_ADDR_1F        0x1F
2591#define IOPB_DMA_CFG0           0x20
2592#define IOPB_DMA_CFG1           0x21
2593#define IOPB_TICKLE             0x22
2594#define IOPB_DMA_REG_WR         0x23
2595#define IOPB_SDMA_STATUS        0x24
2596#define IOPB_SCSI_BYTE_CNT      0x25
2597#define IOPB_HOST_BYTE_CNT      0x26
2598#define IOPB_BYTE_LEFT_TO_XFER  0x27
2599#define IOPB_BYTE_TO_XFER_0     0x28
2600#define IOPB_BYTE_TO_XFER_1     0x29
2601#define IOPB_BYTE_TO_XFER_2     0x2A
2602#define IOPB_BYTE_TO_XFER_3     0x2B
2603#define IOPB_ACC_GRP            0x2C
2604#define IOPB_RES_ADDR_2D        0x2D
2605#define IOPB_DEV_ID             0x2E
2606#define IOPB_RES_ADDR_2F        0x2F
2607#define IOPB_SCSI_DATA          0x30
2608#define IOPB_RES_ADDR_31        0x31
2609#define IOPB_RES_ADDR_32        0x32
2610#define IOPB_SCSI_DATA_HSHK     0x33
2611#define IOPB_SCSI_CTRL          0x34
2612#define IOPB_RES_ADDR_35        0x35
2613#define IOPB_RES_ADDR_36        0x36
2614#define IOPB_RES_ADDR_37        0x37
2615#define IOPB_RAM_BIST           0x38
2616#define IOPB_PLL_TEST           0x39
2617#define IOPB_PCI_INT_CFG        0x3A
2618#define IOPB_RES_ADDR_3B        0x3B
2619#define IOPB_RFIFO_CNT          0x3C
2620#define IOPB_RES_ADDR_3D        0x3D
2621#define IOPB_RES_ADDR_3E        0x3E
2622#define IOPB_RES_ADDR_3F        0x3F
2623
2624/*
2625 * Word I/O register address from base of 'iop_base'.
2626 */
2627#define IOPW_CHIP_ID_0          0x00  /* CID0  */
2628#define IOPW_CTRL_REG           0x02  /* CC    */
2629#define IOPW_RAM_ADDR           0x04  /* LA    */
2630#define IOPW_RAM_DATA           0x06  /* LD    */
2631#define IOPW_RES_ADDR_08        0x08
2632#define IOPW_RISC_CSR           0x0A  /* CSR   */
2633#define IOPW_SCSI_CFG0          0x0C  /* CFG0  */
2634#define IOPW_SCSI_CFG1          0x0E  /* CFG1  */
2635#define IOPW_RES_ADDR_10        0x10
2636#define IOPW_SEL_MASK           0x12  /* SM    */
2637#define IOPW_RES_ADDR_14        0x14
2638#define IOPW_FLASH_ADDR         0x16  /* FA    */
2639#define IOPW_RES_ADDR_18        0x18
2640#define IOPW_EE_CMD             0x1A  /* EC    */
2641#define IOPW_EE_DATA            0x1C  /* ED    */
2642#define IOPW_SFIFO_CNT          0x1E  /* SFC   */
2643#define IOPW_RES_ADDR_20        0x20
2644#define IOPW_Q_BASE             0x22  /* QB    */
2645#define IOPW_QP                 0x24  /* QP    */
2646#define IOPW_IX                 0x26  /* IX    */
2647#define IOPW_SP                 0x28  /* SP    */
2648#define IOPW_PC                 0x2A  /* PC    */
2649#define IOPW_RES_ADDR_2C        0x2C
2650#define IOPW_RES_ADDR_2E        0x2E
2651#define IOPW_SCSI_DATA          0x30  /* SD    */
2652#define IOPW_SCSI_DATA_HSHK     0x32  /* SDH   */
2653#define IOPW_SCSI_CTRL          0x34  /* SC    */
2654#define IOPW_HSHK_CFG           0x36  /* HCFG  */
2655#define IOPW_SXFR_STATUS        0x36  /* SXS   */
2656#define IOPW_SXFR_CNTL          0x38  /* SXL   */
2657#define IOPW_SXFR_CNTH          0x3A  /* SXH   */
2658#define IOPW_RES_ADDR_3C        0x3C
2659#define IOPW_RFIFO_DATA         0x3E  /* RFD   */
2660
2661/*
2662 * Doubleword I/O register address from base of 'iop_base'.
2663 */
2664#define IOPDW_RES_ADDR_0         0x00
2665#define IOPDW_RAM_DATA           0x04
2666#define IOPDW_RES_ADDR_8         0x08
2667#define IOPDW_RES_ADDR_C         0x0C
2668#define IOPDW_RES_ADDR_10        0x10
2669#define IOPDW_COMMA              0x14
2670#define IOPDW_COMMB              0x18
2671#define IOPDW_RES_ADDR_1C        0x1C
2672#define IOPDW_SDMA_ADDR0         0x20
2673#define IOPDW_SDMA_ADDR1         0x24
2674#define IOPDW_SDMA_COUNT         0x28
2675#define IOPDW_SDMA_ERROR         0x2C
2676#define IOPDW_RDMA_ADDR0         0x30
2677#define IOPDW_RDMA_ADDR1         0x34
2678#define IOPDW_RDMA_COUNT         0x38
2679#define IOPDW_RDMA_ERROR         0x3C
2680
2681#define ADV_CHIP_ID_BYTE         0x25
2682#define ADV_CHIP_ID_WORD         0x04C1
2683
2684#define ADV_SC_SCSI_BUS_RESET    0x2000
2685
2686#define ADV_INTR_ENABLE_HOST_INTR                   0x01
2687#define ADV_INTR_ENABLE_SEL_INTR                    0x02
2688#define ADV_INTR_ENABLE_DPR_INTR                    0x04
2689#define ADV_INTR_ENABLE_RTA_INTR                    0x08
2690#define ADV_INTR_ENABLE_RMA_INTR                    0x10
2691#define ADV_INTR_ENABLE_RST_INTR                    0x20
2692#define ADV_INTR_ENABLE_DPE_INTR                    0x40
2693#define ADV_INTR_ENABLE_GLOBAL_INTR                 0x80
2694
2695#define ADV_INTR_STATUS_INTRA            0x01
2696#define ADV_INTR_STATUS_INTRB            0x02
2697#define ADV_INTR_STATUS_INTRC            0x04
2698
2699#define ADV_RISC_CSR_STOP           (0x0000)
2700#define ADV_RISC_TEST_COND          (0x2000)
2701#define ADV_RISC_CSR_RUN            (0x4000)
2702#define ADV_RISC_CSR_SINGLE_STEP    (0x8000)
2703
2704#define ADV_CTRL_REG_HOST_INTR      0x0100
2705#define ADV_CTRL_REG_SEL_INTR       0x0200
2706#define ADV_CTRL_REG_DPR_INTR       0x0400
2707#define ADV_CTRL_REG_RTA_INTR       0x0800
2708#define ADV_CTRL_REG_RMA_INTR       0x1000
2709#define ADV_CTRL_REG_RES_BIT14      0x2000
2710#define ADV_CTRL_REG_DPE_INTR       0x4000
2711#define ADV_CTRL_REG_POWER_DONE     0x8000
2712#define ADV_CTRL_REG_ANY_INTR       0xFF00
2713
2714#define ADV_CTRL_REG_CMD_RESET             0x00C6
2715#define ADV_CTRL_REG_CMD_WR_IO_REG         0x00C5
2716#define ADV_CTRL_REG_CMD_RD_IO_REG         0x00C4
2717#define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE  0x00C3
2718#define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE  0x00C2
2719
2720#define ADV_TICKLE_NOP                      0x00
2721#define ADV_TICKLE_A                        0x01
2722#define ADV_TICKLE_B                        0x02
2723#define ADV_TICKLE_C                        0x03
2724
2725#define ADV_SCSI_CTRL_RSTOUT        0x2000
2726
2727#define AdvIsIntPending(port) \
2728    (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
2729
2730/*
2731 * SCSI_CFG0 Register bit definitions
2732 */
2733#define TIMER_MODEAB    0xC000  /* Watchdog, Second, and Select. Timer Ctrl. */
2734#define PARITY_EN       0x2000  /* Enable SCSI Parity Error detection */
2735#define EVEN_PARITY     0x1000  /* Select Even Parity */
2736#define WD_LONG         0x0800  /* Watchdog Interval, 1: 57 min, 0: 13 sec */
2737#define QUEUE_128       0x0400  /* Queue Size, 1: 128 byte, 0: 64 byte */
2738#define PRIM_MODE       0x0100  /* Primitive SCSI mode */
2739#define SCAM_EN         0x0080  /* Enable SCAM selection */
2740#define SEL_TMO_LONG    0x0040  /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
2741#define CFRM_ID         0x0020  /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
2742#define OUR_ID_EN       0x0010  /* Enable OUR_ID bits */
2743#define OUR_ID          0x000F  /* SCSI ID */
2744
2745/*
2746 * SCSI_CFG1 Register bit definitions
2747 */
2748#define BIG_ENDIAN      0x8000  /* Enable Big Endian Mode MIO:15, EEP:15 */
2749#define TERM_POL        0x2000  /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
2750#define SLEW_RATE       0x1000  /* SCSI output buffer slew rate */
2751#define FILTER_SEL      0x0C00  /* Filter Period Selection */
2752#define  FLTR_DISABLE    0x0000  /* Input Filtering Disabled */
2753#define  FLTR_11_TO_20NS 0x0800  /* Input Filtering 11ns to 20ns */
2754#define  FLTR_21_TO_39NS 0x0C00  /* Input Filtering 21ns to 39ns */
2755#define ACTIVE_DBL      0x0200  /* Disable Active Negation */
2756#define DIFF_MODE       0x0100  /* SCSI differential Mode (Read-Only) */
2757#define DIFF_SENSE      0x0080  /* 1: No SE cables, 0: SE cable (Read-Only) */
2758#define TERM_CTL_SEL    0x0040  /* Enable TERM_CTL_H and TERM_CTL_L */
2759#define TERM_CTL        0x0030  /* External SCSI Termination Bits */
2760#define  TERM_CTL_H      0x0020  /* Enable External SCSI Upper Termination */
2761#define  TERM_CTL_L      0x0010  /* Enable External SCSI Lower Termination */
2762#define CABLE_DETECT    0x000F  /* External SCSI Cable Connection Status */
2763
2764/*
2765 * Addendum for ASC-38C0800 Chip
2766 *
2767 * The ASC-38C1600 Chip uses the same definitions except that the
2768 * bus mode override bits [12:10] have been moved to byte register
2769 * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
2770 * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
2771 * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
2772 * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
2773 * and [1:0]. Bits [14], [7:6], [3:2] are unused.
2774 */
2775#define DIS_TERM_DRV    0x4000  /* 1: Read c_det[3:0], 0: cannot read */
2776#define HVD_LVD_SE      0x1C00  /* Device Detect Bits */
2777#define  HVD             0x1000  /* HVD Device Detect */
2778#define  LVD             0x0800  /* LVD Device Detect */
2779#define  SE              0x0400  /* SE Device Detect */
2780#define TERM_LVD        0x00C0  /* LVD Termination Bits */
2781#define  TERM_LVD_HI     0x0080  /* Enable LVD Upper Termination */
2782#define  TERM_LVD_LO     0x0040  /* Enable LVD Lower Termination */
2783#define TERM_SE         0x0030  /* SE Termination Bits */
2784#define  TERM_SE_HI      0x0020  /* Enable SE Upper Termination */
2785#define  TERM_SE_LO      0x0010  /* Enable SE Lower Termination */
2786#define C_DET_LVD       0x000C  /* LVD Cable Detect Bits */
2787#define  C_DET3          0x0008  /* Cable Detect for LVD External Wide */
2788#define  C_DET2          0x0004  /* Cable Detect for LVD Internal Wide */
2789#define C_DET_SE        0x0003  /* SE Cable Detect Bits */
2790#define  C_DET1          0x0002  /* Cable Detect for SE Internal Wide */
2791#define  C_DET0          0x0001  /* Cable Detect for SE Internal Narrow */
2792
2793
2794#define CABLE_ILLEGAL_A 0x7
2795    /* x 0 0 0  | on  on | Illegal (all 3 connectors are used) */
2796
2797#define CABLE_ILLEGAL_B 0xB
2798    /* 0 x 0 0  | on  on | Illegal (all 3 connectors are used) */
2799
2800/*
2801 * MEM_CFG Register bit definitions
2802 */
2803#define BIOS_EN         0x40    /* BIOS Enable MIO:14,EEP:14 */
2804#define FAST_EE_CLK     0x20    /* Diagnostic Bit */
2805#define RAM_SZ          0x1C    /* Specify size of RAM to RISC */
2806#define  RAM_SZ_2KB      0x00    /* 2 KB */
2807#define  RAM_SZ_4KB      0x04    /* 4 KB */
2808#define  RAM_SZ_8KB      0x08    /* 8 KB */
2809#define  RAM_SZ_16KB     0x0C    /* 16 KB */
2810#define  RAM_SZ_32KB     0x10    /* 32 KB */
2811#define  RAM_SZ_64KB     0x14    /* 64 KB */
2812
2813/*
2814 * DMA_CFG0 Register bit definitions
2815 *
2816 * This register is only accessible to the host.
2817 */
2818#define BC_THRESH_ENB   0x80    /* PCI DMA Start Conditions */
2819#define FIFO_THRESH     0x70    /* PCI DMA FIFO Threshold */
2820#define  FIFO_THRESH_16B  0x00   /* 16 bytes */
2821#define  FIFO_THRESH_32B  0x20   /* 32 bytes */
2822#define  FIFO_THRESH_48B  0x30   /* 48 bytes */
2823#define  FIFO_THRESH_64B  0x40   /* 64 bytes */
2824#define  FIFO_THRESH_80B  0x50   /* 80 bytes (default) */
2825#define  FIFO_THRESH_96B  0x60   /* 96 bytes */
2826#define  FIFO_THRESH_112B 0x70   /* 112 bytes */
2827#define START_CTL       0x0C    /* DMA start conditions */
2828#define  START_CTL_TH    0x00    /* Wait threshold level (default) */
2829#define  START_CTL_ID    0x04    /* Wait SDMA/SBUS idle */
2830#define  START_CTL_THID  0x08    /* Wait threshold and SDMA/SBUS idle */
2831#define  START_CTL_EMFU  0x0C    /* Wait SDMA FIFO empty/full */
2832#define READ_CMD        0x03    /* Memory Read Method */
2833#define  READ_CMD_MR     0x00    /* Memory Read */
2834#define  READ_CMD_MRL    0x02    /* Memory Read Long */
2835#define  READ_CMD_MRM    0x03    /* Memory Read Multiple (default) */
2836
2837/*
2838 * ASC-38C0800 RAM BIST Register bit definitions
2839 */
2840#define RAM_TEST_MODE         0x80
2841#define PRE_TEST_MODE         0x40
2842#define NORMAL_MODE           0x00
2843#define RAM_TEST_DONE         0x10
2844#define RAM_TEST_STATUS       0x0F
2845#define  RAM_TEST_HOST_ERROR   0x08
2846#define  RAM_TEST_INTRAM_ERROR 0x04
2847#define  RAM_TEST_RISC_ERROR   0x02
2848#define  RAM_TEST_SCSI_ERROR   0x01
2849#define  RAM_TEST_SUCCESS      0x00
2850#define PRE_TEST_VALUE        0x05
2851#define NORMAL_VALUE          0x00
2852
2853/*
2854 * ASC38C1600 Definitions
2855 *
2856 * IOPB_PCI_INT_CFG Bit Field Definitions
2857 */
2858
2859#define INTAB_LD        0x80    /* Value loaded from EEPROM Bit 11. */
2860
2861/*
2862 * Bit 1 can be set to change the interrupt for the Function to operate in
2863 * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
2864 * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
2865 * mode, otherwise the operating mode is undefined.
2866 */
2867#define TOTEMPOLE       0x02
2868
2869/*
2870 * Bit 0 can be used to change the Int Pin for the Function. The value is
2871 * 0 by default for both Functions with Function 0 using INT A and Function
2872 * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
2873 * INT A is used.
2874 *
2875 * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
2876 * value specified in the PCI Configuration Space.
2877 */
2878#define INTAB           0x01
2879
2880/* a_advlib.h */
2881
2882/*
2883 * Adv Library Status Definitions
2884 */
2885#define ADV_TRUE        1
2886#define ADV_FALSE       0
2887#define ADV_NOERROR     1
2888#define ADV_SUCCESS     1
2889#define ADV_BUSY        0
2890#define ADV_ERROR       (-1)
2891
2892
2893/*
2894 * ADV_DVC_VAR 'warn_code' values
2895 */
2896#define ASC_WARN_BUSRESET_ERROR         0x0001 /* SCSI Bus Reset error */
2897#define ASC_WARN_EEPROM_CHKSUM          0x0002 /* EEP check sum error */
2898#define ASC_WARN_EEPROM_TERMINATION     0x0004 /* EEP termination bad field */
2899#define ASC_WARN_SET_PCI_CONFIG_SPACE   0x0080 /* PCI config space set error */
2900#define ASC_WARN_ERROR                  0xFFFF /* ADV_ERROR return */
2901
2902#define ADV_MAX_TID                     15 /* max. target identifier */
2903#define ADV_MAX_LUN                     7  /* max. logical unit number */
2904
2905/*
2906 * Error code values are set in ADV_DVC_VAR 'err_code'.
2907 */
2908#define ASC_IERR_WRITE_EEPROM       0x0001 /* write EEPROM error */
2909#define ASC_IERR_MCODE_CHKSUM       0x0002 /* micro code check sum error */
2910#define ASC_IERR_NO_CARRIER         0x0004 /* No more carrier memory. */
2911#define ASC_IERR_START_STOP_CHIP    0x0008 /* start/stop chip failed */
2912#define ASC_IERR_CHIP_VERSION       0x0040 /* wrong chip version */
2913#define ASC_IERR_SET_SCSI_ID        0x0080 /* set SCSI ID failed */
2914#define ASC_IERR_HVD_DEVICE         0x0100 /* HVD attached to LVD connector. */
2915#define ASC_IERR_BAD_SIGNATURE      0x0200 /* signature not found */
2916#define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
2917#define ASC_IERR_SINGLE_END_DEVICE  0x0800 /* Single-end used w/differential */
2918#define ASC_IERR_REVERSED_CABLE     0x1000 /* Narrow flat cable reversed */
2919#define ASC_IERR_BIST_PRE_TEST      0x2000 /* BIST pre-test error */
2920#define ASC_IERR_BIST_RAM_TEST      0x4000 /* BIST RAM test error */
2921#define ASC_IERR_BAD_CHIPTYPE       0x8000 /* Invalid 'chip_type' setting. */
2922
2923/*
2924 * Fixed locations of microcode operating variables.
2925 */
2926#define ASC_MC_CODE_BEGIN_ADDR          0x0028 /* microcode start address */
2927#define ASC_MC_CODE_END_ADDR            0x002A /* microcode end address */
2928#define ASC_MC_CODE_CHK_SUM             0x002C /* microcode code checksum */
2929#define ASC_MC_VERSION_DATE             0x0038 /* microcode version */
2930#define ASC_MC_VERSION_NUM              0x003A /* microcode number */
2931#define ASC_MC_BIOSMEM                  0x0040 /* BIOS RISC Memory Start */
2932#define ASC_MC_BIOSLEN                  0x0050 /* BIOS RISC Memory Length */
2933#define ASC_MC_BIOS_SIGNATURE           0x0058 /* BIOS Signature 0x55AA */
2934#define ASC_MC_BIOS_VERSION             0x005A /* BIOS Version (2 bytes) */
2935#define ASC_MC_SDTR_SPEED1              0x0090 /* SDTR Speed for TID 0-3 */
2936#define ASC_MC_SDTR_SPEED2              0x0092 /* SDTR Speed for TID 4-7 */
2937#define ASC_MC_SDTR_SPEED3              0x0094 /* SDTR Speed for TID 8-11 */
2938#define ASC_MC_SDTR_SPEED4              0x0096 /* SDTR Speed for TID 12-15 */
2939#define ASC_MC_CHIP_TYPE                0x009A
2940#define ASC_MC_INTRB_CODE               0x009B
2941#define ASC_MC_WDTR_ABLE                0x009C
2942#define ASC_MC_SDTR_ABLE                0x009E
2943#define ASC_MC_TAGQNG_ABLE              0x00A0
2944#define ASC_MC_DISC_ENABLE              0x00A2
2945#define ASC_MC_IDLE_CMD_STATUS          0x00A4
2946#define ASC_MC_IDLE_CMD                 0x00A6
2947#define ASC_MC_IDLE_CMD_PARAMETER       0x00A8
2948#define ASC_MC_DEFAULT_SCSI_CFG0        0x00AC
2949#define ASC_MC_DEFAULT_SCSI_CFG1        0x00AE
2950#define ASC_MC_DEFAULT_MEM_CFG          0x00B0
2951#define ASC_MC_DEFAULT_SEL_MASK         0x00B2
2952#define ASC_MC_SDTR_DONE                0x00B6
2953#define ASC_MC_NUMBER_OF_QUEUED_CMD     0x00C0
2954#define ASC_MC_NUMBER_OF_MAX_CMD        0x00D0
2955#define ASC_MC_DEVICE_HSHK_CFG_TABLE    0x0100
2956#define ASC_MC_CONTROL_FLAG             0x0122 /* Microcode control flag. */
2957#define ASC_MC_WDTR_DONE                0x0124
2958#define ASC_MC_CAM_MODE_MASK            0x015E /* CAM mode TID bitmask. */
2959#define ASC_MC_ICQ                      0x0160
2960#define ASC_MC_IRQ                      0x0164
2961#define ASC_MC_PPR_ABLE                 0x017A
2962
2963/*
2964 * BIOS LRAM variable absolute offsets.
2965 */
2966#define BIOS_CODESEG    0x54
2967#define BIOS_CODELEN    0x56
2968#define BIOS_SIGNATURE  0x58
2969#define BIOS_VERSION    0x5A
2970
2971/*
2972 * Microcode Control Flags
2973 *
2974 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
2975 * and handled by the microcode.
2976 */
2977#define CONTROL_FLAG_IGNORE_PERR        0x0001 /* Ignore DMA Parity Errors */
2978#define CONTROL_FLAG_ENABLE_AIPP        0x0002 /* Enabled AIPP checking. */
2979
2980/*
2981 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
2982 */
2983#define HSHK_CFG_WIDE_XFR       0x8000
2984#define HSHK_CFG_RATE           0x0F00
2985#define HSHK_CFG_OFFSET         0x001F
2986
2987#define ASC_DEF_MAX_HOST_QNG    0xFD /* Max. number of host commands (253) */
2988#define ASC_DEF_MIN_HOST_QNG    0x10 /* Min. number of host commands (16) */
2989#define ASC_DEF_MAX_DVC_QNG     0x3F /* Max. number commands per device (63) */
2990#define ASC_DEF_MIN_DVC_QNG     0x04 /* Min. number commands per device (4) */
2991
2992#define ASC_QC_DATA_CHECK  0x01 /* Require ASC_QC_DATA_OUT set or clear. */
2993#define ASC_QC_DATA_OUT    0x02 /* Data out DMA transfer. */
2994#define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
2995#define ASC_QC_NO_OVERRUN  0x08 /* Don't report overrun. */
2996#define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
2997
2998#define ASC_QSC_NO_DISC     0x01 /* Don't allow disconnect for request. */
2999#define ASC_QSC_NO_TAGMSG   0x02 /* Don't allow tag queuing for request. */
3000#define ASC_QSC_NO_SYNC     0x04 /* Don't use Synch. transfer on request. */
3001#define ASC_QSC_NO_WIDE     0x08 /* Don't use Wide transfer on request. */
3002#define ASC_QSC_REDO_DTR    0x10 /* Renegotiate WDTR/SDTR before request. */
3003/*
3004 * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
3005 * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
3006 */
3007#define ASC_QSC_HEAD_TAG    0x40 /* Use Head Tag Message (0x21). */
3008#define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
3009
3010/*
3011 * All fields here are accessed by the board microcode and need to be
3012 * little-endian.
3013 */
3014typedef struct adv_carr_t
3015{
3016    ADV_VADDR   carr_va;       /* Carrier Virtual Address */
3017    ADV_PADDR   carr_pa;       /* Carrier Physical Address */
3018    ADV_VADDR   areq_vpa;      /* ASC_SCSI_REQ_Q Virtual or Physical Address */
3019    /*
3020     * next_vpa [31:4]            Carrier Virtual or Physical Next Pointer
3021     *
3022     * next_vpa [3:1]             Reserved Bits
3023     * next_vpa [0]               Done Flag set in Response Queue.
3024     */
3025    ADV_VADDR   next_vpa;
3026} ADV_CARR_T;
3027
3028/*
3029 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
3030 */
3031#define ASC_NEXT_VPA_MASK       0xFFFFFFF0
3032
3033#define ASC_RQ_DONE             0x00000001
3034#define ASC_RQ_GOOD             0x00000002
3035#define ASC_CQ_STOPPER          0x00000000
3036
3037#define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
3038
3039#define ADV_CARRIER_NUM_PAGE_CROSSING \
3040    (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
3041        (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
3042
3043#define ADV_CARRIER_BUFSIZE \
3044    ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
3045
3046/*
3047 * ASC_SCSI_REQ_Q 'a_flag' definitions
3048 *
3049 * The Adv Library should limit use to the lower nibble (4 bits) of
3050 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
3051 */
3052#define ADV_POLL_REQUEST                0x01   /* poll for request completion */
3053#define ADV_SCSIQ_DONE                  0x02   /* request done */
3054#define ADV_DONT_RETRY                  0x08   /* don't do retry */
3055
3056#define ADV_CHIP_ASC3550          0x01   /* Ultra-Wide IC */
3057#define ADV_CHIP_ASC38C0800       0x02   /* Ultra2-Wide/LVD IC */
3058#define ADV_CHIP_ASC38C1600       0x03   /* Ultra3-Wide/LVD2 IC */
3059
3060/*
3061 * Adapter temporary configuration structure
3062 *
3063 * This structure can be discarded after initialization. Don't add
3064 * fields here needed after initialization.
3065 *
3066 * Field naming convention:
3067 *
3068 *  *_enable indicates the field enables or disables a feature. The
3069 *  value of the field is never reset.
3070 */
3071typedef struct adv_dvc_cfg {
3072  ushort disc_enable;       /* enable disconnection */
3073  uchar  chip_version;      /* chip version */
3074  uchar  termination;       /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
3075  ushort lib_version;       /* Adv Library version number */
3076  ushort control_flag;      /* Microcode Control Flag */
3077  ushort mcode_date;        /* Microcode date */
3078  ushort mcode_version;     /* Microcode version */
3079  ushort pci_slot_info;     /* high byte device/function number */
3080                            /* bits 7-3 device num., bits 2-0 function num. */
3081                            /* low byte bus num. */
3082  ushort serial1;           /* EEPROM serial number word 1 */
3083  ushort serial2;           /* EEPROM serial number word 2 */
3084  ushort serial3;           /* EEPROM serial number word 3 */
3085  struct pci_dev *pci_dev;  /* pointer to the pci dev structure for this board */
3086} ADV_DVC_CFG;
3087
3088struct adv_dvc_var;
3089struct adv_scsi_req_q;
3090
3091typedef void (* ADV_ISR_CALLBACK)
3092    (struct adv_dvc_var *, struct adv_scsi_req_q *);
3093
3094typedef void (* ADV_ASYNC_CALLBACK)
3095    (struct adv_dvc_var *, uchar);
3096
3097/*
3098 * Adapter operation variable structure.
3099 *
3100 * One structure is required per host adapter.
3101 *
3102 * Field naming convention:
3103 *
3104 *  *_able indicates both whether a feature should be enabled or disabled
3105 *  and whether a device isi capable of the feature. At initialization
3106 *  this field may be set, but later if a device is found to be incapable
3107 *  of the feature, the field is cleared.
3108 */
3109typedef struct adv_dvc_var {
3110  AdvPortAddr iop_base;   /* I/O port address */
3111  ushort err_code;        /* fatal error code */
3112  ushort bios_ctrl;       /* BIOS control word, EEPROM word 12 */
3113  ADV_ISR_CALLBACK isr_callback;
3114  ADV_ASYNC_CALLBACK async_callback;
3115  ushort wdtr_able;       /* try WDTR for a device */
3116  ushort sdtr_able;       /* try SDTR for a device */
3117  ushort ultra_able;      /* try SDTR Ultra speed for a device */
3118  ushort sdtr_speed1;     /* EEPROM SDTR Speed for TID 0-3   */
3119  ushort sdtr_speed2;     /* EEPROM SDTR Speed for TID 4-7   */
3120  ushort sdtr_speed3;     /* EEPROM SDTR Speed for TID 8-11  */
3121  ushort sdtr_speed4;     /* EEPROM SDTR Speed for TID 12-15 */
3122  ushort tagqng_able;     /* try tagged queuing with a device */
3123  ushort ppr_able;        /* PPR message capable per TID bitmask. */
3124  uchar  max_dvc_qng;     /* maximum number of tagged commands per device */
3125  ushort start_motor;     /* start motor command allowed */
3126  uchar  scsi_reset_wait; /* delay in seconds after scsi bus reset */
3127  uchar  chip_no;         /* should be assigned by caller */
3128  uchar  max_host_qng;    /* maximum number of Q'ed command allowed */
3129  uchar  irq_no;          /* IRQ number */
3130  ushort no_scam;         /* scam_tolerant of EEPROM */
3131  struct asc_board *drv_ptr; /* driver pointer to private structure */
3132  uchar  chip_scsi_id;    /* chip SCSI target ID */
3133  uchar  chip_type;
3134  uchar  bist_err_code;
3135  ADV_CARR_T *carrier_buf;
3136  ADV_CARR_T *carr_freelist; /* Carrier free list. */
3137  ADV_CARR_T *icq_sp;  /* Initiator command queue stopper pointer. */
3138  ADV_CARR_T *irq_sp;  /* Initiator response queue stopper pointer. */
3139  ushort carr_pending_cnt;    /* Count of pending carriers. */
3140 /*
3141  * Note: The following fields will not be used after initialization. The
3142  * driver may discard the buffer after initialization is done.
3143  */
3144  ADV_DVC_CFG *cfg; /* temporary configuration structure  */
3145} ADV_DVC_VAR;
3146
3147#define NO_OF_SG_PER_BLOCK              15
3148
3149typedef struct asc_sg_block {
3150    uchar reserved1;
3151    uchar reserved2;
3152    uchar reserved3;
3153    uchar sg_cnt;                     /* Valid entries in block. */
3154    ADV_PADDR sg_ptr;                 /* Pointer to next sg block. */
3155    struct  {
3156        ADV_PADDR sg_addr;                  /* SG element address. */
3157        ADV_DCNT  sg_count;                 /* SG element count. */
3158    } sg_list[NO_OF_SG_PER_BLOCK];
3159} ADV_SG_BLOCK;
3160
3161/*
3162 * ADV_SCSI_REQ_Q - microcode request structure
3163 *
3164 * All fields in this structure up to byte 60 are used by the microcode.
3165 * The microcode makes assumptions about the size and ordering of fields
3166 * in this structure. Do not change the structure definition here without
3167 * coordinating the change with the microcode.
3168 *
3169 * All fields accessed by microcode must be maintained in little_endian
3170 * order.
3171 */
3172typedef struct adv_scsi_req_q {
3173    uchar       cntl;           /* Ucode flags and state (ASC_MC_QC_*). */
3174    uchar       target_cmd;
3175    uchar       target_id;      /* Device target identifier. */
3176    uchar       target_lun;     /* Device target logical unit number. */
3177    ADV_PADDR   data_addr;      /* Data buffer physical address. */
3178    ADV_DCNT    data_cnt;       /* Data count. Ucode sets to residual. */
3179    ADV_PADDR   sense_addr;
3180    ADV_PADDR   carr_pa;
3181    uchar       mflag;
3182    uchar       sense_len;
3183    uchar       cdb_len;        /* SCSI CDB length. Must <= 16 bytes. */
3184    uchar       scsi_cntl;
3185    uchar       done_status;    /* Completion status. */
3186    uchar       scsi_status;    /* SCSI status byte. */
3187    uchar       host_status;    /* Ucode host status. */
3188    uchar       sg_working_ix;
3189    uchar       cdb[12];        /* SCSI CDB bytes 0-11. */
3190    ADV_PADDR   sg_real_addr;   /* SG list physical address. */
3191    ADV_PADDR   scsiq_rptr;
3192    uchar       cdb16[4];       /* SCSI CDB bytes 12-15. */
3193    ADV_VADDR   scsiq_ptr;
3194    ADV_VADDR   carr_va;
3195    /*
3196     * End of microcode structure - 60 bytes. The rest of the structure
3197     * is used by the Adv Library and ignored by the microcode.
3198     */
3199    ADV_VADDR   srb_ptr;
3200    ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
3201    char        *vdata_addr;   /* Data buffer virtual address. */
3202    uchar       a_flag;
3203    uchar       pad[2];        /* Pad out to a word boundary. */
3204} ADV_SCSI_REQ_Q;
3205
3206/*
3207 * Microcode idle loop commands
3208 */
3209#define IDLE_CMD_COMPLETED           0
3210#define IDLE_CMD_STOP_CHIP           0x0001
3211#define IDLE_CMD_STOP_CHIP_SEND_INT  0x0002
3212#define IDLE_CMD_SEND_INT            0x0004
3213#define IDLE_CMD_ABORT               0x0008
3214#define IDLE_CMD_DEVICE_RESET        0x0010
3215#define IDLE_CMD_SCSI_RESET_START    0x0020 /* Assert SCSI Bus Reset */
3216#define IDLE_CMD_SCSI_RESET_END      0x0040 /* Deassert SCSI Bus Reset */
3217#define IDLE_CMD_SCSIREQ             0x0080
3218
3219#define IDLE_CMD_STATUS_SUCCESS      0x0001
3220#define IDLE_CMD_STATUS_FAILURE      0x0002
3221
3222/*
3223 * AdvSendIdleCmd() flag definitions.
3224 */
3225#define ADV_NOWAIT     0x01
3226
3227/*
3228 * Wait loop time out values.
3229 */
3230#define SCSI_WAIT_10_SEC             10UL    /* 10 seconds */
3231#define SCSI_WAIT_100_MSEC           100UL   /* 100 milliseconds */
3232#define SCSI_US_PER_MSEC             1000    /* microseconds per millisecond */
3233#define SCSI_MS_PER_SEC              1000UL  /* milliseconds per second */
3234#define SCSI_MAX_RETRY               10      /* retry count */
3235
3236#define ADV_ASYNC_RDMA_FAILURE          0x01 /* Fatal RDMA failure. */
3237#define ADV_ASYNC_SCSI_BUS_RESET_DET    0x02 /* Detected SCSI Bus Reset. */
3238#define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
3239#define ADV_RDMA_IN_CARR_AND_Q_INVALID  0x04 /* RDMAed-in data invalid. */
3240
3241
3242#define ADV_HOST_SCSI_BUS_RESET      0x80 /* Host Initiated SCSI Bus Reset. */
3243
3244/*
3245 * Device drivers must define the following functions.
3246 */
3247STATIC inline ulong DvcEnterCritical(void);
3248STATIC inline void  DvcLeaveCritical(ulong);
3249STATIC void  DvcSleepMilliSecond(ADV_DCNT);
3250STATIC uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort);
3251STATIC void  DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar);
3252STATIC ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
3253                uchar *, ASC_SDCNT *, int);
3254STATIC void  DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
3255
3256/*
3257 * Adv Library functions available to drivers.
3258 */
3259STATIC int     AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3260STATIC int     AdvISR(ADV_DVC_VAR *);
3261STATIC int     AdvInitGetConfig(ADV_DVC_VAR *);
3262STATIC int     AdvInitAsc3550Driver(ADV_DVC_VAR *);
3263STATIC int     AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
3264STATIC int     AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
3265STATIC int     AdvResetChipAndSB(ADV_DVC_VAR *);
3266STATIC int     AdvResetSB(ADV_DVC_VAR *asc_dvc);
3267
3268/*
3269 * Internal Adv Library functions.
3270 */
3271STATIC int    AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
3272STATIC void   AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3273STATIC int    AdvInitFrom3550EEP(ADV_DVC_VAR *);
3274STATIC int    AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
3275STATIC int    AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
3276STATIC ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3277STATIC void   AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3278STATIC ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3279STATIC void   AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3280STATIC ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3281STATIC void   AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3282STATIC void   AdvWaitEEPCmd(AdvPortAddr);
3283STATIC ushort AdvReadEEPWord(AdvPortAddr, int);
3284
3285/*
3286 * PCI Bus Definitions
3287 */
3288#define AscPCICmdRegBits_BusMastering     0x0007
3289#define AscPCICmdRegBits_ParErrRespCtrl   0x0040
3290
3291/* Read byte from a register. */
3292#define AdvReadByteRegister(iop_base, reg_off) \
3293     (ADV_MEM_READB((iop_base) + (reg_off)))
3294
3295/* Write byte to a register. */
3296#define AdvWriteByteRegister(iop_base, reg_off, byte) \
3297     (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
3298
3299/* Read word (2 bytes) from a register. */
3300#define AdvReadWordRegister(iop_base, reg_off) \
3301     (ADV_MEM_READW((iop_base) + (reg_off)))
3302
3303/* Write word (2 bytes) to a register. */
3304#define AdvWriteWordRegister(iop_base, reg_off, word) \
3305     (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
3306
3307/* Write dword (4 bytes) to a register. */
3308#define AdvWriteDWordRegister(iop_base, reg_off, dword) \
3309     (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
3310
3311/* Read byte from LRAM. */
3312#define AdvReadByteLram(iop_base, addr, byte) \
3313do { \
3314    ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3315    (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
3316} while (0)
3317
3318/* Write byte to LRAM. */
3319#define AdvWriteByteLram(iop_base, addr, byte) \
3320    (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3321     ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
3322
3323/* Read word (2 bytes) from LRAM. */
3324#define AdvReadWordLram(iop_base, addr, word) \
3325do { \
3326    ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3327    (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
3328} while (0)
3329
3330/* Write word (2 bytes) to LRAM. */
3331#define AdvWriteWordLram(iop_base, addr, word) \
3332    (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3333     ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3334
3335/* Write little-endian double word (4 bytes) to LRAM */
3336/* Because of unspecified C language ordering don't use auto-increment. */
3337#define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
3338    ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3339      ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3340                     cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
3341     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
3342      ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3343                     cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
3344
3345/* Read word (2 bytes) from LRAM assuming that the address is already set. */
3346#define AdvReadWordAutoIncLram(iop_base) \
3347     (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
3348
3349/* Write word (2 bytes) to LRAM assuming that the address is already set. */
3350#define AdvWriteWordAutoIncLram(iop_base, word) \
3351     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3352
3353
3354/*
3355 * Define macro to check for Condor signature.
3356 *
3357 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
3358 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
3359 */
3360#define AdvFindSignature(iop_base) \
3361    (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
3362    ADV_CHIP_ID_BYTE) && \
3363     (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
3364    ADV_CHIP_ID_WORD)) ?  ADV_TRUE : ADV_FALSE)
3365
3366/*
3367 * Define macro to Return the version number of the chip at 'iop_base'.
3368 *
3369 * The second parameter 'bus_type' is currently unused.
3370 */
3371#define AdvGetChipVersion(iop_base, bus_type) \
3372    AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
3373
3374/*
3375 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
3376 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
3377 *
3378 * If the request has not yet been sent to the device it will simply be
3379 * aborted from RISC memory. If the request is disconnected it will be
3380 * aborted on reselection by sending an Abort Message to the target ID.
3381 *
3382 * Return value:
3383 *      ADV_TRUE(1) - Queue was successfully aborted.
3384 *      ADV_FALSE(0) - Queue was not found on the active queue list.
3385 */
3386#define AdvAbortQueue(asc_dvc, scsiq) \
3387        AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
3388                       (ADV_DCNT) (scsiq))
3389
3390/*
3391 * Send a Bus Device Reset Message to the specified target ID.
3392 *
3393 * All outstanding commands will be purged if sending the
3394 * Bus Device Reset Message is successful.
3395 *
3396 * Return Value:
3397 *      ADV_TRUE(1) - All requests on the target are purged.
3398 *      ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
3399 *                     are not purged.
3400 */
3401#define AdvResetDevice(asc_dvc, target_id) \
3402        AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
3403                    (ADV_DCNT) (target_id))
3404
3405/*
3406 * SCSI Wide Type definition.
3407 */
3408#define ADV_SCSI_BIT_ID_TYPE   ushort
3409
3410/*
3411 * AdvInitScsiTarget() 'cntl_flag' options.
3412 */
3413#define ADV_SCAN_LUN           0x01
3414#define ADV_CAPINFO_NOLUN      0x02
3415
3416/*
3417 * Convert target id to target id bit mask.
3418 */
3419#define ADV_TID_TO_TIDMASK(tid)   (0x01 << ((tid) & ADV_MAX_TID))
3420
3421/*
3422 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
3423 */
3424
3425#define QD_NO_STATUS         0x00       /* Request not completed yet. */
3426#define QD_NO_ERROR          0x01
3427#define QD_ABORTED_BY_HOST   0x02
3428#define QD_WITH_ERROR        0x04
3429
3430#define QHSTA_NO_ERROR              0x00
3431#define QHSTA_M_SEL_TIMEOUT         0x11
3432#define QHSTA_M_DATA_OVER_RUN       0x12
3433#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
3434#define QHSTA_M_QUEUE_ABORTED       0x15
3435#define QHSTA_M_SXFR_SDMA_ERR       0x16 /* SXFR_STATUS SCSI DMA Error */
3436#define QHSTA_M_SXFR_SXFR_PERR      0x17 /* SXFR_STATUS SCSI Bus Parity Error */
3437#define QHSTA_M_RDMA_PERR           0x18 /* RISC PCI DMA parity error */
3438#define QHSTA_M_SXFR_OFF_UFLW       0x19 /* SXFR_STATUS Offset Underflow */
3439#define QHSTA_M_SXFR_OFF_OFLW       0x20 /* SXFR_STATUS Offset Overflow */
3440#define QHSTA_M_SXFR_WD_TMO         0x21 /* SXFR_STATUS Watchdog Timeout */
3441#define QHSTA_M_SXFR_DESELECTED     0x22 /* SXFR_STATUS Deselected */
3442/* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
3443#define QHSTA_M_SXFR_XFR_OFLW       0x12 /* SXFR_STATUS Transfer Overflow */
3444#define QHSTA_M_SXFR_XFR_PH_ERR     0x24 /* SXFR_STATUS Transfer Phase Error */
3445#define QHSTA_M_SXFR_UNKNOWN_ERROR  0x25 /* SXFR_STATUS Unknown Error */
3446#define QHSTA_M_SCSI_BUS_RESET      0x30 /* Request aborted from SBR */
3447#define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
3448#define QHSTA_M_BUS_DEVICE_RESET    0x32 /* Request aborted from BDR */
3449#define QHSTA_M_DIRECTION_ERR       0x35 /* Data Phase mismatch */
3450#define QHSTA_M_DIRECTION_ERR_HUNG  0x36 /* Data Phase mismatch and bus hang */
3451#define QHSTA_M_WTM_TIMEOUT         0x41
3452#define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
3453#define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
3454#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
3455#define QHSTA_M_INVALID_DEVICE      0x45 /* Bad target ID */
3456#define QHSTA_M_FROZEN_TIDQ         0x46 /* TID Queue frozen. */
3457#define QHSTA_M_SGBACKUP_ERROR      0x47 /* Scatter-Gather backup error */
3458
3459
3460/*
3461 * Default EEPROM Configuration structure defined in a_init.c.
3462 */
3463extern ADVEEP_3550_CONFIG Default_3550_EEPROM_Config;
3464extern ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config;
3465extern ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config;
3466
3467/*
3468 * DvcGetPhyAddr() flag arguments
3469 */
3470#define ADV_IS_SCSIQ_FLAG       0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
3471#define ADV_ASCGETSGLIST_VADDR  0x02 /* 'addr' is AscGetSGList() virtual addr */
3472#define ADV_IS_SENSE_FLAG       0x04 /* 'addr' is sense virtual pointer */
3473#define ADV_IS_DATA_FLAG        0x08 /* 'addr' is data virtual pointer */
3474#define ADV_IS_SGLIST_FLAG      0x10 /* 'addr' is sglist virtual pointer */
3475#define ADV_IS_CARRIER_FLAG     0x20 /* 'addr' is ADV_CARR_T pointer */
3476
3477/* Return the address that is aligned at the next doubleword >= to 'addr'. */
3478#define ADV_8BALIGN(addr)      (((ulong) (addr) + 0x7) & ~0x7)
3479#define ADV_16BALIGN(addr)     (((ulong) (addr) + 0xF) & ~0xF)
3480#define ADV_32BALIGN(addr)     (((ulong) (addr) + 0x1F) & ~0x1F)
3481
3482/*
3483 * Total contiguous memory needed for driver SG blocks.
3484 *
3485 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
3486 * number of scatter-gather elements the driver supports in a
3487 * single request.
3488 */
3489
3490#define ADV_SG_LIST_MAX_BYTE_SIZE \
3491         (sizeof(ADV_SG_BLOCK) * \
3492          ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
3493
3494/*
3495 * Inquiry data structure and bitfield macros
3496 *
3497 * Using bitfields to access the subchar data isn't portable across
3498 * endianness, so instead mask and shift. Only quantities of more
3499 * than 1 bit are shifted, since the others are just tested for true
3500 * or false.
3501 */
3502
3503#define ADV_INQ_DVC_TYPE(inq)       ((inq)->periph & 0x1f)
3504#define ADV_INQ_QUALIFIER(inq)      (((inq)->periph & 0xe0) >> 5)
3505#define ADV_INQ_DVC_TYPE_MOD(inq)   ((inq)->devtype & 0x7f)
3506#define ADV_INQ_REMOVABLE(inq)      ((inq)->devtype & 0x80)
3507#define ADV_INQ_ANSI_VER(inq)       ((inq)->ver & 0x07)
3508#define ADV_INQ_ECMA_VER(inq)       (((inq)->ver & 0x38) >> 3)
3509#define ADV_INQ_ISO_VER(inq)        (((inq)->ver & 0xc0) >> 6)
3510#define ADV_INQ_RESPONSE_FMT(inq)   ((inq)->byte3 & 0x0f)
3511#define ADV_INQ_TERM_IO(inq)        ((inq)->byte3 & 0x40)
3512#define ADV_INQ_ASYNC_NOTIF(inq)    ((inq)->byte3 & 0x80)
3513#define ADV_INQ_SOFT_RESET(inq)     ((inq)->flags & 0x01)
3514#define ADV_INQ_CMD_QUEUE(inq)      ((inq)->flags & 0x02)
3515#define ADV_INQ_LINK_CMD(inq)       ((inq)->flags & 0x08)
3516#define ADV_INQ_SYNC(inq)           ((inq)->flags & 0x10)
3517#define ADV_INQ_WIDE16(inq)         ((inq)->flags & 0x20)
3518#define ADV_INQ_WIDE32(inq)         ((inq)->flags & 0x40)
3519#define ADV_INQ_REL_ADDR(inq)       ((inq)->flags & 0x80)
3520#define ADV_INQ_INFO_UNIT(inq)      ((inq)->info & 0x01)
3521#define ADV_INQ_QUICK_ARB(inq)      ((inq)->info & 0x02)
3522#define ADV_INQ_CLOCKING(inq)       (((inq)->info & 0x0c) >> 2)
3523
3524typedef struct {
3525  uchar periph;                 /* peripheral device type [0:4] */
3526                                /* peripheral qualifier [5:7] */
3527  uchar devtype;                /* device type modifier (for SCSI I) [0:6] */
3528                                /* RMB - removable medium bit [7] */
3529  uchar ver;                    /* ANSI approved version [0:2] */
3530                                /* ECMA version [3:5] */
3531                                /* ISO version [6:7] */
3532  uchar byte3;                  /* response data format [0:3] */
3533                                /* 0 SCSI 1 */
3534                                /* 1 CCS */
3535                                /* 2 SCSI-2 */
3536                                /* 3-F reserved */
3537                                /* reserved [4:5] */
3538                                /* terminate I/O process bit (see 5.6.22) [6] */
3539                                /* asynch. event notification (processor) [7] */
3540  uchar add_len;                /* additional length */
3541  uchar res1;                   /* reserved */
3542  uchar res2;                   /* reserved */
3543  uchar flags;                  /* soft reset implemented [0] */
3544                                /* command queuing [1] */
3545                                /* reserved [2] */
3546                                /* linked command for this logical unit [3] */
3547                                /* synchronous data transfer [4] */
3548                                /* wide bus 16 bit data transfer [5] */
3549                                /* wide bus 32 bit data transfer [6] */
3550                                /* relative addressing mode [7] */
3551  uchar vendor_id[8];           /* vendor identification */
3552  uchar product_id[16];         /* product identification */
3553  uchar product_rev_level[4];   /* product revision level */
3554  uchar vendor_specific[20];    /* vendor specific */
3555  uchar info;                   /* information unit supported [0] */
3556                                /* quick arbitrate supported [1] */
3557                                /* clocking field [2:3] */
3558                                /* reserved [4:7] */
3559  uchar res3;                   /* reserved */
3560} ADV_SCSI_INQUIRY; /* 58 bytes */
3561
3562
3563/*
3564 * --- Driver Constants and Macros
3565 */
3566
3567#define ASC_NUM_BOARD_SUPPORTED 16
3568#define ASC_NUM_IOPORT_PROBE    4
3569#define ASC_NUM_BUS             4
3570
3571/* Reference Scsi_Host hostdata */
3572#define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
3573
3574/* asc_board_t flags */
3575#define ASC_HOST_IN_RESET       0x01
3576#define ASC_IS_WIDE_BOARD       0x04    /* AdvanSys Wide Board */
3577#define ASC_SELECT_QUEUE_DEPTHS 0x08
3578
3579#define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
3580#define ASC_WIDE_BOARD(boardp)   ((boardp)->flags & ASC_IS_WIDE_BOARD)
3581
3582#define NO_ISA_DMA              0xff        /* No ISA DMA Channel Used */
3583
3584/*
3585 * If the Linux kernel version supports freeing initialization code
3586 * and data after loading, define macros for this purpose. These macros
3587 * are not used when the driver is built as a module, cf. linux/init.h.
3588 */
3589#if ASC_LINUX_KERNEL24
3590#define ASC_INITFUNC(type, func)        type __init func
3591#elif ASC_LINUX_KERNEL22
3592#define ASC_INITFUNC(type, func)        __initfunc(type func)
3593#endif
3594#define ASC_INITDATA                    __initdata
3595#define ASC_INIT                        __init
3596
3597#define ASC_INFO_SIZE           128            /* advansys_info() line size */
3598
3599#ifdef CONFIG_PROC_FS
3600/* /proc/scsi/advansys/[0...] related definitions */
3601#define ASC_PRTBUF_SIZE         2048
3602#define ASC_PRTLINE_SIZE        160
3603
3604#define ASC_PRT_NEXT() \
3605    if (cp) { \
3606        totlen += len; \
3607        leftlen -= len; \
3608        if (leftlen == 0) { \
3609            return totlen; \
3610        } \
3611        cp += len; \
3612    }
3613
3614#define ASC_MIN(a, b) (((a) < (b)) ? (a) : (b))
3615#endif /* CONFIG_PROC_FS */
3616
3617/* Asc Library return codes */
3618#define ASC_TRUE        1
3619#define ASC_FALSE       0
3620#define ASC_NOERROR     1
3621#define ASC_BUSY        0
3622#define ASC_ERROR       (-1)
3623
3624/* Scsi_Cmnd function return codes */
3625#define STATUS_BYTE(byte)   (byte)
3626#define MSG_BYTE(byte)      ((byte) << 8)
3627#define HOST_BYTE(byte)     ((byte) << 16)
3628#define DRIVER_BYTE(byte)   ((byte) << 24)
3629
3630/*
3631 * The following definitions and macros are OS independent interfaces to
3632 * the queue functions:
3633 *  REQ - SCSI request structure
3634 *  REQP - pointer to SCSI request structure
3635 *  REQPTID(reqp) - reqp's target id
3636 *  REQPNEXT(reqp) - reqp's next pointer
3637 *  REQPNEXTP(reqp) - pointer to reqp's next pointer
3638 *  REQPTIME(reqp) - reqp's time stamp value
3639 *  REQTIMESTAMP() - system time stamp value
3640 */
3641typedef Scsi_Cmnd            REQ, *REQP;
3642#define REQPNEXT(reqp)       ((REQP) ((reqp)->host_scribble))
3643#define REQPNEXTP(reqp)      ((REQP *) &((reqp)->host_scribble))
3644#define REQPTID(reqp)        ((reqp)->device->id)
3645#define REQPTIME(reqp)       ((reqp)->SCp.this_residual)
3646#define REQTIMESTAMP()       (jiffies)
3647
3648#define REQTIMESTAT(function, ascq, reqp, tid) \
3649{ \
3650    /*
3651     * If the request time stamp is less than the system time stamp, then \
3652     * maybe the system time stamp wrapped. Set the request time to zero.\
3653     */ \
3654    if (REQPTIME(reqp) <= REQTIMESTAMP()) { \
3655        REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \
3656    } else { \
3657        /* Indicate an error occurred with the assertion. */ \
3658        ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \
3659        REQPTIME(reqp) = 0; \
3660    } \
3661    /* Handle first minimum time case without external initialization. */ \
3662    if (((ascq)->q_tot_cnt[tid] == 1) ||  \
3663        (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \
3664            (ascq)->q_min_tim[tid] = REQPTIME(reqp); \
3665            ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
3666                (function), (tid), (ascq)->q_min_tim[tid]); \
3667        } \
3668    if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \
3669        (ascq)->q_max_tim[tid] = REQPTIME(reqp); \
3670        ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
3671            (function), tid, (ascq)->q_max_tim[tid]); \
3672    } \
3673    (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \
3674    /* Reset the time stamp field. */ \
3675    REQPTIME(reqp) = 0; \
3676}
3677
3678/* asc_enqueue() flags */
3679#define ASC_FRONT       1
3680#define ASC_BACK        2
3681
3682/* asc_dequeue_list() argument */
3683#define ASC_TID_ALL        (-1)
3684
3685/* Return non-zero, if the queue is empty. */
3686#define ASC_QUEUE_EMPTY(ascq)    ((ascq)->q_tidmask == 0)
3687
3688/* PCI configuration declarations */
3689
3690#define PCI_BASE_CLASS_PREDEFINED               0x00
3691#define PCI_BASE_CLASS_MASS_STORAGE             0x01
3692#define PCI_BASE_CLASS_NETWORK                  0x02
3693#define PCI_BASE_CLASS_DISPLAY                  0x03
3694#define PCI_BASE_CLASS_MULTIMEDIA               0x04
3695#define PCI_BASE_CLASS_MEMORY_CONTROLLER        0x05
3696#define PCI_BASE_CLASS_BRIDGE_DEVICE            0x06
3697
3698/* MASS STORAGE */
3699#define PCI_SUB_CLASS_SCSI_CONTROLLER           0x00
3700#define PCI_SUB_CLASS_IDE_CONTROLLER            0x01
3701#define PCI_SUB_CLASS_FLOPPY_DISK_CONTROLLER    0x02
3702#define PCI_SUB_CLASS_IPI_BUS_CONTROLLER        0x03
3703#define PCI_SUB_CLASS_OTHER_MASS_CONTROLLER     0x80
3704
3705/* NETWORK CONTROLLER */
3706#define PCI_SUB_CLASS_ETHERNET_CONTROLLER       0x00
3707#define PCI_SUB_CLASS_TOKEN_RING_CONTROLLER     0x01
3708#define PCI_SUB_CLASS_FDDI_CONTROLLER           0x02
3709#define PCI_SUB_CLASS_OTHER_NETWORK_CONTROLLER  0x80
3710
3711/* DISPLAY CONTROLLER */
3712#define PCI_SUB_CLASS_VGA_CONTROLLER            0x00
3713#define PCI_SUB_CLASS_XGA_CONTROLLER            0x01
3714#define PCI_SUB_CLASS_OTHER_DISPLAY_CONTROLLER  0x80
3715
3716/* MULTIMEDIA CONTROLLER */
3717#define PCI_SUB_CLASS_VIDEO_DEVICE              0x00
3718#define PCI_SUB_CLASS_AUDIO_DEVICE              0x01
3719#define PCI_SUB_CLASS_OTHER_MULTIMEDIA_DEVICE   0x80
3720
3721/* MEMORY CONTROLLER */
3722#define PCI_SUB_CLASS_RAM_CONTROLLER            0x00
3723#define PCI_SUB_CLASS_FLASH_CONTROLLER          0x01
3724#define PCI_SUB_CLASS_OTHER_MEMORY_CONTROLLER   0x80
3725
3726/* BRIDGE CONTROLLER */
3727#define PCI_SUB_CLASS_HOST_BRIDGE_CONTROLLER    0x00
3728#define PCI_SUB_CLASS_ISA_BRIDGE_CONTROLLER     0x01
3729#define PCI_SUB_CLASS_EISA_BRIDGE_CONTROLLER    0x02
3730#define PCI_SUB_CLASS_MC_BRIDGE_CONTROLLER      0x03
3731#define PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER    0x04
3732#define PCI_SUB_CLASS_PCMCIA_BRIDGE_CONTROLLER  0x05
3733#define PCI_SUB_CLASS_OTHER_BRIDGE_CONTROLLER   0x80
3734
3735#define PCI_MAX_SLOT            0x1F
3736#define PCI_MAX_BUS             0xFF
3737#define PCI_IOADDRESS_MASK      0xFFFE
3738#define ASC_PCI_VENDORID        0x10CD
3739#define ASC_PCI_DEVICE_ID_CNT   6       /* PCI Device ID count. */
3740#define ASC_PCI_DEVICE_ID_1100  0x1100
3741#define ASC_PCI_DEVICE_ID_1200  0x1200
3742#define ASC_PCI_DEVICE_ID_1300  0x1300
3743#define ASC_PCI_DEVICE_ID_2300  0x2300  /* ASC-3550 */
3744#define ASC_PCI_DEVICE_ID_2500  0x2500  /* ASC-38C0800 */
3745#define ASC_PCI_DEVICE_ID_2700  0x2700  /* ASC-38C1600 */
3746
3747/* PCI IO Port Addresses to generate special cycle */
3748
3749#define PCI_CONFIG_ADDRESS_MECH1          0x0CF8
3750#define PCI_CONFIG_DATA_MECH1             0x0CFC
3751
3752#define PCI_CONFIG_FORWARD_REGISTER       0x0CFA    /* 0=type 0; 1=type 1; */
3753
3754#define PCI_CONFIG_BUS_NUMBER_MASK        0x00FF0000
3755#define PCI_CONFIG_DEVICE_FUNCTION_MASK   0x0000FF00
3756#define PCI_CONFIG_REGISTER_NUMBER_MASK   0x000000F8
3757
3758#define PCI_DEVICE_FOUND                0x0000
3759#define PCI_DEVICE_NOT_FOUND            0xffff
3760
3761#define SUBCLASS_OFFSET         0x0A
3762#define CLASSCODE_OFFSET        0x0B
3763#define VENDORID_OFFSET         0x00
3764#define DEVICEID_OFFSET         0x02
3765
3766#ifndef ADVANSYS_STATS
3767#define ASC_STATS(shp, counter)
3768#define ASC_STATS_ADD(shp, counter, count)
3769#else /* ADVANSYS_STATS */
3770#define ASC_STATS(shp, counter) \
3771    (ASC_BOARDP(shp)->asc_stats.counter++)
3772
3773#define ASC_STATS_ADD(shp, counter, count) \
3774    (ASC_BOARDP(shp)->asc_stats.counter += (count))
3775#endif /* ADVANSYS_STATS */
3776
3777#define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
3778
3779/* If the result wraps when calculating tenths, return 0. */
3780#define ASC_TENTHS(num, den) \
3781    (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
3782    0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
3783
3784/*
3785 * Display a message to the console.
3786 */
3787#define ASC_PRINT(s) \
3788    { \
3789        printk("advansys: "); \
3790        printk(s); \
3791    }
3792
3793#define ASC_PRINT1(s, a1) \
3794    { \
3795        printk("advansys: "); \
3796        printk((s), (a1)); \
3797    }
3798
3799#define ASC_PRINT2(s, a1, a2) \
3800    { \
3801        printk("advansys: "); \
3802        printk((s), (a1), (a2)); \
3803    }
3804
3805#define ASC_PRINT3(s, a1, a2, a3) \
3806    { \
3807        printk("advansys: "); \
3808        printk((s), (a1), (a2), (a3)); \
3809    }
3810
3811#define ASC_PRINT4(s, a1, a2, a3, a4) \
3812    { \
3813        printk("advansys: "); \
3814        printk((s), (a1), (a2), (a3), (a4)); \
3815    }
3816
3817
3818#ifndef ADVANSYS_DEBUG
3819
3820#define ASC_DBG(lvl, s)
3821#define ASC_DBG1(lvl, s, a1)
3822#define ASC_DBG2(lvl, s, a1, a2)
3823#define ASC_DBG3(lvl, s, a1, a2, a3)
3824#define ASC_DBG4(lvl, s, a1, a2, a3, a4)
3825#define ASC_DBG_PRT_SCSI_HOST(lvl, s)
3826#define ASC_DBG_PRT_SCSI_CMND(lvl, s)
3827#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
3828#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3829#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
3830#define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3831#define ASC_DBG_PRT_HEX(lvl, name, start, length)
3832#define ASC_DBG_PRT_CDB(lvl, cdb, len)
3833#define ASC_DBG_PRT_SENSE(lvl, sense, len)
3834#define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
3835
3836#else /* ADVANSYS_DEBUG */
3837
3838/*
3839 * Debugging Message Levels:
3840 * 0: Errors Only
3841 * 1: High-Level Tracing
3842 * 2-N: Verbose Tracing
3843 */
3844
3845#define ASC_DBG(lvl, s) \
3846    { \
3847        if (asc_dbglvl >= (lvl)) { \
3848            printk(s); \
3849        } \
3850    }
3851
3852#define ASC_DBG1(lvl, s, a1) \
3853    { \
3854        if (asc_dbglvl >= (lvl)) { \
3855            printk((s), (a1)); \
3856        } \
3857    }
3858
3859#define ASC_DBG2(lvl, s, a1, a2) \
3860    { \
3861        if (asc_dbglvl >= (lvl)) { \
3862            printk((s), (a1), (a2)); \
3863        } \
3864    }
3865
3866#define ASC_DBG3(lvl, s, a1, a2, a3) \
3867    { \
3868        if (asc_dbglvl >= (lvl)) { \
3869            printk((s), (a1), (a2), (a3)); \
3870        } \
3871    }
3872
3873#define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
3874    { \
3875        if (asc_dbglvl >= (lvl)) { \
3876            printk((s), (a1), (a2), (a3), (a4)); \
3877        } \
3878    }
3879
3880#define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
3881    { \
3882        if (asc_dbglvl >= (lvl)) { \
3883            asc_prt_scsi_host(s); \
3884        } \
3885    }
3886
3887#define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
3888    { \
3889        if (asc_dbglvl >= (lvl)) { \
3890            asc_prt_scsi_cmnd(s); \
3891        } \
3892    }
3893
3894#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
3895    { \
3896        if (asc_dbglvl >= (lvl)) { \
3897            asc_prt_asc_scsi_q(scsiqp); \
3898        } \
3899    }
3900
3901#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
3902    { \
3903        if (asc_dbglvl >= (lvl)) { \
3904            asc_prt_asc_qdone_info(qdone); \
3905        } \
3906    }
3907
3908#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
3909    { \
3910        if (asc_dbglvl >= (lvl)) { \
3911            asc_prt_adv_scsi_req_q(scsiqp); \
3912        } \
3913    }
3914
3915#define ASC_DBG_PRT_HEX(lvl, name, start, length) \
3916    { \
3917        if (asc_dbglvl >= (lvl)) { \
3918            asc_prt_hex((name), (start), (length)); \
3919        } \
3920    }
3921
3922#define ASC_DBG_PRT_CDB(lvl, cdb, len) \
3923        ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
3924
3925#define ASC_DBG_PRT_SENSE(lvl, sense, len) \
3926        ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
3927
3928#define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
3929        ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
3930#endif /* ADVANSYS_DEBUG */
3931
3932#ifndef ADVANSYS_ASSERT
3933#define ASC_ASSERT(a)
3934#else /* ADVANSYS_ASSERT */
3935
3936#define ASC_ASSERT(a) \
3937    { \
3938        if (!(a)) { \
3939            printk("ASC_ASSERT() Failure: file %s, line %d\n", \
3940                __FILE__, __LINE__); \
3941        } \
3942    }
3943
3944#endif /* ADVANSYS_ASSERT */
3945
3946
3947/*
3948 * --- Driver Structures
3949 */
3950
3951#ifdef ADVANSYS_STATS
3952
3953/* Per board statistics structure */
3954struct asc_stats {
3955    /* Driver Entrypoint Statistics */
3956    ADV_DCNT queuecommand;    /* # calls to advansys_queuecommand() */
3957    ADV_DCNT reset;           /* # calls to advansys_eh_bus_reset() */
3958    ADV_DCNT biosparam;       /* # calls to advansys_biosparam() */
3959    ADV_DCNT interrupt;       /* # advansys_interrupt() calls */
3960    ADV_DCNT callback;        /* # calls to asc/adv_isr_callback() */
3961    ADV_DCNT done;            /* # calls to request's scsi_done function */
3962    ADV_DCNT build_error;     /* # asc/adv_build_req() ASC_ERROR returns. */
3963    ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
3964    ADV_DCNT adv_build_nosg;  /* # adv_build_req() adv_sgblk_t alloc. fail. */
3965    /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
3966    ADV_DCNT exe_noerror;     /* # ASC_NOERROR returns. */
3967    ADV_DCNT exe_busy;        /* # ASC_BUSY returns. */
3968    ADV_DCNT exe_error;       /* # ASC_ERROR returns. */
3969    ADV_DCNT exe_unknown;     /* # unknown returns. */
3970    /* Data Transfer Statistics */
3971    ADV_DCNT cont_cnt;        /* # non-scatter-gather I/O requests received */
3972    ADV_DCNT cont_xfer;       /* # contiguous transfer 512-bytes */
3973    ADV_DCNT sg_cnt;          /* # scatter-gather I/O requests received */
3974    ADV_DCNT sg_elem;         /* # scatter-gather elements */
3975    ADV_DCNT sg_xfer;         /* # scatter-gather transfer 512-bytes */
3976};
3977#endif /* ADVANSYS_STATS */
3978
3979/*
3980 * Request queuing structure
3981 */
3982typedef struct asc_queue {
3983    ADV_SCSI_BIT_ID_TYPE  q_tidmask;                /* queue mask */
3984    REQP                  q_first[ADV_MAX_TID+1];   /* first queued request */
3985    REQP                  q_last[ADV_MAX_TID+1];    /* last queued request */
3986#ifdef ADVANSYS_STATS
3987    short                 q_cur_cnt[ADV_MAX_TID+1]; /* current queue count */
3988    short                 q_max_cnt[ADV_MAX_TID+1]; /* maximum queue count */
3989    ADV_DCNT              q_tot_cnt[ADV_MAX_TID+1]; /* total enqueue count */
3990    ADV_DCNT              q_tot_tim[ADV_MAX_TID+1]; /* total time queued */
3991    ushort                q_max_tim[ADV_MAX_TID+1]; /* maximum time queued */
3992    ushort                q_min_tim[ADV_MAX_TID+1]; /* minimum time queued */
3993#endif /* ADVANSYS_STATS */
3994} asc_queue_t;
3995
3996/*
3997 * Adv Library Request Structures
3998 *
3999 * The following two structures are used to process Wide Board requests.
4000 *
4001 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
4002 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
4003 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
4004 * Mid-Level SCSI request structure.
4005 *
4006 * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
4007 * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
4008 * up to 255 scatter-gather elements may be used per request or
4009 * ADV_SCSI_REQ_Q.
4010 *
4011 * Both structures must be 32 byte aligned.
4012 */
4013typedef struct adv_sgblk {
4014    ADV_SG_BLOCK        sg_block;     /* Sgblock structure. */
4015    uchar               align[32];    /* Sgblock structure padding. */
4016    struct adv_sgblk    *next_sgblkp; /* Next scatter-gather structure. */
4017} adv_sgblk_t;
4018
4019typedef struct adv_req {
4020    ADV_SCSI_REQ_Q      scsi_req_q;   /* Adv Library request structure. */
4021    uchar               align[32];    /* Request structure padding. */
4022    Scsi_Cmnd           *cmndp;       /* Mid-Level SCSI command pointer. */
4023    adv_sgblk_t         *sgblkp;      /* Adv Library scatter-gather pointer. */
4024    struct adv_req      *next_reqp;   /* Next Request Structure. */
4025} adv_req_t;
4026
4027/*
4028 * Structure allocated for each board.
4029 *
4030 * This structure is allocated by scsi_register() at the end
4031 * of the 'Scsi_Host' structure starting at the 'hostdata'
4032 * field. It is guaranteed to be allocated from DMA-able memory.
4033 */
4034typedef struct asc_board {
4035    int                  id;                    /* Board Id */
4036    uint                 flags;                 /* Board flags */
4037    union {
4038        ASC_DVC_VAR      asc_dvc_var;           /* Narrow board */
4039        ADV_DVC_VAR      adv_dvc_var;           /* Wide board */
4040    } dvc_var;
4041    union {
4042        ASC_DVC_CFG      asc_dvc_cfg;           /* Narrow board */
4043        ADV_DVC_CFG      adv_dvc_cfg;           /* Wide board */
4044    } dvc_cfg;
4045    ushort               asc_n_io_port;         /* Number I/O ports. */
4046    asc_queue_t          active;                /* Active command queue */
4047    asc_queue_t          waiting;               /* Waiting command queue */
4048    asc_queue_t          done;                  /* Done command queue */
4049    ADV_SCSI_BIT_ID_TYPE init_tidmask;          /* Target init./valid mask */
4050    Scsi_Device          *device[ADV_MAX_TID+1]; /* Mid-Level Scsi Device */
4051    ushort               reqcnt[ADV_MAX_TID+1]; /* Starvation request count */
4052    ADV_SCSI_BIT_ID_TYPE queue_full;            /* Queue full mask */
4053    ushort               queue_full_cnt[ADV_MAX_TID+1]; /* Queue full count */
4054    union {
4055        ASCEEP_CONFIG         asc_eep;          /* Narrow EEPROM config. */
4056        ADVEEP_3550_CONFIG    adv_3550_eep;     /* 3550 EEPROM config. */
4057        ADVEEP_38C0800_CONFIG adv_38C0800_eep;  /* 38C0800 EEPROM config. */
4058        ADVEEP_38C1600_CONFIG adv_38C1600_eep;  /* 38C1600 EEPROM config. */
4059    } eep_config;
4060    ulong                last_reset;            /* Saved last reset time */
4061    spinlock_t lock;                            /* Board spinlock */
4062#ifdef CONFIG_PROC_FS
4063    /* /proc/scsi/advansys/[0...] */
4064    char                 *prtbuf;               /* /proc print buffer */
4065#endif /* CONFIG_PROC_FS */
4066#ifdef ADVANSYS_STATS
4067    struct asc_stats     asc_stats;             /* Board statistics */
4068#endif /* ADVANSYS_STATS */
4069    /*
4070     * The following fields are used only for Narrow Boards.
4071     */
4072    /* The following three structures must be in DMA-able memory. */
4073    ASC_SCSI_REQ_Q       scsireqq;
4074    ASC_CAP_INFO         cap_info;
4075    ASC_SCSI_INQUIRY     inquiry;
4076    uchar                sdtr_data[ASC_MAX_TID+1]; /* SDTR information */
4077    /*
4078     * The following fields are used only for Wide Boards.
4079     */
4080    void                 *ioremap_addr;         /* I/O Memory remap address. */
4081    ushort               ioport;                /* I/O Port address. */
4082    ADV_CARR_T           *orig_carrp;           /* ADV_CARR_T memory block. */
4083    adv_req_t            *orig_reqp;            /* adv_req_t memory block. */
4084    adv_req_t            *adv_reqp;             /* Request structures. */
4085    adv_sgblk_t          *adv_sgblkp;           /* Scatter-gather structures. */
4086    ushort               bios_signature;        /* BIOS Signature. */
4087    ushort               bios_version;          /* BIOS Version. */
4088    ushort               bios_codeseg;          /* BIOS Code Segment. */
4089    ushort               bios_codelen;          /* BIOS Code Segment Length. */
4090} asc_board_t;
4091
4092/*
4093 * PCI configuration structures
4094 */
4095typedef struct _PCI_DATA_
4096{
4097    uchar    type;
4098    uchar    bus;
4099    uchar    slot;
4100    uchar    func;
4101    uchar    offset;
4102} PCI_DATA;
4103
4104typedef struct _PCI_DEVICE_
4105{
4106    ushort   vendorID;
4107    ushort   deviceID;
4108    ushort   slotNumber;
4109    ushort   slotFound;
4110    uchar    busNumber;
4111    uchar    maxBusNumber;
4112    uchar    devFunc;
4113    ushort   startSlot;
4114    ushort   endSlot;
4115    uchar    bridge;
4116    uchar    type;
4117} PCI_DEVICE;
4118
4119typedef struct _PCI_CONFIG_SPACE_
4120{
4121    ushort   vendorID;
4122    ushort   deviceID;
4123    ushort   command;
4124    ushort   status;
4125    uchar    revision;
4126    uchar    classCode[3];
4127    uchar    cacheSize;
4128    uchar    latencyTimer;
4129    uchar    headerType;
4130    uchar    bist;
4131    ADV_PADDR baseAddress[6];
4132    ushort   reserved[4];
4133    ADV_PADDR optionRomAddr;
4134    ushort   reserved2[4];
4135    uchar    irqLine;
4136    uchar    irqPin;
4137    uchar    minGnt;
4138    uchar    maxLatency;
4139} PCI_CONFIG_SPACE;
4140
4141
4142/*
4143 * --- Driver Data
4144 */
4145
4146/* Note: All driver global data should be initialized. */
4147
4148#if ASC_LINUX_KERNEL22
4149#ifdef CONFIG_PROC_FS
4150struct proc_dir_entry proc_scsi_advansys =
4151{
4152    PROC_SCSI_ADVANSYS,              /* unsigned short low_ino */
4153    8,                               /* unsigned short namelen */
4154    "advansys",                      /* const char *name */
4155    S_IFDIR | S_IRUGO | S_IXUGO,     /* mode_t mode */
4156    2                                /* nlink_t nlink */
4157};
4158#endif /* CONFIG_PROC_FS */
4159#endif /* ASC_LINUX_KERNEL22 */
4160
4161/* Number of boards detected in system. */
4162STATIC int asc_board_count = 0;
4163STATIC struct Scsi_Host    *asc_host[ASC_NUM_BOARD_SUPPORTED] = { 0 };
4164
4165/* Overrun buffer used by all narrow boards. */
4166STATIC uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
4167
4168/*
4169 * Global structures required to issue a command.
4170 */
4171STATIC ASC_SCSI_Q asc_scsi_q = { { 0 } };
4172STATIC ASC_SG_HEAD asc_sg_head = { 0 };
4173
4174/* List of supported bus types. */
4175STATIC ushort asc_bus[ASC_NUM_BUS] ASC_INITDATA = {
4176    ASC_IS_ISA,
4177    ASC_IS_VL,
4178    ASC_IS_EISA,
4179    ASC_IS_PCI,
4180};
4181
4182/*
4183 * Used with the LILO 'advansys' option to eliminate or
4184 * limit I/O port probing at boot time, cf. advansys_setup().
4185 */
4186STATIC int asc_iopflag = ASC_FALSE;
4187STATIC int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 };
4188
4189#ifdef ADVANSYS_DEBUG
4190STATIC char *
4191asc_bus_name[ASC_NUM_BUS] = {
4192    "ASC_IS_ISA",
4193    "ASC_IS_VL",
4194    "ASC_IS_EISA",
4195    "ASC_IS_PCI",
4196};
4197
4198STATIC int          asc_dbglvl = 3;
4199#endif /* ADVANSYS_DEBUG */
4200
4201/* Declaration for Asc Library internal data referenced by driver. */
4202STATIC PortAddr     _asc_def_iop_base[];
4203
4204
4205/*
4206 * --- Driver Function Prototypes
4207 *
4208 * advansys.h contains function prototypes for functions global to Linux.
4209 */
4210
4211STATIC irqreturn_t advansys_interrupt(int, void *, struct pt_regs *);
4212STATIC int        advansys_slave_configure(Scsi_Device *);
4213STATIC void       asc_scsi_done_list(Scsi_Cmnd *, int from_isr);
4214STATIC int        asc_execute_scsi_cmnd(Scsi_Cmnd *);
4215STATIC int        asc_build_req(asc_board_t *, Scsi_Cmnd *);
4216STATIC int        adv_build_req(asc_board_t *, Scsi_Cmnd *, ADV_SCSI_REQ_Q **);
4217STATIC int        adv_get_sglist(asc_board_t *, adv_req_t *, Scsi_Cmnd *);
4218STATIC void       asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
4219STATIC void       adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
4220STATIC void       adv_async_callback(ADV_DVC_VAR *, uchar);
4221STATIC void       asc_enqueue(asc_queue_t *, REQP, int);
4222STATIC REQP       asc_dequeue(asc_queue_t *, int);
4223STATIC REQP       asc_dequeue_list(asc_queue_t *, REQP *, int);
4224STATIC int        asc_rmqueue(asc_queue_t *, REQP);
4225STATIC void       asc_execute_queue(asc_queue_t *);
4226#ifdef CONFIG_PROC_FS
4227STATIC int        asc_proc_copy(off_t, off_t, char *, int , char *, int);
4228STATIC int        asc_prt_board_devices(struct Scsi_Host *, char *, int);
4229STATIC int        asc_prt_adv_bios(struct Scsi_Host *, char *, int);
4230STATIC int        asc_get_eeprom_string(ushort *serialnum, uchar *cp);
4231STATIC int        asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
4232STATIC int        asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
4233STATIC int        asc_prt_driver_conf(struct Scsi_Host *, char *, int);
4234STATIC int        asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
4235STATIC int        asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
4236STATIC int        asc_prt_line(char *, int, char *fmt, ...);
4237#endif /* CONFIG_PROC_FS */
4238
4239/* Declaration for Asc Library internal functions referenced by driver. */
4240STATIC int          AscFindSignature(PortAddr);
4241STATIC ushort       AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
4242
4243/* Statistics function prototypes. */
4244#ifdef ADVANSYS_STATS
4245#ifdef CONFIG_PROC_FS
4246STATIC int          asc_prt_board_stats(struct Scsi_Host *, char *, int);
4247STATIC int          asc_prt_target_stats(struct Scsi_Host *, int, char *, int);
4248#endif /* CONFIG_PROC_FS */
4249#endif /* ADVANSYS_STATS */
4250
4251/* Debug function prototypes. */
4252#ifdef ADVANSYS_DEBUG
4253STATIC void         asc_prt_scsi_host(struct Scsi_Host *);
4254STATIC void         asc_prt_scsi_cmnd(Scsi_Cmnd *);
4255STATIC void         asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
4256STATIC void         asc_prt_asc_dvc_var(ASC_DVC_VAR *);
4257STATIC void         asc_prt_asc_scsi_q(ASC_SCSI_Q *);
4258STATIC void         asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
4259STATIC void         asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
4260STATIC void         asc_prt_adv_dvc_var(ADV_DVC_VAR *);
4261STATIC void         asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
4262STATIC void         asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
4263STATIC void         asc_prt_hex(char *f, uchar *, int);
4264#endif /* ADVANSYS_DEBUG */
4265
4266
4267/*
4268 * --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
4269 */
4270
4271#ifdef CONFIG_PROC_FS
4272/*
4273 * advansys_proc_info() - /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
4274 *
4275 * *buffer: I/O buffer
4276 * **start: if inout == FALSE pointer into buffer where user read should start
4277 * offset: current offset into a /proc/scsi/advansys/[0...] file
4278 * length: length of buffer
4279 * hostno: Scsi_Host host_no
4280 * inout: TRUE - user is writing; FALSE - user is reading
4281 *
4282 * Return the number of bytes read from or written to a
4283 * /proc/scsi/advansys/[0...] file.
4284 *
4285 * Note: This function uses the per board buffer 'prtbuf' which is
4286 * allocated when the board is initialized in advansys_detect(). The
4287 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
4288 * used to write to the buffer. The way asc_proc_copy() is written
4289 * if 'prtbuf' is too small it will not be overwritten. Instead the
4290 * user just won't get all the available statistics.
4291 */
4292int
4293advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
4294                off_t offset, int length, int inout)
4295{
4296    struct Scsi_Host    *shp;
4297    asc_board_t         *boardp;
4298    int                 i;
4299    char                *cp;
4300    int                 cplen;
4301    int                 cnt;
4302    int                 totcnt;
4303    int                 leftlen;
4304    char                *curbuf;
4305    off_t               advoffset;
4306#ifdef ADVANSYS_STATS
4307    int                 tgt_id;
4308#endif /* ADVANSYS_STATS */
4309
4310    ASC_DBG(1, "advansys_proc_info: begin\n");
4311
4312    /*
4313     * User write not supported.
4314     */
4315    if (inout == TRUE) {
4316        return(-ENOSYS);
4317    }
4318
4319    /*
4320     * User read of /proc/scsi/advansys/[0...] file.
4321     */
4322
4323    /* Find the specified board. */
4324    for (i = 0; i < asc_board_count; i++) {
4325        if (asc_host[i]->host_no == shost->host_no) {
4326            break;
4327        }
4328    }
4329    if (i == asc_board_count) {
4330        return(-ENOENT);
4331    }
4332
4333    shp = asc_host[i];
4334    boardp = ASC_BOARDP(shp);
4335
4336    /* Copy read data starting at the beginning of the buffer. */
4337    *start = buffer;
4338    curbuf = buffer;
4339    advoffset = 0;
4340    totcnt = 0;
4341    leftlen = length;
4342
4343    /*
4344     * Get board configuration information.
4345     *
4346     * advansys_info() returns the board string from its own static buffer.
4347     */
4348    cp = (char *) advansys_info(shp);
4349    strcat(cp, "\n");
4350    cplen = strlen(cp);
4351    /* Copy board information. */
4352    cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4353    totcnt += cnt;
4354    leftlen -= cnt;
4355    if (leftlen == 0) {
4356        ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4357        return totcnt;
4358    }
4359    advoffset += cplen;
4360    curbuf += cnt;
4361
4362    /*
4363     * Display Wide Board BIOS Information.
4364     */
4365    if (ASC_WIDE_BOARD(boardp)) {
4366        cp = boardp->prtbuf;
4367        cplen = asc_prt_adv_bios(shp, cp, ASC_PRTBUF_SIZE);
4368        ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4369        cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4370        totcnt += cnt;
4371        leftlen -= cnt;
4372        if (leftlen == 0) {
4373            ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4374            return totcnt;
4375        }
4376        advoffset += cplen;
4377        curbuf += cnt;
4378    }
4379
4380    /*
4381     * Display driver information for each device attached to the board.
4382     */
4383    cp = boardp->prtbuf;
4384    cplen = asc_prt_board_devices(shp, cp, ASC_PRTBUF_SIZE);
4385    ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4386    cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4387    totcnt += cnt;
4388    leftlen -= cnt;
4389    if (leftlen == 0) {
4390        ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4391        return totcnt;
4392    }
4393    advoffset += cplen;
4394    curbuf += cnt;
4395
4396    /*
4397     * Display EEPROM configuration for the board.
4398     */
4399    cp = boardp->prtbuf;
4400    if (ASC_NARROW_BOARD(boardp)) {
4401        cplen = asc_prt_asc_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
4402    } else {
4403        cplen = asc_prt_adv_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
4404    }
4405    ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4406    cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4407    totcnt += cnt;
4408    leftlen -= cnt;
4409    if (leftlen == 0) {
4410        ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4411        return totcnt;
4412    }
4413    advoffset += cplen;
4414    curbuf += cnt;
4415
4416    /*
4417     * Display driver configuration and information for the board.
4418     */
4419    cp = boardp->prtbuf;
4420    cplen = asc_prt_driver_conf(shp, cp, ASC_PRTBUF_SIZE);
4421    ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4422    cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4423    totcnt += cnt;
4424    leftlen -= cnt;
4425    if (leftlen == 0) {
4426        ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4427        return totcnt;
4428    }
4429    advoffset += cplen;
4430    curbuf += cnt;
4431
4432#ifdef ADVANSYS_STATS
4433    /*
4434     * Display driver statistics for the board.
4435     */
4436    cp = boardp->prtbuf;
4437    cplen = asc_prt_board_stats(shp, cp, ASC_PRTBUF_SIZE);
4438    ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4439    cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4440    totcnt += cnt;
4441    leftlen -= cnt;
4442    if (leftlen == 0) {
4443        ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4444        return totcnt;
4445    }
4446    advoffset += cplen;
4447    curbuf += cnt;
4448
4449    /*
4450     * Display driver statistics for each target.
4451     */
4452    for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) {
4453      cp = boardp->prtbuf;
4454      cplen = asc_prt_target_stats(shp, tgt_id, cp, ASC_PRTBUF_SIZE);
4455      ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4456      cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4457      totcnt += cnt;
4458      leftlen -= cnt;
4459      if (leftlen == 0) {
4460        ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4461        return totcnt;
4462      }
4463      advoffset += cplen;
4464      curbuf += cnt;
4465    }
4466#endif /* ADVANSYS_STATS */
4467
4468    /*
4469     * Display Asc Library dynamic configuration information
4470     * for the board.
4471     */
4472    cp = boardp->prtbuf;
4473    if (ASC_NARROW_BOARD(boardp)) {
4474        cplen = asc_prt_asc_board_info(shp, cp, ASC_PRTBUF_SIZE);
4475    } else {
4476        cplen = asc_prt_adv_board_info(shp, cp, ASC_PRTBUF_SIZE);
4477    }
4478    ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4479    cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4480    totcnt += cnt;
4481    leftlen -= cnt;
4482    if (leftlen == 0) {
4483        ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4484        return totcnt;
4485    }
4486    advoffset += cplen;
4487    curbuf += cnt;
4488
4489    ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4490
4491    return totcnt;
4492}
4493#endif /* CONFIG_PROC_FS */
4494
4495/*
4496 * advansys_detect()
4497 *
4498 * Detect function for AdvanSys adapters.
4499 *
4500 * Argument is a pointer to the host driver's scsi_hosts entry.
4501 *
4502 * Return number of adapters found.
4503 *
4504 * Note: Because this function is called during system initialization
4505 * it must not call SCSI mid-level functions including scsi_malloc()
4506 * and scsi_free().
4507 */
4508ASC_INITFUNC(
4509int,
4510advansys_detect(Scsi_Host_Template *tpnt)
4511)
4512{
4513    static int          detect_called = ASC_FALSE;
4514    int                 iop;
4515    int                 bus;
4516    struct Scsi_Host    *shp = NULL;
4517    asc_board_t         *boardp = NULL;
4518    ASC_DVC_VAR         *asc_dvc_varp = NULL;
4519    ADV_DVC_VAR         *adv_dvc_varp = NULL;
4520    adv_sgblk_t         *sgp = NULL;
4521    int                 ioport = 0;
4522    int                 share_irq = FALSE;
4523    int                 iolen = 0;
4524#ifdef CONFIG_PCI
4525    int                 pci_init_search = 0;
4526    struct pci_dev      *pci_devicep[ASC_NUM_BOARD_SUPPORTED];
4527    int                 pci_card_cnt_max = 0;
4528    int                 pci_card_cnt = 0;
4529    struct pci_dev      *pci_devp = NULL;
4530    int                 pci_device_id_cnt = 0;
4531    unsigned int        pci_device_id[ASC_PCI_DEVICE_ID_CNT] = {
4532                                    ASC_PCI_DEVICE_ID_1100,
4533                                    ASC_PCI_DEVICE_ID_1200,
4534                                    ASC_PCI_DEVICE_ID_1300,
4535                                    ASC_PCI_DEVICE_ID_2300,
4536                                    ASC_PCI_DEVICE_ID_2500,
4537                                    ASC_PCI_DEVICE_ID_2700
4538                        };
4539    ADV_PADDR           pci_memory_address;
4540#endif /* CONFIG_PCI */
4541    int                 warn_code, err_code;
4542    int                 ret;
4543
4544    if (detect_called == ASC_FALSE) {
4545        detect_called = ASC_TRUE;
4546    } else {
4547        printk("AdvanSys SCSI: advansys_detect() multiple calls ignored\n");
4548        return 0;
4549    }
4550
4551    ASC_DBG(1, "advansys_detect: begin\n");
4552
4553#if ASC_LINUX_KERNEL24
4554    tpnt->proc_name = "advansys";
4555#elif ASC_LINUX_KERNEL22
4556    tpnt->proc_dir = &proc_scsi_advansys;
4557#endif
4558
4559    asc_board_count = 0;
4560
4561    /*
4562     * If I/O port probing has been modified, then verify and
4563     * clean-up the 'asc_ioport' list.
4564     */
4565    if (asc_iopflag == ASC_TRUE) {
4566        for (ioport = 0; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
4567            ASC_DBG2(1, "advansys_detect: asc_ioport[%d] 0x%x\n",
4568                ioport, asc_ioport[ioport]);
4569            if (asc_ioport[ioport] != 0) {
4570                for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX; iop++) {
4571                    if (_asc_def_iop_base[iop] == asc_ioport[ioport]) {
4572                        break;
4573                    }
4574                }
4575                if (iop == ASC_IOADR_TABLE_MAX_IX) {
4576                    printk(
4577"AdvanSys SCSI: specified I/O Port 0x%X is invalid\n",
4578                        asc_ioport[ioport]);
4579                    asc_ioport[ioport] = 0;
4580                }
4581            }
4582        }
4583        ioport = 0;
4584    }
4585
4586    for (bus = 0; bus < ASC_NUM_BUS; bus++) {
4587
4588        ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n",
4589            bus, asc_bus_name[bus]);
4590        iop = 0;
4591
4592        while (asc_board_count < ASC_NUM_BOARD_SUPPORTED) {
4593
4594            ASC_DBG1(2, "advansys_detect: asc_board_count %d\n",
4595                asc_board_count);
4596
4597            switch (asc_bus[bus]) {
4598            case ASC_IS_ISA:
4599            case ASC_IS_VL:
4600#ifdef CONFIG_ISA
4601                if (asc_iopflag == ASC_FALSE) {
4602                    iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
4603                } else {
4604                    /*
4605                     * ISA and VL I/O port scanning has either been
4606                     * eliminated or limited to selected ports on
4607                     * the LILO command line, /etc/lilo.conf, or
4608                     * by setting variables when the module was loaded.
4609                     */
4610                    ASC_DBG(1, "advansys_detect: I/O port scanning modified\n");
4611                ioport_try_again:
4612                    iop = 0;
4613                    for (; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
4614                        if ((iop = asc_ioport[ioport]) != 0) {
4615                            break;
4616                        }
4617                    }
4618                    if (iop) {
4619                        ASC_DBG1(1,
4620                                "advansys_detect: probing I/O port 0x%x...\n",
4621                            iop);
4622                        if (check_region(iop, ASC_IOADR_GAP) != 0) {
4623                            printk(
4624"AdvanSys SCSI: specified I/O Port 0x%X is busy\n", iop);
4625                            /* Don't try this I/O port twice. */
4626                            asc_ioport[ioport] = 0;
4627                            goto ioport_try_again;
4628                        } else if (AscFindSignature(iop) == ASC_FALSE) {
4629                            printk(
4630"AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n", iop);
4631                            /* Don't try this I/O port twice. */
4632                            asc_ioport[ioport] = 0;
4633                            goto ioport_try_again;
4634                        } else {
4635                            /*
4636                             * If this isn't an ISA board, then it must be
4637                             * a VL board. If currently looking an ISA
4638                             * board is being looked for then try for
4639                             * another ISA board in 'asc_ioport'.
4640                             */
4641                            if (asc_bus[bus] == ASC_IS_ISA &&
4642                                (AscGetChipVersion(iop, ASC_IS_ISA) &
4643                                 ASC_CHIP_VER_ISA_BIT) == 0) {
4644                                 /*
4645                                  * Don't clear 'asc_ioport[ioport]'. Try
4646                                  * this board again for VL. Increment
4647                                  * 'ioport' past this board.
4648                                  */
4649                                 ioport++;
4650                                 goto ioport_try_again;
4651                            }
4652                        }
4653                        /*
4654                         * This board appears good, don't try the I/O port
4655                         * again by clearing its value. Increment 'ioport'
4656                         * for the next iteration.
4657                         */
4658                        asc_ioport[ioport++] = 0;
4659                    }
4660                }
4661#endif /* CONFIG_ISA */
4662                break;
4663
4664            case ASC_IS_EISA:
4665#ifdef CONFIG_ISA
4666                iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
4667#endif /* CONFIG_ISA */
4668                break;
4669
4670            case ASC_IS_PCI:
4671#ifdef CONFIG_PCI
4672                if (pci_init_search == 0) {
4673                    int i, j;
4674
4675                    pci_init_search = 1;
4676
4677                    /* Find all PCI cards. */
4678                    while (pci_device_id_cnt < ASC_PCI_DEVICE_ID_CNT) {
4679                        if ((pci_devp = pci_find_device(ASC_PCI_VENDORID,
4680                            pci_device_id[pci_device_id_cnt], pci_devp)) ==
4681                            NULL) {
4682                            pci_device_id_cnt++;
4683                        } else {
4684#if ASC_LINUX_KERNEL24
4685                            if (pci_enable_device(pci_devp) == 0) {
4686                                pci_devicep[pci_card_cnt_max++] = pci_devp;
4687                            }
4688#elif ASC_LINUX_KERNEL22
4689                            pci_devicep[pci_card_cnt_max++] = pci_devp;
4690#endif
4691                        }
4692                    }
4693
4694                    /*
4695                     * Sort PCI cards in ascending order by PCI Bus, Slot,
4696                     * and Device Number.
4697                     */
4698                    for (i = 0; i < pci_card_cnt_max - 1; i++)
4699                    {
4700                        for (j = i + 1; j < pci_card_cnt_max; j++) {
4701                            if ((pci_devicep[j]->bus->number <
4702                                 pci_devicep[i]->bus->number) ||
4703                                ((pci_devicep[j]->bus->number ==
4704                                  pci_devicep[i]->bus->number) &&
4705                                  (pci_devicep[j]->devfn <
4706                                   pci_devicep[i]->devfn))) {
4707                                pci_devp = pci_devicep[i];
4708                                pci_devicep[i] = pci_devicep[j];
4709                                pci_devicep[j] = pci_devp;
4710                            }
4711                        }
4712                    }
4713
4714                    pci_card_cnt = 0;
4715                } else {
4716                    pci_card_cnt++;
4717                }
4718
4719                if (pci_card_cnt == pci_card_cnt_max) {
4720                    iop = 0;
4721                } else {
4722                    pci_devp = pci_devicep[pci_card_cnt];
4723
4724                    ASC_DBG2(2,
4725                        "advansys_detect: devfn %d, bus number %d\n",
4726                        pci_devp->devfn, pci_devp->bus->number);
4727#if ASC_LINUX_KERNEL24
4728                    iop = pci_resource_start(pci_devp, 0);
4729#elif ASC_LINUX_KERNEL22
4730                    iop = pci_devp->base_address[0] & PCI_IOADDRESS_MASK;
4731#endif
4732                    ASC_DBG2(1,
4733                        "advansys_detect: vendorID %X, deviceID %X\n",
4734                        pci_devp->vendor, pci_devp->device);
4735                    ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n",
4736                        iop, pci_devp->irq);
4737                }
4738#endif /* CONFIG_PCI */
4739                break;
4740
4741            default:
4742                ASC_PRINT1("advansys_detect: unknown bus type: %d\n",
4743                    asc_bus[bus]);
4744                break;
4745            }
4746            ASC_DBG1(1, "advansys_detect: iop 0x%x\n", iop);
4747
4748            /*
4749             * Adapter not found, try next bus type.
4750             */
4751            if (iop == 0) {
4752                break;
4753            }
4754
4755            /*
4756             * Adapter found.
4757             *
4758             * Register the adapter, get its configuration, and
4759             * initialize it.
4760             */
4761            ASC_DBG(2, "advansys_detect: scsi_register()\n");
4762            shp = scsi_register(tpnt, sizeof(asc_board_t));
4763
4764            if (shp == NULL) {
4765                continue;
4766            }
4767
4768            scsi_set_device(shp, &pci_devp->dev);
4769
4770            /* Save a pointer to the Scsi_Host of each board found. */
4771            asc_host[asc_board_count++] = shp;
4772
4773            /* Initialize private per board data */
4774            boardp = ASC_BOARDP(shp);
4775            memset(boardp, 0, sizeof(asc_board_t));
4776            boardp->id = asc_board_count - 1;
4777
4778            /* Initialize spinlock. */
4779            boardp->lock = SPIN_LOCK_UNLOCKED;
4780
4781            /*
4782             * Handle both narrow and wide boards.
4783             *
4784             * If a Wide board was detected, set the board structure
4785             * wide board flag. Set-up the board structure based on
4786             * the board type.
4787             */
4788#ifdef CONFIG_PCI
4789            if (asc_bus[bus] == ASC_IS_PCI &&
4790                (pci_devp->device == ASC_PCI_DEVICE_ID_2300 ||
4791                 pci_devp->device == ASC_PCI_DEVICE_ID_2500 ||
4792                 pci_devp->device == ASC_PCI_DEVICE_ID_2700))
4793            {
4794                boardp->flags |= ASC_IS_WIDE_BOARD;
4795            }
4796#endif /* CONFIG_PCI */
4797
4798            if (ASC_NARROW_BOARD(boardp)) {
4799                ASC_DBG(1, "advansys_detect: narrow board\n");
4800                asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4801                asc_dvc_varp->bus_type = asc_bus[bus];
4802                asc_dvc_varp->drv_ptr = boardp;
4803                asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
4804                asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
4805                asc_dvc_varp->iop_base = iop;
4806                asc_dvc_varp->isr_callback = asc_isr_callback;
4807            } else {
4808                ASC_DBG(1, "advansys_detect: wide board\n");
4809                adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4810                adv_dvc_varp->drv_ptr = boardp;
4811                adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
4812                adv_dvc_varp->isr_callback = adv_isr_callback;
4813                adv_dvc_varp->async_callback = adv_async_callback;
4814#ifdef CONFIG_PCI
4815                if (pci_devp->device == ASC_PCI_DEVICE_ID_2300)
4816                {
4817                    ASC_DBG(1, "advansys_detect: ASC-3550\n");
4818                    adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
4819                } else if (pci_devp->device == ASC_PCI_DEVICE_ID_2500)
4820                {
4821                    ASC_DBG(1, "advansys_detect: ASC-38C0800\n");
4822                    adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
4823                } else
4824                {
4825                    ASC_DBG(1, "advansys_detect: ASC-38C1600\n");
4826                    adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
4827                }
4828#endif /* CONFIG_PCI */
4829
4830                /*
4831                 * Map the board's registers into virtual memory for
4832                 * PCI slave access. Only memory accesses are used to
4833                 * access the board's registers.
4834                 *
4835                 * Note: The PCI register base address is not always
4836                 * page aligned, but the address passed to ioremap()
4837                 * must be page aligned. It is guaranteed that the
4838                 * PCI register base address will not cross a page
4839                 * boundary.
4840                 */
4841                if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
4842                {
4843                    iolen = ADV_3550_IOLEN;
4844                } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
4845                {
4846                    iolen = ADV_38C0800_IOLEN;
4847                } else
4848                {
4849                    iolen = ADV_38C1600_IOLEN;
4850                }
4851#ifdef CONFIG_PCI
4852#if ASC_LINUX_KERNEL24
4853                pci_memory_address = pci_resource_start(pci_devp, 1);
4854#elif ASC_LINUX_KERNEL22
4855                pci_memory_address = pci_devp->base_address[1];
4856#endif
4857                ASC_DBG1(1, "advansys_detect: pci_memory_address: 0x%lx\n",
4858                    (ulong) pci_memory_address);
4859                if ((boardp->ioremap_addr =
4860                    ioremap(pci_memory_address & PAGE_MASK,
4861                         PAGE_SIZE)) == 0) {
4862                   ASC_PRINT3(
4863"advansys_detect: board %d: ioremap(%x, %d) returned NULL\n",
4864                       boardp->id, pci_memory_address, iolen);
4865                   scsi_unregister(shp);
4866                   asc_board_count--;
4867                   continue;
4868                }
4869                ASC_DBG1(1, "advansys_detect: ioremap_addr: 0x%lx\n",
4870                    (ulong) boardp->ioremap_addr);
4871                adv_dvc_varp->iop_base = (AdvPortAddr)
4872                    (boardp->ioremap_addr +
4873                     (pci_memory_address - (pci_memory_address & PAGE_MASK)));
4874                ASC_DBG1(1, "advansys_detect: iop_base: 0x%lx\n",
4875                    adv_dvc_varp->iop_base);
4876#endif /* CONFIG_PCI */
4877
4878                /*
4879                 * Even though it isn't used to access wide boards, other
4880                 * than for the debug line below, save I/O Port address so
4881                 * that it can be reported.
4882                 */
4883                boardp->ioport = iop;
4884
4885                ASC_DBG2(1,
4886"advansys_detect: iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
4887                    (ushort) inp(iop + 1), (ushort) inpw(iop));
4888            }
4889
4890#ifdef CONFIG_PROC_FS
4891            /*
4892             * Allocate buffer for printing information from
4893             * /proc/scsi/advansys/[0...].
4894             */
4895            if ((boardp->prtbuf =
4896                kmalloc(ASC_PRTBUF_SIZE, GFP_ATOMIC)) == NULL) {
4897                ASC_PRINT3(
4898"advansys_detect: board %d: kmalloc(%d, %d) returned NULL\n",
4899                    boardp->id, ASC_PRTBUF_SIZE, GFP_ATOMIC);
4900                scsi_unregister(shp);
4901                asc_board_count--;
4902                continue;
4903            }
4904#endif /* CONFIG_PROC_FS */
4905
4906            if (ASC_NARROW_BOARD(boardp)) {
4907                /*
4908                 * Set the board bus type and PCI IRQ before
4909                 * calling AscInitGetConfig().
4910                 */
4911                switch (asc_dvc_varp->bus_type) {
4912#ifdef CONFIG_ISA
4913                case ASC_IS_ISA:
4914                    shp->unchecked_isa_dma = TRUE;
4915                    share_irq = FALSE;
4916                    break;
4917                case ASC_IS_VL:
4918                    shp->unchecked_isa_dma = FALSE;
4919                    share_irq = FALSE;
4920                    break;
4921                case ASC_IS_EISA:
4922                    shp->unchecked_isa_dma = FALSE;
4923                    share_irq = TRUE;
4924                    break;
4925#endif /* CONFIG_ISA */
4926#ifdef CONFIG_PCI
4927                case ASC_IS_PCI:
4928                    shp->irq = asc_dvc_varp->irq_no = pci_devp->irq;
4929                    asc_dvc_varp->cfg->pci_dev = pci_devp;
4930                    asc_dvc_varp->cfg->pci_slot_info =
4931                        ASC_PCI_MKID(pci_devp->bus->number,
4932                            PCI_SLOT(pci_devp->devfn),
4933                            PCI_FUNC(pci_devp->devfn));
4934                    shp->unchecked_isa_dma = FALSE;
4935                    share_irq = TRUE;
4936                    break;
4937#endif /* CONFIG_PCI */
4938                default:
4939                    ASC_PRINT2(
4940"advansys_detect: board %d: unknown adapter type: %d\n",
4941                        boardp->id, asc_dvc_varp->bus_type);
4942                    shp->unchecked_isa_dma = TRUE;
4943                    share_irq = FALSE;
4944                    break;
4945                }
4946            } else {
4947                /*
4948                 * For Wide boards set PCI information before calling
4949                 * AdvInitGetConfig().
4950                 */
4951#ifdef CONFIG_PCI
4952                shp->irq = adv_dvc_varp->irq_no = pci_devp->irq;
4953                adv_dvc_varp->cfg->pci_dev = pci_devp;
4954                adv_dvc_varp->cfg->pci_slot_info =
4955                    ASC_PCI_MKID(pci_devp->bus->number,
4956                        PCI_SLOT(pci_devp->devfn),
4957                        PCI_FUNC(pci_devp->devfn));
4958                shp->unchecked_isa_dma = FALSE;
4959                share_irq = TRUE;
4960#endif /* CONFIG_PCI */
4961            }
4962
4963            /*
4964             * Read the board configuration.
4965             */
4966            if (ASC_NARROW_BOARD(boardp)) {
4967                 /*
4968                  * NOTE: AscInitGetConfig() may change the board's
4969                  * bus_type value. The asc_bus[bus] value should no
4970                  * longer be used. If the bus_type field must be
4971                  * referenced only use the bit-wise AND operator "&".
4972                  */
4973                ASC_DBG(2, "advansys_detect: AscInitGetConfig()\n");
4974                switch(ret = AscInitGetConfig(asc_dvc_varp)) {
4975                case 0:    /* No error */
4976                    break;
4977                case ASC_WARN_IO_PORT_ROTATE:
4978                    ASC_PRINT1(
4979"AscInitGetConfig: board %d: I/O port address modified\n",
4980                        boardp->id);
4981                    break;
4982                case ASC_WARN_AUTO_CONFIG:
4983                    ASC_PRINT1(
4984"AscInitGetConfig: board %d: I/O port increment switch enabled\n",
4985                        boardp->id);
4986                    break;
4987                case ASC_WARN_EEPROM_CHKSUM:
4988                    ASC_PRINT1(
4989"AscInitGetConfig: board %d: EEPROM checksum error\n",
4990                        boardp->id);
4991                    break;
4992                case ASC_WARN_IRQ_MODIFIED:
4993                    ASC_PRINT1(
4994"AscInitGetConfig: board %d: IRQ modified\n",
4995                        boardp->id);
4996                    break;
4997                case ASC_WARN_CMD_QNG_CONFLICT:
4998                    ASC_PRINT1(
4999"AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
5000                        boardp->id);
5001                    break;
5002                default:
5003                    ASC_PRINT2(
5004"AscInitGetConfig: board %d: unknown warning: 0x%x\n",
5005                        boardp->id, ret);
5006                    break;
5007                }
5008                if ((err_code = asc_dvc_varp->err_code) != 0) {
5009                    ASC_PRINT3(
5010"AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
5011                        boardp->id, asc_dvc_varp->init_state,
5012                        asc_dvc_varp->err_code);
5013                }
5014            } else {
5015                ASC_DBG(2, "advansys_detect: AdvInitGetConfig()\n");
5016                if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
5017                    ASC_PRINT2("AdvInitGetConfig: board %d: warning: 0x%x\n",
5018                        boardp->id, ret);
5019                }
5020                if ((err_code = adv_dvc_varp->err_code) != 0) {
5021                    ASC_PRINT2(
5022"AdvInitGetConfig: board %d error: err_code 0x%x\n",
5023                        boardp->id, adv_dvc_varp->err_code);
5024                }
5025            }
5026
5027            if (err_code != 0) {
5028#ifdef CONFIG_PROC_FS
5029                kfree(boardp->prtbuf);
5030#endif /* CONFIG_PROC_FS */
5031                scsi_unregister(shp);
5032                asc_board_count--;
5033                continue;
5034            }
5035
5036            /*
5037             * Save the EEPROM configuration so that it can be displayed
5038             * from /proc/scsi/advansys/[0...].
5039             */
5040            if (ASC_NARROW_BOARD(boardp)) {
5041
5042                ASCEEP_CONFIG *ep;
5043
5044                /*
5045                 * Set the adapter's target id bit in the 'init_tidmask' field.
5046                 */
5047                boardp->init_tidmask |=
5048                    ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
5049
5050                /*
5051                 * Save EEPROM settings for the board.
5052                 */
5053                ep = &boardp->eep_config.asc_eep;
5054
5055                ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
5056                ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
5057                ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
5058                ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
5059                ep->start_motor = asc_dvc_varp->start_motor;
5060                ep->cntl = asc_dvc_varp->dvc_cntl;
5061                ep->no_scam = asc_dvc_varp->no_scam;
5062                ep->max_total_qng = asc_dvc_varp->max_total_qng;
5063                ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
5064                /* 'max_tag_qng' is set to the same value for every device. */
5065                ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
5066                ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
5067                ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
5068                ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
5069                ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
5070                ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
5071                ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
5072
5073               /*
5074                * Modify board configuration.
5075                */
5076                ASC_DBG(2, "advansys_detect: AscInitSetConfig()\n");
5077                switch (ret = AscInitSetConfig(asc_dvc_varp)) {
5078                case 0:    /* No error. */
5079                    break;
5080                case ASC_WARN_IO_PORT_ROTATE:
5081                    ASC_PRINT1(
5082"AscInitSetConfig: board %d: I/O port address modified\n",
5083                        boardp->id);
5084                    break;
5085                case ASC_WARN_AUTO_CONFIG:
5086                    ASC_PRINT1(
5087"AscInitSetConfig: board %d: I/O port increment switch enabled\n",
5088                        boardp->id);
5089                    break;
5090                case ASC_WARN_EEPROM_CHKSUM:
5091                    ASC_PRINT1(
5092"AscInitSetConfig: board %d: EEPROM checksum error\n",
5093                        boardp->id);
5094                    break;
5095                case ASC_WARN_IRQ_MODIFIED:
5096                    ASC_PRINT1(
5097"AscInitSetConfig: board %d: IRQ modified\n",
5098                        boardp->id);
5099                    break;
5100                case ASC_WARN_CMD_QNG_CONFLICT:
5101                    ASC_PRINT1(
5102"AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
5103                        boardp->id);
5104                    break;
5105                default:
5106                    ASC_PRINT2(
5107"AscInitSetConfig: board %d: unknown warning: 0x%x\n",
5108                        boardp->id, ret);
5109                    break;
5110                }
5111                if (asc_dvc_varp->err_code != 0) {
5112                    ASC_PRINT3(
5113"AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
5114                        boardp->id, asc_dvc_varp->init_state,
5115                        asc_dvc_varp->err_code);
5116#ifdef CONFIG_PROC_FS
5117                    kfree(boardp->prtbuf);
5118#endif /* CONFIG_PROC_FS */
5119                    scsi_unregister(shp);
5120                    asc_board_count--;
5121                    continue;
5122                }
5123
5124                /*
5125                 * Finish initializing the 'Scsi_Host' structure.
5126                 */
5127                /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
5128                if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
5129                    shp->irq = asc_dvc_varp->irq_no;
5130                }
5131            } else {
5132                ADVEEP_3550_CONFIG      *ep_3550;
5133                ADVEEP_38C0800_CONFIG   *ep_38C0800;
5134                ADVEEP_38C1600_CONFIG   *ep_38C1600;
5135
5136                /*
5137                 * Save Wide EEP Configuration Information.
5138                 */
5139                if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
5140                {
5141                    ep_3550 = &boardp->eep_config.adv_3550_eep;
5142
5143                    ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
5144                    ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
5145                    ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
5146                    ep_3550->termination = adv_dvc_varp->cfg->termination;
5147                    ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
5148                    ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
5149                    ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
5150                    ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
5151                    ep_3550->ultra_able = adv_dvc_varp->ultra_able;
5152                    ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
5153                    ep_3550->start_motor = adv_dvc_varp->start_motor;
5154                    ep_3550->scsi_reset_delay = adv_dvc_varp->scsi_reset_wait;
5155                    ep_3550->serial_number_word1 =
5156                        adv_dvc_varp->cfg->serial1;
5157                    ep_3550->serial_number_word2 =
5158                        adv_dvc_varp->cfg->serial2;
5159                    ep_3550->serial_number_word3 =
5160                        adv_dvc_varp->cfg->serial3;
5161                } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
5162                {
5163                    ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
5164
5165                    ep_38C0800->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
5166                    ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
5167                    ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
5168                    ep_38C0800->termination_lvd =
5169                        adv_dvc_varp->cfg->termination;
5170                    ep_38C0800->disc_enable = adv_dvc_varp->cfg->disc_enable;
5171                    ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
5172                    ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
5173                    ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
5174                    ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
5175                    ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
5176                    ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
5177                    ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
5178                    ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
5179                    ep_38C0800->start_motor = adv_dvc_varp->start_motor;
5180                    ep_38C0800->scsi_reset_delay =
5181                        adv_dvc_varp->scsi_reset_wait;
5182                    ep_38C0800->serial_number_word1 =
5183                        adv_dvc_varp->cfg->serial1;
5184                    ep_38C0800->serial_number_word2 =
5185                        adv_dvc_varp->cfg->serial2;
5186                    ep_38C0800->serial_number_word3 =
5187                        adv_dvc_varp->cfg->serial3;
5188                } else
5189                {
5190                    ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
5191
5192                    ep_38C1600->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
5193                    ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
5194                    ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
5195                    ep_38C1600->termination_lvd =
5196                        adv_dvc_varp->cfg->termination;
5197                    ep_38C1600->disc_enable = adv_dvc_varp->cfg->disc_enable;
5198                    ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
5199                    ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
5200                    ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
5201                    ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
5202                    ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
5203                    ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
5204                    ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
5205                    ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
5206                    ep_38C1600->start_motor = adv_dvc_varp->start_motor;
5207                    ep_38C1600->scsi_reset_delay =
5208                        adv_dvc_varp->scsi_reset_wait;
5209                    ep_38C1600->serial_number_word1 =
5210                        adv_dvc_varp->cfg->serial1;
5211                    ep_38C1600->serial_number_word2 =
5212                        adv_dvc_varp->cfg->serial2;
5213                    ep_38C1600->serial_number_word3 =
5214                        adv_dvc_varp->cfg->serial3;
5215                }
5216
5217                /*
5218                 * Set the adapter's target id bit in the 'init_tidmask' field.
5219                 */
5220                boardp->init_tidmask |=
5221                    ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
5222
5223                /*
5224                 * Finish initializing the 'Scsi_Host' structure.
5225                 */
5226                shp->irq = adv_dvc_varp->irq_no;
5227            }
5228
5229            /*
5230             * Channels are numbered beginning with 0. For AdvanSys one host
5231             * structure supports one channel. Multi-channel boards have a
5232             * separate host structure for each channel.
5233             */
5234            shp->max_channel = 0;
5235            if (ASC_NARROW_BOARD(boardp)) {
5236                shp->max_id = ASC_MAX_TID + 1;
5237                shp->max_lun = ASC_MAX_LUN + 1;
5238
5239                shp->io_port = asc_dvc_varp->iop_base;
5240                boardp->asc_n_io_port = ASC_IOADR_GAP;
5241                shp->this_id = asc_dvc_varp->cfg->chip_scsi_id;
5242
5243                /* Set maximum number of queues the adapter can handle. */
5244                shp->can_queue = asc_dvc_varp->max_total_qng;
5245            } else {
5246                shp->max_id = ADV_MAX_TID + 1;
5247                shp->max_lun = ADV_MAX_LUN + 1;
5248
5249                /*
5250                 * Save the I/O Port address and length even though
5251                 * I/O ports are not used to access Wide boards.
5252                 * Instead the Wide boards are accessed with
5253                 * PCI Memory Mapped I/O.
5254                 */
5255                shp->io_port = iop;
5256                boardp->asc_n_io_port = iolen;
5257
5258                shp->this_id = adv_dvc_varp->chip_scsi_id;
5259
5260                /* Set maximum number of queues the adapter can handle. */
5261                shp->can_queue = adv_dvc_varp->max_host_qng;
5262            }
5263
5264            /*
5265             * 'n_io_port' currently is one byte.
5266             *
5267             * Set a value to 'n_io_port', but never referenced it because
5268             * it may be truncated.
5269             */
5270            shp->n_io_port = boardp->asc_n_io_port <= 255 ?
5271                boardp->asc_n_io_port : 255;
5272
5273            /*
5274             * Following v1.3.89, 'cmd_per_lun' is no longer needed
5275             * and should be set to zero.
5276             *
5277             * But because of a bug introduced in v1.3.89 if the driver is
5278             * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
5279             * SCSI function 'allocate_device' will panic. To allow the driver
5280             * to work as a module in these kernels set 'cmd_per_lun' to 1.
5281             *
5282             * Note: This is wrong.  cmd_per_lun should be set to the depth
5283             * you want on untagged devices always.
5284#ifdef MODULE
5285             */
5286            shp->cmd_per_lun = 1;
5287/* #else
5288            shp->cmd_per_lun = 0;
5289#endif */
5290
5291            /*
5292             * Set the maximum number of scatter-gather elements the
5293             * adapter can handle.
5294             */
5295            if (ASC_NARROW_BOARD(boardp)) {
5296                /*
5297                 * Allow two commands with 'sg_tablesize' scatter-gather
5298                 * elements to be executed simultaneously. This value is
5299                 * the theoretical hardware limit. It may be decreased
5300                 * below.
5301                 */
5302                shp->sg_tablesize =
5303                    (((asc_dvc_varp->max_total_qng - 2) / 2) *
5304                    ASC_SG_LIST_PER_Q) + 1;
5305            } else {
5306                shp->sg_tablesize = ADV_MAX_SG_LIST;
5307            }
5308
5309            /*
5310             * The value of 'sg_tablesize' can not exceed the SCSI
5311             * mid-level driver definition of SG_ALL. SG_ALL also
5312             * must not be exceeded, because it is used to define the
5313             * size of the scatter-gather table in 'struct asc_sg_head'.
5314             */
5315            if (shp->sg_tablesize > SG_ALL) {
5316                shp->sg_tablesize = SG_ALL;
5317            }
5318
5319            ASC_DBG1(1, "advansys_detect: sg_tablesize: %d\n",
5320                shp->sg_tablesize);
5321
5322            /* BIOS start address. */
5323            if (ASC_NARROW_BOARD(boardp)) {
5324#if ASC_LINUX_KERNEL24
5325                shp->base =
5326#elif ASC_LINUX_KERNEL22
5327                shp->base = (char *)
5328#endif
5329                        ((ulong) AscGetChipBiosAddress(
5330                            asc_dvc_varp->iop_base,
5331                            asc_dvc_varp->bus_type));
5332            } else {
5333                /*
5334                 * Fill-in BIOS board variables. The Wide BIOS saves
5335                 * information in LRAM that is used by the driver.
5336                 */
5337                AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_SIGNATURE,
5338                    boardp->bios_signature);
5339                AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_VERSION,
5340                    boardp->bios_version);
5341                AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODESEG,
5342                    boardp->bios_codeseg);
5343                AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODELEN,
5344                    boardp->bios_codelen);
5345
5346                ASC_DBG2(1,
5347                    "advansys_detect: bios_signature 0x%x, bios_version 0x%x\n",
5348                    boardp->bios_signature, boardp->bios_version);
5349
5350                ASC_DBG2(1,
5351                    "advansys_detect: bios_codeseg 0x%x, bios_codelen 0x%x\n",
5352                    boardp->bios_codeseg, boardp->bios_codelen);
5353
5354                /*
5355                 * If the BIOS saved a valid signature, then fill in
5356                 * the BIOS code segment base address.
5357                 */
5358                if (boardp->bios_signature == 0x55AA) {
5359                    /*
5360                     * Convert x86 realmode code segment to a linear
5361                     * address by shifting left 4.
5362                     */
5363                    shp->base =
5364#if ASC_LINUX_KERNEL22
5365                        (char *)
5366#endif
5367                        ((ulong) boardp->bios_codeseg << 4);
5368                } else {
5369                    shp->base = 0;
5370                }
5371            }
5372
5373            /*
5374             * Register Board Resources - I/O Port, DMA, IRQ
5375             */
5376
5377            /*
5378             * Register I/O port range.
5379             *
5380             * For Wide boards the I/O ports are not used to access
5381             * the board, but request the region anyway.
5382             *
5383             * 'shp->n_io_port' is not referenced, because it may be truncated.
5384             */
5385            ASC_DBG2(2,
5386                "advansys_detect: request_region port 0x%lx, len 0x%x\n",
5387                (ulong) shp->io_port, boardp->asc_n_io_port);
5388#if ASC_LINUX_KERNEL24
5389            if (request_region(shp->io_port, boardp->asc_n_io_port,
5390                               "advansys") == NULL) {
5391                ASC_PRINT3(
5392"advansys_detect: board %d: request_region() failed, port 0x%lx, len 0x%x\n",
5393                    boardp->id, (ulong) shp->io_port, boardp->asc_n_io_port);
5394#ifdef CONFIG_PROC_FS
5395                kfree(boardp->prtbuf);
5396#endif /* CONFIG_PROC_FS */
5397                scsi_unregister(shp);
5398                asc_board_count--;
5399                continue;
5400            }
5401#elif ASC_LINUX_KERNEL22
5402            request_region(shp->io_port, boardp->asc_n_io_port, "advansys");
5403#endif
5404
5405            /* Register DMA Channel for Narrow boards. */
5406            shp->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
5407#ifdef CONFIG_ISA
5408            if (ASC_NARROW_BOARD(boardp)) {
5409                /* Register DMA channel for ISA bus. */
5410                if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
5411                    shp->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
5412                    if ((ret =
5413                         request_dma(shp->dma_channel, "advansys")) != 0) {
5414                        ASC_PRINT3(
5415"advansys_detect: board %d: request_dma() %d failed %d\n",
5416                            boardp->id, shp->dma_channel, ret);
5417                        release_region(shp->io_port, boardp->asc_n_io_port);
5418#ifdef CONFIG_PROC_FS
5419                        kfree(boardp->prtbuf);
5420#endif /* CONFIG_PROC_FS */
5421                        scsi_unregister(shp);
5422                        asc_board_count--;
5423                        continue;
5424                    }
5425                    AscEnableIsaDma(shp->dma_channel);
5426                }
5427            }
5428#endif /* CONFIG_ISA */
5429
5430            /* Register IRQ Number. */
5431            ASC_DBG1(2, "advansys_detect: request_irq() %d\n", shp->irq);
5432           /*
5433            * If request_irq() fails with the SA_INTERRUPT flag set,
5434            * then try again without the SA_INTERRUPT flag set. This
5435            * allows IRQ sharing to work even with other drivers that
5436            * do not set the SA_INTERRUPT flag.
5437            *
5438            * If SA_INTERRUPT is not set, then interrupts are enabled
5439            * before the driver interrupt function is called.
5440            */
5441            if (((ret = request_irq(shp->irq, advansys_interrupt,
5442                            SA_INTERRUPT | (share_irq == TRUE ? SA_SHIRQ : 0),
5443                            "advansys", boardp)) != 0) &&
5444                ((ret = request_irq(shp->irq, advansys_interrupt,
5445                            (share_irq == TRUE ? SA_SHIRQ : 0),
5446                            "advansys", boardp)) != 0))
5447            {
5448                if (ret == -EBUSY) {
5449                    ASC_PRINT2(
5450"advansys_detect: board %d: request_irq(): IRQ 0x%x already in use.\n",
5451                        boardp->id, shp->irq);
5452                } else if (ret == -EINVAL) {
5453                    ASC_PRINT2(
5454"advansys_detect: board %d: request_irq(): IRQ 0x%x not valid.\n",
5455                        boardp->id, shp->irq);
5456                } else {
5457                    ASC_PRINT3(
5458"advansys_detect: board %d: request_irq(): IRQ 0x%x failed with %d\n",
5459                        boardp->id, shp->irq, ret);
5460                }
5461                release_region(shp->io_port, boardp->asc_n_io_port);
5462                iounmap(boardp->ioremap_addr);
5463                if (shp->dma_channel != NO_ISA_DMA) {
5464                    free_dma(shp->dma_channel);
5465                }
5466#ifdef CONFIG_PROC_FS
5467                kfree(boardp->prtbuf);
5468#endif /* CONFIG_PROC_FS */
5469                scsi_unregister(shp);
5470                asc_board_count--;
5471                continue;
5472            }
5473
5474            /*
5475             * Initialize board RISC chip and enable interrupts.
5476             */
5477            if (ASC_NARROW_BOARD(boardp)) {
5478                ASC_DBG(2, "advansys_detect: AscInitAsc1000Driver()\n");
5479                warn_code = AscInitAsc1000Driver(asc_dvc_varp);
5480                err_code = asc_dvc_varp->err_code;
5481
5482                if (warn_code || err_code) {
5483                    ASC_PRINT4(
5484"advansys_detect: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
5485                        boardp->id, asc_dvc_varp->init_state,
5486                        warn_code, err_code);
5487                }
5488            } else {
5489                ADV_CARR_T      *carrp;
5490                int             req_cnt = 0;
5491                adv_req_t       *reqp = NULL;
5492                int             sg_cnt = 0;
5493
5494                /*
5495                 * Allocate buffer carrier structures. The total size
5496                 * is about 4 KB, so allocate all at once.
5497                 */
5498                carrp =
5499                    (ADV_CARR_T *) kmalloc(ADV_CARRIER_BUFSIZE, GFP_ATOMIC);
5500                ASC_DBG1(1, "advansys_detect: carrp 0x%lx\n", (ulong) carrp);
5501
5502                if (carrp == NULL) {
5503                    goto kmalloc_error;
5504                }
5505
5506                /*
5507                 * Allocate up to 'max_host_qng' request structures for
5508                 * the Wide board. The total size is about 16 KB, so
5509                 * allocate all at once. If the allocation fails decrement
5510                 * and try again.
5511                 */
5512                for (req_cnt = adv_dvc_varp->max_host_qng;
5513                    req_cnt > 0; req_cnt--) {
5514
5515                    reqp = (adv_req_t *)
5516                        kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC);
5517
5518                    ASC_DBG3(1,
5519                        "advansys_detect: reqp 0x%lx, req_cnt %d, bytes %lu\n",
5520                        (ulong) reqp, req_cnt,
5521                        (ulong) sizeof(adv_req_t) * req_cnt);
5522
5523                    if (reqp != NULL) {
5524                        break;
5525                    }
5526                }
5527                if (reqp == NULL)
5528                {
5529                    goto kmalloc_error;
5530                }
5531
5532                /*
5533                 * Allocate up to ADV_TOT_SG_BLOCK request structures for
5534                 * the Wide board. Each structure is about 136 bytes.
5535                 */
5536                boardp->adv_sgblkp = NULL;
5537                for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
5538
5539                    sgp = (adv_sgblk_t *)
5540                        kmalloc(sizeof(adv_sgblk_t), GFP_ATOMIC);
5541
5542                    if (sgp == NULL) {
5543                        break;
5544                    }
5545
5546                    sgp->next_sgblkp = boardp->adv_sgblkp;
5547                    boardp->adv_sgblkp = sgp;
5548
5549                }
5550                ASC_DBG3(1,
5551                    "advansys_detect: sg_cnt %d * %u = %u bytes\n",
5552                    sg_cnt, sizeof(adv_sgblk_t),
5553                    (unsigned) (sizeof(adv_sgblk_t) * sg_cnt));
5554
5555                /*
5556                 * If no request structures or scatter-gather structures could
5557                 * be allocated, then return an error. Otherwise continue with
5558                 * initialization.
5559                 */
5560    kmalloc_error:
5561                if (carrp == NULL)
5562                {
5563                    ASC_PRINT1(
5564"advansys_detect: board %d error: failed to kmalloc() carrier buffer.\n",
5565                        boardp->id);
5566                    err_code = ADV_ERROR;
5567                } else if (reqp == NULL) {
5568                    kfree(carrp);
5569                    ASC_PRINT1(
5570"advansys_detect: board %d error: failed to kmalloc() adv_req_t buffer.\n",
5571                        boardp->id);
5572                    err_code = ADV_ERROR;
5573                } else if (boardp->adv_sgblkp == NULL) {
5574                    kfree(carrp);
5575                    kfree(reqp);
5576                    ASC_PRINT1(
5577"advansys_detect: board %d error: failed to kmalloc() adv_sgblk_t buffers.\n",
5578                        boardp->id);
5579                    err_code = ADV_ERROR;
5580                } else {
5581
5582                    /* Save carrier buffer pointer. */
5583                    boardp->orig_carrp = carrp;
5584
5585                    /*
5586                     * Save original pointer for kfree() in case the
5587                     * driver is built as a module and can be unloaded.
5588                     */
5589                    boardp->orig_reqp = reqp;
5590
5591                    adv_dvc_varp->carrier_buf = carrp;
5592
5593                    /*
5594                     * Point 'adv_reqp' to the request structures and
5595                     * link them together.
5596                     */
5597                    req_cnt--;
5598                    reqp[req_cnt].next_reqp = NULL;
5599                    for (; req_cnt > 0; req_cnt--) {
5600                        reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
5601                    }
5602                    boardp->adv_reqp = &reqp[0];
5603
5604                    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
5605                    {
5606                        ASC_DBG(2,
5607                            "advansys_detect: AdvInitAsc3550Driver()\n");
5608                        warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
5609                    } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5610                        ASC_DBG(2,
5611                            "advansys_detect: AdvInitAsc38C0800Driver()\n");
5612                        warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
5613                    } else {
5614                        ASC_DBG(2,
5615                            "advansys_detect: AdvInitAsc38C1600Driver()\n");
5616                        warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
5617                    }
5618                    err_code = adv_dvc_varp->err_code;
5619
5620                    if (warn_code || err_code) {
5621                        ASC_PRINT3(
5622"advansys_detect: board %d error: warn 0x%x, error 0x%x\n",
5623                            boardp->id, warn_code, err_code);
5624                    }
5625                }
5626            }
5627
5628            if (err_code != 0) {
5629                release_region(shp->io_port, boardp->asc_n_io_port);
5630                if (ASC_WIDE_BOARD(boardp)) {
5631                    iounmap(boardp->ioremap_addr);
5632                    if (boardp->orig_carrp) {
5633                        kfree(boardp->orig_carrp);
5634                        boardp->orig_carrp = NULL;
5635                    }
5636                    if (boardp->orig_reqp) {
5637                        kfree(boardp->orig_reqp);
5638                        boardp->orig_reqp = boardp->adv_reqp = NULL;
5639                    }
5640                    while ((sgp = boardp->adv_sgblkp) != NULL)
5641                    {
5642                        boardp->adv_sgblkp = sgp->next_sgblkp;
5643                        kfree(sgp);
5644                    }
5645                }
5646                if (shp->dma_channel != NO_ISA_DMA) {
5647                    free_dma(shp->dma_channel);
5648                }
5649#ifdef CONFIG_PROC_FS
5650                kfree(boardp->prtbuf);
5651#endif /* CONFIG_PROC_FS */
5652                free_irq(shp->irq, boardp);
5653                scsi_unregister(shp);
5654                asc_board_count--;
5655                continue;
5656            }
5657            ASC_DBG_PRT_SCSI_HOST(2, shp);
5658        }
5659    }
5660
5661    ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n", asc_board_count);
5662    return asc_board_count;
5663}
5664
5665/*
5666 * advansys_release()
5667 *
5668 * Release resources allocated for a single AdvanSys adapter.
5669 */
5670int
5671advansys_release(struct Scsi_Host *shp)
5672{
5673    asc_board_t    *boardp;
5674
5675    ASC_DBG(1, "advansys_release: begin\n");
5676    boardp = ASC_BOARDP(shp);
5677    free_irq(shp->irq, boardp);
5678    if (shp->dma_channel != NO_ISA_DMA) {
5679        ASC_DBG(1, "advansys_release: free_dma()\n");
5680        free_dma(shp->dma_channel);
5681    }
5682    release_region(shp->io_port, boardp->asc_n_io_port);
5683    if (ASC_WIDE_BOARD(boardp)) {
5684        adv_sgblk_t    *sgp = NULL;
5685
5686        iounmap(boardp->ioremap_addr);
5687        if (boardp->orig_carrp) {
5688            kfree(boardp->orig_carrp);
5689            boardp->orig_carrp = NULL;
5690        }
5691        if (boardp->orig_reqp) {
5692            kfree(boardp->orig_reqp);
5693            boardp->orig_reqp = boardp->adv_reqp = NULL;
5694        }
5695        while ((sgp = boardp->adv_sgblkp) != NULL)
5696        {
5697            boardp->adv_sgblkp = sgp->next_sgblkp;
5698            kfree(sgp);
5699        }
5700    }
5701#ifdef CONFIG_PROC_FS
5702    ASC_ASSERT(boardp->prtbuf != NULL);
5703    kfree(boardp->prtbuf);
5704#endif /* CONFIG_PROC_FS */
5705    scsi_unregister(shp);
5706    ASC_DBG(1, "advansys_release: end\n");
5707    return 0;
5708}
5709
5710/*
5711 * advansys_info()
5712 *
5713 * Return suitable for printing on the console with the argument
5714 * adapter's configuration information.
5715 *
5716 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
5717 * otherwise the static 'info' array will be overrun.
5718 */
5719const char *
5720advansys_info(struct Scsi_Host *shp)
5721{
5722    static char     info[ASC_INFO_SIZE];
5723    asc_board_t     *boardp;
5724    ASC_DVC_VAR     *asc_dvc_varp;
5725    ADV_DVC_VAR     *adv_dvc_varp;
5726    char            *busname;
5727    int             iolen;
5728    char            *widename = NULL;
5729
5730    boardp = ASC_BOARDP(shp);
5731    if (ASC_NARROW_BOARD(boardp)) {
5732        asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
5733        ASC_DBG(1, "advansys_info: begin\n");
5734        if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
5735            if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) == ASC_IS_ISAPNP) {
5736                busname = "ISA PnP";
5737            } else {
5738                busname = "ISA";
5739            }
5740            /* Don't reference 'shp->n_io_port'; It may be truncated. */
5741            sprintf(info,
5742"AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
5743                ASC_VERSION, busname,
5744                (ulong) shp->io_port,
5745                (ulong) shp->io_port + boardp->asc_n_io_port - 1,
5746                shp->irq, shp->dma_channel);
5747        } else {
5748            if (asc_dvc_varp->bus_type & ASC_IS_VL) {
5749                busname = "VL";
5750            } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
5751                busname = "EISA";
5752            } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
5753                if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
5754                    == ASC_IS_PCI_ULTRA) {
5755                    busname = "PCI Ultra";
5756                } else {
5757                    busname = "PCI";
5758                }
5759            } else {
5760                busname = "?";
5761                ASC_PRINT2( "advansys_info: board %d: unknown bus type %d\n",
5762                    boardp->id, asc_dvc_varp->bus_type);
5763            }
5764            /* Don't reference 'shp->n_io_port'; It may be truncated. */
5765            sprintf(info,
5766                "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
5767                ASC_VERSION, busname,
5768                (ulong) shp->io_port,
5769                (ulong) shp->io_port + boardp->asc_n_io_port - 1,
5770                shp->irq);
5771        }
5772    } else {
5773        /*
5774         * Wide Adapter Information
5775         *
5776         * Memory-mapped I/O is used instead of I/O space to access
5777         * the adapter, but display the I/O Port range. The Memory
5778         * I/O address is displayed through the driver /proc file.
5779         */
5780        adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5781        if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
5782        {
5783            iolen = ADV_3550_IOLEN;
5784            widename = "Ultra-Wide";
5785        } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
5786        {
5787            iolen = ADV_38C0800_IOLEN;
5788            widename = "Ultra2-Wide";
5789        } else
5790        {
5791            iolen = ADV_38C1600_IOLEN;
5792            widename = "Ultra3-Wide";
5793        }
5794        sprintf(info, "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
5795            ASC_VERSION,
5796            widename,
5797            (ulong) adv_dvc_varp->iop_base,
5798            (ulong) adv_dvc_varp->iop_base + iolen - 1,
5799            shp->irq);
5800    }
5801    ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
5802    ASC_DBG(1, "advansys_info: end\n");
5803    return info;
5804}
5805
5806/*
5807 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
5808 *
5809 * This function always returns 0. Command return status is saved
5810 * in the 'scp' result field.
5811 */
5812int
5813advansys_queuecommand(Scsi_Cmnd *scp, void (*done)(Scsi_Cmnd *))
5814{
5815    struct Scsi_Host    *shp;
5816    asc_board_t         *boardp;
5817    ulong               flags;
5818    Scsi_Cmnd           *done_scp;
5819
5820    shp = scp->device->host;
5821    boardp = ASC_BOARDP(shp);
5822    ASC_STATS(shp, queuecommand);
5823
5824    /* host_lock taken by mid-level prior to call but need to protect */
5825    /* against own ISR */
5826    spin_lock_irqsave(&boardp->lock, flags);
5827
5828    /*
5829     * Block new commands while handling a reset or abort request.
5830     */
5831    if (boardp->flags & ASC_HOST_IN_RESET) {
5832        ASC_DBG1(1,
5833            "advansys_queuecommand: scp 0x%lx blocked for reset request\n",
5834            (ulong) scp);
5835        scp->result = HOST_BYTE(DID_RESET);
5836
5837        /*
5838         * Add blocked requests to the board's 'done' queue. The queued
5839         * requests will be completed at the end of the abort or reset
5840         * handling.
5841         */
5842        asc_enqueue(&boardp->done, scp, ASC_BACK);
5843        spin_unlock_irqrestore(&boardp->lock, flags);
5844        return 0;
5845    }
5846
5847    /*
5848     * Attempt to execute any waiting commands for the board.
5849     */
5850    if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
5851        ASC_DBG(1,
5852            "advansys_queuecommand: before asc_execute_queue() waiting\n");
5853        asc_execute_queue(&boardp->waiting);
5854    }
5855
5856    /*
5857     * Save the function pointer to Linux mid-level 'done' function
5858     * and attempt to execute the command.
5859     *
5860     * If ASC_NOERROR is returned the request has been added to the
5861     * board's 'active' queue and will be completed by the interrupt
5862     * handler.
5863     *
5864     * If ASC_BUSY is returned add the request to the board's per
5865     * target waiting list. This is the first time the request has
5866     * been tried. Add it to the back of the waiting list. It will be
5867     * retried later.
5868     *
5869     * If an error occurred, the request will have been placed on the
5870     * board's 'done' queue and must be completed before returning.
5871     */
5872    scp->scsi_done = done;
5873    switch (asc_execute_scsi_cmnd(scp)) {
5874    case ASC_NOERROR:
5875        break;
5876    case ASC_BUSY:
5877        asc_enqueue(&boardp->waiting, scp, ASC_BACK);
5878        break;
5879    case ASC_ERROR:
5880    default:
5881        done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
5882        /* Interrupts could be enabled here. */
5883        asc_scsi_done_list(done_scp, 0);
5884        break;
5885    }
5886    spin_unlock_irqrestore(&boardp->lock, flags);
5887
5888    return 0;
5889}
5890
5891/*
5892 * advansys_reset()
5893 *
5894 * Reset the bus associated with the command 'scp'.
5895 *
5896 * This function runs its own thread. Interrupts must be blocked but
5897 * sleeping is allowed and no locking other than for host structures is
5898 * required. Returns SUCCESS or FAILED.
5899 */
5900int
5901advansys_reset(Scsi_Cmnd *scp)
5902{
5903    struct Scsi_Host     *shp;
5904    asc_board_t          *boardp;
5905    ASC_DVC_VAR          *asc_dvc_varp;
5906    ADV_DVC_VAR          *adv_dvc_varp;
5907    ulong                flags;
5908    Scsi_Cmnd            *done_scp = NULL, *last_scp = NULL;
5909    Scsi_Cmnd            *tscp, *new_last_scp;
5910    int                  status;
5911    int                  ret = SUCCESS;
5912
5913    ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong) scp);
5914
5915#ifdef ADVANSYS_STATS
5916    if (scp->device->host != NULL) {
5917        ASC_STATS(scp->device->host, reset);
5918    }
5919#endif /* ADVANSYS_STATS */
5920
5921    if ((shp = scp->device->host) == NULL) {
5922        scp->result = HOST_BYTE(DID_ERROR);
5923        return FAILED;
5924    }
5925
5926    boardp = ASC_BOARDP(shp);
5927
5928    ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
5929        boardp->id);
5930    /*
5931     * Check for re-entrancy.
5932     */
5933    spin_lock_irqsave(&boardp->lock, flags);
5934    if (boardp->flags & ASC_HOST_IN_RESET) {
5935        spin_unlock_irqrestore(&boardp->lock, flags);
5936        return FAILED;
5937    }
5938    boardp->flags |= ASC_HOST_IN_RESET;
5939    spin_unlock_irqrestore(&boardp->lock, flags);
5940
5941    if (ASC_NARROW_BOARD(boardp)) {
5942        /*
5943         * Narrow Board
5944         */
5945        asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
5946
5947        /*
5948         * Reset the chip and SCSI bus.
5949         */
5950        ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
5951        status = AscInitAsc1000Driver(asc_dvc_varp);
5952
5953        /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
5954        if (asc_dvc_varp->err_code) {
5955            ASC_PRINT2(
5956                "advansys_reset: board %d: SCSI bus reset error: 0x%x\n",
5957                boardp->id, asc_dvc_varp->err_code);
5958            ret = FAILED;
5959        } else if (status) {
5960            ASC_PRINT2(
5961                "advansys_reset: board %d: SCSI bus reset warning: 0x%x\n",
5962                boardp->id, status);
5963        } else {
5964            ASC_PRINT1(
5965                "advansys_reset: board %d: SCSI bus reset successful.\n",
5966                boardp->id);
5967        }
5968
5969        ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
5970        spin_lock_irqsave(&boardp->lock, flags);
5971
5972    } else {
5973        /*
5974         * Wide Board
5975         *
5976         * If the suggest reset bus flags are set, then reset the bus.
5977         * Otherwise only reset the device.
5978         */
5979        adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5980
5981        /*
5982         * Reset the target's SCSI bus.
5983         */
5984        ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
5985        switch (AdvResetChipAndSB(adv_dvc_varp)) {
5986        case ASC_TRUE:
5987            ASC_PRINT1("advansys_reset: board %d: SCSI bus reset successful.\n",
5988                boardp->id);
5989            break;
5990        case ASC_FALSE:
5991        default:
5992            ASC_PRINT1("advansys_reset: board %d: SCSI bus reset error.\n",
5993                boardp->id);
5994            ret = FAILED;
5995            break;
5996        }
5997        spin_lock_irqsave(&boardp->lock, flags);
5998        (void) AdvISR(adv_dvc_varp);
5999    }
6000    /* Board lock is held. */
6001
6002    /*
6003     * Dequeue all board 'done' requests. A pointer to the last request
6004     * is returned in 'last_scp'.
6005     */
6006    done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL);
6007
6008    /*
6009     * Dequeue all board 'active' requests for all devices and set
6010     * the request status to DID_RESET. A pointer to the last request
6011     * is returned in 'last_scp'.
6012     */
6013    if (done_scp == NULL) {
6014        done_scp = asc_dequeue_list(&boardp->active, &last_scp, ASC_TID_ALL);
6015        for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
6016            tscp->result = HOST_BYTE(DID_RESET);
6017        }
6018    } else {
6019        /* Append to 'done_scp' at the end with 'last_scp'. */
6020        ASC_ASSERT(last_scp != NULL);
6021        last_scp->host_scribble = (unsigned char *)asc_dequeue_list(
6022                        &boardp->active, &new_last_scp, ASC_TID_ALL);
6023        if (new_last_scp != NULL) {
6024            ASC_ASSERT(REQPNEXT(last_scp) != NULL);
6025            for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
6026                tscp->result = HOST_BYTE(DID_RESET);
6027            }
6028            last_scp = new_last_scp;
6029        }
6030    }
6031
6032    /*
6033     * Dequeue all 'waiting' requests and set the request status
6034     * to DID_RESET.
6035     */
6036    if (done_scp == NULL) {
6037        done_scp = asc_dequeue_list(&boardp->waiting, &last_scp, ASC_TID_ALL);
6038        for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
6039            tscp->result = HOST_BYTE(DID_RESET);
6040        }
6041    } else {
6042        /* Append to 'done_scp' at the end with 'last_scp'. */
6043        ASC_ASSERT(last_scp != NULL);
6044        last_scp->host_scribble = (unsigned char *)asc_dequeue_list(
6045                        &boardp->waiting, &new_last_scp, ASC_TID_ALL);
6046        if (new_last_scp != NULL) {
6047            ASC_ASSERT(REQPNEXT(last_scp) != NULL);
6048            for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
6049                tscp->result = HOST_BYTE(DID_RESET);
6050            }
6051            last_scp = new_last_scp;
6052        }
6053    }
6054
6055    /* Save the time of the most recently completed reset. */
6056    boardp->last_reset = jiffies;
6057
6058    /* Clear reset flag. */
6059    boardp->flags &= ~ASC_HOST_IN_RESET;
6060    spin_unlock_irqrestore(&boardp->lock, flags);
6061
6062    /*
6063     * Complete all the 'done_scp' requests.
6064     */
6065    if (done_scp != NULL) {
6066        asc_scsi_done_list(done_scp, 0);
6067    }
6068
6069    ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
6070
6071    return ret;
6072}
6073
6074/*
6075 * advansys_biosparam()
6076 *
6077 * Translate disk drive geometry if the "BIOS greater than 1 GB"
6078 * support is enabled for a drive.
6079 *
6080 * ip (information pointer) is an int array with the following definition:
6081 * ip[0]: heads
6082 * ip[1]: sectors
6083 * ip[2]: cylinders
6084 */
6085int
6086advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
6087                sector_t capacity, int ip[])
6088{
6089    asc_board_t     *boardp;
6090
6091    ASC_DBG(1, "advansys_biosparam: begin\n");
6092    ASC_STATS(sdev->host, biosparam);
6093    boardp = ASC_BOARDP(sdev->host);
6094    if (ASC_NARROW_BOARD(boardp)) {
6095        if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
6096             ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
6097                ip[0] = 255;
6098                ip[1] = 63;
6099        } else {
6100                ip[0] = 64;
6101                ip[1] = 32;
6102        }
6103    } else {
6104        if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
6105             BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
6106                ip[0] = 255;
6107                ip[1] = 63;
6108        } else {
6109                ip[0] = 64;
6110                ip[1] = 32;
6111        }
6112    }
6113    ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
6114    ASC_DBG(1, "advansys_biosparam: end\n");
6115    return 0;
6116}
6117
6118/*
6119 * advansys_setup()
6120 *
6121 * This function is called from init/main.c at boot time.
6122 * It it passed LILO parameters that can be set from the
6123 * LILO command line or in /etc/lilo.conf.
6124 *
6125 * It is used by the AdvanSys driver to either disable I/O
6126 * port scanning or to limit scanning to 1 - 4 I/O ports.
6127 * Regardless of the option setting EISA and PCI boards
6128 * will still be searched for and detected. This option
6129 * only affects searching for ISA and VL boards.
6130 *
6131 * If ADVANSYS_DEBUG is defined the driver debug level may
6132 * be set using the 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port.
6133 *
6134 * Examples:
6135 * 1. Eliminate I/O port scanning:
6136 *         boot: linux advansys=
6137 *       or
6138 *         boot: linux advansys=0x0
6139 * 2. Limit I/O port scanning to one I/O port:
6140 *        boot: linux advansys=0x110
6141 * 3. Limit I/O port scanning to four I/O ports:
6142 *        boot: linux advansys=0x110,0x210,0x230,0x330
6143 * 4. If ADVANSYS_DEBUG, limit I/O port scanning to four I/O ports and
6144 *    set the driver debug level to 2.
6145 *        boot: linux advansys=0x110,0x210,0x230,0x330,0xdeb2
6146 *
6147 * ints[0] - number of arguments
6148 * ints[1] - first argument
6149 * ints[2] - second argument
6150 * ...
6151 */
6152ASC_INITFUNC(
6153void,
6154advansys_setup(char *str, int *ints)
6155)
6156{
6157    int    i;
6158
6159    if (asc_iopflag == ASC_TRUE) {
6160        printk("AdvanSys SCSI: 'advansys' LILO option may appear only once\n");
6161        return;
6162    }
6163
6164    asc_iopflag = ASC_TRUE;
6165
6166    if (ints[0] > ASC_NUM_IOPORT_PROBE) {
6167#ifdef ADVANSYS_DEBUG
6168        if ((ints[0] == ASC_NUM_IOPORT_PROBE + 1) &&
6169            (ints[ASC_NUM_IOPORT_PROBE + 1] >> 4 == 0xdeb)) {
6170            asc_dbglvl = ints[ASC_NUM_IOPORT_PROBE + 1] & 0xf;
6171        } else {
6172#endif /* ADVANSYS_DEBUG */
6173            printk("AdvanSys SCSI: only %d I/O ports accepted\n",
6174                ASC_NUM_IOPORT_PROBE);
6175#ifdef ADVANSYS_DEBUG
6176        }
6177#endif /* ADVANSYS_DEBUG */
6178    }
6179
6180#ifdef ADVANSYS_DEBUG
6181    ASC_DBG1(1, "advansys_setup: ints[0] %d\n", ints[0]);
6182    for (i = 1; i < ints[0]; i++) {
6183        ASC_DBG2(1, " ints[%d] 0x%x", i, ints[i]);
6184    }
6185    ASC_DBG(1, "\n");
6186#endif /* ADVANSYS_DEBUG */
6187
6188    for (i = 1; i <= ints[0] && i <= ASC_NUM_IOPORT_PROBE; i++) {
6189        asc_ioport[i-1] = ints[i];
6190        ASC_DBG2(1, "advansys_setup: asc_ioport[%d] 0x%x\n",
6191            i - 1, asc_ioport[i-1]);
6192    }
6193}
6194
6195
6196/*
6197 * --- Loadable Driver Support
6198 */
6199
6200static Scsi_Host_Template driver_template = {
6201    .proc_name                  = "advansys",
6202#ifdef CONFIG_PROC_FS
6203    .proc_info                  = advansys_proc_info,
6204#endif
6205    .name                       = "advansys",
6206    .detect                     = advansys_detect, 
6207    .release                    = advansys_release,
6208    .info                       = advansys_info,
6209    .queuecommand               = advansys_queuecommand,
6210    .eh_bus_reset_handler       = advansys_reset,
6211    .bios_param                 = advansys_biosparam,
6212    .slave_configure            = advansys_slave_configure,
6213    /*
6214     * Because the driver may control an ISA adapter 'unchecked_isa_dma'
6215     * must be set. The flag will be cleared in advansys_detect for non-ISA
6216     * adapters. Refer to the comment in scsi_module.c for more information.
6217     */
6218    .unchecked_isa_dma          = 1,
6219    /*
6220     * All adapters controlled by this driver are capable of large
6221     * scatter-gather lists. According to the mid-level SCSI documentation
6222     * this obviates any performance gain provided by setting
6223     * 'use_clustering'. But empirically while CPU utilization is increased
6224     * by enabling clustering, I/O throughput increases as well.
6225     */
6226    .use_clustering             = ENABLE_CLUSTERING,
6227};
6228#include "scsi_module.c"
6229
6230
6231/*
6232 * --- Miscellaneous Driver Functions
6233 */
6234
6235/*
6236 * First-level interrupt handler.
6237 *
6238 * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
6239 * all boards are currently checked for interrupts on each interrupt, 'dev_id'
6240 * is not referenced. 'dev_id' could be used to identify an interrupt passed
6241 * to the AdvanSys driver which is for a device sharing an interrupt with
6242 * an AdvanSys adapter.
6243 */
6244STATIC irqreturn_t
6245advansys_interrupt(int irq, void *dev_id, struct pt_regs *regs)
6246{
6247    ulong           flags;
6248    int             i;
6249    asc_board_t     *boardp;
6250    Scsi_Cmnd       *done_scp = NULL, *last_scp = NULL;
6251    Scsi_Cmnd       *new_last_scp;
6252    struct Scsi_Host *shp;
6253
6254    ASC_DBG(1, "advansys_interrupt: begin\n");
6255
6256    /*
6257     * Check for interrupts on all boards.
6258     * AscISR() will call asc_isr_callback().
6259     */
6260    for (i = 0; i < asc_board_count; i++) {
6261        shp = asc_host[i];
6262        boardp = ASC_BOARDP(shp);
6263        ASC_DBG2(2, "advansys_interrupt: i %d, boardp 0x%lx\n",
6264            i, (ulong) boardp);
6265        spin_lock_irqsave(&boardp->lock, flags);
6266        if (ASC_NARROW_BOARD(boardp)) {
6267            /*
6268             * Narrow Board
6269             */
6270            if (AscIsIntPending(shp->io_port)) {
6271                ASC_STATS(shp, interrupt);
6272                ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
6273                AscISR(&boardp->dvc_var.asc_dvc_var);
6274            }
6275        } else {
6276            /*
6277             * Wide Board
6278             */
6279            ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
6280            if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
6281                ASC_STATS(shp, interrupt);
6282            }
6283        }
6284
6285        /*
6286         * Start waiting requests and create a list of completed requests.
6287         *
6288         * If a reset request is being performed for the board, the reset
6289         * handler will complete pending requests after it has completed.
6290         */
6291        if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
6292            ASC_DBG2(1, "advansys_interrupt: done_scp 0x%lx, last_scp 0x%lx\n",
6293                (ulong) done_scp, (ulong) last_scp);
6294
6295            /* Start any waiting commands for the board. */
6296            if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
6297                ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
6298                asc_execute_queue(&boardp->waiting);
6299            }
6300
6301             /*
6302              * Add to the list of requests that must be completed.
6303              *
6304              * 'done_scp' will always be NULL on the first iteration
6305              * of this loop. 'last_scp' is set at the same time as
6306              * 'done_scp'.
6307              */
6308            if (done_scp == NULL) {
6309                done_scp = asc_dequeue_list(&boardp->done, &last_scp,
6310                    ASC_TID_ALL);
6311            } else {
6312                ASC_ASSERT(last_scp != NULL);
6313                last_scp->host_scribble = (unsigned char *)asc_dequeue_list(
6314                        &boardp->done, &new_last_scp, ASC_TID_ALL);
6315                if (new_last_scp != NULL) {
6316                    ASC_ASSERT(REQPNEXT(last_scp) != NULL);
6317                    last_scp = new_last_scp;
6318                }
6319            }
6320        }
6321        spin_unlock_irqrestore(&boardp->lock, flags);
6322    }
6323
6324    /*
6325     * If interrupts were enabled on entry, then they
6326     * are now enabled here.
6327     *
6328     * Complete all requests on the done list.
6329     */
6330
6331    asc_scsi_done_list(done_scp, 1);
6332
6333    ASC_DBG(1, "advansys_interrupt: end\n");
6334    return IRQ_HANDLED;
6335}
6336
6337/*
6338 * Set the number of commands to queue per device for the
6339 * specified host adapter.
6340 */
6341STATIC int
6342advansys_slave_configure(Scsi_Device *device)
6343{
6344    asc_board_t        *boardp;
6345
6346    boardp = ASC_BOARDP(device->host);
6347    boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
6348    /*
6349     * Save a pointer to the device and set its initial/maximum
6350     * queue depth.  Only save the pointer for a lun0 dev though.
6351     */
6352    if(device->lun == 0)
6353        boardp->device[device->id] = device;
6354    if(device->tagged_supported) {
6355        if (ASC_NARROW_BOARD(boardp)) {
6356            scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
6357                boardp->dvc_var.asc_dvc_var.max_dvc_qng[device->id]);
6358        } else {
6359            scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
6360                boardp->dvc_var.adv_dvc_var.max_dvc_qng);
6361        }
6362    } else {
6363        scsi_adjust_queue_depth(device, 0, device->host->cmd_per_lun);
6364    }
6365    ASC_DBG4(1, "advansys_slave_configure: device 0x%lx, boardp 0x%lx, id %d, depth %d\n",
6366            (ulong) device, (ulong) boardp, device->id, device->queue_depth);
6367    return 0;
6368}
6369
6370/*
6371 * Complete all requests on the singly linked list pointed
6372 * to by 'scp'.
6373 *
6374 * Interrupts can be enabled on entry.
6375 */
6376STATIC void
6377asc_scsi_done_list(Scsi_Cmnd *scp, int from_isr)
6378{
6379    Scsi_Cmnd    *tscp;
6380    ulong         flags = 0;
6381
6382    ASC_DBG(2, "asc_scsi_done_list: begin\n");
6383    while (scp != NULL) {
6384        ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong) scp);
6385        tscp = REQPNEXT(scp);
6386        scp->host_scribble = NULL;
6387        ASC_STATS(scp->device->host, done);
6388        ASC_ASSERT(scp->scsi_done != NULL);
6389        if (from_isr)
6390            spin_lock_irqsave(scp->device->host->host_lock, flags);
6391        scp->scsi_done(scp);
6392        if (from_isr)
6393            spin_unlock_irqrestore(scp->device->host->host_lock, flags);
6394        scp = tscp;
6395    }
6396    ASC_DBG(2, "asc_scsi_done_list: done\n");
6397    return;
6398}
6399
6400/*
6401 * Execute a single 'Scsi_Cmnd'.
6402 *
6403 * The function 'done' is called when the request has been completed.
6404 *
6405 * Scsi_Cmnd:
6406 *
6407 *  host - board controlling device
6408 *  device - device to send command
6409 *  target - target of device
6410 *  lun - lun of device
6411 *  cmd_len - length of SCSI CDB
6412 *  cmnd - buffer for SCSI 8, 10, or 12 byte CDB
6413 *  use_sg - if non-zero indicates scatter-gather request with use_sg elements
6414 *
6415 *  if (use_sg == 0) {
6416 *    request_buffer - buffer address for request
6417 *    request_bufflen - length of request buffer
6418 *  } else {
6419 *    request_buffer - pointer to scatterlist structure
6420 *  }
6421 *
6422 *  sense_buffer - sense command buffer
6423 *
6424 *  result (4 bytes of an int):
6425 *    Byte Meaning
6426 *    0 SCSI Status Byte Code
6427 *    1 SCSI One Byte Message Code
6428 *    2 Host Error Code
6429 *    3 Mid-Level Error Code
6430 *
6431 *  host driver fields:
6432 *    SCp - Scsi_Pointer used for command processing status
6433 *    scsi_done - used to save caller's done function
6434 *    host_scribble - used for pointer to another Scsi_Cmnd
6435 *
6436 * If this function returns ASC_NOERROR the request has been enqueued
6437 * on the board's 'active' queue and will be completed from the
6438 * interrupt handler.
6439 *
6440 * If this function returns ASC_NOERROR the request has been enqueued
6441 * on the board's 'done' queue and must be completed by the caller.
6442 *
6443 * If ASC_BUSY is returned the request will be enqueued by the
6444 * caller on the target's waiting queue and re-tried later.
6445 */
6446STATIC int
6447asc_execute_scsi_cmnd(Scsi_Cmnd *scp)
6448{
6449    asc_board_t        *boardp;
6450    ASC_DVC_VAR        *asc_dvc_varp;
6451    ADV_DVC_VAR        *adv_dvc_varp;
6452    ADV_SCSI_REQ_Q     *adv_scsiqp;
6453    Scsi_Device        *device;
6454    int                ret;
6455
6456    ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
6457        (ulong) scp, (ulong) scp->scsi_done);
6458
6459    boardp = ASC_BOARDP(scp->device->host);
6460    device = boardp->device[scp->device->id];
6461
6462    if (ASC_NARROW_BOARD(boardp)) {
6463        /*
6464         * Build and execute Narrow Board request.
6465         */
6466
6467        asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6468
6469        /*
6470         * Build Asc Library request structure using the
6471         * global structures 'asc_scsi_req' and 'asc_sg_head'.
6472         *
6473         * If an error is returned, then the request has been
6474         * queued on the board done queue. It will be completed
6475         * by the caller.
6476         *
6477         * asc_build_req() can not return ASC_BUSY.
6478         */
6479        if (asc_build_req(boardp, scp) == ASC_ERROR) {
6480            ASC_STATS(scp->device->host, build_error);
6481            return ASC_ERROR;
6482        }
6483
6484        /*
6485         * Execute the command. If there is no error, add the command
6486         * to the active queue.
6487         */
6488        switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
6489        case ASC_NOERROR:
6490            ASC_STATS(scp->device->host, exe_noerror);
6491            /*
6492             * Increment monotonically increasing per device successful
6493             * request counter. Wrapping doesn't matter.
6494             */
6495            boardp->reqcnt[scp->device->id]++;
6496            asc_enqueue(&boardp->active, scp, ASC_BACK);
6497            ASC_DBG(1,
6498                "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
6499            break;
6500        case ASC_BUSY:
6501            /*
6502             * Caller will enqueue request on the target's waiting queue
6503             * and retry later.
6504             */
6505            ASC_STATS(scp->device->host, exe_busy);
6506            break;
6507        case ASC_ERROR:
6508            ASC_PRINT2(
6509"asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
6510                boardp->id, asc_dvc_varp->err_code);
6511            ASC_STATS(scp->device->host, exe_error);
6512            scp->result = HOST_BYTE(DID_ERROR);
6513            asc_enqueue(&boardp->done, scp, ASC_BACK);
6514            break;
6515        default:
6516            ASC_PRINT2(
6517"asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code 0x%x\n",
6518                boardp->id, asc_dvc_varp->err_code);
6519            ASC_STATS(scp->device->host, exe_unknown);
6520            scp->result = HOST_BYTE(DID_ERROR);
6521            asc_enqueue(&boardp->done, scp, ASC_BACK);
6522            break;
6523        }
6524    } else {
6525        /*
6526         * Build and execute Wide Board request.
6527         */
6528        adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6529
6530        /*
6531         * Build and get a pointer to an Adv Library request structure.
6532         *
6533         * If the request is successfully built then send it below,
6534         * otherwise return with an error.
6535         */
6536        switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
6537        case ASC_NOERROR:
6538            ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
6539            break;
6540        case ASC_BUSY:
6541            ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
6542            /*
6543             * If busy is returned the request has not been enqueued.
6544             * It will be enqueued by the caller on the target's waiting
6545             * queue and retried later.
6546             *
6547             * The asc_stats fields 'adv_build_noreq' and 'adv_build_nosg'
6548             * count wide board busy conditions. They are updated in
6549             * adv_build_req and adv_get_sglist, respectively.
6550             */
6551            return ASC_BUSY;
6552        case ASC_ERROR:
6553             /* 
6554              * If an error is returned, then the request has been
6555              * queued on the board done queue. It will be completed
6556              * by the caller.
6557              */
6558        default:
6559            ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
6560            ASC_STATS(scp->device->host, build_error);
6561            return ASC_ERROR;
6562        }
6563
6564        /*
6565         * Execute the command. If there is no error, add the command
6566         * to the active queue.
6567         */
6568        switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
6569        case ASC_NOERROR:
6570            ASC_STATS(scp->device->host, exe_noerror);
6571            /*
6572             * Increment monotonically increasing per device successful
6573             * request counter. Wrapping doesn't matter.
6574             */
6575            boardp->reqcnt[scp->device->id]++;
6576            asc_enqueue(&boardp->active, scp, ASC_BACK);
6577            ASC_DBG(1,
6578                "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
6579            break;
6580        case ASC_BUSY:
6581            /*
6582             * Caller will enqueue request on the target's waiting queue
6583             * and retry later.
6584             */
6585            ASC_STATS(scp->device->host, exe_busy);
6586            break;
6587        case ASC_ERROR:
6588            ASC_PRINT2(
6589"asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
6590                boardp->id, adv_dvc_varp->err_code);
6591            ASC_STATS(scp->device->host, exe_error);
6592            scp->result = HOST_BYTE(DID_ERROR);
6593            asc_enqueue(&boardp->done, scp, ASC_BACK);
6594            break;
6595        default:
6596            ASC_PRINT2(
6597"asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code 0x%x\n",
6598                boardp->id, adv_dvc_varp->err_code);
6599            ASC_STATS(scp->device->host, exe_unknown);
6600            scp->result = HOST_BYTE(DID_ERROR);
6601            asc_enqueue(&boardp->done, scp, ASC_BACK);
6602            break;
6603        }
6604    }
6605
6606    ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
6607    return ret;
6608}
6609
6610/*
6611 * Build a request structure for the Asc Library (Narrow Board).
6612 *
6613 * The global structures 'asc_scsi_q' and 'asc_sg_head' are
6614 * used to build the request.
6615 *
6616 * If an error occurs, then queue the request on the board done
6617 * queue and return ASC_ERROR.
6618 */
6619STATIC int
6620asc_build_req(asc_board_t *boardp, Scsi_Cmnd *scp)
6621{
6622    /*
6623     * Mutually exclusive access is required to 'asc_scsi_q' and
6624     * 'asc_sg_head' until after the request is started.
6625     */
6626    memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
6627
6628    /*
6629     * Point the ASC_SCSI_Q to the 'Scsi_Cmnd'.
6630     */
6631    asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
6632
6633    /*
6634     * Build the ASC_SCSI_Q request.
6635     *
6636     * For narrow boards a CDB length maximum of 12 bytes
6637     * is supported.
6638     */
6639    if (scp->cmd_len > ASC_MAX_CDB_LEN) {
6640        ASC_PRINT3(
6641"asc_build_req: board %d: cmd_len %d > ASC_MAX_CDB_LEN  %d\n",
6642            boardp->id, scp->cmd_len, ASC_MAX_CDB_LEN);
6643        scp->result = HOST_BYTE(DID_ERROR);
6644        asc_enqueue(&boardp->done, scp, ASC_BACK);
6645        return ASC_ERROR;
6646    }
6647    asc_scsi_q.cdbptr = &scp->cmnd[0];
6648    asc_scsi_q.q2.cdb_len = scp->cmd_len;
6649    asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
6650    asc_scsi_q.q1.target_lun = scp->device->lun;
6651    asc_scsi_q.q2.target_ix = ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
6652    asc_scsi_q.q1.sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
6653    asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
6654
6655    /*
6656     * If there are any outstanding requests for the current target,
6657     * then every 255th request send an ORDERED request. This heuristic
6658     * tries to retain the benefit of request sorting while preventing
6659     * request starvation. 255 is the max number of tags or pending commands
6660     * a device may have outstanding.
6661     *
6662     * The request count is incremented below for every successfully
6663     * started request.
6664     *
6665     */
6666    if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
6667        (boardp->reqcnt[scp->device->id] % 255) == 0) {
6668        asc_scsi_q.q2.tag_code = M2_QTAG_MSG_ORDERED;
6669    } else {
6670        asc_scsi_q.q2.tag_code = M2_QTAG_MSG_SIMPLE;
6671    }
6672
6673    /*
6674     * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
6675     * buffer command.
6676     */
6677    if (scp->use_sg == 0) {
6678        /*
6679         * CDB request of single contiguous buffer.
6680         */
6681        ASC_STATS(scp->device->host, cont_cnt);
6682        asc_scsi_q.q1.data_addr =
6683            cpu_to_le32(virt_to_bus(scp->request_buffer));
6684        asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
6685        ASC_STATS_ADD(scp->device->host, cont_xfer,
6686                      ASC_CEILING(scp->request_bufflen, 512));
6687        asc_scsi_q.q1.sg_queue_cnt = 0;
6688        asc_scsi_q.sg_head = NULL;
6689    } else {
6690        /*
6691         * CDB scatter-gather request list.
6692         */
6693        int                     sgcnt;
6694        struct scatterlist      *slp;
6695
6696        if (scp->use_sg > scp->device->host->sg_tablesize) {
6697            ASC_PRINT3(
6698"asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
6699                boardp->id, scp->use_sg, scp->device->host->sg_tablesize);
6700            scp->result = HOST_BYTE(DID_ERROR);
6701            asc_enqueue(&boardp->done, scp, ASC_BACK);
6702            return ASC_ERROR;
6703        }
6704
6705        ASC_STATS(scp->device->host, sg_cnt);
6706
6707        /*
6708         * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
6709         * structure to point to it.
6710         */
6711        memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
6712
6713        asc_scsi_q.q1.cntl |= QC_SG_HEAD;
6714        asc_scsi_q.sg_head = &asc_sg_head;
6715        asc_scsi_q.q1.data_cnt = 0;
6716        asc_scsi_q.q1.data_addr = 0;
6717        /* This is a byte value, otherwise it would need to be swapped. */
6718        asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = scp->use_sg;
6719        ASC_STATS_ADD(scp->device->host, sg_elem, asc_sg_head.entry_cnt);
6720
6721        /*
6722         * Convert scatter-gather list into ASC_SG_HEAD list.
6723         */
6724        slp = (struct scatterlist *) scp->request_buffer;
6725        for (sgcnt = 0; sgcnt < scp->use_sg; sgcnt++, slp++) {
6726            asc_sg_head.sg_list[sgcnt].addr =
6727                cpu_to_le32(virt_to_bus(
6728                (unsigned char *)page_address(slp->page) + slp->offset));
6729            asc_sg_head.sg_list[sgcnt].bytes = cpu_to_le32(slp->length);
6730            ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(slp->length, 512));
6731        }
6732    }
6733
6734    ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
6735    ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
6736
6737    return ASC_NOERROR;
6738}
6739
6740/*
6741 * Build a request structure for the Adv Library (Wide Board).
6742 *
6743 * If an adv_req_t can not be allocated to issue the request,
6744 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
6745 *
6746 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
6747 * microcode for DMA addresses or math operations are byte swapped
6748 * to little-endian order.
6749 */
6750STATIC int
6751adv_build_req(asc_board_t *boardp, Scsi_Cmnd *scp,
6752    ADV_SCSI_REQ_Q **adv_scsiqpp)
6753{
6754    adv_req_t           *reqp;
6755    ADV_SCSI_REQ_Q      *scsiqp;
6756    int                 i;
6757    int                 ret;
6758
6759    /*
6760     * Allocate an adv_req_t structure from the board to execute
6761     * the command.
6762     */
6763    if (boardp->adv_reqp == NULL) {
6764        ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
6765        ASC_STATS(scp->device->host, adv_build_noreq);
6766        return ASC_BUSY;
6767    } else {
6768        reqp = boardp->adv_reqp;
6769        boardp->adv_reqp = reqp->next_reqp;
6770        reqp->next_reqp = NULL;
6771    }
6772
6773    /*
6774     * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
6775     */
6776    scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q);
6777
6778    /*
6779     * Initialize the structure.
6780     */
6781    scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
6782
6783    /*
6784     * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
6785     */
6786    scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
6787
6788    /*
6789     * Set the adv_req_t 'cmndp' to point to the Scsi_Cmnd structure.
6790     */
6791    reqp->cmndp = scp;
6792
6793    /*
6794     * Build the ADV_SCSI_REQ_Q request.
6795     */
6796
6797    /*
6798     * Set CDB length and copy it to the request structure.
6799     * For wide  boards a CDB length maximum of 16 bytes
6800     * is supported.
6801     */
6802    if (scp->cmd_len > ADV_MAX_CDB_LEN) {
6803        ASC_PRINT3(
6804"adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN  %d\n",
6805            boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN);
6806        scp->result = HOST_BYTE(DID_ERROR);
6807        asc_enqueue(&boardp->done, scp, ASC_BACK);
6808        return ASC_ERROR;
6809    }
6810    scsiqp->cdb_len = scp->cmd_len;
6811    /* Copy first 12 CDB bytes to cdb[]. */
6812    for (i = 0; i < scp->cmd_len && i < 12; i++) {
6813        scsiqp->cdb[i] = scp->cmnd[i];
6814    }
6815    /* Copy last 4 CDB bytes, if present, to cdb16[]. */
6816    for (; i < scp->cmd_len; i++) {
6817        scsiqp->cdb16[i - 12] = scp->cmnd[i];
6818    }
6819
6820    scsiqp->target_id = scp->device->id;
6821    scsiqp->target_lun = scp->device->lun;
6822
6823    scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
6824    scsiqp->sense_len = sizeof(scp->sense_buffer);
6825
6826    /*
6827     * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
6828     * buffer command.
6829     */
6830    scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
6831    scsiqp->vdata_addr = scp->request_buffer;
6832    scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
6833
6834    if (scp->use_sg == 0) {
6835        /*
6836         * CDB request of single contiguous buffer.
6837         */
6838        reqp->sgblkp = NULL;
6839        scsiqp->sg_list_ptr = NULL;
6840        scsiqp->sg_real_addr = 0;
6841        ASC_STATS(scp->device->host, cont_cnt);
6842        ASC_STATS_ADD(scp->device->host, cont_xfer,
6843                      ASC_CEILING(scp->request_bufflen, 512));
6844    } else {
6845        /*
6846         * CDB scatter-gather request list.
6847         */
6848        if (scp->use_sg > ADV_MAX_SG_LIST) {
6849            ASC_PRINT3(
6850"adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
6851                boardp->id, scp->use_sg, scp->device->host->sg_tablesize);
6852            scp->result = HOST_BYTE(DID_ERROR);
6853            asc_enqueue(&boardp->done, scp, ASC_BACK);
6854
6855            /*
6856             * Free the 'adv_req_t' structure by adding it back to the
6857             * board free list.
6858             */
6859            reqp->next_reqp = boardp->adv_reqp;
6860            boardp->adv_reqp = reqp;
6861
6862            return ASC_ERROR;
6863        }
6864
6865        if ((ret = adv_get_sglist(boardp, reqp, scp)) != ADV_SUCCESS) {
6866            /*
6867             * Free the adv_req_t structure by adding it back to the
6868             * board free list.
6869             */
6870            reqp->next_reqp = boardp->adv_reqp;
6871            boardp->adv_reqp = reqp;
6872
6873            return ret;
6874        }
6875
6876        ASC_STATS(scp->device->host, sg_cnt);
6877        ASC_STATS_ADD(scp->device->host, sg_elem, scp->use_sg);
6878    }
6879
6880    ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
6881    ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
6882
6883    *adv_scsiqpp = scsiqp;
6884
6885    return ASC_NOERROR;
6886}
6887
6888/*
6889 * Build scatter-gather list for Adv Library (Wide Board).
6890 *
6891 * Additional ADV_SG_BLOCK structures will need to be allocated
6892 * if the total number of scatter-gather elements exceeds
6893 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
6894 * assumed to be physically contiguous.
6895 *
6896 * Return:
6897 *      ADV_SUCCESS(1) - SG List successfully created
6898 *      ADV_ERROR(-1) - SG List creation failed
6899 */
6900STATIC int
6901adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, Scsi_Cmnd *scp)
6902{
6903    adv_sgblk_t         *sgblkp;
6904    ADV_SCSI_REQ_Q      *scsiqp;
6905    struct scatterlist  *slp;
6906    int                 sg_elem_cnt;
6907    ADV_SG_BLOCK        *sg_block, *prev_sg_block;
6908    ADV_PADDR           sg_block_paddr;
6909    int                 i;
6910
6911    scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q);
6912    slp = (struct scatterlist *) scp->request_buffer;
6913    sg_elem_cnt = scp->use_sg;
6914    prev_sg_block = NULL;
6915    reqp->sgblkp = NULL;
6916
6917    do
6918    {
6919        /*
6920         * Allocate a 'adv_sgblk_t' structure from the board free
6921         * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
6922         * (15) scatter-gather elements.
6923         */
6924        if ((sgblkp = boardp->adv_sgblkp) == NULL) {
6925            ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
6926            ASC_STATS(scp->device->host, adv_build_nosg);
6927
6928            /*
6929             * Allocation failed. Free 'adv_sgblk_t' structures already
6930             * allocated for the request.
6931             */
6932            while ((sgblkp = reqp->sgblkp) != NULL)
6933            {
6934                /* Remove 'sgblkp' from the request list. */
6935                reqp->sgblkp = sgblkp->next_sgblkp;
6936
6937                /* Add 'sgblkp' to the board free list. */
6938                sgblkp->next_sgblkp = boardp->adv_sgblkp;
6939                boardp->adv_sgblkp = sgblkp;
6940            }
6941            return ASC_BUSY;
6942        } else {
6943            /* Complete 'adv_sgblk_t' board allocation. */
6944            boardp->adv_sgblkp = sgblkp->next_sgblkp;
6945            sgblkp->next_sgblkp = NULL;
6946
6947            /*
6948             * Get 8 byte aligned virtual and physical addresses for
6949             * the allocated ADV_SG_BLOCK structure.
6950             */
6951            sg_block = (ADV_SG_BLOCK *) ADV_8BALIGN(&sgblkp->sg_block);
6952            sg_block_paddr = virt_to_bus(sg_block);
6953
6954            /*
6955             * Check if this is the first 'adv_sgblk_t' for the request.
6956             */
6957            if (reqp->sgblkp == NULL)
6958            {
6959                /* Request's first scatter-gather block. */
6960                reqp->sgblkp = sgblkp;
6961
6962                /*
6963                 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
6964                 * address pointers.
6965                 */
6966                scsiqp->sg_list_ptr = sg_block;
6967                scsiqp->sg_real_addr = cpu_to_le32(sg_block_paddr);
6968            } else
6969            {
6970                /* Request's second or later scatter-gather block. */
6971                sgblkp->next_sgblkp = reqp->sgblkp;
6972                reqp->sgblkp = sgblkp;
6973
6974                /*
6975                 * Point the previous ADV_SG_BLOCK structure to
6976                 * the newly allocated ADV_SG_BLOCK structure.
6977                 */
6978                ASC_ASSERT(prev_sg_block != NULL);
6979                prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr);
6980            }
6981        }
6982
6983        for (i = 0; i < NO_OF_SG_PER_BLOCK; i++)
6984        {
6985            sg_block->sg_list[i].sg_addr =
6986                cpu_to_le32(virt_to_bus(
6987                   (unsigned char *)page_address(slp->page) + slp->offset));
6988            sg_block->sg_list[i].sg_count = cpu_to_le32(slp->length);
6989            ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(slp->length, 512));
6990
6991            if (--sg_elem_cnt == 0)
6992            {   /* Last ADV_SG_BLOCK and scatter-gather entry. */
6993                sg_block->sg_cnt = i + 1;
6994                sg_block->sg_ptr = 0L;    /* Last ADV_SG_BLOCK in list. */
6995                return ADV_SUCCESS;
6996            }
6997            slp++;
6998        }
6999        sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
7000        prev_sg_block = sg_block;
7001    }
7002    while (1);
7003    /* NOTREACHED */
7004}
7005
7006/*
7007 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
7008 *
7009 * Interrupt callback function for the Narrow SCSI Asc Library.
7010 */
7011STATIC void
7012asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
7013{
7014    asc_board_t         *boardp;
7015    Scsi_Cmnd           *scp;
7016    struct Scsi_Host    *shp;
7017    int                 i;
7018
7019    ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
7020        (ulong) asc_dvc_varp, (ulong) qdonep);
7021    ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
7022
7023    /*
7024     * Get the Scsi_Cmnd structure and Scsi_Host structure for the
7025     * command that has been completed.
7026     */
7027    scp = (Scsi_Cmnd *) ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
7028    ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong) scp);
7029
7030    if (scp == NULL) {
7031        ASC_PRINT("asc_isr_callback: scp is NULL\n");
7032        return;
7033    }
7034    ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
7035
7036    /*
7037     * If the request's host pointer is not valid, display a
7038     * message and return.
7039     */
7040    shp = scp->device->host;
7041    for (i = 0; i < asc_board_count; i++) {
7042        if (asc_host[i] == shp) {
7043            break;
7044        }
7045    }
7046    if (i == asc_board_count) {
7047        ASC_PRINT2(
7048            "asc_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n",
7049            (ulong) scp, (ulong) shp);
7050        return;
7051    }
7052
7053    ASC_STATS(shp, callback);
7054    ASC_DBG1(1, "asc_isr_callback: shp 0x%lx\n", (ulong) shp);
7055
7056    /*
7057     * If the request isn't found on the active queue, it may
7058     * have been removed to handle a reset request.
7059     * Display a message and return.
7060     */
7061    boardp = ASC_BOARDP(shp);
7062    ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
7063    if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
7064        ASC_PRINT2(
7065            "asc_isr_callback: board %d: scp 0x%lx not on active queue\n",
7066            boardp->id, (ulong) scp);
7067        return;
7068    }
7069
7070    /*
7071     * 'qdonep' contains the command's ending status.
7072     */
7073    switch (qdonep->d3.done_stat) {
7074    case QD_NO_ERROR:
7075        ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
7076        scp->result = 0;
7077
7078        /*
7079         * If an INQUIRY command completed successfully, then call
7080         * the AscInquiryHandling() function to set-up the device.
7081         */
7082        if (scp->cmnd[0] == SCSICMD_Inquiry && scp->device->lun == 0 &&
7083            (scp->request_bufflen - qdonep->remain_bytes) >= 8)
7084        {
7085            AscInquiryHandling(asc_dvc_varp, scp->device->id & 0x7,
7086                (ASC_SCSI_INQUIRY *) scp->request_buffer);
7087        }
7088
7089#if ASC_LINUX_KERNEL24
7090        /*
7091         * Check for an underrun condition.
7092         *
7093         * If there was no error and an underrun condition, then
7094         * then return the number of underrun bytes.
7095         */
7096        if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
7097            qdonep->remain_bytes <= scp->request_bufflen) {
7098            ASC_DBG1(1, "asc_isr_callback: underrun condition %u bytes\n",
7099            (unsigned) qdonep->remain_bytes);
7100            scp->resid = qdonep->remain_bytes;
7101        }
7102#endif
7103        break;
7104
7105    case QD_WITH_ERROR:
7106        ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
7107        switch (qdonep->d3.host_stat) {
7108        case QHSTA_NO_ERROR:
7109            if (qdonep->d3.scsi_stat == SS_CHK_CONDITION) {
7110                ASC_DBG(2, "asc_isr_callback: SS_CHK_CONDITION\n");
7111                ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
7112                    sizeof(scp->sense_buffer));
7113                /*
7114                 * Note: The 'status_byte()' macro used by target drivers
7115                 * defined in scsi.h shifts the status byte returned by
7116                 * host drivers right by 1 bit. This is why target drivers
7117                 * also use right shifted status byte definitions. For
7118                 * instance target drivers use CHECK_CONDITION, defined to
7119                 * 0x1, instead of the SCSI defined check condition value
7120                 * of 0x2. Host drivers are supposed to return the status
7121                 * byte as it is defined by SCSI.
7122                 */
7123                scp->result = DRIVER_BYTE(DRIVER_SENSE) |
7124                    STATUS_BYTE(qdonep->d3.scsi_stat);
7125            } else {
7126                scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
7127            }
7128            break;
7129
7130        default:
7131            /* QHSTA error occurred */
7132            ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
7133                qdonep->d3.host_stat);
7134            scp->result = HOST_BYTE(DID_BAD_TARGET);
7135            break;
7136        }
7137        break;
7138
7139    case QD_ABORTED_BY_HOST:
7140        ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
7141        scp->result = HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.scsi_msg) |
7142                STATUS_BYTE(qdonep->d3.scsi_stat);
7143        break;
7144
7145    default:
7146        ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n", qdonep->d3.done_stat);
7147        scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.scsi_msg) |
7148                STATUS_BYTE(qdonep->d3.scsi_stat);
7149        break;
7150    }
7151
7152    /*
7153     * If the 'init_tidmask' bit isn't already set for the target and the
7154     * current request finished normally, then set the bit for the target
7155     * to indicate that a device is present.
7156     */
7157    if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
7158        qdonep->d3.done_stat == QD_NO_ERROR &&
7159        qdonep->d3.host_stat == QHSTA_NO_ERROR) {
7160        boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
7161    }
7162
7163    /*
7164     * Because interrupts may be enabled by the 'Scsi_Cmnd' done
7165     * function, add the command to the end of the board's done queue.
7166     * The done function for the command will be called from
7167     * advansys_interrupt().
7168     */
7169    asc_enqueue(&boardp->done, scp, ASC_BACK);
7170
7171    return;
7172}
7173
7174/*
7175 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
7176 *
7177 * Callback function for the Wide SCSI Adv Library.
7178 */
7179STATIC void
7180adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
7181{
7182    asc_board_t         *boardp;
7183    adv_req_t           *reqp;
7184    adv_sgblk_t         *sgblkp;
7185    Scsi_Cmnd           *scp;
7186    struct Scsi_Host    *shp;
7187    int                 i;
7188#if ASC_LINUX_KERNEL24
7189    ADV_DCNT            resid_cnt;
7190#endif
7191
7192
7193    ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
7194        (ulong) adv_dvc_varp, (ulong) scsiqp);
7195    ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
7196
7197    /*
7198     * Get the adv_req_t structure for the command that has been
7199     * completed. The adv_req_t structure actually contains the
7200     * completed ADV_SCSI_REQ_Q structure.
7201     */
7202    reqp = (adv_req_t *) ADV_U32_TO_VADDR(scsiqp->srb_ptr);
7203    ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong) reqp);
7204    if (reqp == NULL) {
7205        ASC_PRINT("adv_isr_callback: reqp is NULL\n");
7206        return;
7207    }
7208
7209    /*
7210     * Get the Scsi_Cmnd structure and Scsi_Host structure for the
7211     * command that has been completed.
7212     *
7213     * Note: The adv_req_t request structure and adv_sgblk_t structure,
7214     * if any, are dropped, because a board structure pointer can not be
7215     * determined.
7216     */
7217    scp = reqp->cmndp;
7218    ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong) scp);
7219    if (scp == NULL) {
7220        ASC_PRINT("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
7221        return;
7222    }
7223    ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
7224
7225    /*
7226     * If the request's host pointer is not valid, display a message
7227     * and return.
7228     */
7229    shp = scp->device->host;
7230    for (i = 0; i < asc_board_count; i++) {
7231        if (asc_host[i] == shp) {
7232            break;
7233        }
7234    }
7235    /*
7236     * Note: If the host structure is not found, the adv_req_t request
7237     * structure and adv_sgblk_t structure, if any, is dropped.
7238     */
7239    if (i == asc_board_count) {
7240        ASC_PRINT2(
7241            "adv_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n",
7242            (ulong) scp, (ulong) shp);
7243        return;
7244    }
7245
7246    ASC_STATS(shp, callback);
7247    ASC_DBG1(1, "adv_isr_callback: shp 0x%lx\n", (ulong) shp);
7248
7249    /*
7250     * If the request isn't found on the active queue, it may have been
7251     * removed to handle a reset request. Display a message and return.
7252     *
7253     * Note: Because the structure may still be in use don't attempt
7254     * to free the adv_req_t and adv_sgblk_t, if any, structures.
7255     */
7256    boardp = ASC_BOARDP(shp);
7257    ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
7258    if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
7259        ASC_PRINT2(
7260            "adv_isr_callback: board %d: scp 0x%lx not on active queue\n",
7261            boardp->id, (ulong) scp);
7262        return;
7263    }
7264
7265    /*
7266     * 'done_status' contains the command's ending status.
7267     */
7268    switch (scsiqp->done_status) {
7269    case QD_NO_ERROR:
7270        ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
7271        scp->result = 0;
7272
7273#if ASC_LINUX_KERNEL24
7274        /*
7275         * Check for an underrun condition.
7276         *
7277         * If there was no error and an underrun condition, then
7278         * then return the number of underrun bytes.
7279         */
7280        resid_cnt = le32_to_cpu(scsiqp->data_cnt);
7281        if (scp->request_bufflen != 0 && resid_cnt != 0 &&
7282            resid_cnt <= scp->request_bufflen) {
7283            ASC_DBG1(1, "adv_isr_callback: underrun condition %lu bytes\n",
7284                (ulong) resid_cnt);
7285            scp->resid = resid_cnt;
7286        }
7287#endif
7288        break;
7289
7290    case QD_WITH_ERROR:
7291        ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
7292        switch (scsiqp->host_status) {
7293        case QHSTA_NO_ERROR:
7294            if (scsiqp->scsi_status == SS_CHK_CONDITION) {
7295                ASC_DBG(2, "adv_isr_callback: SS_CHK_CONDITION\n");
7296                ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
7297                    sizeof(scp->sense_buffer));
7298                /*
7299                 * Note: The 'status_byte()' macro used by target drivers
7300                 * defined in scsi.h shifts the status byte returned by
7301                 * host drivers right by 1 bit. This is why target drivers
7302                 * also use right shifted status byte definitions. For
7303                 * instance target drivers use CHECK_CONDITION, defined to
7304                 * 0x1, instead of the SCSI defined check condition value
7305                 * of 0x2. Host drivers are supposed to return the status
7306                 * byte as it is defined by SCSI.
7307                 */
7308                scp->result = DRIVER_BYTE(DRIVER_SENSE) |
7309                    STATUS_BYTE(scsiqp->scsi_status);
7310            } else {
7311                scp->result = STATUS_BYTE(scsiqp->scsi_status);
7312            }
7313            break;
7314
7315        default:
7316            /* Some other QHSTA error occurred. */
7317            ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
7318                scsiqp->host_status);
7319            scp->result = HOST_BYTE(DID_BAD_TARGET);
7320            break;
7321        }
7322        break;
7323
7324    case QD_ABORTED_BY_HOST:
7325        ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
7326        scp->result = HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
7327        break;
7328
7329    default:
7330        ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n", scsiqp->done_status);
7331        scp->result = HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
7332        break;
7333    }
7334
7335    /*
7336     * If the 'init_tidmask' bit isn't already set for the target and the
7337     * current request finished normally, then set the bit for the target
7338     * to indicate that a device is present.
7339     */
7340    if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
7341        scsiqp->done_status == QD_NO_ERROR &&
7342        scsiqp->host_status == QHSTA_NO_ERROR) {
7343        boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
7344    }
7345
7346    /*
7347     * Because interrupts may be enabled by the 'Scsi_Cmnd' done
7348     * function, add the command to the end of the board's done queue.
7349     * The done function for the command will be called from
7350     * advansys_interrupt().
7351     */
7352    asc_enqueue(&boardp->done, scp, ASC_BACK);
7353
7354    /*
7355     * Free all 'adv_sgblk_t' structures allocated for the request.
7356     */
7357    while ((sgblkp = reqp->sgblkp) != NULL)
7358    {
7359        /* Remove 'sgblkp' from the request list. */
7360        reqp->sgblkp = sgblkp->next_sgblkp;
7361
7362        /* Add 'sgblkp' to the board free list. */
7363        sgblkp->next_sgblkp = boardp->adv_sgblkp;
7364        boardp->adv_sgblkp = sgblkp;
7365    }
7366
7367    /*
7368     * Free the adv_req_t structure used with the command by adding
7369     * it back to the board free list.
7370     */
7371    reqp->next_reqp = boardp->adv_reqp;
7372    boardp->adv_reqp = reqp;
7373
7374    ASC_DBG(1, "adv_isr_callback: done\n");
7375
7376    return;
7377}
7378
7379/*
7380 * adv_async_callback() - Adv Library asynchronous event callback function.
7381 */
7382STATIC void
7383adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
7384{
7385    switch (code)
7386    {
7387    case ADV_ASYNC_SCSI_BUS_RESET_DET:
7388        /*
7389         * The firmware detected a SCSI Bus reset.
7390         */
7391        ASC_DBG(0, "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
7392        break;
7393
7394    case ADV_ASYNC_RDMA_FAILURE:
7395        /*
7396         * Handle RDMA failure by resetting the SCSI Bus and
7397         * possibly the chip if it is unresponsive. Log the error
7398         * with a unique code.
7399         */
7400        ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
7401        AdvResetChipAndSB(adv_dvc_varp);
7402        break;
7403
7404    case ADV_HOST_SCSI_BUS_RESET:
7405        /*
7406         * Host generated SCSI bus reset occurred.
7407         */
7408        ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
7409        break;
7410
7411    default:
7412        ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
7413        break;
7414    }
7415}
7416
7417/*
7418 * Add a 'REQP' to the end of specified queue. Set 'tidmask'
7419 * to indicate a command is queued for the device.
7420 *
7421 * 'flag' may be either ASC_FRONT or ASC_BACK.
7422 *
7423 * 'REQPNEXT(reqp)' returns reqp's next pointer.
7424 */
7425STATIC void
7426asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
7427{
7428    int        tid;
7429
7430    ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n",
7431        (ulong) ascq, (ulong) reqp, flag);
7432    ASC_ASSERT(reqp != NULL);
7433    ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
7434    tid = REQPTID(reqp);
7435    ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7436    if (flag == ASC_FRONT) {
7437        reqp->host_scribble = (unsigned char *)ascq->q_first[tid];
7438        ascq->q_first[tid] = reqp;
7439        /* If the queue was empty, set the last pointer. */
7440        if (ascq->q_last[tid] == NULL) {
7441            ascq->q_last[tid] = reqp;
7442        }
7443    } else { /* ASC_BACK */
7444        if (ascq->q_last[tid] != NULL) {
7445            ascq->q_last[tid]->host_scribble = (unsigned char *)reqp;
7446        }
7447        ascq->q_last[tid] = reqp;
7448        reqp->host_scribble = NULL;
7449        /* If the queue was empty, set the first pointer. */
7450        if (ascq->q_first[tid] == NULL) {
7451            ascq->q_first[tid] = reqp;
7452        }
7453    }
7454    /* The queue has at least one entry, set its bit. */
7455    ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
7456#ifdef ADVANSYS_STATS
7457    /* Maintain request queue statistics. */
7458    ascq->q_tot_cnt[tid]++;
7459    ascq->q_cur_cnt[tid]++;
7460    if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
7461        ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
7462        ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
7463            tid, ascq->q_max_cnt[tid]);
7464    }
7465    REQPTIME(reqp) = REQTIMESTAMP();
7466#endif /* ADVANSYS_STATS */
7467    ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong) reqp);
7468    return;
7469}
7470
7471/*
7472 * Return first queued 'REQP' on the specified queue for
7473 * the specified target device. Clear the 'tidmask' bit for
7474 * the device if no more commands are left queued for it.
7475 *
7476 * 'REQPNEXT(reqp)' returns reqp's next pointer.
7477 */
7478STATIC REQP
7479asc_dequeue(asc_queue_t *ascq, int tid)
7480{
7481    REQP    reqp;
7482
7483    ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong) ascq, tid);
7484    ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7485    if ((reqp = ascq->q_first[tid]) != NULL) {
7486        ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
7487        ascq->q_first[tid] = REQPNEXT(reqp);
7488        /* If the queue is empty, clear its bit and the last pointer. */
7489        if (ascq->q_first[tid] == NULL) {
7490            ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7491            ASC_ASSERT(ascq->q_last[tid] == reqp);
7492            ascq->q_last[tid] = NULL;
7493        }
7494#ifdef ADVANSYS_STATS
7495        /* Maintain request queue statistics. */
7496        ascq->q_cur_cnt[tid]--;
7497        ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
7498        REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
7499#endif /* ADVANSYS_STATS */
7500    }
7501    ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong) reqp);
7502    return reqp;
7503}
7504
7505/*
7506 * Return a pointer to a singly linked list of all the requests queued
7507 * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
7508 *
7509 * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
7510 * the last request returned in the singly linked list.
7511 *
7512 * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
7513 * then all queued requests are concatenated into one list and
7514 * returned.
7515 *
7516 * Note: If 'lastpp' is used to append a new list to the end of
7517 * an old list, only change the old list last pointer if '*lastpp'
7518 * (or the function return value) is not NULL, i.e. use a temporary
7519 * variable for 'lastpp' and check its value after the function return
7520 * before assigning it to the list last pointer.
7521 *
7522 * Unfortunately collecting queuing time statistics adds overhead to
7523 * the function that isn't inherent to the function's algorithm.
7524 */
7525STATIC REQP
7526asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
7527{
7528    REQP    firstp, lastp;
7529    int     i;
7530
7531    ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong) ascq, tid);
7532    ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
7533
7534    /*
7535     * If 'tid' is not ASC_TID_ALL, return requests only for
7536     * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
7537     * requests for all tids.
7538     */
7539    if (tid != ASC_TID_ALL) {
7540        /* Return all requests for the specified 'tid'. */
7541        if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
7542            /* List is empty; Set first and last return pointers to NULL. */
7543            firstp = lastp = NULL;
7544        } else {
7545            firstp = ascq->q_first[tid];
7546            lastp = ascq->q_last[tid];
7547            ascq->q_first[tid] = ascq->q_last[tid] = NULL;
7548            ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7549#ifdef ADVANSYS_STATS
7550            {
7551                REQP reqp;
7552                ascq->q_cur_cnt[tid] = 0;
7553                for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
7554                    REQTIMESTAT("asc_dequeue_list", ascq, reqp, tid);
7555                }
7556            }
7557#endif /* ADVANSYS_STATS */
7558        }
7559    } else {
7560        /* Return all requests for all tids. */
7561        firstp = lastp = NULL;
7562        for (i = 0; i <= ADV_MAX_TID; i++) {
7563            if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
7564                if (firstp == NULL) {
7565                    firstp = ascq->q_first[i];
7566                    lastp = ascq->q_last[i];
7567                } else {
7568                    ASC_ASSERT(lastp != NULL);
7569                    lastp->host_scribble = (unsigned char *)ascq->q_first[i];
7570                    lastp = ascq->q_last[i];
7571                }
7572                ascq->q_first[i] = ascq->q_last[i] = NULL;
7573                ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7574#ifdef ADVANSYS_STATS
7575                ascq->q_cur_cnt[i] = 0;
7576#endif /* ADVANSYS_STATS */
7577            }
7578        }
7579#ifdef ADVANSYS_STATS
7580        {
7581            REQP reqp;
7582            for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
7583                REQTIMESTAT("asc_dequeue_list", ascq, reqp, reqp->device->id);
7584            }
7585        }
7586#endif /* ADVANSYS_STATS */
7587    }
7588    if (lastpp) {
7589        *lastpp = lastp;
7590    }
7591    ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong) firstp);
7592    return firstp;
7593}
7594
7595/*
7596 * Remove the specified 'REQP' from the specified queue for
7597 * the specified target device. Clear the 'tidmask' bit for the
7598 * device if no more commands are left queued for it.
7599 *
7600 * 'REQPNEXT(reqp)' returns reqp's the next pointer.
7601 *
7602 * Return ASC_TRUE if the command was found and removed,
7603 * otherwise return ASC_FALSE.
7604 */
7605STATIC int
7606asc_rmqueue(asc_queue_t *ascq, REQP reqp)
7607{
7608    REQP        currp, prevp;
7609    int         tid;
7610    int         ret = ASC_FALSE;
7611
7612    ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n",
7613        (ulong) ascq, (ulong) reqp);
7614    ASC_ASSERT(reqp != NULL);
7615
7616    tid = REQPTID(reqp);
7617    ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7618
7619    /*
7620     * Handle the common case of 'reqp' being the first
7621     * entry on the queue.
7622     */
7623    if (reqp == ascq->q_first[tid]) {
7624        ret = ASC_TRUE;
7625        ascq->q_first[tid] = REQPNEXT(reqp);
7626        /* If the queue is now empty, clear its bit and the last pointer. */
7627        if (ascq->q_first[tid] == NULL) {
7628            ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7629            ASC_ASSERT(ascq->q_last[tid] == reqp);
7630            ascq->q_last[tid] = NULL;
7631        }
7632    } else if (ascq->q_first[tid] != NULL) {
7633        ASC_ASSERT(ascq->q_last[tid] != NULL);
7634        /*
7635         * Because the case of 'reqp' being the first entry has been
7636         * handled above and it is known the queue is not empty, if
7637         * 'reqp' is found on the queue it is guaranteed the queue will
7638         * not become empty and that 'q_first[tid]' will not be changed.
7639         *
7640         * Set 'prevp' to the first entry, 'currp' to the second entry,
7641         * and search for 'reqp'.
7642         */
7643        for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
7644             currp; prevp = currp, currp = REQPNEXT(currp)) {
7645            if (currp == reqp) {
7646                ret = ASC_TRUE;
7647                prevp->host_scribble = (unsigned char *)REQPNEXT(currp);
7648                reqp->host_scribble = NULL;
7649                if (ascq->q_last[tid] == reqp) {
7650                    ascq->q_last[tid] = prevp;
7651                }
7652                break;
7653            }
7654        }
7655    }
7656#ifdef ADVANSYS_STATS
7657    /* Maintain request queue statistics. */
7658    if (ret == ASC_TRUE) {
7659        ascq->q_cur_cnt[tid]--;
7660        REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
7661    }
7662    ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
7663#endif /* ADVANSYS_STATS */
7664    ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong) reqp, ret);
7665    return ret;
7666}
7667
7668/*
7669 * Execute as many queued requests as possible for the specified queue.
7670 *
7671 * Calls asc_execute_scsi_cmnd() to execute a REQP/Scsi_Cmnd.
7672 */
7673STATIC void
7674asc_execute_queue(asc_queue_t *ascq)
7675{
7676    ADV_SCSI_BIT_ID_TYPE    scan_tidmask;
7677    REQP                    reqp;
7678    int                     i;
7679
7680    ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong) ascq);
7681    /*
7682     * Execute queued commands for devices attached to
7683     * the current board in round-robin fashion.
7684     */
7685    scan_tidmask = ascq->q_tidmask;
7686    do {
7687        for (i = 0; i <= ADV_MAX_TID; i++) {
7688            if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
7689                if ((reqp = asc_dequeue(ascq, i)) == NULL) {
7690                    scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7691                } else if (asc_execute_scsi_cmnd((Scsi_Cmnd *) reqp)
7692                            == ASC_BUSY) {
7693                    scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7694                    /*
7695                     * The request returned ASC_BUSY. Enqueue at the front of
7696                     * target's waiting list to maintain correct ordering.
7697                     */
7698                    asc_enqueue(ascq, reqp, ASC_FRONT);
7699                }
7700            }
7701        }
7702    } while (scan_tidmask);
7703    return;
7704}
7705
7706#ifdef CONFIG_PROC_FS
7707/*
7708 * asc_prt_board_devices()
7709 *
7710 * Print driver information for devices attached to the board.
7711 *
7712 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7713 * cf. asc_prt_line().
7714 *
7715 * Return the number of characters copied into 'cp'. No more than
7716 * 'cplen' characters will be copied to 'cp'.
7717 */
7718STATIC int
7719asc_prt_board_devices(struct Scsi_Host *shp, char *cp, int cplen)
7720{
7721    asc_board_t        *boardp;
7722    int                leftlen;
7723    int                totlen;
7724    int                len;
7725    int                chip_scsi_id;
7726    int                i;
7727
7728    boardp = ASC_BOARDP(shp);
7729    leftlen = cplen;
7730    totlen = len = 0;
7731
7732    len = asc_prt_line(cp, leftlen,
7733"\nDevice Information for AdvanSys SCSI Host %d:\n", shp->host_no);
7734    ASC_PRT_NEXT();
7735
7736    if (ASC_NARROW_BOARD(boardp)) {
7737        chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
7738    } else {
7739        chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
7740    }
7741
7742    len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
7743    ASC_PRT_NEXT();
7744    for (i = 0; i <= ADV_MAX_TID; i++) {
7745        if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
7746            len = asc_prt_line(cp, leftlen, " %X,", i);
7747            ASC_PRT_NEXT();
7748        }
7749    }
7750    len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
7751    ASC_PRT_NEXT();
7752
7753    return totlen;
7754}
7755
7756/*
7757 * Display Wide Board BIOS Information.
7758 */
7759STATIC int
7760asc_prt_adv_bios(struct Scsi_Host *shp, char *cp, int cplen)
7761{
7762    asc_board_t        *boardp;
7763    int                leftlen;
7764    int                totlen;
7765    int                len;
7766    ushort             major, minor, letter;
7767
7768    boardp = ASC_BOARDP(shp);
7769    leftlen = cplen;
7770    totlen = len = 0;
7771
7772    len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
7773    ASC_PRT_NEXT();
7774
7775    /*
7776     * If the BIOS saved a valid signature, then fill in
7777     * the BIOS code segment base address.
7778     */
7779    if (boardp->bios_signature != 0x55AA) {
7780        len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
7781        ASC_PRT_NEXT();
7782        len = asc_prt_line(cp, leftlen,
7783"BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
7784        ASC_PRT_NEXT();
7785        len = asc_prt_line(cp, leftlen,
7786"can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
7787        ASC_PRT_NEXT();
7788    } else {
7789        major = (boardp->bios_version >> 12) & 0xF;
7790        minor = (boardp->bios_version >> 8) & 0xF;
7791        letter = (boardp->bios_version & 0xFF);
7792
7793        len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
7794            major, minor, letter >= 26 ? '?' : letter + 'A');
7795        ASC_PRT_NEXT();
7796
7797        /*
7798         * Current available ROM BIOS release is 3.1I for UW
7799         * and 3.2I for U2W. This code doesn't differentiate
7800         * UW and U2W boards.
7801         */
7802        if (major < 3 || (major <= 3 && minor < 1) ||
7803            (major <= 3 && minor <= 1 && letter < ('I'- 'A'))) {
7804            len = asc_prt_line(cp, leftlen,
7805"Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
7806            ASC_PRT_NEXT();
7807            len = asc_prt_line(cp, leftlen,
7808"ftp://ftp.connectcom.net/pub\n");
7809            ASC_PRT_NEXT();
7810        }
7811    }
7812
7813    return totlen;
7814}
7815
7816/*
7817 * Add serial number to information bar if signature AAh
7818 * is found in at bit 15-9 (7 bits) of word 1.
7819 *
7820 * Serial Number consists fo 12 alpha-numeric digits.
7821 *
7822 *       1 - Product type (A,B,C,D..)  Word0: 15-13 (3 bits)
7823 *       2 - MFG Location (A,B,C,D..)  Word0: 12-10 (3 bits)
7824 *     3-4 - Product ID (0-99)         Word0: 9-0 (10 bits)
7825 *       5 - Product revision (A-J)    Word0:  "         "
7826 *
7827 *           Signature                 Word1: 15-9 (7 bits)
7828 *       6 - Year (0-9)                Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
7829 *     7-8 - Week of the year (1-52)   Word1: 5-0 (6 bits)
7830 *
7831 *    9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
7832 *
7833 * Note 1: Only production cards will have a serial number.
7834 *
7835 * Note 2: Signature is most significant 7 bits (0xFE).
7836 *
7837 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
7838 */
7839STATIC int
7840asc_get_eeprom_string(ushort *serialnum, uchar *cp)
7841{
7842    ushort      w, num;
7843
7844    if ((serialnum[1] & 0xFE00) != ((ushort) 0xAA << 8)) {
7845        return ASC_FALSE;
7846    } else {
7847        /*
7848         * First word - 6 digits.
7849         */
7850        w = serialnum[0];
7851
7852        /* Product type - 1st digit. */
7853        if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
7854            /* Product type is P=Prototype */
7855            *cp += 0x8;
7856        }
7857        cp++;
7858
7859        /* Manufacturing location - 2nd digit. */
7860        *cp++ = 'A' + ((w & 0x1C00) >> 10);
7861
7862        /* Product ID - 3rd, 4th digits. */
7863        num = w & 0x3FF;
7864        *cp++ = '0' + (num / 100);
7865        num %= 100;
7866        *cp++ = '0' + (num / 10);
7867
7868        /* Product revision - 5th digit. */
7869        *cp++ = 'A' + (num % 10);
7870
7871        /*
7872         * Second word
7873         */
7874        w = serialnum[1];
7875
7876        /*
7877         * Year - 6th digit.
7878         *
7879         * If bit 15 of third word is set, then the
7880         * last digit of the year is greater than 7.
7881         */
7882        if (serialnum[2] & 0x8000) {
7883            *cp++ = '8' + ((w & 0x1C0) >> 6);
7884        } else {
7885            *cp++ = '0' + ((w & 0x1C0) >> 6);
7886        }
7887
7888        /* Week of year - 7th, 8th digits. */
7889        num = w & 0x003F;
7890        *cp++ = '0' + num / 10;
7891        num %= 10;
7892        *cp++ = '0' + num;
7893
7894        /*
7895         * Third word
7896         */
7897        w = serialnum[2] & 0x7FFF;
7898
7899        /* Serial number - 9th digit. */
7900        *cp++ = 'A' + (w / 1000);
7901
7902        /* 10th, 11th, 12th digits. */
7903        num = w % 1000;
7904        *cp++ = '0' + num / 100;
7905        num %= 100;
7906        *cp++ = '0' + num / 10;
7907        num %= 10;
7908        *cp++ = '0' + num;
7909
7910        *cp = '\0';     /* Null Terminate the string. */
7911        return ASC_TRUE;
7912    }
7913}
7914
7915/*
7916 * asc_prt_asc_board_eeprom()
7917 *
7918 * Print board EEPROM configuration.
7919 *
7920 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7921 * cf. asc_prt_line().
7922 *
7923 * Return the number of characters copied into 'cp'. No more than
7924 * 'cplen' characters will be copied to 'cp'.
7925 */
7926STATIC int
7927asc_prt_asc_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
7928{
7929    asc_board_t        *boardp;
7930    ASC_DVC_VAR        *asc_dvc_varp;
7931    int                leftlen;
7932    int                totlen;
7933    int                len;
7934    ASCEEP_CONFIG      *ep;
7935    int                i;
7936#ifdef CONFIG_ISA
7937    int                isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
7938#endif /* CONFIG_ISA */
7939    uchar              serialstr[13];
7940
7941    boardp = ASC_BOARDP(shp);
7942    asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
7943    ep = &boardp->eep_config.asc_eep;
7944
7945    leftlen = cplen;
7946    totlen = len = 0;
7947
7948    len = asc_prt_line(cp, leftlen,
7949"\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
7950    ASC_PRT_NEXT();
7951
7952    if (asc_get_eeprom_string((ushort *) &ep->adapter_info[0], serialstr) ==
7953        ASC_TRUE) {
7954        len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
7955        ASC_PRT_NEXT();
7956    } else {
7957        if (ep->adapter_info[5] == 0xBB) {
7958            len = asc_prt_line(cp, leftlen,
7959                " Default Settings Used for EEPROM-less Adapter.\n");
7960            ASC_PRT_NEXT();
7961        } else {
7962            len = asc_prt_line(cp, leftlen,
7963                " Serial Number Signature Not Present.\n");
7964            ASC_PRT_NEXT();
7965        }
7966    }
7967
7968    len = asc_prt_line(cp, leftlen,
7969" Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
7970        ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng, ep->max_tag_qng);
7971    ASC_PRT_NEXT();
7972
7973    len = asc_prt_line(cp, leftlen,
7974" cntl 0x%x, no_scam 0x%x\n",
7975        ep->cntl, ep->no_scam);
7976    ASC_PRT_NEXT();
7977
7978    len = asc_prt_line(cp, leftlen,
7979" Target ID:           ");
7980    ASC_PRT_NEXT();
7981    for (i = 0; i <= ASC_MAX_TID; i++) {
7982        len = asc_prt_line(cp, leftlen, " %d", i);
7983        ASC_PRT_NEXT();
7984    }
7985    len = asc_prt_line(cp, leftlen, "\n");
7986    ASC_PRT_NEXT();
7987
7988    len = asc_prt_line(cp, leftlen,
7989" Disconnects:         ");
7990    ASC_PRT_NEXT();
7991    for (i = 0; i <= ASC_MAX_TID; i++) {
7992        len = asc_prt_line(cp, leftlen, " %c",
7993            (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7994        ASC_PRT_NEXT();
7995    }
7996    len = asc_prt_line(cp, leftlen, "\n");
7997    ASC_PRT_NEXT();
7998
7999    len = asc_prt_line(cp, leftlen,
8000" Command Queuing:     ");
8001    ASC_PRT_NEXT();
8002    for (i = 0; i <= ASC_MAX_TID; i++) {
8003        len = asc_prt_line(cp, leftlen, " %c",
8004            (ep->use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8005        ASC_PRT_NEXT();
8006    }
8007    len = asc_prt_line(cp, leftlen, "\n");
8008    ASC_PRT_NEXT();
8009
8010    len = asc_prt_line(cp, leftlen,
8011" Start Motor:         ");
8012    ASC_PRT_NEXT();
8013    for (i = 0; i <= ASC_MAX_TID; i++) {
8014        len = asc_prt_line(cp, leftlen, " %c",
8015            (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8016        ASC_PRT_NEXT();
8017    }
8018    len = asc_prt_line(cp, leftlen, "\n");
8019    ASC_PRT_NEXT();
8020
8021    len = asc_prt_line(cp, leftlen,
8022" Synchronous Transfer:");
8023    ASC_PRT_NEXT();
8024    for (i = 0; i <= ASC_MAX_TID; i++) {
8025        len = asc_prt_line(cp, leftlen, " %c",
8026            (ep->init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8027        ASC_PRT_NEXT();
8028    }
8029    len = asc_prt_line(cp, leftlen, "\n");
8030    ASC_PRT_NEXT();
8031
8032#ifdef CONFIG_ISA
8033    if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
8034        len = asc_prt_line(cp, leftlen,
8035" Host ISA DMA speed:   %d MB/S\n",
8036            isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
8037        ASC_PRT_NEXT();
8038    }
8039#endif /* CONFIG_ISA */
8040
8041     return totlen;
8042}
8043
8044/*
8045 * asc_prt_adv_board_eeprom()
8046 *
8047 * Print board EEPROM configuration.
8048 *
8049 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8050 * cf. asc_prt_line().
8051 *
8052 * Return the number of characters copied into 'cp'. No more than
8053 * 'cplen' characters will be copied to 'cp'.
8054 */
8055STATIC int
8056asc_prt_adv_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
8057{
8058    asc_board_t                 *boardp;
8059    ADV_DVC_VAR                 *adv_dvc_varp;
8060    int                         leftlen;
8061    int                         totlen;
8062    int                         len;
8063    int                         i;
8064    char                        *termstr;
8065    uchar                       serialstr[13];
8066    ADVEEP_3550_CONFIG          *ep_3550 = NULL;
8067    ADVEEP_38C0800_CONFIG       *ep_38C0800 = NULL;
8068    ADVEEP_38C1600_CONFIG       *ep_38C1600 = NULL;
8069    ushort                      word;
8070    ushort                      *wordp;
8071    ushort                      sdtr_speed = 0;
8072
8073    boardp = ASC_BOARDP(shp);
8074    adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
8075    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8076    {
8077        ep_3550 = &boardp->eep_config.adv_3550_eep;
8078    } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8079    {
8080        ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
8081    } else
8082    {
8083        ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
8084    }
8085
8086    leftlen = cplen;
8087    totlen = len = 0;
8088
8089    len = asc_prt_line(cp, leftlen,
8090"\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
8091    ASC_PRT_NEXT();
8092
8093    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8094    {
8095        wordp = &ep_3550->serial_number_word1;
8096    } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8097    {
8098        wordp = &ep_38C0800->serial_number_word1;
8099    } else
8100    {
8101        wordp = &ep_38C1600->serial_number_word1;
8102    }
8103
8104    if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
8105        len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
8106        ASC_PRT_NEXT();
8107    } else {
8108        len = asc_prt_line(cp, leftlen,
8109            " Serial Number Signature Not Present.\n");
8110        ASC_PRT_NEXT();
8111    }
8112
8113    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8114    {
8115        len = asc_prt_line(cp, leftlen,
8116" Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
8117            ep_3550->adapter_scsi_id, ep_3550->max_host_qng,
8118            ep_3550->max_dvc_qng);
8119        ASC_PRT_NEXT();
8120    } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8121    {
8122        len = asc_prt_line(cp, leftlen,
8123" Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
8124            ep_38C0800->adapter_scsi_id, ep_38C0800->max_host_qng,
8125            ep_38C0800->max_dvc_qng);
8126        ASC_PRT_NEXT();
8127    } else
8128    {
8129        len = asc_prt_line(cp, leftlen,
8130" Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
8131            ep_38C1600->adapter_scsi_id, ep_38C1600->max_host_qng,
8132            ep_38C1600->max_dvc_qng);
8133        ASC_PRT_NEXT();
8134    }
8135    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8136    {
8137        word = ep_3550->termination;
8138    } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8139    {
8140        word = ep_38C0800->termination_lvd;
8141    } else
8142    {
8143        word = ep_38C1600->termination_lvd;
8144    }
8145    switch (word) {
8146        case 1:
8147            termstr = "Low Off/High Off";
8148            break;
8149        case 2:
8150            termstr = "Low Off/High On";
8151            break;
8152        case 3:
8153            termstr = "Low On/High On";
8154            break;
8155        default:
8156        case 0:
8157            termstr = "Automatic";
8158            break;
8159    }
8160
8161    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8162    {
8163        len = asc_prt_line(cp, leftlen,
8164" termination: %u (%s), bios_ctrl: 0x%x\n",
8165            ep_3550->termination, termstr, ep_3550->bios_ctrl);
8166        ASC_PRT_NEXT();
8167    } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8168    {
8169        len = asc_prt_line(cp, leftlen,
8170" termination: %u (%s), bios_ctrl: 0x%x\n",
8171            ep_38C0800->termination_lvd, termstr, ep_38C0800->bios_ctrl);
8172        ASC_PRT_NEXT();
8173    } else
8174    {
8175        len = asc_prt_line(cp, leftlen,
8176" termination: %u (%s), bios_ctrl: 0x%x\n",
8177            ep_38C1600->termination_lvd, termstr, ep_38C1600->bios_ctrl);
8178        ASC_PRT_NEXT();
8179    }
8180
8181    len = asc_prt_line(cp, leftlen,
8182" Target ID:           ");
8183    ASC_PRT_NEXT();
8184    for (i = 0; i <= ADV_MAX_TID; i++) {
8185        len = asc_prt_line(cp, leftlen, " %X", i);
8186        ASC_PRT_NEXT();
8187    }
8188    len = asc_prt_line(cp, leftlen, "\n");
8189    ASC_PRT_NEXT();
8190
8191    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8192    {
8193        word = ep_3550->disc_enable;
8194    } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8195    {
8196        word = ep_38C0800->disc_enable;
8197    } else
8198    {
8199        word = ep_38C1600->disc_enable;
8200    }
8201    len = asc_prt_line(cp, leftlen,
8202" Disconnects:         ");
8203    ASC_PRT_NEXT();
8204    for (i = 0; i <= ADV_MAX_TID; i++) {
8205        len = asc_prt_line(cp, leftlen, " %c",
8206            (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8207        ASC_PRT_NEXT();
8208    }
8209    len = asc_prt_line(cp, leftlen, "\n");
8210    ASC_PRT_NEXT();
8211
8212    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8213    {
8214        word = ep_3550->tagqng_able;
8215    } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8216    {
8217        word = ep_38C0800->tagqng_able;
8218    } else
8219    {
8220        word = ep_38C1600->tagqng_able;
8221    }
8222    len = asc_prt_line(cp, leftlen,
8223" Command Queuing:     ");
8224    ASC_PRT_NEXT();
8225    for (i = 0; i <= ADV_MAX_TID; i++) {
8226        len = asc_prt_line(cp, leftlen, " %c",
8227            (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8228        ASC_PRT_NEXT();
8229    }
8230    len = asc_prt_line(cp, leftlen, "\n");
8231    ASC_PRT_NEXT();
8232
8233    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8234    {
8235        word = ep_3550->start_motor;
8236    } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8237    {
8238        word = ep_38C0800->start_motor;
8239    } else
8240    {
8241        word = ep_38C1600->start_motor;
8242    }
8243    len = asc_prt_line(cp, leftlen,
8244" Start Motor:         ");
8245    ASC_PRT_NEXT();
8246    for (i = 0; i <= ADV_MAX_TID; i++) {
8247        len = asc_prt_line(cp, leftlen, " %c",
8248            (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8249        ASC_PRT_NEXT();
8250    }
8251    len = asc_prt_line(cp, leftlen, "\n");
8252    ASC_PRT_NEXT();
8253
8254    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8255    {
8256        len = asc_prt_line(cp, leftlen,
8257" Synchronous Transfer:");
8258        ASC_PRT_NEXT();
8259        for (i = 0; i <= ADV_MAX_TID; i++) {
8260            len = asc_prt_line(cp, leftlen, " %c",
8261                (ep_3550->sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8262            ASC_PRT_NEXT();
8263        }
8264        len = asc_prt_line(cp, leftlen, "\n");
8265        ASC_PRT_NEXT();
8266    }
8267
8268    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8269    {
8270        len = asc_prt_line(cp, leftlen,
8271" Ultra Transfer:      ");
8272    ASC_PRT_NEXT();
8273        for (i = 0; i <= ADV_MAX_TID; i++) {
8274            len = asc_prt_line(cp, leftlen, " %c",
8275                (ep_3550->ultra_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8276            ASC_PRT_NEXT();
8277        }
8278        len = asc_prt_line(cp, leftlen, "\n");
8279        ASC_PRT_NEXT();
8280    }
8281
8282    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8283    {
8284        word = ep_3550->wdtr_able;
8285    } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8286    {
8287        word = ep_38C0800->wdtr_able;
8288    } else
8289    {
8290        word = ep_38C1600->wdtr_able;
8291    }
8292    len = asc_prt_line(cp, leftlen,
8293" Wide Transfer:       ");
8294    ASC_PRT_NEXT();
8295    for (i = 0; i <= ADV_MAX_TID; i++) {
8296        len = asc_prt_line(cp, leftlen, " %c",
8297            (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8298        ASC_PRT_NEXT();
8299    }
8300    len = asc_prt_line(cp, leftlen, "\n");
8301    ASC_PRT_NEXT();
8302
8303    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
8304        adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600)
8305    {
8306        len = asc_prt_line(cp, leftlen,
8307" Synchronous Transfer Speed (Mhz):\n  ");
8308        ASC_PRT_NEXT();
8309        for (i = 0; i <= ADV_MAX_TID; i++) {
8310            char *speed_str;
8311
8312            if (i == 0)
8313            {
8314                sdtr_speed = adv_dvc_varp->sdtr_speed1;
8315            } else if (i == 4)
8316            {
8317                sdtr_speed = adv_dvc_varp->sdtr_speed2;
8318            } else if (i == 8)
8319            {
8320                sdtr_speed = adv_dvc_varp->sdtr_speed3;
8321            } else if (i == 12)
8322            {
8323                sdtr_speed = adv_dvc_varp->sdtr_speed4;
8324            }
8325            switch (sdtr_speed & ADV_MAX_TID)
8326            {
8327                case 0:  speed_str = "Off"; break;
8328                case 1:  speed_str = "  5"; break;
8329                case 2:  speed_str = " 10"; break;
8330                case 3:  speed_str = " 20"; break;
8331                case 4:  speed_str = " 40"; break;
8332                case 5:  speed_str = " 80"; break;
8333                default: speed_str = "Unk"; break;
8334            }
8335            len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
8336            ASC_PRT_NEXT();
8337            if (i == 7)
8338            {
8339                len = asc_prt_line(cp, leftlen, "\n  ");
8340                ASC_PRT_NEXT();
8341            }
8342            sdtr_speed >>= 4;
8343        }
8344        len = asc_prt_line(cp, leftlen, "\n");
8345        ASC_PRT_NEXT();
8346    }
8347
8348    return totlen;
8349}
8350
8351/*
8352 * asc_prt_driver_conf()
8353 *
8354 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8355 * cf. asc_prt_line().
8356 *
8357 * Return the number of characters copied into 'cp'. No more than
8358 * 'cplen' characters will be copied to 'cp'.
8359 */
8360STATIC int
8361asc_prt_driver_conf(struct Scsi_Host *shp, char *cp, int cplen)
8362{
8363    asc_board_t            *boardp;
8364    int                    leftlen;
8365    int                    totlen;
8366    int                    len;
8367    int                    chip_scsi_id;
8368
8369    boardp = ASC_BOARDP(shp);
8370
8371    leftlen = cplen;
8372    totlen = len = 0;
8373
8374    len = asc_prt_line(cp, leftlen,
8375"\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
8376        shp->host_no);
8377    ASC_PRT_NEXT();
8378
8379    len = asc_prt_line(cp, leftlen,
8380" host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
8381        shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun,
8382        shp->max_channel);
8383    ASC_PRT_NEXT();
8384
8385    len = asc_prt_line(cp, leftlen,
8386" unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
8387        shp->unique_id, shp->can_queue, shp->this_id, shp->sg_tablesize,
8388        shp->cmd_per_lun);
8389    ASC_PRT_NEXT();
8390
8391    len = asc_prt_line(cp, leftlen,
8392" unchecked_isa_dma %d, use_clustering %d\n",
8393        shp->unchecked_isa_dma, shp->use_clustering);
8394    ASC_PRT_NEXT();
8395
8396    len = asc_prt_line(cp, leftlen,
8397" flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
8398        boardp->flags, boardp->last_reset, jiffies, boardp->asc_n_io_port);
8399    ASC_PRT_NEXT();
8400
8401     /* 'shp->n_io_port' may be truncated because it is only one byte. */
8402    len = asc_prt_line(cp, leftlen,
8403" io_port 0x%x, n_io_port 0x%x\n",
8404        shp->io_port, shp->n_io_port);
8405    ASC_PRT_NEXT();
8406
8407    if (ASC_NARROW_BOARD(boardp)) {
8408        chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
8409    } else {
8410        chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
8411    }
8412
8413    return totlen;
8414}
8415
8416/*
8417 * asc_prt_asc_board_info()
8418 *
8419 * Print dynamic board configuration information.
8420 *
8421 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8422 * cf. asc_prt_line().
8423 *
8424 * Return the number of characters copied into 'cp'. No more than
8425 * 'cplen' characters will be copied to 'cp'.
8426 */
8427STATIC int
8428asc_prt_asc_board_info(struct Scsi_Host *shp, char *cp, int cplen)
8429{
8430    asc_board_t            *boardp;
8431    int                    chip_scsi_id;
8432    int                    leftlen;
8433    int                    totlen;
8434    int                    len;
8435    ASC_DVC_VAR            *v;
8436    ASC_DVC_CFG            *c;
8437    int                    i;
8438    int                    renegotiate = 0;
8439
8440    boardp = ASC_BOARDP(shp);
8441    v = &boardp->dvc_var.asc_dvc_var;
8442    c = &boardp->dvc_cfg.asc_dvc_cfg;
8443    chip_scsi_id = c->chip_scsi_id;
8444
8445    leftlen = cplen;
8446    totlen = len = 0;
8447
8448    len = asc_prt_line(cp, leftlen,
8449"\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
8450    shp->host_no);
8451    ASC_PRT_NEXT();
8452
8453    len = asc_prt_line(cp, leftlen,
8454" chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
8455        c->chip_version, c->lib_version, c->lib_serial_no, c->mcode_date);
8456    ASC_PRT_NEXT();
8457
8458    len = asc_prt_line(cp, leftlen,
8459" mcode_version 0x%x, err_code %u\n",
8460         c->mcode_version, v->err_code);
8461    ASC_PRT_NEXT();
8462
8463    /* Current number of commands waiting for the host. */
8464    len = asc_prt_line(cp, leftlen,
8465" Total Command Pending: %d\n", v->cur_total_qng);
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        if ((chip_scsi_id == i) ||
8473            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8474            continue;
8475        }
8476        len = asc_prt_line(cp, leftlen, " %X:%c",
8477            i, (v->use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8478        ASC_PRT_NEXT();
8479    }
8480    len = asc_prt_line(cp, leftlen, "\n");
8481    ASC_PRT_NEXT();
8482
8483    /* Current number of commands waiting for a device. */
8484    len = asc_prt_line(cp, leftlen,
8485" Command Queue Pending:");
8486    ASC_PRT_NEXT();
8487    for (i = 0; i <= ASC_MAX_TID; i++) {
8488        if ((chip_scsi_id == i) ||
8489            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8490            continue;
8491        }
8492        len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
8493        ASC_PRT_NEXT();
8494    }
8495    len = asc_prt_line(cp, leftlen, "\n");
8496    ASC_PRT_NEXT();
8497
8498    /* Current limit on number of commands that can be sent to a device. */
8499    len = asc_prt_line(cp, leftlen,
8500" Command Queue Limit:");
8501    ASC_PRT_NEXT();
8502    for (i = 0; i <= ASC_MAX_TID; i++) {
8503        if ((chip_scsi_id == i) ||
8504            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8505            continue;
8506        }
8507        len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
8508        ASC_PRT_NEXT();
8509    }
8510    len = asc_prt_line(cp, leftlen, "\n");
8511    ASC_PRT_NEXT();
8512
8513    /* Indicate whether the device has returned queue full status. */
8514    len = asc_prt_line(cp, leftlen,
8515" Command Queue Full:");
8516    ASC_PRT_NEXT();
8517    for (i = 0; i <= ASC_MAX_TID; i++) {
8518        if ((chip_scsi_id == i) ||
8519            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8520            continue;
8521        }
8522        if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
8523            len = asc_prt_line(cp, leftlen, " %X:Y-%d",
8524                i, boardp->queue_full_cnt[i]);
8525        } else {
8526            len = asc_prt_line(cp, leftlen, " %X:N", i);
8527        }
8528        ASC_PRT_NEXT();
8529    }
8530    len = asc_prt_line(cp, leftlen, "\n");
8531    ASC_PRT_NEXT();
8532
8533    len = asc_prt_line(cp, leftlen,
8534" Synchronous Transfer:");
8535    ASC_PRT_NEXT();
8536    for (i = 0; i <= ASC_MAX_TID; i++) {
8537        if ((chip_scsi_id == i) ||
8538            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8539            continue;
8540        }
8541        len = asc_prt_line(cp, leftlen, " %X:%c",
8542            i, (v->sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8543        ASC_PRT_NEXT();
8544    }
8545    len = asc_prt_line(cp, leftlen, "\n");
8546    ASC_PRT_NEXT();
8547
8548    for (i = 0; i <= ASC_MAX_TID; i++) {
8549        uchar syn_period_ix;
8550
8551        if ((chip_scsi_id == i) ||
8552            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
8553            ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
8554            continue;
8555        }
8556
8557        len = asc_prt_line(cp, leftlen, "  %X:", i);
8558        ASC_PRT_NEXT();
8559
8560        if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0)
8561        {
8562            len = asc_prt_line(cp, leftlen, " Asynchronous");
8563            ASC_PRT_NEXT();
8564        } else
8565        {
8566            syn_period_ix =
8567                (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index - 1);
8568
8569            len = asc_prt_line(cp, leftlen,
8570                " Transfer Period Factor: %d (%d.%d Mhz),",
8571                v->sdtr_period_tbl[syn_period_ix],
8572                250 / v->sdtr_period_tbl[syn_period_ix],
8573                ASC_TENTHS(250, v->sdtr_period_tbl[syn_period_ix]));
8574            ASC_PRT_NEXT();
8575
8576            len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
8577                boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET);
8578            ASC_PRT_NEXT();
8579        }
8580
8581        if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8582            len = asc_prt_line(cp, leftlen, "*\n");
8583            renegotiate = 1;
8584        } else
8585        {
8586            len = asc_prt_line(cp, leftlen, "\n");
8587        }
8588        ASC_PRT_NEXT();
8589    }
8590
8591    if (renegotiate)
8592    {
8593        len = asc_prt_line(cp, leftlen,
8594            " * = Re-negotiation pending before next command.\n");
8595        ASC_PRT_NEXT();
8596    }
8597
8598    return totlen;
8599}
8600
8601/*
8602 * asc_prt_adv_board_info()
8603 *
8604 * Print dynamic board configuration information.
8605 *
8606 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8607 * cf. asc_prt_line().
8608 *
8609 * Return the number of characters copied into 'cp'. No more than
8610 * 'cplen' characters will be copied to 'cp'.
8611 */
8612STATIC int
8613asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen)
8614{
8615    asc_board_t            *boardp;
8616    int                    leftlen;
8617    int                    totlen;
8618    int                    len;
8619    int                    i;
8620    ADV_DVC_VAR            *v;
8621    ADV_DVC_CFG            *c;
8622    AdvPortAddr            iop_base;
8623    ushort                 chip_scsi_id;
8624    ushort                 lramword;
8625    uchar                  lrambyte;
8626    ushort                 tagqng_able;
8627    ushort                 sdtr_able, wdtr_able;
8628    ushort                 wdtr_done, sdtr_done;
8629    ushort                 period = 0;
8630    int                    renegotiate = 0;
8631
8632    boardp = ASC_BOARDP(shp);
8633    v = &boardp->dvc_var.adv_dvc_var;
8634    c = &boardp->dvc_cfg.adv_dvc_cfg;
8635    iop_base = v->iop_base;
8636    chip_scsi_id = v->chip_scsi_id;
8637
8638    leftlen = cplen;
8639    totlen = len = 0;
8640
8641    len = asc_prt_line(cp, leftlen,
8642"\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
8643    shp->host_no);
8644    ASC_PRT_NEXT();
8645
8646    len = asc_prt_line(cp, leftlen,
8647" iop_base 0x%lx, cable_detect: %X, err_code %u\n",
8648         v->iop_base,
8649         AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1) & CABLE_DETECT,
8650         v->err_code);
8651    ASC_PRT_NEXT();
8652
8653    len = asc_prt_line(cp, leftlen,
8654" chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
8655        c->chip_version, c->lib_version, c->mcode_date, c->mcode_version);
8656    ASC_PRT_NEXT();
8657
8658    AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
8659    len = asc_prt_line(cp, leftlen,
8660" Queuing Enabled:");
8661    ASC_PRT_NEXT();
8662    for (i = 0; i <= ADV_MAX_TID; i++) {
8663        if ((chip_scsi_id == i) ||
8664            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8665            continue;
8666        }
8667
8668        len = asc_prt_line(cp, leftlen, " %X:%c",
8669            i, (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8670        ASC_PRT_NEXT();
8671    }
8672    len = asc_prt_line(cp, leftlen, "\n");
8673    ASC_PRT_NEXT();
8674
8675    len = asc_prt_line(cp, leftlen,
8676" Queue Limit:");
8677    ASC_PRT_NEXT();
8678    for (i = 0; i <= ADV_MAX_TID; i++) {
8679        if ((chip_scsi_id == i) ||
8680            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8681            continue;
8682        }
8683
8684        AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i, lrambyte);
8685
8686        len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
8687        ASC_PRT_NEXT();
8688    }
8689    len = asc_prt_line(cp, leftlen, "\n");
8690    ASC_PRT_NEXT();
8691
8692    len = asc_prt_line(cp, leftlen,
8693" Command Pending:");
8694    ASC_PRT_NEXT();
8695    for (i = 0; i <= ADV_MAX_TID; i++) {
8696        if ((chip_scsi_id == i) ||
8697            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8698            continue;
8699        }
8700
8701        AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i, lrambyte);
8702
8703        len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
8704        ASC_PRT_NEXT();
8705    }
8706    len = asc_prt_line(cp, leftlen, "\n");
8707    ASC_PRT_NEXT();
8708
8709    AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8710    len = asc_prt_line(cp, leftlen,
8711" Wide Enabled:");
8712    ASC_PRT_NEXT();
8713    for (i = 0; i <= ADV_MAX_TID; i++) {
8714        if ((chip_scsi_id == i) ||
8715            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8716            continue;
8717        }
8718
8719        len = asc_prt_line(cp, leftlen, " %X:%c",
8720            i, (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8721        ASC_PRT_NEXT();
8722    }
8723    len = asc_prt_line(cp, leftlen, "\n");
8724    ASC_PRT_NEXT();
8725
8726    AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
8727    len = asc_prt_line(cp, leftlen,
8728" Transfer Bit Width:");
8729    ASC_PRT_NEXT();
8730    for (i = 0; i <= ADV_MAX_TID; i++) {
8731        if ((chip_scsi_id == i) ||
8732            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8733            continue;
8734        }
8735
8736        AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
8737            lramword);
8738
8739        len = asc_prt_line(cp, leftlen, " %X:%d",
8740            i, (lramword & 0x8000) ? 16 : 8);
8741        ASC_PRT_NEXT();
8742
8743        if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
8744            (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8745            len = asc_prt_line(cp, leftlen, "*");
8746            ASC_PRT_NEXT();
8747            renegotiate = 1;
8748        }
8749    }
8750    len = asc_prt_line(cp, leftlen, "\n");
8751    ASC_PRT_NEXT();
8752
8753    AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8754    len = asc_prt_line(cp, leftlen,
8755" Synchronous Enabled:");
8756    ASC_PRT_NEXT();
8757    for (i = 0; i <= ADV_MAX_TID; i++) {
8758        if ((chip_scsi_id == i) ||
8759            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8760            continue;
8761        }
8762
8763        len = asc_prt_line(cp, leftlen, " %X:%c",
8764            i, (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8765        ASC_PRT_NEXT();
8766    }
8767    len = asc_prt_line(cp, leftlen, "\n");
8768    ASC_PRT_NEXT();
8769
8770    AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
8771    for (i = 0; i <= ADV_MAX_TID; i++) {
8772
8773        AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
8774            lramword);
8775        lramword &= ~0x8000;
8776
8777        if ((chip_scsi_id == i) ||
8778            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
8779            ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
8780            continue;
8781        }
8782
8783        len = asc_prt_line(cp, leftlen, "  %X:", i);
8784        ASC_PRT_NEXT();
8785
8786        if ((lramword & 0x1F) == 0) /* Check for REQ/ACK Offset 0. */
8787        {
8788            len = asc_prt_line(cp, leftlen, " Asynchronous");
8789            ASC_PRT_NEXT();
8790        } else
8791        {
8792            len = asc_prt_line(cp, leftlen, " Transfer Period Factor: ");
8793            ASC_PRT_NEXT();
8794
8795            if ((lramword & 0x1F00) == 0x1100) /* 80 Mhz */
8796            {
8797                len = asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
8798                ASC_PRT_NEXT();
8799            } else if ((lramword & 0x1F00) == 0x1000) /* 40 Mhz */
8800            {
8801                len = asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
8802                ASC_PRT_NEXT();
8803            } else /* 20 Mhz or below. */
8804            {
8805                period = (((lramword >> 8) * 25) + 50)/4;
8806
8807                if (period == 0) /* Should never happen. */
8808                {
8809                    len = asc_prt_line(cp, leftlen, "%d (? Mhz), ");
8810                    ASC_PRT_NEXT();
8811                } else
8812                {
8813                    len = asc_prt_line(cp, leftlen,
8814                        "%d (%d.%d Mhz),",
8815                        period, 250/period, ASC_TENTHS(250, period));
8816                    ASC_PRT_NEXT();
8817                }
8818            }
8819
8820            len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
8821                lramword & 0x1F);
8822            ASC_PRT_NEXT();
8823        }
8824
8825        if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8826            len = asc_prt_line(cp, leftlen, "*\n");
8827            renegotiate = 1;
8828        } else
8829        {
8830            len = asc_prt_line(cp, leftlen, "\n");
8831        }
8832        ASC_PRT_NEXT();
8833    }
8834
8835    if (renegotiate)
8836    {
8837        len = asc_prt_line(cp, leftlen,
8838            " * = Re-negotiation pending before next command.\n");
8839        ASC_PRT_NEXT();
8840    }
8841
8842    return totlen;
8843}
8844
8845/*
8846 * asc_proc_copy()
8847 *
8848 * Copy proc information to a read buffer taking into account the current
8849 * read offset in the file and the remaining space in the read buffer.
8850 */
8851STATIC int
8852asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
8853              char *cp, int cplen)
8854{
8855    int cnt = 0;
8856
8857    ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
8858            (unsigned) offset, (unsigned) advoffset, cplen);
8859    if (offset <= advoffset) {
8860        /* Read offset below current offset, copy everything. */
8861        cnt = ASC_MIN(cplen, leftlen);
8862        ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
8863                (ulong) curbuf, (ulong) cp, cnt);
8864        memcpy(curbuf, cp, cnt);
8865    } else if (offset < advoffset + cplen) {
8866        /* Read offset within current range, partial copy. */
8867        cnt = (advoffset + cplen) - offset;
8868        cp = (cp + cplen) - cnt;
8869        cnt = ASC_MIN(cnt, leftlen);
8870        ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
8871                (ulong) curbuf, (ulong) cp, cnt);
8872        memcpy(curbuf, cp, cnt);
8873    }
8874    return cnt;
8875}
8876
8877/*
8878 * asc_prt_line()
8879 *
8880 * If 'cp' is NULL print to the console, otherwise print to a buffer.
8881 *
8882 * Return 0 if printing to the console, otherwise return the number of
8883 * bytes written to the buffer.
8884 *
8885 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
8886 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
8887 */
8888STATIC int
8889asc_prt_line(char *buf, int buflen, char *fmt, ...)
8890{
8891    va_list        args;
8892    int            ret;
8893    char           s[ASC_PRTLINE_SIZE];
8894
8895    va_start(args, fmt);
8896    ret = vsprintf(s, fmt, args);
8897    ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
8898    if (buf == NULL) {
8899        (void) printk(s);
8900        ret = 0;
8901    } else {
8902        ret = ASC_MIN(buflen, ret);
8903        memcpy(buf, s, ret);
8904    }
8905    va_end(args);
8906    return ret;
8907}
8908#endif /* CONFIG_PROC_FS */
8909
8910
8911/*
8912 * --- Functions Required by the Asc Library
8913 */
8914
8915/*
8916 * Delay for 'n' milliseconds. Don't use the 'jiffies'
8917 * global variable which is incremented once every 5 ms
8918 * from a timer interrupt, because this function may be
8919 * called when interrupts are disabled.
8920 */
8921STATIC void
8922DvcSleepMilliSecond(ADV_DCNT n)
8923{
8924    ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong) n);
8925    mdelay(n);
8926}
8927
8928/*
8929 * Currently and inline noop but leave as a placeholder.
8930 * Leave DvcEnterCritical() as a noop placeholder.
8931 */
8932STATIC inline ulong
8933DvcEnterCritical(void)
8934{
8935    return 0;
8936}
8937
8938/*
8939 * Critical sections are all protected by the board spinlock.
8940 * Leave DvcLeaveCritical() as a noop placeholder.
8941 */
8942STATIC inline void
8943DvcLeaveCritical(ulong flags)
8944{
8945    return;
8946}
8947
8948/*
8949 * void
8950 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
8951 *
8952 * Calling/Exit State:
8953 *    none
8954 *
8955 * Description:
8956 *     Output an ASC_SCSI_Q structure to the chip
8957 */
8958STATIC void
8959DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
8960{
8961    int    i;
8962
8963    ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
8964    AscSetChipLramAddr(iop_base, s_addr);
8965    for (i = 0; i < 2 * words; i += 2) {
8966        if (i == 4 || i == 20) {
8967            continue;
8968        }
8969        outpw(iop_base + IOP_RAM_DATA,
8970            ((ushort) outbuf[i + 1] << 8) | outbuf[i]);
8971    }
8972}
8973
8974/*
8975 * void
8976 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
8977 *
8978 * Calling/Exit State:
8979 *    none
8980 *
8981 * Description:
8982 *     Input an ASC_QDONE_INFO structure from the chip
8983 */
8984STATIC void
8985DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
8986{
8987    int    i;
8988    ushort word;
8989
8990    AscSetChipLramAddr(iop_base, s_addr);
8991    for (i = 0; i < 2 * words; i += 2) {
8992        if (i == 10) {
8993            continue;
8994        }
8995        word = inpw(iop_base + IOP_RAM_DATA);
8996        inbuf[i] = word & 0xff;
8997        inbuf[i + 1] = (word >> 8) & 0xff;
8998    }
8999    ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
9000}
9001
9002/*
9003 * Read a PCI configuration byte.
9004 */
9005ASC_INITFUNC(
9006STATIC uchar,
9007DvcReadPCIConfigByte(
9008        ASC_DVC_VAR *asc_dvc,
9009        ushort offset)
9010)
9011{
9012#ifdef CONFIG_PCI
9013    uchar byte_data;
9014    pci_read_config_byte(asc_dvc->cfg->pci_dev, offset, &byte_data);
9015    return byte_data;
9016#else /* !defined(CONFIG_PCI) */
9017    return 0;
9018#endif /* !defined(CONFIG_PCI) */
9019}
9020
9021/*
9022 * Write a PCI configuration byte.
9023 */
9024ASC_INITFUNC(
9025STATIC void,
9026DvcWritePCIConfigByte(
9027        ASC_DVC_VAR *asc_dvc,
9028        ushort offset,
9029        uchar  byte_data)
9030)
9031{
9032#ifdef CONFIG_PCI
9033    pci_write_config_byte(asc_dvc->cfg->pci_dev, offset, byte_data);
9034#endif /* CONFIG_PCI */
9035}
9036
9037/*
9038 * Return the BIOS address of the adapter at the specified
9039 * I/O port and with the specified bus type.
9040 */
9041ASC_INITFUNC(
9042STATIC ushort,
9043AscGetChipBiosAddress(
9044        PortAddr iop_base,
9045        ushort bus_type
9046)
9047)
9048{
9049    ushort  cfg_lsw;
9050    ushort  bios_addr;
9051
9052    /*
9053     * The PCI BIOS is re-located by the motherboard BIOS. Because
9054     * of this the driver can not determine where a PCI BIOS is
9055     * loaded and executes.
9056     */
9057    if (bus_type & ASC_IS_PCI)
9058    {
9059        return(0);
9060    }
9061
9062#ifdef CONFIG_ISA
9063    if((bus_type & ASC_IS_EISA) != 0)
9064    {
9065        cfg_lsw = AscGetEisaChipCfg(iop_base);
9066        cfg_lsw &= 0x000F;
9067        bios_addr = (ushort)(ASC_BIOS_MIN_ADDR  +
9068                                (cfg_lsw * ASC_BIOS_BANK_SIZE));
9069        return(bios_addr);
9070    }/* if */
9071#endif /* CONFIG_ISA */
9072
9073    cfg_lsw = AscGetChipCfgLsw(iop_base);
9074
9075    /*
9076    *  ISA PnP uses the top bit as the 32K BIOS flag
9077    */
9078    if (bus_type == ASC_IS_ISAPNP)
9079    {
9080        cfg_lsw &= 0x7FFF;
9081    }/* if */
9082
9083    bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) +
9084            ASC_BIOS_MIN_ADDR);
9085    return(bios_addr);
9086}
9087
9088
9089/*
9090 * --- Functions Required by the Adv Library
9091 */
9092
9093/*
9094 * DvcGetPhyAddr()
9095 *
9096 * Return the physical address of 'vaddr' and set '*lenp' to the
9097 * number of physically contiguous bytes that follow 'vaddr'.
9098 * 'flag' indicates the type of structure whose physical address
9099 * is being translated.
9100 *
9101 * Note: Because Linux currently doesn't page the kernel and all
9102 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
9103 */
9104ADV_PADDR
9105DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
9106        uchar *vaddr, ADV_SDCNT *lenp, int flag)
9107{
9108    ADV_PADDR           paddr;
9109
9110    paddr = virt_to_bus(vaddr);
9111
9112    ASC_DBG4(4,
9113        "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
9114        (ulong) vaddr, (ulong) lenp, (ulong) *((ulong *) lenp), (ulong) paddr);
9115
9116    return paddr;
9117}
9118
9119/*
9120 * Read a PCI configuration byte.
9121 */
9122ASC_INITFUNC(
9123STATIC uchar,
9124DvcAdvReadPCIConfigByte(
9125        ADV_DVC_VAR *asc_dvc,
9126        ushort offset)
9127)
9128{
9129#ifdef CONFIG_PCI
9130    uchar byte_data;
9131    pci_read_config_byte(asc_dvc->cfg->pci_dev, offset, &byte_data);
9132    return byte_data;
9133#else /* CONFIG_PCI */
9134    return 0;
9135#endif /* CONFIG_PCI */
9136}
9137
9138/*
9139 * Write a PCI configuration byte.
9140 */
9141ASC_INITFUNC(
9142STATIC void,
9143DvcAdvWritePCIConfigByte(
9144        ADV_DVC_VAR *asc_dvc,
9145        ushort offset,
9146        uchar  byte_data)
9147)
9148{
9149#ifdef CONFIG_PCI
9150    pci_write_config_byte(asc_dvc->cfg->pci_dev, offset, byte_data);
9151#else /* CONFIG_PCI */
9152    return 0;
9153#endif /* CONFIG_PCI */
9154}
9155
9156/*
9157 * --- Tracing and Debugging Functions
9158 */
9159
9160#ifdef ADVANSYS_STATS
9161#ifdef CONFIG_PROC_FS
9162/*
9163 * asc_prt_board_stats()
9164 *
9165 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
9166 * cf. asc_prt_line().
9167 *
9168 * Return the number of characters copied into 'cp'. No more than
9169 * 'cplen' characters will be copied to 'cp'.
9170 */
9171STATIC int
9172asc_prt_board_stats(struct Scsi_Host *shp, char *cp, int cplen)
9173{
9174    int                    leftlen;
9175    int                    totlen;
9176    int                    len;
9177    struct asc_stats       *s;
9178    asc_board_t            *boardp;
9179
9180    leftlen = cplen;
9181    totlen = len = 0;
9182
9183    boardp = ASC_BOARDP(shp);
9184    s = &boardp->asc_stats;
9185
9186    len = asc_prt_line(cp, leftlen,
9187"\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", shp->host_no);
9188    ASC_PRT_NEXT();
9189
9190    len = asc_prt_line(cp, leftlen,
9191" queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
9192        s->queuecommand, s->reset, s->biosparam, s->interrupt);
9193    ASC_PRT_NEXT();
9194
9195    len = asc_prt_line(cp, leftlen,
9196" callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
9197        s->callback, s->done, s->build_error, s->adv_build_noreq,
9198        s->adv_build_nosg);
9199    ASC_PRT_NEXT();
9200
9201    len = asc_prt_line(cp, leftlen,
9202" exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
9203        s->exe_noerror, s->exe_busy, s->exe_error, s->exe_unknown);
9204    ASC_PRT_NEXT();
9205
9206    /*
9207     * Display data transfer statistics.
9208     */
9209    if (s->cont_cnt > 0) {
9210        len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
9211        ASC_PRT_NEXT();
9212
9213        len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
9214                    s->cont_xfer/2,
9215                    ASC_TENTHS(s->cont_xfer, 2));
9216        ASC_PRT_NEXT();
9217
9218        /* Contiguous transfer average size */
9219        len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
9220                    (s->cont_xfer/2)/s->cont_cnt,
9221                    ASC_TENTHS((s->cont_xfer/2), s->cont_cnt));
9222        ASC_PRT_NEXT();
9223    }
9224
9225    if (s->sg_cnt > 0) {
9226
9227        len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
9228                    s->sg_cnt, s->sg_elem);
9229        ASC_PRT_NEXT();
9230
9231        len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
9232                    s->sg_xfer/2,
9233                    ASC_TENTHS(s->sg_xfer, 2));
9234        ASC_PRT_NEXT();
9235
9236        /* Scatter gather transfer statistics */
9237        len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
9238                    s->sg_elem/s->sg_cnt,
9239                    ASC_TENTHS(s->sg_elem, s->sg_cnt));
9240        ASC_PRT_NEXT();
9241
9242        len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
9243                    (s->sg_xfer/2)/s->sg_elem,
9244                    ASC_TENTHS((s->sg_xfer/2), s->sg_elem));
9245        ASC_PRT_NEXT();
9246
9247        len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
9248                    (s->sg_xfer/2)/s->sg_cnt,
9249                    ASC_TENTHS((s->sg_xfer/2), s->sg_cnt));
9250        ASC_PRT_NEXT();
9251    }
9252
9253    /*
9254     * Display request queuing statistics.
9255     */
9256    len = asc_prt_line(cp, leftlen,
9257" Active and Waiting Request Queues (Time Unit: %d HZ):\n", HZ);
9258    ASC_PRT_NEXT();
9259
9260
9261     return totlen;
9262}
9263
9264/*
9265 * asc_prt_target_stats()
9266 *
9267 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
9268 * cf. asc_prt_line().
9269 *
9270 * This is separated from asc_prt_board_stats because a full set
9271 * of targets will overflow ASC_PRTBUF_SIZE.
9272 *
9273 * Return the number of characters copied into 'cp'. No more than
9274 * 'cplen' characters will be copied to 'cp'.
9275 */
9276STATIC int
9277asc_prt_target_stats(struct Scsi_Host *shp, int tgt_id, char *cp, int cplen)
9278{
9279    int                    leftlen;
9280    int                    totlen;
9281    int                    len;
9282    struct asc_stats       *s;
9283    ushort                 chip_scsi_id;
9284    asc_board_t            *boardp;
9285    asc_queue_t            *active;
9286    asc_queue_t            *waiting;
9287
9288    leftlen = cplen;
9289    totlen = len = 0;
9290
9291    boardp = ASC_BOARDP(shp);
9292    s = &boardp->asc_stats;
9293
9294    active = &ASC_BOARDP(shp)->active;
9295    waiting = &ASC_BOARDP(shp)->waiting;
9296
9297    if (ASC_NARROW_BOARD(boardp)) {
9298        chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
9299    } else {
9300        chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
9301    }
9302
9303    if ((chip_scsi_id == tgt_id) ||
9304        ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) {
9305        return 0;
9306    }
9307
9308    do {
9309        if (active->q_tot_cnt[tgt_id] > 0 || waiting->q_tot_cnt[tgt_id] > 0) {
9310            len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id);
9311            ASC_PRT_NEXT();
9312
9313            len = asc_prt_line(cp, leftlen,
9314"   active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
9315                active->q_cur_cnt[tgt_id], active->q_max_cnt[tgt_id],
9316                active->q_tot_cnt[tgt_id],
9317                active->q_min_tim[tgt_id], active->q_max_tim[tgt_id],
9318                (active->q_tot_cnt[tgt_id] == 0) ? 0 :
9319                (active->q_tot_tim[tgt_id]/active->q_tot_cnt[tgt_id]),
9320                (active->q_tot_cnt[tgt_id] == 0) ? 0 :
9321                ASC_TENTHS(active->q_tot_tim[tgt_id],
9322                active->q_tot_cnt[tgt_id]));
9323             ASC_PRT_NEXT();
9324
9325             len = asc_prt_line(cp, leftlen,
9326"   waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
9327                waiting->q_cur_cnt[tgt_id], waiting->q_max_cnt[tgt_id],
9328                waiting->q_tot_cnt[tgt_id],
9329                waiting->q_min_tim[tgt_id], waiting->q_max_tim[tgt_id],
9330                (waiting->q_tot_cnt[tgt_id] == 0) ? 0 :
9331                (waiting->q_tot_tim[tgt_id]/waiting->q_tot_cnt[tgt_id]),
9332                (waiting->q_tot_cnt[tgt_id] == 0) ? 0 :
9333                ASC_TENTHS(waiting->q_tot_tim[tgt_id],
9334                waiting->q_tot_cnt[tgt_id]));
9335             ASC_PRT_NEXT();
9336        }
9337    } while (0);
9338
9339     return totlen;
9340}
9341#endif /* CONFIG_PROC_FS */
9342#endif /* ADVANSYS_STATS */
9343
9344#ifdef ADVANSYS_DEBUG
9345/*
9346 * asc_prt_scsi_host()
9347 */
9348STATIC void
9349asc_prt_scsi_host(struct Scsi_Host *s)
9350{
9351    asc_board_t         *boardp;
9352
9353    boardp = ASC_BOARDP(s);
9354
9355    printk("Scsi_Host at addr 0x%lx\n", (ulong) s);
9356    printk(
9357" host_busy %u, host_no %d, last_reset %d,\n",
9358        s->host_busy, s->host_no,
9359        (unsigned) s->last_reset);
9360
9361#if ASC_LINUX_KERNEL24
9362    printk(
9363" hostt 0x%lx\n",
9364        (ulong) s->hostt);
9365#elif ASC_LINUX_KERNEL22
9366    printk(
9367" host_queue 0x%lx, hostt 0x%lx, block 0x%lx,\n",
9368        (ulong) s->host_queue, (ulong) s->hostt, (ulong) s->block);
9369#endif
9370
9371    printk(
9372" base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n",
9373        (ulong) s->base, (ulong) s->io_port, s->n_io_port, s->irq);
9374
9375    printk(
9376" dma_channel %d, this_id %d, can_queue %d,\n",
9377        s->dma_channel, s->this_id, s->can_queue);
9378
9379    printk(
9380" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
9381        s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
9382
9383    if (ASC_NARROW_BOARD(boardp)) {
9384        asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
9385        asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
9386    } else {
9387        asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
9388        asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
9389    }
9390}
9391
9392/*
9393 * asc_prt_scsi_cmnd()
9394 */
9395STATIC void
9396asc_prt_scsi_cmnd(Scsi_Cmnd *s)
9397{
9398    printk("Scsi_Cmnd at addr 0x%lx\n", (ulong) s);
9399
9400    printk(
9401" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
9402        (ulong) s->device->host, (ulong) s->device, s->device->id, s->device->lun,
9403        s->device->channel);
9404
9405    asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
9406
9407#if ASC_LINUX_KERNEL24
9408    printk (
9409"sc_data_direction %u, resid %d\n",
9410        s->sc_data_direction, s->resid);
9411#endif
9412
9413    printk(
9414" use_sg %u, sglist_len %u, abort_reason 0x%x\n",
9415        s->use_sg, s->sglist_len, s->abort_reason);
9416
9417    printk(
9418" serial_number 0x%x, serial_number_at_timeout 0x%x, retries %d, allowed %d\n",
9419        (unsigned) s->serial_number, (unsigned) s->serial_number_at_timeout,
9420         s->retries, s->allowed);
9421
9422    printk(
9423" timeout_per_command %d, timeout_total %d, timeout %d\n",
9424        s->timeout_per_command, s->timeout_total, s->timeout);
9425
9426#if ASC_LINUX_KERNEL24
9427    printk(
9428" internal_timeout %u, flags %u\n",
9429        s->internal_timeout, s->flags);
9430#elif ASC_LINUX_KERNEL22
9431    printk(
9432" internal_timeout %u, flags %u, this_count %d\n",
9433        s->internal_timeout, s->flags,s->this_count);
9434#endif
9435
9436    printk(
9437" scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n",
9438        (ulong) s->scsi_done, (ulong) s->done,
9439        (ulong) s->host_scribble, s->result);
9440
9441    printk(
9442" tag %u, pid %u\n",
9443        (unsigned) s->tag, (unsigned) s->pid);
9444}
9445
9446/*
9447 * asc_prt_asc_dvc_var()
9448 */
9449STATIC void
9450asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
9451{
9452    printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong) h);
9453
9454    printk(
9455" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl %d,\n",
9456        h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
9457
9458    printk(
9459" bus_type %d, isr_callback 0x%lx, exe_callback 0x%lx, init_sdtr 0x%x,\n",
9460        h->bus_type, (ulong) h->isr_callback, (ulong) h->exe_callback,
9461        (unsigned) h->init_sdtr);
9462
9463    printk(
9464" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, chip_no 0x%x,\n",
9465        (unsigned) h->sdtr_done, (unsigned) h->use_tagged_qng,
9466        (unsigned) h->unit_not_ready, (unsigned) h->chip_no);
9467
9468    printk(
9469" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait %u,\n",
9470        (unsigned) h->queue_full_or_busy, (unsigned) h->start_motor,
9471        (unsigned) h->scsi_reset_wait);
9472
9473    printk(
9474" is_in_int %u, max_total_qng %u, cur_total_qng %u, in_critical_cnt %u,\n",
9475        (unsigned) h->is_in_int, (unsigned) h->max_total_qng,
9476        (unsigned) h->cur_total_qng, (unsigned) h->in_critical_cnt);
9477
9478    printk(
9479" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, pci_fix_asyn_xfer 0x%x,\n",
9480        (unsigned) h->last_q_shortage, (unsigned) h->init_state,
9481        (unsigned) h->no_scam, (unsigned) h->pci_fix_asyn_xfer);
9482
9483    printk(
9484" cfg 0x%lx, irq_no 0x%x\n",
9485        (ulong) h->cfg, (unsigned) h->irq_no);
9486}
9487
9488/*
9489 * asc_prt_asc_dvc_cfg()
9490 */
9491STATIC void
9492asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
9493{
9494    printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong) h);
9495
9496    printk(
9497" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
9498            h->can_tagged_qng, h->cmd_qng_enabled);
9499    printk(
9500" disc_enable 0x%x, sdtr_enable 0x%x,\n",
9501            h->disc_enable, h->sdtr_enable);
9502
9503    printk(
9504" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
9505             h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
9506             h->chip_version);
9507
9508    printk(
9509" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
9510          h->pci_dev->device, h->lib_serial_no, h->lib_version, h->mcode_date);
9511
9512    printk(
9513" mcode_version %d, overrun_buf 0x%lx\n",
9514            h->mcode_version, (ulong) h->overrun_buf);
9515}
9516
9517/*
9518 * asc_prt_asc_scsi_q()
9519 */
9520STATIC void
9521asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
9522{
9523    ASC_SG_HEAD    *sgp;
9524    int i;
9525
9526    printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong) q);
9527
9528    printk(
9529" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
9530            q->q2.target_ix, q->q1.target_lun,
9531            (ulong) q->q2.srb_ptr, q->q2.tag_code);
9532
9533    printk(
9534" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
9535            (ulong) le32_to_cpu(q->q1.data_addr),
9536            (ulong) le32_to_cpu(q->q1.data_cnt),
9537            (ulong) le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
9538
9539    printk(
9540" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
9541            (ulong) q->cdbptr, q->q2.cdb_len,
9542            (ulong) q->sg_head, q->q1.sg_queue_cnt);
9543
9544    if (q->sg_head) {
9545        sgp = q->sg_head;
9546        printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong) sgp);
9547        printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, sgp->queue_cnt);
9548        for (i = 0; i < sgp->entry_cnt; i++) {
9549            printk(" [%u]: addr 0x%lx, bytes %lu\n",
9550                i, (ulong) le32_to_cpu(sgp->sg_list[i].addr),
9551                (ulong) le32_to_cpu(sgp->sg_list[i].bytes));
9552        }
9553
9554    }
9555}
9556
9557/*
9558 * asc_prt_asc_qdone_info()
9559 */
9560STATIC void
9561asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
9562{
9563    printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong) q);
9564    printk(
9565" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
9566            (ulong) q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
9567            q->d2.tag_code);
9568    printk(
9569" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
9570            q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
9571}
9572
9573/*
9574 * asc_prt_adv_dvc_var()
9575 *
9576 * Display an ADV_DVC_VAR structure.
9577 */
9578STATIC void
9579asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
9580{
9581    printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong) h);
9582
9583    printk(
9584"  iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
9585        (ulong) h->iop_base, h->err_code, (unsigned) h->ultra_able);
9586
9587    printk(
9588"  isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
9589        (ulong) h->isr_callback, (unsigned) h->sdtr_able,
9590        (unsigned) h->wdtr_able);
9591
9592    printk(
9593"  start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
9594        (unsigned) h->start_motor,
9595        (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
9596
9597    printk(
9598"  max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
9599        (unsigned) h->max_host_qng, (unsigned) h->max_dvc_qng,
9600        (ulong) h->carr_freelist);
9601
9602    printk(
9603"  icq_sp 0x%lx, irq_sp 0x%lx\n",
9604        (ulong) h->icq_sp, (ulong) h->irq_sp);
9605
9606    printk(
9607"  no_scam 0x%x, tagqng_able 0x%x\n",
9608        (unsigned) h->no_scam, (unsigned) h->tagqng_able);
9609
9610    printk(
9611"  chip_scsi_id 0x%x, cfg 0x%lx\n",
9612        (unsigned) h->chip_scsi_id, (ulong) h->cfg);
9613}
9614
9615/*
9616 * asc_prt_adv_dvc_cfg()
9617 *
9618 * Display an ADV_DVC_CFG structure.
9619 */
9620STATIC void
9621asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
9622{
9623    printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong) h);
9624
9625    printk(
9626"  disc_enable 0x%x, termination 0x%x\n",
9627        h->disc_enable, h->termination);
9628
9629    printk(
9630"  chip_version 0x%x, mcode_date 0x%x\n",
9631        h->chip_version, h->mcode_date);
9632
9633    printk(
9634"  mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
9635       h->mcode_version, h->pci_dev->device, h->lib_version);
9636
9637    printk(
9638"  control_flag 0x%x, pci_slot_info 0x%x\n",
9639       h->control_flag, h->pci_slot_info);
9640}
9641
9642/*
9643 * asc_prt_adv_scsi_req_q()
9644 *
9645 * Display an ADV_SCSI_REQ_Q structure.
9646 */
9647STATIC void
9648asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
9649{
9650    int                 sg_blk_cnt;
9651    struct asc_sg_block *sg_ptr;
9652
9653    printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong) q);
9654
9655    printk(
9656"  target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
9657            q->target_id, q->target_lun, (ulong) q->srb_ptr, q->a_flag);
9658
9659    printk("  cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
9660            q->cntl, (ulong) le32_to_cpu(q->data_addr), (ulong) q->vdata_addr);
9661
9662    printk(
9663"  data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
9664            (ulong) le32_to_cpu(q->data_cnt),
9665            (ulong) le32_to_cpu(q->sense_addr), q->sense_len);
9666
9667    printk(
9668"  cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
9669            q->cdb_len, q->done_status, q->host_status, q->scsi_status);
9670
9671    printk(
9672"  sg_working_ix 0x%x, target_cmd %u\n",
9673            q->sg_working_ix, q->target_cmd);
9674
9675    printk(
9676"  scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
9677            (ulong) le32_to_cpu(q->scsiq_rptr),
9678            (ulong) le32_to_cpu(q->sg_real_addr), (ulong) q->sg_list_ptr);
9679
9680    /* Display the request's ADV_SG_BLOCK structures. */
9681    if (q->sg_list_ptr != NULL)
9682    {
9683        sg_blk_cnt = 0;
9684        while (1) {
9685            /*
9686             * 'sg_ptr' is a physical address. Convert it to a virtual
9687             * address by indexing 'sg_blk_cnt' into the virtual address
9688             * array 'sg_list_ptr'.
9689             *
9690             * XXX - Assumes all SG physical blocks are virtually contiguous.
9691             */
9692            sg_ptr = &(((ADV_SG_BLOCK *) (q->sg_list_ptr))[sg_blk_cnt]);
9693            asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
9694            if (sg_ptr->sg_ptr == 0)
9695            {
9696                break;
9697            }
9698            sg_blk_cnt++;
9699        }
9700    }
9701}
9702
9703/*
9704 * asc_prt_adv_sgblock()
9705 *
9706 * Display an ADV_SG_BLOCK structure.
9707 */
9708STATIC void
9709asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
9710{
9711    int i;
9712
9713    printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
9714        (ulong) b, sgblockno);
9715    printk("  sg_cnt %u, sg_ptr 0x%lx\n",
9716        b->sg_cnt, (ulong) le32_to_cpu(b->sg_ptr));
9717    ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
9718    if (b->sg_ptr != 0)
9719    {
9720        ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
9721    }
9722    for (i = 0; i < b->sg_cnt; i++) {
9723        printk("  [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
9724            i, (ulong) b->sg_list[i].sg_addr, (ulong) b->sg_list[i].sg_count);
9725    }
9726}
9727
9728/*
9729 * asc_prt_hex()
9730 *
9731 * Print hexadecimal output in 4 byte groupings 32 bytes
9732 * or 8 double-words per line.
9733 */
9734STATIC void
9735asc_prt_hex(char *f, uchar *s, int l)
9736{
9737    int            i;
9738    int            j;
9739    int            k;
9740    int            m;
9741
9742    printk("%s: (%d bytes)\n", f, l);
9743
9744    for (i = 0; i < l; i += 32) {
9745
9746        /* Display a maximum of 8 double-words per line. */
9747        if ((k = (l - i) / 4) >= 8) {
9748            k = 8;
9749            m = 0;
9750        } else {
9751            m = (l - i) % 4;
9752        }
9753
9754        for (j = 0; j < k; j++) {
9755            printk(" %2.2X%2.2X%2.2X%2.2X",
9756                (unsigned) s[i+(j*4)], (unsigned) s[i+(j*4)+1],
9757                (unsigned) s[i+(j*4)+2], (unsigned) s[i+(j*4)+3]);
9758        }
9759
9760        switch (m) {
9761        case 0:
9762        default:
9763            break;
9764        case 1:
9765            printk(" %2.2X",
9766                (unsigned) s[i+(j*4)]);
9767            break;
9768        case 2:
9769            printk(" %2.2X%2.2X",
9770                (unsigned) s[i+(j*4)],
9771                (unsigned) s[i+(j*4)+1]);
9772            break;
9773        case 3:
9774            printk(" %2.2X%2.2X%2.2X",
9775                (unsigned) s[i+(j*4)+1],
9776                (unsigned) s[i+(j*4)+2],
9777                (unsigned) s[i+(j*4)+3]);
9778            break;
9779        }
9780
9781        printk("\n");
9782    }
9783}
9784#endif /* ADVANSYS_DEBUG */
9785
9786/*
9787 * --- Asc Library Functions
9788 */
9789
9790ASC_INITFUNC(
9791STATIC ushort,
9792AscGetEisaChipCfg(
9793                     PortAddr iop_base
9794)
9795)
9796{
9797    PortAddr            eisa_cfg_iop;
9798
9799    eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
9800      (PortAddr) (ASC_EISA_CFG_IOP_MASK);
9801    return (inpw(eisa_cfg_iop));
9802}
9803
9804ASC_INITFUNC(
9805STATIC uchar,
9806AscSetChipScsiID(
9807                    PortAddr iop_base,
9808                    uchar new_host_id
9809)
9810)
9811{
9812    ushort              cfg_lsw;
9813
9814    if (AscGetChipScsiID(iop_base) == new_host_id) {
9815        return (new_host_id);
9816    }
9817    cfg_lsw = AscGetChipCfgLsw(iop_base);
9818    cfg_lsw &= 0xF8FF;
9819    cfg_lsw |= (ushort) ((new_host_id & ASC_MAX_TID) << 8);
9820    AscSetChipCfgLsw(iop_base, cfg_lsw);
9821    return (AscGetChipScsiID(iop_base));
9822}
9823
9824ASC_INITFUNC(
9825STATIC uchar,
9826AscGetChipScsiCtrl(
9827                      PortAddr iop_base
9828)
9829)
9830{
9831    uchar               sc;
9832
9833    AscSetBank(iop_base, 1);
9834    sc = inp(iop_base + IOP_REG_SC);
9835    AscSetBank(iop_base, 0);
9836    return (sc);
9837}
9838
9839ASC_INITFUNC(
9840STATIC uchar,
9841AscGetChipVersion(
9842                     PortAddr iop_base,
9843                     ushort bus_type
9844)
9845)
9846{
9847    if ((bus_type & ASC_IS_EISA) != 0) {
9848        PortAddr            eisa_iop;
9849        uchar               revision;
9850        eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
9851          (PortAddr) ASC_EISA_REV_IOP_MASK;
9852        revision = inp(eisa_iop);
9853        return ((uchar) ((ASC_CHIP_MIN_VER_EISA - 1) + revision));
9854    }
9855    return (AscGetChipVerNo(iop_base));
9856}
9857
9858ASC_INITFUNC(
9859STATIC ushort,
9860AscGetChipBusType(
9861                     PortAddr iop_base
9862)
9863)
9864{
9865    ushort              chip_ver;
9866
9867    chip_ver = AscGetChipVerNo(iop_base);
9868    if (
9869           (chip_ver >= ASC_CHIP_MIN_VER_VL)
9870           && (chip_ver <= ASC_CHIP_MAX_VER_VL)
9871) {
9872        if (
9873               ((iop_base & 0x0C30) == 0x0C30)
9874               || ((iop_base & 0x0C50) == 0x0C50)
9875) {
9876            return (ASC_IS_EISA);
9877        }
9878        return (ASC_IS_VL);
9879    }
9880    if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
9881        (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
9882        if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
9883            return (ASC_IS_ISAPNP);
9884        }
9885        return (ASC_IS_ISA);
9886    } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
9887               (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
9888        return (ASC_IS_PCI);
9889    }
9890    return (0);
9891}
9892
9893STATIC ASC_DCNT
9894AscLoadMicroCode(
9895                    PortAddr iop_base,
9896                    ushort s_addr,
9897                    uchar *mcode_buf,
9898                    ushort mcode_size
9899)
9900{
9901    ASC_DCNT            chksum;
9902    ushort              mcode_word_size;
9903    ushort              mcode_chksum;
9904
9905    /* Write the microcode buffer starting at LRAM address 0. */
9906    mcode_word_size = (ushort) (mcode_size >> 1);
9907    AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
9908    AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
9909
9910    chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
9911    ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong) chksum);
9912    mcode_chksum = (ushort) AscMemSumLramWord(iop_base,
9913          (ushort) ASC_CODE_SEC_BEG,
9914          (ushort) ((mcode_size - s_addr - (ushort) ASC_CODE_SEC_BEG) / 2));
9915    ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
9916        (ulong) mcode_chksum);
9917    AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
9918    AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
9919    return (chksum);
9920}
9921
9922STATIC int
9923AscFindSignature(
9924                    PortAddr iop_base
9925)
9926{
9927    ushort              sig_word;
9928
9929    ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
9930        iop_base, AscGetChipSignatureByte(iop_base));
9931    if (AscGetChipSignatureByte(iop_base) == (uchar) ASC_1000_ID1B) {
9932        ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
9933            iop_base, AscGetChipSignatureWord(iop_base));
9934        sig_word = AscGetChipSignatureWord(iop_base);
9935        if ((sig_word == (ushort) ASC_1000_ID0W) ||
9936            (sig_word == (ushort) ASC_1000_ID0W_FIX)) {
9937            return (1);
9938        }
9939    }
9940    return (0);
9941}
9942
9943STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] ASC_INITDATA =
9944{
9945    0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
9946    ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
9947};
9948
9949#ifdef CONFIG_ISA
9950STATIC uchar _isa_pnp_inited ASC_INITDATA = 0;
9951
9952ASC_INITFUNC(
9953STATIC PortAddr,
9954AscSearchIOPortAddr(
9955                       PortAddr iop_beg,
9956                       ushort bus_type
9957)
9958)
9959{
9960    if (bus_type & ASC_IS_VL) {
9961        while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
9962            if (AscGetChipVersion(iop_beg, bus_type) <= ASC_CHIP_MAX_VER_VL) {
9963                return (iop_beg);
9964            }
9965        }
9966        return (0);
9967    }
9968    if (bus_type & ASC_IS_ISA) {
9969        if (_isa_pnp_inited == 0) {
9970            AscSetISAPNPWaitForKey();
9971            _isa_pnp_inited++;
9972        }
9973        while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
9974            if ((AscGetChipVersion(iop_beg, bus_type) & ASC_CHIP_VER_ISA_BIT) != 0) {
9975                return (iop_beg);
9976            }
9977        }
9978        return (0);
9979    }
9980    if (bus_type & ASC_IS_EISA) {
9981        if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) {
9982            return (iop_beg);
9983        }
9984        return (0);
9985    }
9986    return (0);
9987}
9988
9989ASC_INITFUNC(
9990STATIC PortAddr,
9991AscSearchIOPortAddr11(
9992                         PortAddr s_addr
9993)
9994)
9995{
9996    int                 i;
9997    PortAddr            iop_base;
9998
9999    for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) {
10000        if (_asc_def_iop_base[i] > s_addr) {
10001            break;
10002        }
10003    }
10004    for (; i < ASC_IOADR_TABLE_MAX_IX; i++) {
10005        iop_base = _asc_def_iop_base[i];
10006        if (check_region(iop_base, ASC_IOADR_GAP) != 0) {
10007            ASC_DBG1(1,
10008               "AscSearchIOPortAddr11: check_region() failed I/O port 0x%x\n",
10009                     iop_base);
10010            continue;
10011        }
10012        ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port 0x%x\n", iop_base);
10013        if (AscFindSignature(iop_base)) {
10014            return (iop_base);
10015        }
10016    }
10017    return (0);
10018}
10019
10020ASC_INITFUNC(
10021STATIC void,
10022AscSetISAPNPWaitForKey(
10023    void)
10024)
10025{
10026    outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
10027    outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
10028    return;
10029}
10030#endif /* CONFIG_ISA */
10031
10032ASC_INITFUNC(
10033STATIC void,
10034AscToggleIRQAct(
10035                   PortAddr iop_base
10036)
10037)
10038{
10039    AscSetChipStatus(iop_base, CIW_IRQ_ACT);
10040    AscSetChipStatus(iop_base, 0);
10041    return;
10042}
10043
10044ASC_INITFUNC(
10045STATIC uchar,
10046AscGetChipIRQ(
10047                 PortAddr iop_base,
10048                 ushort bus_type
10049)
10050)
10051{
10052    ushort              cfg_lsw;
10053    uchar               chip_irq;
10054
10055    if ((bus_type & ASC_IS_EISA) != 0) {
10056        cfg_lsw = AscGetEisaChipCfg(iop_base);
10057        chip_irq = (uchar) (((cfg_lsw >> 8) & 0x07) + 10);
10058        if ((chip_irq == 13) || (chip_irq > 15)) {
10059            return (0);
10060        }
10061        return (chip_irq);
10062    }
10063    if ((bus_type & ASC_IS_VL) != 0) {
10064        cfg_lsw = AscGetChipCfgLsw(iop_base);
10065        chip_irq = (uchar) (((cfg_lsw >> 2) & 0x07));
10066        if ((chip_irq == 0) ||
10067            (chip_irq == 4) ||
10068            (chip_irq == 7)) {
10069            return (0);
10070        }
10071        return ((uchar) (chip_irq + (ASC_MIN_IRQ_NO - 1)));
10072    }
10073    cfg_lsw = AscGetChipCfgLsw(iop_base);
10074    chip_irq = (uchar) (((cfg_lsw >> 2) & 0x03));
10075    if (chip_irq == 3)
10076        chip_irq += (uchar) 2;
10077    return ((uchar) (chip_irq + ASC_MIN_IRQ_NO));
10078}
10079
10080ASC_INITFUNC(
10081STATIC uchar,
10082AscSetChipIRQ(
10083                 PortAddr iop_base,
10084                 uchar irq_no,
10085                 ushort bus_type
10086)
10087)
10088{
10089    ushort              cfg_lsw;
10090
10091    if ((bus_type & ASC_IS_VL) != 0) {
10092        if (irq_no != 0) {
10093            if ((irq_no < ASC_MIN_IRQ_NO) || (irq_no > ASC_MAX_IRQ_NO)) {
10094                irq_no = 0;
10095            } else {
10096                irq_no -= (uchar) ((ASC_MIN_IRQ_NO - 1));
10097            }
10098        }
10099        cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE3);
10100        cfg_lsw |= (ushort) 0x0010;
10101        AscSetChipCfgLsw(iop_base, cfg_lsw);
10102        AscToggleIRQAct(iop_base);
10103        cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE0);
10104        cfg_lsw |= (ushort) ((irq_no & 0x07) << 2);
10105        AscSetChipCfgLsw(iop_base, cfg_lsw);
10106        AscToggleIRQAct(iop_base);
10107        return (AscGetChipIRQ(iop_base, bus_type));
10108    }
10109    if ((bus_type & (ASC_IS_ISA)) != 0) {
10110        if (irq_no == 15)
10111            irq_no -= (uchar) 2;
10112        irq_no -= (uchar) ASC_MIN_IRQ_NO;
10113        cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFF3);
10114        cfg_lsw |= (ushort) ((irq_no & 0x03) << 2);
10115        AscSetChipCfgLsw(iop_base, cfg_lsw);
10116        return (AscGetChipIRQ(iop_base, bus_type));
10117    }
10118    return (0);
10119}
10120
10121#ifdef CONFIG_ISA
10122ASC_INITFUNC(
10123STATIC void,
10124AscEnableIsaDma(
10125                   uchar dma_channel
10126)
10127)
10128{
10129    if (dma_channel < 4) {
10130        outp(0x000B, (ushort) (0xC0 | dma_channel));
10131        outp(0x000A, dma_channel);
10132    } else if (dma_channel < 8) {
10133        outp(0x00D6, (ushort) (0xC0 | (dma_channel - 4)));
10134        outp(0x00D4, (ushort) (dma_channel - 4));
10135    }
10136    return;
10137}
10138#endif /* CONFIG_ISA */
10139
10140STATIC int
10141AscIsrChipHalted(
10142                    ASC_DVC_VAR *asc_dvc
10143)
10144{
10145    EXT_MSG             ext_msg;
10146    EXT_MSG             out_msg;
10147    ushort              halt_q_addr;
10148    int                 sdtr_accept;
10149    ushort              int_halt_code;
10150    ASC_SCSI_BIT_ID_TYPE scsi_busy;
10151    ASC_SCSI_BIT_ID_TYPE target_id;
10152    PortAddr            iop_base;
10153    uchar               tag_code;
10154    uchar               q_status;
10155    uchar               halt_qp;
10156    uchar               sdtr_data;
10157    uchar               target_ix;
10158    uchar               q_cntl, tid_no;
10159    uchar               cur_dvc_qng;
10160    uchar               asyn_sdtr;
10161    uchar               scsi_status;
10162    asc_board_t         *boardp;
10163
10164    ASC_ASSERT(asc_dvc->drv_ptr != NULL);
10165    boardp = asc_dvc->drv_ptr;
10166
10167    iop_base = asc_dvc->iop_base;
10168    int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
10169
10170    halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
10171    halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
10172    target_ix = AscReadLramByte(iop_base,
10173                   (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TARGET_IX));
10174    q_cntl = AscReadLramByte(iop_base,
10175                        (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL));
10176    tid_no = ASC_TIX_TO_TID(target_ix);
10177    target_id = (uchar) ASC_TID_TO_TARGET_ID(tid_no);
10178    if (asc_dvc->pci_fix_asyn_xfer & target_id) {
10179        asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
10180    } else {
10181        asyn_sdtr = 0;
10182    }
10183    if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
10184        if (asc_dvc->pci_fix_asyn_xfer & target_id) {
10185            AscSetChipSDTR(iop_base, 0, tid_no);
10186            boardp->sdtr_data[tid_no] = 0;
10187        }
10188        AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10189        return (0);
10190    } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
10191        if (asc_dvc->pci_fix_asyn_xfer & target_id) {
10192            AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10193            boardp->sdtr_data[tid_no] = asyn_sdtr;
10194        }
10195        AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10196        return (0);
10197    } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
10198
10199        AscMemWordCopyPtrFromLram(iop_base,
10200                               ASCV_MSGIN_BEG,
10201                               (uchar *) &ext_msg,
10202                               sizeof(EXT_MSG) >> 1);
10203
10204        if (ext_msg.msg_type == MS_EXTEND &&
10205            ext_msg.msg_req == MS_SDTR_CODE &&
10206            ext_msg.msg_len == MS_SDTR_LEN) {
10207            sdtr_accept = TRUE;
10208            if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
10209
10210                sdtr_accept = FALSE;
10211                ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
10212            }
10213            if ((ext_msg.xfer_period <
10214                 asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index]) ||
10215                (ext_msg.xfer_period >
10216                 asc_dvc->sdtr_period_tbl[asc_dvc->max_sdtr_index])) {
10217                sdtr_accept = FALSE;
10218                ext_msg.xfer_period =
10219                    asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index];
10220            }
10221            if (sdtr_accept) {
10222                sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
10223                                           ext_msg.req_ack_offset);
10224                if ((sdtr_data == 0xFF)) {
10225
10226                    q_cntl |= QC_MSG_OUT;
10227                    asc_dvc->init_sdtr &= ~target_id;
10228                    asc_dvc->sdtr_done &= ~target_id;
10229                    AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10230                    boardp->sdtr_data[tid_no] = asyn_sdtr;
10231                }
10232            }
10233            if (ext_msg.req_ack_offset == 0) {
10234
10235                q_cntl &= ~QC_MSG_OUT;
10236                asc_dvc->init_sdtr &= ~target_id;
10237                asc_dvc->sdtr_done &= ~target_id;
10238                AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10239            } else {
10240                if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
10241
10242                    q_cntl &= ~QC_MSG_OUT;
10243                    asc_dvc->sdtr_done |= target_id;
10244                    asc_dvc->init_sdtr |= target_id;
10245                    asc_dvc->pci_fix_asyn_xfer &= ~target_id;
10246                    sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
10247                                               ext_msg.req_ack_offset);
10248                    AscSetChipSDTR(iop_base, sdtr_data, tid_no);
10249                    boardp->sdtr_data[tid_no] = sdtr_data;
10250                } else {
10251
10252                    q_cntl |= QC_MSG_OUT;
10253                    AscMsgOutSDTR(asc_dvc,
10254                                  ext_msg.xfer_period,
10255                                  ext_msg.req_ack_offset);
10256                    asc_dvc->pci_fix_asyn_xfer &= ~target_id;
10257                    sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
10258                                               ext_msg.req_ack_offset);
10259                    AscSetChipSDTR(iop_base, sdtr_data, tid_no);
10260                    boardp->sdtr_data[tid_no] = sdtr_data;
10261                    asc_dvc->sdtr_done |= target_id;
10262                    asc_dvc->init_sdtr |= target_id;
10263                }
10264            }
10265
10266            AscWriteLramByte(iop_base,
10267                         (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10268                             q_cntl);
10269            AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10270            return (0);
10271        } else if (ext_msg.msg_type == MS_EXTEND &&
10272                   ext_msg.msg_req == MS_WDTR_CODE &&
10273                   ext_msg.msg_len == MS_WDTR_LEN) {
10274
10275            ext_msg.wdtr_width = 0;
10276            AscMemWordCopyPtrToLram(iop_base,
10277                                 ASCV_MSGOUT_BEG,
10278                                 (uchar *) &ext_msg,
10279                                 sizeof(EXT_MSG) >> 1);
10280            q_cntl |= QC_MSG_OUT;
10281            AscWriteLramByte(iop_base,
10282                         (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10283                             q_cntl);
10284            AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10285            return (0);
10286        } else {
10287
10288            ext_msg.msg_type = M1_MSG_REJECT;
10289            AscMemWordCopyPtrToLram(iop_base,
10290                                 ASCV_MSGOUT_BEG,
10291                                 (uchar *) &ext_msg,
10292                                 sizeof(EXT_MSG) >> 1);
10293            q_cntl |= QC_MSG_OUT;
10294            AscWriteLramByte(iop_base,
10295                         (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10296                             q_cntl);
10297            AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10298            return (0);
10299        }
10300    } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
10301
10302        q_cntl |= QC_REQ_SENSE;
10303
10304        if ((asc_dvc->init_sdtr & target_id) != 0) {
10305
10306            asc_dvc->sdtr_done &= ~target_id;
10307
10308            sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10309            q_cntl |= QC_MSG_OUT;
10310            AscMsgOutSDTR(asc_dvc,
10311                          asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
10312                           (uchar) (asc_dvc->max_sdtr_index - 1)],
10313                          (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
10314        }
10315
10316        AscWriteLramByte(iop_base,
10317                         (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10318                         q_cntl);
10319
10320        tag_code = AscReadLramByte(iop_base,
10321                    (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE));
10322        tag_code &= 0xDC;
10323        if (
10324               (asc_dvc->pci_fix_asyn_xfer & target_id)
10325               && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
10326) {
10327
10328            tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
10329                         | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
10330
10331        }
10332        AscWriteLramByte(iop_base,
10333                     (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE),
10334                         tag_code);
10335
10336        q_status = AscReadLramByte(iop_base,
10337                      (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS));
10338        q_status |= (QS_READY | QS_BUSY);
10339        AscWriteLramByte(iop_base,
10340                       (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10341                         q_status);
10342
10343        scsi_busy = AscReadLramByte(iop_base,
10344                                    (ushort) ASCV_SCSIBUSY_B);
10345        scsi_busy &= ~target_id;
10346        AscWriteLramByte(iop_base, (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10347
10348        AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10349        return (0);
10350    } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
10351
10352        AscMemWordCopyPtrFromLram(iop_base,
10353                               ASCV_MSGOUT_BEG,
10354                               (uchar *) &out_msg,
10355                               sizeof(EXT_MSG) >> 1);
10356
10357        if ((out_msg.msg_type == MS_EXTEND) &&
10358            (out_msg.msg_len == MS_SDTR_LEN) &&
10359            (out_msg.msg_req == MS_SDTR_CODE)) {
10360
10361            asc_dvc->init_sdtr &= ~target_id;
10362            asc_dvc->sdtr_done &= ~target_id;
10363            AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10364            boardp->sdtr_data[tid_no] = asyn_sdtr;
10365        }
10366        q_cntl &= ~QC_MSG_OUT;
10367        AscWriteLramByte(iop_base,
10368                         (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10369                         q_cntl);
10370        AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10371        return (0);
10372    } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
10373
10374        scsi_status = AscReadLramByte(iop_base,
10375          (ushort) ((ushort) halt_q_addr + (ushort) ASC_SCSIQ_SCSI_STATUS));
10376        cur_dvc_qng = AscReadLramByte(iop_base,
10377                     (ushort) ((ushort) ASC_QADR_BEG + (ushort) target_ix));
10378        if ((cur_dvc_qng > 0) &&
10379            (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
10380
10381            scsi_busy = AscReadLramByte(iop_base,
10382                                        (ushort) ASCV_SCSIBUSY_B);
10383            scsi_busy |= target_id;
10384            AscWriteLramByte(iop_base,
10385                             (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10386            asc_dvc->queue_full_or_busy |= target_id;
10387
10388            if (scsi_status == SS_QUEUE_FULL) {
10389                if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
10390                    cur_dvc_qng -= 1;
10391                    asc_dvc->max_dvc_qng[tid_no] = cur_dvc_qng;
10392
10393                    AscWriteLramByte(iop_base,
10394                          (ushort) ((ushort) ASCV_MAX_DVC_QNG_BEG +
10395                           (ushort) tid_no),
10396                          cur_dvc_qng);
10397
10398                    /*
10399                     * Set the device queue depth to the number of
10400                     * active requests when the QUEUE FULL condition
10401                     * was encountered.
10402                     */
10403                    boardp->queue_full |= target_id;
10404                    boardp->queue_full_cnt[tid_no] = cur_dvc_qng;
10405                }
10406            }
10407        }
10408        AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10409        return (0);
10410    }
10411#if CC_VERY_LONG_SG_LIST
10412    else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC)
10413    {
10414        uchar              q_no;
10415        ushort             q_addr;
10416        uchar              sg_wk_q_no;
10417        uchar              first_sg_wk_q_no;
10418        ASC_SCSI_Q         *scsiq; /* Ptr to driver request. */
10419        ASC_SG_HEAD        *sg_head; /* Ptr to driver SG request. */
10420        ASC_SG_LIST_Q      scsi_sg_q; /* Structure written to queue. */
10421        ushort             sg_list_dwords;
10422        ushort             sg_entry_cnt;
10423        uchar              next_qp;
10424        int                i;
10425
10426        q_no = AscReadLramByte(iop_base, (ushort) ASCV_REQ_SG_LIST_QP);
10427        if (q_no == ASC_QLINK_END)
10428        {
10429            return(0);
10430        }
10431
10432        q_addr = ASC_QNO_TO_QADDR(q_no);
10433
10434        /*
10435         * Convert the request's SRB pointer to a host ASC_SCSI_REQ
10436         * structure pointer using a macro provided by the driver.
10437         * The ASC_SCSI_REQ pointer provides a pointer to the
10438         * host ASC_SG_HEAD structure.
10439         */
10440        /* Read request's SRB pointer. */
10441        scsiq = (ASC_SCSI_Q *)
10442           ASC_SRB2SCSIQ(
10443               ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
10444               (ushort) (q_addr + ASC_SCSIQ_D_SRBPTR))));
10445
10446        /*
10447         * Get request's first and working SG queue.
10448         */
10449        sg_wk_q_no = AscReadLramByte(iop_base,
10450            (ushort) (q_addr + ASC_SCSIQ_B_SG_WK_QP));
10451
10452        first_sg_wk_q_no = AscReadLramByte(iop_base,
10453            (ushort) (q_addr + ASC_SCSIQ_B_FIRST_SG_WK_QP));
10454
10455        /*
10456         * Reset request's working SG queue back to the
10457         * first SG queue.
10458         */
10459        AscWriteLramByte(iop_base,
10460            (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SG_WK_QP),
10461            first_sg_wk_q_no);
10462
10463        sg_head = scsiq->sg_head;
10464
10465        /*
10466         * Set sg_entry_cnt to the number of SG elements
10467         * that will be completed on this interrupt.
10468         *
10469         * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
10470         * SG elements. The data_cnt and data_addr fields which
10471         * add 1 to the SG element capacity are not used when
10472         * restarting SG handling after a halt.
10473         */
10474        if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1))
10475        {
10476             sg_entry_cnt = ASC_MAX_SG_LIST - 1;
10477
10478             /*
10479              * Keep track of remaining number of SG elements that will
10480              * need to be handled on the next interrupt.
10481              */
10482             scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
10483        } else
10484        {
10485             sg_entry_cnt = scsiq->remain_sg_entry_cnt;
10486             scsiq->remain_sg_entry_cnt = 0;
10487        }
10488
10489        /*
10490         * Copy SG elements into the list of allocated SG queues.
10491         *
10492         * Last index completed is saved in scsiq->next_sg_index.
10493         */
10494        next_qp = first_sg_wk_q_no;
10495        q_addr = ASC_QNO_TO_QADDR(next_qp);
10496        scsi_sg_q.sg_head_qp = q_no;
10497        scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
10498        for( i = 0; i < sg_head->queue_cnt; i++)
10499        {
10500             scsi_sg_q.seq_no = i + 1;
10501             if (sg_entry_cnt > ASC_SG_LIST_PER_Q)
10502             {
10503                 sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
10504                 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
10505                 /*
10506                  * After very first SG queue RISC FW uses next
10507                  * SG queue first element then checks sg_list_cnt
10508                  * against zero and then decrements, so set
10509                  * sg_list_cnt 1 less than number of SG elements
10510                  * in each SG queue.
10511                  */
10512                 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
10513                 scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
10514             } else {
10515                 /*
10516                  * This is the last SG queue in the list of
10517                  * allocated SG queues. If there are more
10518                  * SG elements than will fit in the allocated
10519                  * queues, then set the QCSG_SG_XFER_MORE flag.
10520                  */
10521                 if (scsiq->remain_sg_entry_cnt != 0)
10522                 {
10523                     scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
10524                 } else
10525                 {
10526                     scsi_sg_q.cntl |= QCSG_SG_XFER_END;
10527                 }
10528                 /* equals sg_entry_cnt * 2 */
10529                 sg_list_dwords = sg_entry_cnt << 1;
10530                 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
10531                 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
10532                 sg_entry_cnt = 0;
10533             }
10534
10535             scsi_sg_q.q_no = next_qp;
10536             AscMemWordCopyPtrToLram(iop_base,
10537                          q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
10538                          (uchar *) &scsi_sg_q,
10539                          sizeof(ASC_SG_LIST_Q) >> 1);
10540
10541             AscMemDWordCopyPtrToLram(iop_base,
10542                          q_addr + ASC_SGQ_LIST_BEG,
10543                          (uchar *) &sg_head->sg_list[scsiq->next_sg_index],
10544                          sg_list_dwords);
10545
10546             scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
10547
10548             /*
10549              * If the just completed SG queue contained the
10550              * last SG element, then no more SG queues need
10551              * to be written.
10552              */
10553             if (scsi_sg_q.cntl & QCSG_SG_XFER_END)
10554             {
10555                 break;
10556             }
10557
10558             next_qp = AscReadLramByte( iop_base,
10559                          ( ushort )( q_addr+ASC_SCSIQ_B_FWD ) );
10560             q_addr = ASC_QNO_TO_QADDR( next_qp );
10561        }
10562
10563        /*
10564         * Clear the halt condition so the RISC will be restarted
10565         * after the return.
10566         */
10567        AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10568        return(0);
10569    }
10570#endif /* CC_VERY_LONG_SG_LIST */
10571    return (0);
10572}
10573
10574STATIC uchar
10575_AscCopyLramScsiDoneQ(
10576                         PortAddr iop_base,
10577                         ushort q_addr,
10578                         ASC_QDONE_INFO * scsiq,
10579                         ASC_DCNT max_dma_count
10580)
10581{
10582    ushort              _val;
10583    uchar               sg_queue_cnt;
10584
10585    DvcGetQinfo(iop_base,
10586                q_addr + ASC_SCSIQ_DONE_INFO_BEG,
10587                (uchar *) scsiq,
10588                (sizeof (ASC_SCSIQ_2) + sizeof (ASC_SCSIQ_3)) / 2);
10589
10590    _val = AscReadLramWord(iop_base,
10591                           (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS));
10592    scsiq->q_status = (uchar) _val;
10593    scsiq->q_no = (uchar) (_val >> 8);
10594    _val = AscReadLramWord(iop_base,
10595                           (ushort) (q_addr + (ushort) ASC_SCSIQ_B_CNTL));
10596    scsiq->cntl = (uchar) _val;
10597    sg_queue_cnt = (uchar) (_val >> 8);
10598    _val = AscReadLramWord(iop_base,
10599                        (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SENSE_LEN));
10600    scsiq->sense_len = (uchar) _val;
10601    scsiq->extra_bytes = (uchar) (_val >> 8);
10602
10603    /*
10604     * Read high word of remain bytes from alternate location.
10605     */
10606    scsiq->remain_bytes = (((ADV_DCNT) AscReadLramWord( iop_base,
10607                      (ushort) (q_addr+ (ushort) ASC_SCSIQ_W_ALT_DC1))) << 16);
10608    /*
10609     * Read low word of remain bytes from original location.
10610     */
10611    scsiq->remain_bytes += AscReadLramWord(iop_base,
10612        (ushort) (q_addr+ (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT));
10613
10614    scsiq->remain_bytes &= max_dma_count;
10615    return (sg_queue_cnt);
10616}
10617
10618STATIC int
10619AscIsrQDone(
10620               ASC_DVC_VAR *asc_dvc
10621)
10622{
10623    uchar               next_qp;
10624    uchar               n_q_used;
10625    uchar               sg_list_qp;
10626    uchar               sg_queue_cnt;
10627    uchar               q_cnt;
10628    uchar               done_q_tail;
10629    uchar               tid_no;
10630    ASC_SCSI_BIT_ID_TYPE scsi_busy;
10631    ASC_SCSI_BIT_ID_TYPE target_id;
10632    PortAddr            iop_base;
10633    ushort              q_addr;
10634    ushort              sg_q_addr;
10635    uchar               cur_target_qng;
10636    ASC_QDONE_INFO      scsiq_buf;
10637    ASC_QDONE_INFO *scsiq;
10638    int                 false_overrun;
10639    ASC_ISR_CALLBACK    asc_isr_callback;
10640
10641    iop_base = asc_dvc->iop_base;
10642    asc_isr_callback = asc_dvc->isr_callback;
10643    n_q_used = 1;
10644    scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
10645    done_q_tail = (uchar) AscGetVarDoneQTail(iop_base);
10646    q_addr = ASC_QNO_TO_QADDR(done_q_tail);
10647    next_qp = AscReadLramByte(iop_base,
10648                              (ushort) (q_addr + (ushort) ASC_SCSIQ_B_FWD));
10649    if (next_qp != ASC_QLINK_END) {
10650        AscPutVarDoneQTail(iop_base, next_qp);
10651        q_addr = ASC_QNO_TO_QADDR(next_qp);
10652        sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
10653            asc_dvc->max_dma_count);
10654        AscWriteLramByte(iop_base,
10655                         (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10656             (uchar) (scsiq->q_status & (uchar) ~ (QS_READY | QS_ABORTED)));
10657        tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
10658        target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
10659        if ((scsiq->cntl & QC_SG_HEAD) != 0) {
10660            sg_q_addr = q_addr;
10661            sg_list_qp = next_qp;
10662            for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
10663                sg_list_qp = AscReadLramByte(iop_base,
10664                           (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_FWD));
10665                sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
10666                if (sg_list_qp == ASC_QLINK_END) {
10667                    AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SG_Q_LINKS);
10668                    scsiq->d3.done_stat = QD_WITH_ERROR;
10669                    scsiq->d3.host_stat = QHSTA_D_QDONE_SG_LIST_CORRUPTED;
10670                    goto FATAL_ERR_QDONE;
10671                }
10672                AscWriteLramByte(iop_base,
10673                         (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10674                                 QS_FREE);
10675            }
10676            n_q_used = sg_queue_cnt + 1;
10677            AscPutVarDoneQTail(iop_base, sg_list_qp);
10678        }
10679        if (asc_dvc->queue_full_or_busy & target_id) {
10680            cur_target_qng = AscReadLramByte(iop_base,
10681            (ushort) ((ushort) ASC_QADR_BEG + (ushort) scsiq->d2.target_ix));
10682            if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
10683                scsi_busy = AscReadLramByte(iop_base,
10684                                            (ushort) ASCV_SCSIBUSY_B);
10685                scsi_busy &= ~target_id;
10686                AscWriteLramByte(iop_base,
10687                                 (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10688                asc_dvc->queue_full_or_busy &= ~target_id;
10689            }
10690        }
10691        if (asc_dvc->cur_total_qng >= n_q_used) {
10692            asc_dvc->cur_total_qng -= n_q_used;
10693            if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
10694                asc_dvc->cur_dvc_qng[tid_no]--;
10695            }
10696        } else {
10697            AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
10698            scsiq->d3.done_stat = QD_WITH_ERROR;
10699            goto FATAL_ERR_QDONE;
10700        }
10701        if ((scsiq->d2.srb_ptr == 0UL) ||
10702            ((scsiq->q_status & QS_ABORTED) != 0)) {
10703            return (0x11);
10704        } else if (scsiq->q_status == QS_DONE) {
10705            false_overrun = FALSE;
10706            if (scsiq->extra_bytes != 0) {
10707                scsiq->remain_bytes += (ADV_DCNT) scsiq->extra_bytes;
10708            }
10709            if (scsiq->d3.done_stat == QD_WITH_ERROR) {
10710                if (scsiq->d3.host_stat == QHSTA_M_DATA_OVER_RUN) {
10711                    if ((scsiq->cntl & (QC_DATA_IN | QC_DATA_OUT)) == 0) {
10712                        scsiq->d3.done_stat = QD_NO_ERROR;
10713                        scsiq->d3.host_stat = QHSTA_NO_ERROR;
10714                    } else if (false_overrun) {
10715                        scsiq->d3.done_stat = QD_NO_ERROR;
10716                        scsiq->d3.host_stat = QHSTA_NO_ERROR;
10717                    }
10718                } else if (scsiq->d3.host_stat ==
10719                           QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
10720                    AscStopChip(iop_base);
10721                    AscSetChipControl(iop_base,
10722                        (uchar) (CC_SCSI_RESET | CC_HALT));
10723                    DvcDelayNanoSecond(asc_dvc, 60000);
10724                    AscSetChipControl(iop_base, CC_HALT);
10725                    AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10726                    AscSetChipStatus(iop_base, 0);
10727                    AscSetChipControl(iop_base, 0);
10728                }
10729            }
10730            if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
10731                (*asc_isr_callback) (asc_dvc, scsiq);
10732            } else {
10733                if ((AscReadLramByte(iop_base,
10734                          (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG)) ==
10735                     SCSICMD_StartStopUnit)) {
10736                    asc_dvc->unit_not_ready &= ~target_id;
10737                    if (scsiq->d3.done_stat != QD_NO_ERROR) {
10738                        asc_dvc->start_motor &= ~target_id;
10739                    }
10740                }
10741            }
10742            return (1);
10743        } else {
10744            AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
10745          FATAL_ERR_QDONE:
10746            if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
10747                (*asc_isr_callback) (asc_dvc, scsiq);
10748            }
10749            return (0x80);
10750        }
10751    }
10752    return (0);
10753}
10754
10755STATIC int
10756AscISR(
10757          ASC_DVC_VAR *asc_dvc
10758)
10759{
10760    ASC_CS_TYPE         chipstat;
10761    PortAddr            iop_base;
10762    ushort              saved_ram_addr;
10763    uchar               ctrl_reg;
10764    uchar               saved_ctrl_reg;
10765    int                 int_pending;
10766    int                 status;
10767    uchar               host_flag;
10768
10769    iop_base = asc_dvc->iop_base;
10770    int_pending = FALSE;
10771
10772    if (AscIsIntPending(iop_base) == 0)
10773    {
10774        return int_pending;
10775    }
10776
10777    if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
10778        || (asc_dvc->isr_callback == 0)
10779) {
10780        return (ERR);
10781    }
10782    if (asc_dvc->in_critical_cnt != 0) {
10783        AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
10784        return (ERR);
10785    }
10786    if (asc_dvc->is_in_int) {
10787        AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
10788        return (ERR);
10789    }
10790    asc_dvc->is_in_int = TRUE;
10791    ctrl_reg = AscGetChipControl(iop_base);
10792    saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
10793                                   CC_SINGLE_STEP | CC_DIAG | CC_TEST));
10794    chipstat = AscGetChipStatus(iop_base);
10795    if (chipstat & CSW_SCSI_RESET_LATCH) {
10796        if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
10797            int i = 10;
10798            int_pending = TRUE;
10799            asc_dvc->sdtr_done = 0;
10800            saved_ctrl_reg &= (uchar) (~CC_HALT);
10801            while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) &&
10802                   (i-- > 0))
10803            {
10804                  DvcSleepMilliSecond(100);
10805            }
10806            AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
10807            AscSetChipControl(iop_base, CC_HALT);
10808            AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10809            AscSetChipStatus(iop_base, 0);
10810            chipstat = AscGetChipStatus(iop_base);
10811        }
10812    }
10813    saved_ram_addr = AscGetChipLramAddr(iop_base);
10814    host_flag = AscReadLramByte(iop_base,
10815        ASCV_HOST_FLAG_B) & (uchar) (~ASC_HOST_FLAG_IN_ISR);
10816    AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
10817                     (uchar) (host_flag | (uchar) ASC_HOST_FLAG_IN_ISR));
10818    if ((chipstat & CSW_INT_PENDING)
10819        || (int_pending)
10820) {
10821        AscAckInterrupt(iop_base);
10822        int_pending = TRUE;
10823        if ((chipstat & CSW_HALTED) &&
10824            (ctrl_reg & CC_SINGLE_STEP)) {
10825            if (AscIsrChipHalted(asc_dvc) == ERR) {
10826                goto ISR_REPORT_QDONE_FATAL_ERROR;
10827            } else {
10828                saved_ctrl_reg &= (uchar) (~CC_HALT);
10829            }
10830        } else {
10831          ISR_REPORT_QDONE_FATAL_ERROR:
10832            if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
10833                while (((status = AscIsrQDone(asc_dvc)) & 0x01) != 0) {
10834                }
10835            } else {
10836                do {
10837                    if ((status = AscIsrQDone(asc_dvc)) == 1) {
10838                        break;
10839                    }
10840                } while (status == 0x11);
10841            }
10842            if ((status & 0x80) != 0)
10843                int_pending = ERR;
10844        }
10845    }
10846    AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
10847    AscSetChipLramAddr(iop_base, saved_ram_addr);
10848    AscSetChipControl(iop_base, saved_ctrl_reg);
10849    asc_dvc->is_in_int = FALSE;
10850    return (int_pending);
10851}
10852
10853/* Microcode buffer is kept after initialization for error recovery. */
10854STATIC uchar _asc_mcode_buf[] =
10855{
10856  0x01,  0x03,  0x01,  0x19,  0x0F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
10857  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
10858  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
10859  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
10860  0x00,  0x00,  0x00,  0x00,  0xC3,  0x12,  0x0D,  0x05,  0x01,  0x00,  0x00,  0x00,  0x00,  0xFF,  0x00,  0x00,
10861  0x00,  0x00,  0x00,  0x00,  0xFF,  0x80,  0xFF,  0xFF,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
10862  0x00,  0x00,  0x00,  0x23,  0x00,  0x00,  0x00,  0x00,  0x00,  0x07,  0x00,  0xFF,  0x00,  0x00,  0x00,  0x00,
10863  0xFF,  0xFF,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xE4,  0x88,  0x00,  0x00,  0x00,  0x00,
10864  0x80,  0x73,  0x48,  0x04,  0x36,  0x00,  0x00,  0xA2,  0xC2,  0x00,  0x80,  0x73,  0x03,  0x23,  0x36,  0x40,
10865  0xB6,  0x00,  0x36,  0x00,  0x05,  0xD6,  0x0C,  0xD2,  0x12,  0xDA,  0x00,  0xA2,  0xC2,  0x00,  0x92,  0x80,
10866  0x1E,  0x98,  0x50,  0x00,  0xF5,  0x00,  0x48,  0x98,  0xDF,  0x23,  0x36,  0x60,  0xB6,  0x00,  0x92,  0x80,
10867  0x4F,  0x00,  0xF5,  0x00,  0x48,  0x98,  0xEF,  0x23,  0x36,  0x60,  0xB6,  0x00,  0x92,  0x80,  0x80,  0x62,
10868  0x92,  0x80,  0x00,  0x46,  0x15,  0xEE,  0x13,  0xEA,  0x02,  0x01,  0x09,  0xD8,  0xCD,  0x04,  0x4D,  0x00,
10869  0x00,  0xA3,  0xD6,  0x00,  0xA6,  0x97,  0x7F,  0x23,  0x04,  0x61,  0x84,  0x01,  0xE6,  0x84,  0xD2,  0xC1,
10870  0x80,  0x73,  0xCD,  0x04,  0x4D,  0x00,  0x00,  0xA3,  0xDA,  0x01,  0xA6,  0x97,  0xC6,  0x81,  0xC2,  0x88,
10871  0x80,  0x73,  0x80,  0x77,  0x00,  0x01,  0x01,  0xA1,  0xFE,  0x00,  0x4F,  0x00,  0x84,  0x97,  0x07,  0xA6,
10872  0x08,  0x01,  0x00,  0x33,  0x03,  0x00,  0xC2,  0x88,  0x03,  0x03,  0x01,  0xDE,  0xC2,  0x88,  0xCE,  0x00,
10873  0x69,  0x60,  0xCE,  0x00,  0x02,  0x03,  0x4A,  0x60,  0x00,  0xA2,  0x78,  0x01,  0x80,  0x63,  0x07,  0xA6,
10874  0x24,  0x01,  0x78,  0x81,  0x03,  0x03,  0x80,  0x63,  0xE2,  0x00,  0x07,  0xA6,  0x34,  0x01,  0x00,  0x33,
10875  0x04,  0x00,  0xC2,  0x88,  0x03,  0x07,  0x02,  0x01,  0x04,  0xCA,  0x0D,  0x23,  0x68,  0x98,  0x4D,  0x04,
10876  0x04,  0x85,  0x05,  0xD8,  0x0D,  0x23,  0x68,  0x98,  0xCD,  0x04,  0x15,  0x23,  0xF8,  0x88,  0xFB,  0x23,
10877  0x02,  0x61,  0x82,  0x01,  0x80,  0x63,  0x02,  0x03,  0x06,  0xA3,  0x62,  0x01,  0x00,  0x33,  0x0A,  0x00,
10878  0xC2,  0x88,  0x4E,  0x00,  0x07,  0xA3,  0x6E,  0x01,  0x00,  0x33,  0x0B,  0x00,  0xC2,  0x88,  0xCD,  0x04,
10879  0x36,  0x2D,  0x00,  0x33,  0x1A,  0x00,  0xC2,  0x88,  0x50,  0x04,  0x88,  0x81,  0x06,  0xAB,  0x82,  0x01,
10880  0x88,  0x81,  0x4E,  0x00,  0x07,  0xA3,  0x92,  0x01,  0x50,  0x00,  0x00,  0xA3,  0x3C,  0x01,  0x00,  0x05,
10881  0x7C,  0x81,  0x46,  0x97,  0x02,  0x01,  0x05,  0xC6,  0x04,  0x23,  0xA0,  0x01,  0x15,  0x23,  0xA1,  0x01,
10882  0xBE,  0x81,  0xFD,  0x23,  0x02,  0x61,  0x82,  0x01,  0x0A,  0xDA,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA0,
10883  0xB4,  0x01,  0x80,  0x63,  0xCD,  0x04,  0x36,  0x2D,  0x00,  0x33,  0x1B,  0x00,  0xC2,  0x88,  0x06,  0x23,
10884  0x68,  0x98,  0xCD,  0x04,  0xE6,  0x84,  0x06,  0x01,  0x00,  0xA2,  0xD4,  0x01,  0x57,  0x60,  0x00,  0xA0,
10885  0xDA,  0x01,  0xE6,  0x84,  0x80,  0x23,  0xA0,  0x01,  0xE6,  0x84,  0x80,  0x73,  0x4B,  0x00,  0x06,  0x61,
10886  0x00,  0xA2,  0x00,  0x02,  0x04,  0x01,  0x0C,  0xDE,  0x02,  0x01,  0x03,  0xCC,  0x4F,  0x00,  0x84,  0x97,
10887  0xFC,  0x81,  0x08,  0x23,  0x02,  0x41,  0x82,  0x01,  0x4F,  0x00,  0x62,  0x97,  0x48,  0x04,  0x84,  0x80,
10888  0xF0,  0x97,  0x00,  0x46,  0x56,  0x00,  0x03,  0xC0,  0x01,  0x23,  0xE8,  0x00,  0x81,  0x73,  0x06,  0x29,
10889  0x03,  0x42,  0x06,  0xE2,  0x03,  0xEE,  0x6B,  0xEB,  0x11,  0x23,  0xF8,  0x88,  0x04,  0x98,  0xF0,  0x80,
10890  0x80,  0x73,  0x80,  0x77,  0x07,  0xA4,  0x2A,  0x02,  0x7C,  0x95,  0x06,  0xA6,  0x34,  0x02,  0x03,  0xA6,
10891  0x4C,  0x04,  0x46,  0x82,  0x04,  0x01,  0x03,  0xD8,  0xB4,  0x98,  0x6A,  0x96,  0x46,  0x82,  0xFE,  0x95,
10892  0x80,  0x67,  0x83,  0x03,  0x80,  0x63,  0xB6,  0x2D,  0x02,  0xA6,  0x6C,  0x02,  0x07,  0xA6,  0x5A,  0x02,
10893  0x06,  0xA6,  0x5E,  0x02,  0x03,  0xA6,  0x62,  0x02,  0xC2,  0x88,  0x7C,  0x95,  0x48,  0x82,  0x60,  0x96,
10894  0x48,  0x82,  0x04,  0x23,  0xA0,  0x01,  0x14,  0x23,  0xA1,  0x01,  0x3C,  0x84,  0x04,  0x01,  0x0C,  0xDC,
10895  0xE0,  0x23,  0x25,  0x61,  0xEF,  0x00,  0x14,  0x01,  0x4F,  0x04,  0xA8,  0x01,  0x6F,  0x00,  0xA5,  0x01,
10896  0x03,  0x23,  0xA4,  0x01,  0x06,  0x23,  0x9C,  0x01,  0x24,  0x2B,  0x1C,  0x01,  0x02,  0xA6,  0xAA,  0x02,
10897  0x07,  0xA6,  0x5A,  0x02,  0x06,  0xA6,  0x5E,  0x02,  0x03,  0xA6,  0x20,  0x04,  0x01,  0xA6,  0xB4,  0x02,
10898  0x00,  0xA6,  0xB4,  0x02,  0x00,  0x33,  0x12,  0x00,  0xC2,  0x88,  0x00,  0x0E,  0x80,  0x63,  0x00,  0x43,
10899  0x00,  0xA0,  0x8C,  0x02,  0x4D,  0x04,  0x04,  0x01,  0x0B,  0xDC,  0xE7,  0x23,  0x04,  0x61,  0x84,  0x01,
10900  0x10,  0x31,  0x12,  0x35,  0x14,  0x01,  0xEC,  0x00,  0x6C,  0x38,  0x00,  0x3F,  0x00,  0x00,  0xEA,  0x82,
10901  0x18,  0x23,  0x04,  0x61,  0x18,  0xA0,  0xE2,  0x02,  0x04,  0x01,  0xA2,  0xC8,  0x00,  0x33,  0x1F,  0x00,
10902  0xC2,  0x88,  0x08,  0x31,  0x0A,  0x35,  0x0C,  0x39,  0x0E,  0x3D,  0x7E,  0x98,  0xB6,  0x2D,  0x01,  0xA6,
10903  0x14,  0x03,  0x00,  0xA6,  0x14,  0x03,  0x07,  0xA6,  0x0C,  0x03,  0x06,  0xA6,  0x10,  0x03,  0x03,  0xA6,
10904  0x20,  0x04,  0x02,  0xA6,  0x6C,  0x02,  0x00,  0x33,  0x33,  0x00,  0xC2,  0x88,  0x7C,  0x95,  0xEE,  0x82,
10905  0x60,  0x96,  0xEE,  0x82,  0x82,  0x98,  0x80,  0x42,  0x7E,  0x98,  0x64,  0xE4,  0x04,  0x01,  0x2D,  0xC8,
10906  0x31,  0x05,  0x07,  0x01,  0x00,  0xA2,  0x54,  0x03,  0x00,  0x43,  0x87,  0x01,  0x05,  0x05,  0x86,  0x98,
10907  0x7E,  0x98,  0x00,  0xA6,  0x16,  0x03,  0x07,  0xA6,  0x4C,  0x03,  0x03,  0xA6,  0x3C,  0x04,  0x06,  0xA6,
10908  0x50,  0x03,  0x01,  0xA6,  0x16,  0x03,  0x00,  0x33,  0x25,  0x00,  0xC2,  0x88,  0x7C,  0x95,  0x32,  0x83,
10909  0x60,  0x96,  0x32,  0x83,  0x04,  0x01,  0x10,  0xCE,  0x07,  0xC8,  0x05,  0x05,  0xEB,  0x04,  0x00,  0x33,
10910  0x00,  0x20,  0xC0,  0x20,  0x81,  0x62,  0x72,  0x83,  0x00,  0x01,  0x05,  0x05,  0xFF,  0xA2,  0x7A,  0x03,
10911  0xB1,  0x01,  0x08,  0x23,  0xB2,  0x01,  0x2E,  0x83,  0x05,  0x05,  0x15,  0x01,  0x00,  0xA2,  0x9A,  0x03,
10912  0xEC,  0x00,  0x6E,  0x00,  0x95,  0x01,  0x6C,  0x38,  0x00,  0x3F,  0x00,  0x00,  0x01,  0xA6,  0x96,  0x03,
10913  0x00,  0xA6,  0x96,  0x03,  0x10,  0x84,  0x80,  0x42,  0x7E,  0x98,  0x01,  0xA6,  0xA4,  0x03,  0x00,  0xA6,
10914  0xBC,  0x03,  0x10,  0x84,  0xA8,  0x98,  0x80,  0x42,  0x01,  0xA6,  0xA4,  0x03,  0x07,  0xA6,  0xB2,  0x03,
10915  0xD4,  0x83,  0x7C,  0x95,  0xA8,  0x83,  0x00,  0x33,  0x2F,  0x00,  0xC2,  0x88,  0xA8,  0x98,  0x80,  0x42,
10916  0x00,  0xA6,  0xBC,  0x03,  0x07,  0xA6,  0xCA,  0x03,  0xD4,  0x83,  0x7C,  0x95,  0xC0,  0x83,  0x00,  0x33,
10917  0x26,  0x00,  0xC2,  0x88,  0x38,  0x2B,  0x80,  0x32,  0x80,  0x36,  0x04,  0x23,  0xA0,  0x01,  0x12,  0x23,
10918  0xA1,  0x01,  0x10,  0x84,  0x07,  0xF0,  0x06,  0xA4,  0xF4,  0x03,  0x80,  0x6B,  0x80,  0x67,  0x05,  0x23,
10919  0x83,  0x03,  0x80,  0x63,  0x03,  0xA6,  0x0E,  0x04,  0x07,  0xA6,  0x06,  0x04,  0x06,  0xA6,  0x0A,  0x04,
10920  0x00,  0x33,  0x17,  0x00,  0xC2,  0x88,  0x7C,  0x95,  0xF4,  0x83,  0x60,  0x96,  0xF4,  0x83,  0x20,  0x84,
10921  0x07,  0xF0,  0x06,  0xA4,  0x20,  0x04,  0x80,  0x6B,  0x80,  0x67,  0x05,  0x23,  0x83,  0x03,  0x80,  0x63,
10922  0xB6,  0x2D,  0x03,  0xA6,  0x3C,  0x04,  0x07,  0xA6,  0x34,  0x04,  0x06,  0xA6,  0x38,  0x04,  0x00,  0x33,
10923  0x30,  0x00,  0xC2,  0x88,  0x7C,  0x95,  0x20,  0x84,  0x60,  0x96,  0x20,  0x84,  0x1D,  0x01,  0x06,  0xCC,
10924  0x00,  0x33,  0x00,  0x84,  0xC0,  0x20,  0x00,  0x23,  0xEA,  0x00,  0x81,  0x62,  0xA2,  0x0D,  0x80,  0x63,
10925  0x07,  0xA6,  0x5A,  0x04,  0x00,  0x33,  0x18,  0x00,  0xC2,  0x88,  0x03,  0x03,  0x80,  0x63,  0xA3,  0x01,
10926  0x07,  0xA4,  0x64,  0x04,  0x23,  0x01,  0x00,  0xA2,  0x86,  0x04,  0x0A,  0xA0,  0x76,  0x04,  0xE0,  0x00,
10927  0x00,  0x33,  0x1D,  0x00,  0xC2,  0x88,  0x0B,  0xA0,  0x82,  0x04,  0xE0,  0x00,  0x00,  0x33,  0x1E,  0x00,
10928  0xC2,  0x88,  0x42,  0x23,  0xF8,  0x88,  0x00,  0x23,  0x22,  0xA3,  0xE6,  0x04,  0x08,  0x23,  0x22,  0xA3,
10929  0xA2,  0x04,  0x28,  0x23,  0x22,  0xA3,  0xAE,  0x04,  0x02,  0x23,  0x22,  0xA3,  0xC4,  0x04,  0x42,  0x23,
10930  0xF8,  0x88,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA0,  0xAE,  0x04,  0x45,  0x23,  0xF8,  0x88,  0x04,  0x98,
10931  0x00,  0xA2,  0xC0,  0x04,  0xB4,  0x98,  0x00,  0x33,  0x00,  0x82,  0xC0,  0x20,  0x81,  0x62,  0xE8,  0x81,
10932  0x47,  0x23,  0xF8,  0x88,  0x04,  0x01,  0x0B,  0xDE,  0x04,  0x98,  0xB4,  0x98,  0x00,  0x33,  0x00,  0x81,
10933  0xC0,  0x20,  0x81,  0x62,  0x14,  0x01,  0x00,  0xA0,  0x00,  0x02,  0x43,  0x23,  0xF8,  0x88,  0x04,  0x23,
10934  0xA0,  0x01,  0x44,  0x23,  0xA1,  0x01,  0x80,  0x73,  0x4D,  0x00,  0x03,  0xA3,  0xF4,  0x04,  0x00,  0x33,
10935  0x27,  0x00,  0xC2,  0x88,  0x04,  0x01,  0x04,  0xDC,  0x02,  0x23,  0xA2,  0x01,  0x04,  0x23,  0xA0,  0x01,
10936  0x04,  0x98,  0x26,  0x95,  0x4B,  0x00,  0xF6,  0x00,  0x4F,  0x04,  0x4F,  0x00,  0x00,  0xA3,  0x22,  0x05,
10937  0x00,  0x05,  0x76,  0x00,  0x06,  0x61,  0x00,  0xA2,  0x1C,  0x05,  0x0A,  0x85,  0x46,  0x97,  0xCD,  0x04,
10938  0x24,  0x85,  0x48,  0x04,  0x84,  0x80,  0x02,  0x01,  0x03,  0xDA,  0x80,  0x23,  0x82,  0x01,  0x34,  0x85,
10939  0x02,  0x23,  0xA0,  0x01,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA2,  0x40,  0x05,  0x1D,  0x01,  0x04,  0xD6,
10940  0xFF,  0x23,  0x86,  0x41,  0x4B,  0x60,  0xCB,  0x00,  0xFF,  0x23,  0x80,  0x01,  0x49,  0x00,  0x81,  0x01,
10941  0x04,  0x01,  0x02,  0xC8,  0x30,  0x01,  0x80,  0x01,  0xF7,  0x04,  0x03,  0x01,  0x49,  0x04,  0x80,  0x01,
10942  0xC9,  0x00,  0x00,  0x05,  0x00,  0x01,  0xFF,  0xA0,  0x60,  0x05,  0x77,  0x04,  0x01,  0x23,  0xEA,  0x00,
10943  0x5D,  0x00,  0xFE,  0xC7,  0x00,  0x62,  0x00,  0x23,  0xEA,  0x00,  0x00,  0x63,  0x07,  0xA4,  0xF8,  0x05,
10944  0x03,  0x03,  0x02,  0xA0,  0x8E,  0x05,  0xF4,  0x85,  0x00,  0x33,  0x2D,  0x00,  0xC2,  0x88,  0x04,  0xA0,
10945  0xB8,  0x05,  0x80,  0x63,  0x00,  0x23,  0xDF,  0x00,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA2,  0xA4,  0x05,
10946  0x1D,  0x01,  0x06,  0xD6,  0x02,  0x23,  0x02,  0x41,  0x82,  0x01,  0x50,  0x00,  0x62,  0x97,  0x04,  0x85,
10947  0x04,  0x23,  0x02,  0x41,  0x82,  0x01,  0x04,  0x85,  0x08,  0xA0,  0xBE,  0x05,  0xF4,  0x85,  0x03,  0xA0,
10948  0xC4,  0x05,  0xF4,  0x85,  0x01,  0xA0,  0xCE,  0x05,  0x88,  0x00,  0x80,  0x63,  0xCC,  0x86,  0x07,  0xA0,
10949  0xEE,  0x05,  0x5F,  0x00,  0x00,  0x2B,  0xDF,  0x08,  0x00,  0xA2,  0xE6,  0x05,  0x80,  0x67,  0x80,  0x63,
10950  0x01,  0xA2,  0x7A,  0x06,  0x7C,  0x85,  0x06,  0x23,  0x68,  0x98,  0x48,  0x23,  0xF8,  0x88,  0x07,  0x23,
10951  0x80,  0x00,  0x06,  0x87,  0x80,  0x63,  0x7C,  0x85,  0x00,  0x23,  0xDF,  0x00,  0x00,  0x63,  0x4A,  0x00,
10952  0x06,  0x61,  0x00,  0xA2,  0x36,  0x06,  0x1D,  0x01,  0x16,  0xD4,  0xC0,  0x23,  0x07,  0x41,  0x83,  0x03,
10953  0x80,  0x63,  0x06,  0xA6,  0x1C,  0x06,  0x00,  0x33,  0x37,  0x00,  0xC2,  0x88,  0x1D,  0x01,  0x01,  0xD6,
10954  0x20,  0x23,  0x63,  0x60,  0x83,  0x03,  0x80,  0x63,  0x02,  0x23,  0xDF,  0x00,  0x07,  0xA6,  0x7C,  0x05,
10955  0xEF,  0x04,  0x6F,  0x00,  0x00,  0x63,  0x4B,  0x00,  0x06,  0x41,  0xCB,  0x00,  0x52,  0x00,  0x06,  0x61,
10956  0x00,  0xA2,  0x4E,  0x06,  0x1D,  0x01,  0x03,  0xCA,  0xC0,  0x23,  0x07,  0x41,  0x00,  0x63,  0x1D,  0x01,
10957  0x04,  0xCC,  0x00,  0x33,  0x00,  0x83,  0xC0,  0x20,  0x81,  0x62,  0x80,  0x23,  0x07,  0x41,  0x00,  0x63,
10958  0x80,  0x67,  0x08,  0x23,  0x83,  0x03,  0x80,  0x63,  0x00,  0x63,  0x01,  0x23,  0xDF,  0x00,  0x06,  0xA6,
10959  0x84,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x80,  0x67,  0x80,  0x63,  0x00,  0x33,  0x00,  0x40,  0xC0,  0x20,
10960  0x81,  0x62,  0x00,  0x63,  0x00,  0x00,  0xFE,  0x95,  0x83,  0x03,  0x80,  0x63,  0x06,  0xA6,  0x94,  0x06,
10961  0x07,  0xA6,  0x7C,  0x05,  0x00,  0x00,  0x01,  0xA0,  0x14,  0x07,  0x00,  0x2B,  0x40,  0x0E,  0x80,  0x63,
10962  0x01,  0x00,  0x06,  0xA6,  0xAA,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x40,  0x0E,  0x80,  0x63,  0x00,  0x43,
10963  0x00,  0xA0,  0xA2,  0x06,  0x06,  0xA6,  0xBC,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x80,  0x67,  0x40,  0x0E,
10964  0x80,  0x63,  0x07,  0xA6,  0x7C,  0x05,  0x00,  0x23,  0xDF,  0x00,  0x00,  0x63,  0x07,  0xA6,  0xD6,  0x06,
10965  0x00,  0x33,  0x2A,  0x00,  0xC2,  0x88,  0x03,  0x03,  0x80,  0x63,  0x89,  0x00,  0x0A,  0x2B,  0x07,  0xA6,
10966  0xE8,  0x06,  0x00,  0x33,  0x29,  0x00,  0xC2,  0x88,  0x00,  0x43,  0x00,  0xA2,  0xF4,  0x06,  0xC0,  0x0E,
10967  0x80,  0x63,  0xDE,  0x86,  0xC0,  0x0E,  0x00,  0x33,  0x00,  0x80,  0xC0,  0x20,  0x81,  0x62,  0x04,  0x01,
10968  0x02,  0xDA,  0x80,  0x63,  0x7C,  0x85,  0x80,  0x7B,  0x80,  0x63,  0x06,  0xA6,  0x8C,  0x06,  0x00,  0x33,
10969  0x2C,  0x00,  0xC2,  0x88,  0x0C,  0xA2,  0x2E,  0x07,  0xFE,  0x95,  0x83,  0x03,  0x80,  0x63,  0x06,  0xA6,
10970  0x2C,  0x07,  0x07,  0xA6,  0x7C,  0x05,  0x00,  0x33,  0x3D,  0x00,  0xC2,  0x88,  0x00,  0x00,  0x80,  0x67,
10971  0x83,  0x03,  0x80,  0x63,  0x0C,  0xA0,  0x44,  0x07,  0x07,  0xA6,  0x7C,  0x05,  0xBF,  0x23,  0x04,  0x61,
10972  0x84,  0x01,  0xE6,  0x84,  0x00,  0x63,  0xF0,  0x04,  0x01,  0x01,  0xF1,  0x00,  0x00,  0x01,  0xF2,  0x00,
10973  0x01,  0x05,  0x80,  0x01,  0x72,  0x04,  0x71,  0x00,  0x81,  0x01,  0x70,  0x04,  0x80,  0x05,  0x81,  0x05,
10974  0x00,  0x63,  0xF0,  0x04,  0xF2,  0x00,  0x72,  0x04,  0x01,  0x01,  0xF1,  0x00,  0x70,  0x00,  0x81,  0x01,
10975  0x70,  0x04,  0x71,  0x00,  0x81,  0x01,  0x72,  0x00,  0x80,  0x01,  0x71,  0x04,  0x70,  0x00,  0x80,  0x01,
10976  0x70,  0x04,  0x00,  0x63,  0xF0,  0x04,  0xF2,  0x00,  0x72,  0x04,  0x00,  0x01,  0xF1,  0x00,  0x70,  0x00,
10977  0x80,  0x01,  0x70,  0x04,  0x71,  0x00,  0x80,  0x01,  0x72,  0x00,  0x81,  0x01,  0x71,  0x04,  0x70,  0x00,
10978  0x81,  0x01,  0x70,  0x04,  0x00,  0x63,  0x00,  0x23,  0xB3,  0x01,  0x83,  0x05,  0xA3,  0x01,  0xA2,  0x01,
10979  0xA1,  0x01,  0x01,  0x23,  0xA0,  0x01,  0x00,  0x01,  0xC8,  0x00,  0x03,  0xA1,  0xC4,  0x07,  0x00,  0x33,
10980  0x07,  0x00,  0xC2,  0x88,  0x80,  0x05,  0x81,  0x05,  0x04,  0x01,  0x11,  0xC8,  0x48,  0x00,  0xB0,  0x01,
10981  0xB1,  0x01,  0x08,  0x23,  0xB2,  0x01,  0x05,  0x01,  0x48,  0x04,  0x00,  0x43,  0x00,  0xA2,  0xE4,  0x07,
10982  0x00,  0x05,  0xDA,  0x87,  0x00,  0x01,  0xC8,  0x00,  0xFF,  0x23,  0x80,  0x01,  0x05,  0x05,  0x00,  0x63,
10983  0xF7,  0x04,  0x1A,  0x09,  0xF6,  0x08,  0x6E,  0x04,  0x00,  0x02,  0x80,  0x43,  0x76,  0x08,  0x80,  0x02,
10984  0x77,  0x04,  0x00,  0x63,  0xF7,  0x04,  0x1A,  0x09,  0xF6,  0x08,  0x6E,  0x04,  0x00,  0x02,  0x00,  0xA0,
10985  0x14,  0x08,  0x16,  0x88,  0x00,  0x43,  0x76,  0x08,  0x80,  0x02,  0x77,  0x04,  0x00,  0x63,  0xF3,  0x04,
10986  0x00,  0x23,  0xF4,  0x00,  0x74,  0x00,  0x80,  0x43,  0xF4,  0x00,  0xCF,  0x40,  0x00,  0xA2,  0x44,  0x08,
10987  0x74,  0x04,  0x02,  0x01,  0xF7,  0xC9,  0xF6,  0xD9,  0x00,  0x01,  0x01,  0xA1,  0x24,  0x08,  0x04,  0x98,
10988  0x26,  0x95,  0x24,  0x88,  0x73,  0x04,  0x00,  0x63,  0xF3,  0x04,  0x75,  0x04,  0x5A,  0x88,  0x02,  0x01,
10989  0x04,  0xD8,  0x46,  0x97,  0x04,  0x98,  0x26,  0x95,  0x4A,  0x88,  0x75,  0x00,  0x00,  0xA3,  0x64,  0x08,
10990  0x00,  0x05,  0x4E,  0x88,  0x73,  0x04,  0x00,  0x63,  0x80,  0x7B,  0x80,  0x63,  0x06,  0xA6,  0x76,  0x08,
10991  0x00,  0x33,  0x3E,  0x00,  0xC2,  0x88,  0x80,  0x67,  0x83,  0x03,  0x80,  0x63,  0x00,  0x63,  0x38,  0x2B,
10992  0x9C,  0x88,  0x38,  0x2B,  0x92,  0x88,  0x32,  0x09,  0x31,  0x05,  0x92,  0x98,  0x05,  0x05,  0xB2,  0x09,
10993  0x00,  0x63,  0x00,  0x32,  0x00,  0x36,  0x00,  0x3A,  0x00,  0x3E,  0x00,  0x63,  0x80,  0x32,  0x80,  0x36,
10994  0x80,  0x3A,  0x80,  0x3E,  0xB4,  0x3D,  0x00,  0x63,  0x38,  0x2B,  0x40,  0x32,  0x40,  0x36,  0x40,  0x3A,
10995  0x40,  0x3E,  0x00,  0x63,  0x5A,  0x20,  0xC9,  0x40,  0x00,  0xA0,  0xB4,  0x08,  0x5D,  0x00,  0xFE,  0xC3,
10996  0x00,  0x63,  0x80,  0x73,  0xE6,  0x20,  0x02,  0x23,  0xE8,  0x00,  0x82,  0x73,  0xFF,  0xFD,  0x80,  0x73,
10997  0x13,  0x23,  0xF8,  0x88,  0x66,  0x20,  0xC0,  0x20,  0x04,  0x23,  0xA0,  0x01,  0xA1,  0x23,  0xA1,  0x01,
10998  0x81,  0x62,  0xE2,  0x88,  0x80,  0x73,  0x80,  0x77,  0x68,  0x00,  0x00,  0xA2,  0x80,  0x00,  0x03,  0xC2,
10999  0xF1,  0xC7,  0x41,  0x23,  0xF8,  0x88,  0x11,  0x23,  0xA1,  0x01,  0x04,  0x23,  0xA0,  0x01,  0xE6,  0x84,
11000};
11001
11002STATIC ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
11003STATIC ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
11004
11005#define ASC_SYN_OFFSET_ONE_DISABLE_LIST  16
11006STATIC uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] =
11007{
11008    SCSICMD_Inquiry,
11009    SCSICMD_RequestSense,
11010    SCSICMD_ReadCapacity,
11011    SCSICMD_ReadTOC,
11012    SCSICMD_ModeSelect6,
11013    SCSICMD_ModeSense6,
11014    SCSICMD_ModeSelect10,
11015    SCSICMD_ModeSense10,
11016    0xFF,
11017    0xFF,
11018    0xFF,
11019    0xFF,
11020    0xFF,
11021    0xFF,
11022    0xFF,
11023    0xFF
11024};
11025
11026STATIC int
11027AscExeScsiQueue(
11028                   ASC_DVC_VAR *asc_dvc,
11029                   ASC_SCSI_Q *scsiq
11030)
11031{
11032    PortAddr            iop_base;
11033    ulong               last_int_level;
11034    int                 sta;
11035    int                 n_q_required;
11036    int                 disable_syn_offset_one_fix;
11037    int                 i;
11038    ASC_PADDR           addr;
11039    ASC_EXE_CALLBACK    asc_exe_callback;
11040    ushort              sg_entry_cnt = 0;
11041    ushort              sg_entry_cnt_minus_one = 0;
11042    uchar               target_ix;
11043    uchar               tid_no;
11044    uchar               sdtr_data;
11045    uchar               extra_bytes;
11046    uchar               scsi_cmd;
11047    uchar               disable_cmd;
11048    ASC_SG_HEAD         *sg_head;
11049    ASC_DCNT            data_cnt;
11050
11051    iop_base = asc_dvc->iop_base;
11052    sg_head = scsiq->sg_head;
11053    asc_exe_callback = asc_dvc->exe_callback;
11054    if (asc_dvc->err_code != 0)
11055        return (ERR);
11056    if (scsiq == (ASC_SCSI_Q *) 0L) {
11057        AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
11058        return (ERR);
11059    }
11060    scsiq->q1.q_no = 0;
11061    if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
11062        scsiq->q1.extra_bytes = 0;
11063    }
11064    sta = 0;
11065    target_ix = scsiq->q2.target_ix;
11066    tid_no = ASC_TIX_TO_TID(target_ix);
11067    n_q_required = 1;
11068    if (scsiq->cdbptr[0] == SCSICMD_RequestSense) {
11069        if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
11070            asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
11071            sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
11072            AscMsgOutSDTR(asc_dvc,
11073                          asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
11074                          (uchar) (asc_dvc->max_sdtr_index - 1)],
11075                          (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
11076            scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
11077        }
11078    }
11079    last_int_level = DvcEnterCritical();
11080    if (asc_dvc->in_critical_cnt != 0) {
11081        DvcLeaveCritical(last_int_level);
11082        AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
11083        return (ERR);
11084    }
11085    asc_dvc->in_critical_cnt++;
11086    if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
11087        if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
11088            asc_dvc->in_critical_cnt--;
11089            DvcLeaveCritical(last_int_level);
11090            return (ERR);
11091        }
11092#if !CC_VERY_LONG_SG_LIST
11093        if (sg_entry_cnt > ASC_MAX_SG_LIST)
11094        {
11095            asc_dvc->in_critical_cnt--;
11096            DvcLeaveCritical(last_int_level);
11097            return(ERR);
11098        }
11099#endif /* !CC_VERY_LONG_SG_LIST */
11100        if (sg_entry_cnt == 1) {
11101            scsiq->q1.data_addr = (ADV_PADDR) sg_head->sg_list[0].addr;
11102            scsiq->q1.data_cnt = (ADV_DCNT) sg_head->sg_list[0].bytes;
11103            scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
11104        }
11105        sg_entry_cnt_minus_one = sg_entry_cnt - 1;
11106    }
11107    scsi_cmd = scsiq->cdbptr[0];
11108    disable_syn_offset_one_fix = FALSE;
11109    if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
11110        !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
11111        if (scsiq->q1.cntl & QC_SG_HEAD) {
11112            data_cnt = 0;
11113            for (i = 0; i < sg_entry_cnt; i++) {
11114                data_cnt += (ADV_DCNT) le32_to_cpu(sg_head->sg_list[i].bytes);
11115            }
11116        } else {
11117            data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
11118        }
11119        if (data_cnt != 0UL) {
11120            if (data_cnt < 512UL) {
11121                disable_syn_offset_one_fix = TRUE;
11122            } else {
11123                for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST; i++) {
11124                    disable_cmd = _syn_offset_one_disable_cmd[i];
11125                    if (disable_cmd == 0xFF) {
11126                        break;
11127                    }
11128                    if (scsi_cmd == disable_cmd) {
11129                        disable_syn_offset_one_fix = TRUE;
11130                        break;
11131                    }
11132                }
11133            }
11134        }
11135    }
11136    if (disable_syn_offset_one_fix) {
11137        scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
11138        scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
11139                               ASC_TAG_FLAG_DISABLE_DISCONNECT);
11140    } else {
11141        scsiq->q2.tag_code &= 0x27;
11142    }
11143    if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
11144        if (asc_dvc->bug_fix_cntl) {
11145            if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
11146                if ((scsi_cmd == SCSICMD_Read6) ||
11147                    (scsi_cmd == SCSICMD_Read10)) {
11148                    addr =
11149                        (ADV_PADDR) le32_to_cpu(
11150                            sg_head->sg_list[sg_entry_cnt_minus_one].addr) +
11151                        (ADV_DCNT) le32_to_cpu(
11152                            sg_head->sg_list[sg_entry_cnt_minus_one].bytes);
11153                    extra_bytes = (uchar) ((ushort) addr & 0x0003);
11154                    if ((extra_bytes != 0) &&
11155                        ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
11156                         == 0)) {
11157                        scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
11158                        scsiq->q1.extra_bytes = extra_bytes;
11159                        data_cnt = le32_to_cpu(
11160                            sg_head->sg_list[sg_entry_cnt_minus_one].bytes);
11161                        data_cnt -= (ASC_DCNT) extra_bytes;
11162                        sg_head->sg_list[sg_entry_cnt_minus_one].bytes =
11163                            cpu_to_le32(data_cnt);
11164                    }
11165                }
11166            }
11167        }
11168        sg_head->entry_to_copy = sg_head->entry_cnt;
11169#if CC_VERY_LONG_SG_LIST
11170        /*
11171         * Set the sg_entry_cnt to the maximum possible. The rest of
11172         * the SG elements will be copied when the RISC completes the
11173         * SG elements that fit and halts.
11174         */
11175        if (sg_entry_cnt > ASC_MAX_SG_LIST)
11176        {
11177             sg_entry_cnt = ASC_MAX_SG_LIST;
11178        }
11179#endif /* CC_VERY_LONG_SG_LIST */
11180        n_q_required = AscSgListToQueue(sg_entry_cnt);
11181        if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
11182            (uint) n_q_required) || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
11183            if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
11184                                        n_q_required)) == 1) {
11185                asc_dvc->in_critical_cnt--;
11186                if (asc_exe_callback != 0) {
11187                    (*asc_exe_callback) (asc_dvc, scsiq);
11188                }
11189                DvcLeaveCritical(last_int_level);
11190                return (sta);
11191            }
11192        }
11193    } else {
11194        if (asc_dvc->bug_fix_cntl) {
11195            if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
11196                if ((scsi_cmd == SCSICMD_Read6) ||
11197                    (scsi_cmd == SCSICMD_Read10)) {
11198                    addr = le32_to_cpu(scsiq->q1.data_addr) +
11199                        le32_to_cpu(scsiq->q1.data_cnt);
11200                    extra_bytes = (uchar) ((ushort) addr & 0x0003);
11201                    if ((extra_bytes != 0) &&
11202                        ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
11203                          == 0)) {
11204                        data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
11205                        if (((ushort) data_cnt & 0x01FF) == 0) {
11206                            scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
11207                            data_cnt -= (ASC_DCNT) extra_bytes;
11208                            scsiq->q1.data_cnt = cpu_to_le32(data_cnt);
11209                            scsiq->q1.extra_bytes = extra_bytes;
11210                        }
11211                    }
11212                }
11213            }
11214        }
11215        n_q_required = 1;
11216        if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
11217            ((scsiq->q1.cntl & QC_URGENT) != 0)) {
11218            if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
11219                                        n_q_required)) == 1) {
11220                asc_dvc->in_critical_cnt--;
11221                if (asc_exe_callback != 0) {
11222                    (*asc_exe_callback) (asc_dvc, scsiq);
11223                }
11224                DvcLeaveCritical(last_int_level);
11225                return (sta);
11226            }
11227        }
11228    }
11229    asc_dvc->in_critical_cnt--;
11230    DvcLeaveCritical(last_int_level);
11231    return (sta);
11232}
11233
11234STATIC int
11235AscSendScsiQueue(
11236                    ASC_DVC_VAR *asc_dvc,
11237                    ASC_SCSI_Q *scsiq,
11238                    uchar n_q_required
11239)
11240{
11241    PortAddr            iop_base;
11242    uchar               free_q_head;
11243    uchar               next_qp;
11244    uchar               tid_no;
11245    uchar               target_ix;
11246    int                 sta;
11247
11248    iop_base = asc_dvc->iop_base;
11249    target_ix = scsiq->q2.target_ix;
11250    tid_no = ASC_TIX_TO_TID(target_ix);
11251    sta = 0;
11252    free_q_head = (uchar) AscGetVarFreeQHead(iop_base);
11253    if (n_q_required > 1) {
11254        if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
11255                                       free_q_head, (uchar) (n_q_required)))
11256            != (uchar) ASC_QLINK_END) {
11257            asc_dvc->last_q_shortage = 0;
11258            scsiq->sg_head->queue_cnt = n_q_required - 1;
11259            scsiq->q1.q_no = free_q_head;
11260            if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
11261                                              free_q_head)) == 1) {
11262                AscPutVarFreeQHead(iop_base, next_qp);
11263                asc_dvc->cur_total_qng += (uchar) (n_q_required);
11264                asc_dvc->cur_dvc_qng[tid_no]++;
11265            }
11266            return (sta);
11267        }
11268    } else if (n_q_required == 1) {
11269        if ((next_qp = AscAllocFreeQueue(iop_base,
11270                                         free_q_head)) != ASC_QLINK_END) {
11271            scsiq->q1.q_no = free_q_head;
11272            if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
11273                                        free_q_head)) == 1) {
11274                AscPutVarFreeQHead(iop_base, next_qp);
11275                asc_dvc->cur_total_qng++;
11276                asc_dvc->cur_dvc_qng[tid_no]++;
11277            }
11278            return (sta);
11279        }
11280    }
11281    return (sta);
11282}
11283
11284STATIC int
11285AscSgListToQueue(
11286                    int sg_list
11287)
11288{
11289    int                 n_sg_list_qs;
11290
11291    n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
11292    if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
11293        n_sg_list_qs++;
11294    return (n_sg_list_qs + 1);
11295}
11296
11297
11298STATIC uint
11299AscGetNumOfFreeQueue(
11300                        ASC_DVC_VAR *asc_dvc,
11301                        uchar target_ix,
11302                        uchar n_qs
11303)
11304{
11305    uint                cur_used_qs;
11306    uint                cur_free_qs;
11307    ASC_SCSI_BIT_ID_TYPE target_id;
11308    uchar               tid_no;
11309
11310    target_id = ASC_TIX_TO_TARGET_ID(target_ix);
11311    tid_no = ASC_TIX_TO_TID(target_ix);
11312    if ((asc_dvc->unit_not_ready & target_id) ||
11313        (asc_dvc->queue_full_or_busy & target_id)) {
11314        return (0);
11315    }
11316    if (n_qs == 1) {
11317        cur_used_qs = (uint) asc_dvc->cur_total_qng +
11318          (uint) asc_dvc->last_q_shortage +
11319          (uint) ASC_MIN_FREE_Q;
11320    } else {
11321        cur_used_qs = (uint) asc_dvc->cur_total_qng +
11322          (uint) ASC_MIN_FREE_Q;
11323    }
11324    if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
11325        cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
11326        if (asc_dvc->cur_dvc_qng[tid_no] >=
11327            asc_dvc->max_dvc_qng[tid_no]) {
11328            return (0);
11329        }
11330        return (cur_free_qs);
11331    }
11332    if (n_qs > 1) {
11333        if ((n_qs > asc_dvc->last_q_shortage) && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
11334            asc_dvc->last_q_shortage = n_qs;
11335        }
11336    }
11337    return (0);
11338}
11339
11340STATIC int
11341AscPutReadyQueue(
11342                    ASC_DVC_VAR *asc_dvc,
11343                    ASC_SCSI_Q *scsiq,
11344                    uchar q_no
11345)
11346{
11347    ushort              q_addr;
11348    uchar               tid_no;
11349    uchar               sdtr_data;
11350    uchar               syn_period_ix;
11351    uchar               syn_offset;
11352    PortAddr            iop_base;
11353
11354    iop_base = asc_dvc->iop_base;
11355    if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
11356        ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
11357        tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
11358        sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
11359        syn_period_ix = (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
11360        syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
11361        AscMsgOutSDTR(asc_dvc,
11362                      asc_dvc->sdtr_period_tbl[syn_period_ix],
11363                      syn_offset);
11364        scsiq->q1.cntl |= QC_MSG_OUT;
11365    }
11366    q_addr = ASC_QNO_TO_QADDR(q_no);
11367    if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
11368        scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
11369    }
11370    scsiq->q1.status = QS_FREE;
11371    AscMemWordCopyPtrToLram(iop_base,
11372                         q_addr + ASC_SCSIQ_CDB_BEG,
11373                         (uchar *) scsiq->cdbptr,
11374                         scsiq->q2.cdb_len >> 1);
11375
11376    DvcPutScsiQ(iop_base,
11377                q_addr + ASC_SCSIQ_CPY_BEG,
11378                (uchar *) &scsiq->q1.cntl,
11379                ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
11380    AscWriteLramWord(iop_base,
11381                     (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
11382             (ushort) (((ushort) scsiq->q1.q_no << 8) | (ushort) QS_READY));
11383    return (1);
11384}
11385
11386STATIC int
11387AscPutReadySgListQueue(
11388                          ASC_DVC_VAR *asc_dvc,
11389                          ASC_SCSI_Q *scsiq,
11390                          uchar q_no
11391)
11392{
11393    int                 sta;
11394    int                 i;
11395    ASC_SG_HEAD *sg_head;
11396    ASC_SG_LIST_Q       scsi_sg_q;
11397    ASC_DCNT            saved_data_addr;
11398    ASC_DCNT            saved_data_cnt;
11399    PortAddr            iop_base;
11400    ushort              sg_list_dwords;
11401    ushort              sg_index;
11402    ushort              sg_entry_cnt;
11403    ushort              q_addr;
11404    uchar               next_qp;
11405
11406    iop_base = asc_dvc->iop_base;
11407    sg_head = scsiq->sg_head;
11408    saved_data_addr = scsiq->q1.data_addr;
11409    saved_data_cnt = scsiq->q1.data_cnt;
11410    scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
11411    scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
11412#if CC_VERY_LONG_SG_LIST
11413    /*
11414     * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
11415     * then not all SG elements will fit in the allocated queues.
11416     * The rest of the SG elements will be copied when the RISC
11417     * completes the SG elements that fit and halts.
11418     */
11419    if (sg_head->entry_cnt > ASC_MAX_SG_LIST)
11420    {
11421         /*
11422          * Set sg_entry_cnt to be the number of SG elements that
11423          * will fit in the allocated SG queues. It is minus 1, because
11424          * the first SG element is handled above. ASC_MAX_SG_LIST is
11425          * already inflated by 1 to account for this. For example it
11426          * may be 50 which is 1 + 7 queues * 7 SG elements.
11427          */
11428         sg_entry_cnt = ASC_MAX_SG_LIST - 1;
11429
11430         /*
11431          * Keep track of remaining number of SG elements that will
11432          * need to be handled from a_isr.c.
11433          */
11434         scsiq->remain_sg_entry_cnt = sg_head->entry_cnt - ASC_MAX_SG_LIST;
11435    } else
11436    {
11437#endif /* CC_VERY_LONG_SG_LIST */
11438         /*
11439          * Set sg_entry_cnt to be the number of SG elements that
11440          * will fit in the allocated SG queues. It is minus 1, because
11441          * the first SG element is handled above.
11442          */
11443         sg_entry_cnt = sg_head->entry_cnt - 1;
11444#if CC_VERY_LONG_SG_LIST
11445    }
11446#endif /* CC_VERY_LONG_SG_LIST */
11447    if (sg_entry_cnt != 0) {
11448        scsiq->q1.cntl |= QC_SG_HEAD;
11449        q_addr = ASC_QNO_TO_QADDR(q_no);
11450        sg_index = 1;
11451        scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
11452        scsi_sg_q.sg_head_qp = q_no;
11453        scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
11454        for (i = 0; i < sg_head->queue_cnt; i++) {
11455            scsi_sg_q.seq_no = i + 1;
11456            if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
11457                sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
11458                sg_entry_cnt -= ASC_SG_LIST_PER_Q;
11459                if (i == 0) {
11460                    scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q;
11461                    scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q;
11462                } else {
11463                    scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
11464                    scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
11465                }
11466            } else {
11467#if CC_VERY_LONG_SG_LIST
11468                /*
11469                 * This is the last SG queue in the list of
11470                 * allocated SG queues. If there are more
11471                 * SG elements than will fit in the allocated
11472                 * queues, then set the QCSG_SG_XFER_MORE flag.
11473                 */
11474                if (sg_head->entry_cnt > ASC_MAX_SG_LIST)
11475                {
11476                    scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
11477                } else
11478                {
11479#endif /* CC_VERY_LONG_SG_LIST */
11480                    scsi_sg_q.cntl |= QCSG_SG_XFER_END;
11481#if CC_VERY_LONG_SG_LIST
11482                }
11483#endif /* CC_VERY_LONG_SG_LIST */
11484                sg_list_dwords = sg_entry_cnt << 1;
11485                if (i == 0) {
11486                    scsi_sg_q.sg_list_cnt = sg_entry_cnt;
11487                    scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt;
11488                } else {
11489                    scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
11490                    scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
11491                }
11492                sg_entry_cnt = 0;
11493            }
11494            next_qp = AscReadLramByte(iop_base,
11495                                      (ushort) (q_addr + ASC_SCSIQ_B_FWD));
11496            scsi_sg_q.q_no = next_qp;
11497            q_addr = ASC_QNO_TO_QADDR(next_qp);
11498            AscMemWordCopyPtrToLram(iop_base,
11499                                q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
11500                                (uchar *) &scsi_sg_q,
11501                                sizeof(ASC_SG_LIST_Q) >> 1);
11502            AscMemDWordCopyPtrToLram(iop_base,
11503                                q_addr + ASC_SGQ_LIST_BEG,
11504                                (uchar *) &sg_head->sg_list[sg_index],
11505                                sg_list_dwords);
11506            sg_index += ASC_SG_LIST_PER_Q;
11507            scsiq->next_sg_index = sg_index;
11508        }
11509    } else {
11510        scsiq->q1.cntl &= ~QC_SG_HEAD;
11511    }
11512    sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
11513    scsiq->q1.data_addr = saved_data_addr;
11514    scsiq->q1.data_cnt = saved_data_cnt;
11515    return (sta);
11516}
11517
11518STATIC int
11519AscSetRunChipSynRegAtID(
11520                           PortAddr iop_base,
11521                           uchar tid_no,
11522                           uchar sdtr_data
11523)
11524{
11525    int                 sta = FALSE;
11526
11527    if (AscHostReqRiscHalt(iop_base)) {
11528        sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
11529        AscStartChip(iop_base);
11530        return (sta);
11531    }
11532    return (sta);
11533}
11534
11535STATIC int
11536AscSetChipSynRegAtID(
11537                        PortAddr iop_base,
11538                        uchar id,
11539                        uchar sdtr_data
11540)
11541{
11542    ASC_SCSI_BIT_ID_TYPE org_id;
11543    int                 i;
11544    int                 sta = TRUE;
11545
11546    AscSetBank(iop_base, 1);
11547    org_id = AscReadChipDvcID(iop_base);
11548    for (i = 0; i <= ASC_MAX_TID; i++) {
11549        if (org_id == (0x01 << i))
11550            break;
11551    }
11552    org_id = (ASC_SCSI_BIT_ID_TYPE) i;
11553    AscWriteChipDvcID(iop_base, id);
11554    if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
11555        AscSetBank(iop_base, 0);
11556        AscSetChipSyn(iop_base, sdtr_data);
11557        if (AscGetChipSyn(iop_base) != sdtr_data) {
11558            sta = FALSE;
11559        }
11560    } else {
11561        sta = FALSE;
11562    }
11563    AscSetBank(iop_base, 1);
11564    AscWriteChipDvcID(iop_base, org_id);
11565    AscSetBank(iop_base, 0);
11566    return (sta);
11567}
11568
11569STATIC ushort
11570AscInitLram(
11571               ASC_DVC_VAR *asc_dvc
11572)
11573{
11574    uchar               i;
11575    ushort              s_addr;
11576    PortAddr            iop_base;
11577    ushort              warn_code;
11578
11579    iop_base = asc_dvc->iop_base;
11580    warn_code = 0;
11581    AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
11582               (ushort) (((int) (asc_dvc->max_total_qng + 2 + 1) * 64) >> 1)
11583);
11584    i = ASC_MIN_ACTIVE_QNO;
11585    s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
11586    AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11587                     (uchar) (i + 1));
11588    AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11589                     (uchar) (asc_dvc->max_total_qng));
11590    AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11591                     (uchar) i);
11592    i++;
11593    s_addr += ASC_QBLK_SIZE;
11594    for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
11595        AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11596                         (uchar) (i + 1));
11597        AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11598                         (uchar) (i - 1));
11599        AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11600                         (uchar) i);
11601    }
11602    AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11603                     (uchar) ASC_QLINK_END);
11604    AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11605                     (uchar) (asc_dvc->max_total_qng - 1));
11606    AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11607                     (uchar) asc_dvc->max_total_qng);
11608    i++;
11609    s_addr += ASC_QBLK_SIZE;
11610    for (; i <= (uchar) (asc_dvc->max_total_qng + 3);
11611         i++, s_addr += ASC_QBLK_SIZE) {
11612        AscWriteLramByte(iop_base,
11613                         (ushort) (s_addr + (ushort) ASC_SCSIQ_B_FWD), i);
11614        AscWriteLramByte(iop_base,
11615                         (ushort) (s_addr + (ushort) ASC_SCSIQ_B_BWD), i);
11616        AscWriteLramByte(iop_base,
11617                         (ushort) (s_addr + (ushort) ASC_SCSIQ_B_QNO), i);
11618    }
11619    return (warn_code);
11620}
11621
11622STATIC ushort
11623AscInitQLinkVar(
11624                   ASC_DVC_VAR *asc_dvc
11625)
11626{
11627    PortAddr            iop_base;
11628    int                 i;
11629    ushort              lram_addr;
11630
11631    iop_base = asc_dvc->iop_base;
11632    AscPutRiscVarFreeQHead(iop_base, 1);
11633    AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
11634    AscPutVarFreeQHead(iop_base, 1);
11635    AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
11636    AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
11637                     (uchar) ((int) asc_dvc->max_total_qng + 1));
11638    AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
11639                     (uchar) ((int) asc_dvc->max_total_qng + 2));
11640    AscWriteLramByte(iop_base, (ushort) ASCV_TOTAL_READY_Q_B,
11641                     asc_dvc->max_total_qng);
11642    AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
11643    AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
11644    AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
11645    AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
11646    AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
11647    AscPutQDoneInProgress(iop_base, 0);
11648    lram_addr = ASC_QADR_BEG;
11649    for (i = 0; i < 32; i++, lram_addr += 2) {
11650        AscWriteLramWord(iop_base, lram_addr, 0);
11651    }
11652    return (0);
11653}
11654
11655STATIC int
11656AscSetLibErrorCode(
11657                      ASC_DVC_VAR *asc_dvc,
11658                      ushort err_code
11659)
11660{
11661    if (asc_dvc->err_code == 0) {
11662        asc_dvc->err_code = err_code;
11663        AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
11664                         err_code);
11665    }
11666    return (err_code);
11667}
11668
11669
11670STATIC uchar
11671AscMsgOutSDTR(
11672                 ASC_DVC_VAR *asc_dvc,
11673                 uchar sdtr_period,
11674                 uchar sdtr_offset
11675)
11676{
11677    EXT_MSG             sdtr_buf;
11678    uchar               sdtr_period_index;
11679    PortAddr            iop_base;
11680
11681    iop_base = asc_dvc->iop_base;
11682    sdtr_buf.msg_type = MS_EXTEND;
11683    sdtr_buf.msg_len = MS_SDTR_LEN;
11684    sdtr_buf.msg_req = MS_SDTR_CODE;
11685    sdtr_buf.xfer_period = sdtr_period;
11686    sdtr_offset &= ASC_SYN_MAX_OFFSET;
11687    sdtr_buf.req_ack_offset = sdtr_offset;
11688    if ((sdtr_period_index =
11689         AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
11690        asc_dvc->max_sdtr_index) {
11691        AscMemWordCopyPtrToLram(iop_base,
11692                             ASCV_MSGOUT_BEG,
11693                             (uchar *) &sdtr_buf,
11694                             sizeof (EXT_MSG) >> 1);
11695        return ((sdtr_period_index << 4) | sdtr_offset);
11696    } else {
11697
11698        sdtr_buf.req_ack_offset = 0;
11699        AscMemWordCopyPtrToLram(iop_base,
11700                             ASCV_MSGOUT_BEG,
11701                             (uchar *) &sdtr_buf,
11702                             sizeof (EXT_MSG) >> 1);
11703        return (0);
11704    }
11705}
11706
11707STATIC uchar
11708AscCalSDTRData(
11709                  ASC_DVC_VAR *asc_dvc,
11710                  uchar sdtr_period,
11711                  uchar syn_offset
11712)
11713{
11714    uchar               byte;
11715    uchar               sdtr_period_ix;
11716
11717    sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
11718    if (
11719           (sdtr_period_ix > asc_dvc->max_sdtr_index)
11720) {
11721        return (0xFF);
11722    }
11723    byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
11724    return (byte);
11725}
11726
11727STATIC void
11728AscSetChipSDTR(
11729                  PortAddr iop_base,
11730                  uchar sdtr_data,
11731                  uchar tid_no
11732)
11733{
11734    AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
11735    AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
11736    return;
11737}
11738
11739STATIC uchar
11740AscGetSynPeriodIndex(
11741                        ASC_DVC_VAR *asc_dvc,
11742                        uchar syn_time
11743)
11744{
11745    uchar             *period_table;
11746    int                 max_index;
11747    int                 min_index;
11748    int                 i;
11749
11750    period_table = asc_dvc->sdtr_period_tbl;
11751    max_index = (int) asc_dvc->max_sdtr_index;
11752    min_index = (int)asc_dvc->host_init_sdtr_index;
11753    if ((syn_time <= period_table[max_index])) {
11754        for (i = min_index; i < (max_index - 1); i++) {
11755            if (syn_time <= period_table[i]) {
11756                return ((uchar) i);
11757            }
11758        }
11759        return ((uchar) max_index);
11760    } else {
11761        return ((uchar) (max_index + 1));
11762    }
11763}
11764
11765STATIC uchar
11766AscAllocFreeQueue(
11767                     PortAddr iop_base,
11768                     uchar free_q_head
11769)
11770{
11771    ushort              q_addr;
11772    uchar               next_qp;
11773    uchar               q_status;
11774
11775    q_addr = ASC_QNO_TO_QADDR(free_q_head);
11776    q_status = (uchar) AscReadLramByte(iop_base,
11777                                    (ushort) (q_addr + ASC_SCSIQ_B_STATUS));
11778    next_qp = AscReadLramByte(iop_base,
11779                              (ushort) (q_addr + ASC_SCSIQ_B_FWD));
11780    if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
11781        return (next_qp);
11782    }
11783    return (ASC_QLINK_END);
11784}
11785
11786STATIC uchar
11787AscAllocMultipleFreeQueue(
11788                             PortAddr iop_base,
11789                             uchar free_q_head,
11790                             uchar n_free_q
11791)
11792{
11793    uchar               i;
11794
11795    for (i = 0; i < n_free_q; i++) {
11796        if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
11797            == ASC_QLINK_END) {
11798            return (ASC_QLINK_END);
11799        }
11800    }
11801    return (free_q_head);
11802}
11803
11804STATIC int
11805AscHostReqRiscHalt(
11806                      PortAddr iop_base
11807)
11808{
11809    int                 count = 0;
11810    int                 sta = 0;
11811    uchar               saved_stop_code;
11812
11813    if (AscIsChipHalted(iop_base))
11814        return (1);
11815    saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
11816    AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
11817                     ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP
11818);
11819    do {
11820        if (AscIsChipHalted(iop_base)) {
11821            sta = 1;
11822            break;
11823        }
11824        DvcSleepMilliSecond(100);
11825    } while (count++ < 20);
11826    AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
11827    return (sta);
11828}
11829
11830STATIC int
11831AscStopQueueExe(
11832                   PortAddr iop_base
11833)
11834{
11835    int                 count = 0;
11836
11837    if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
11838        AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
11839                         ASC_STOP_REQ_RISC_STOP);
11840        do {
11841            if (
11842                   AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
11843                   ASC_STOP_ACK_RISC_STOP) {
11844                return (1);
11845            }
11846            DvcSleepMilliSecond(100);
11847        } while (count++ < 20);
11848    }
11849    return (0);
11850}
11851
11852STATIC void
11853DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
11854{
11855    udelay(micro_sec);
11856}
11857
11858STATIC void
11859DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
11860{
11861    udelay((nano_sec + 999)/1000);
11862}
11863
11864#ifdef CONFIG_ISA
11865ASC_INITFUNC(
11866STATIC ASC_DCNT,
11867AscGetEisaProductID(
11868                       PortAddr iop_base
11869)
11870)
11871{
11872    PortAddr            eisa_iop;
11873    ushort              product_id_high, product_id_low;
11874    ASC_DCNT            product_id;
11875
11876    eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK;
11877    product_id_low = inpw(eisa_iop);
11878    product_id_high = inpw(eisa_iop + 2);
11879    product_id = ((ASC_DCNT) product_id_high << 16) |
11880        (ASC_DCNT) product_id_low;
11881    return (product_id);
11882}
11883
11884ASC_INITFUNC(
11885STATIC PortAddr,
11886AscSearchIOPortAddrEISA(
11887                           PortAddr iop_base
11888)
11889)
11890{
11891    ASC_DCNT            eisa_product_id;
11892
11893    if (iop_base == 0) {
11894        iop_base = ASC_EISA_MIN_IOP_ADDR;
11895    } else {
11896        if (iop_base == ASC_EISA_MAX_IOP_ADDR)
11897            return (0);
11898        if ((iop_base & 0x0050) == 0x0050) {
11899            iop_base += ASC_EISA_BIG_IOP_GAP;
11900        } else {
11901            iop_base += ASC_EISA_SMALL_IOP_GAP;
11902        }
11903    }
11904    while (iop_base <= ASC_EISA_MAX_IOP_ADDR) {
11905        eisa_product_id = AscGetEisaProductID(iop_base);
11906        if ((eisa_product_id == ASC_EISA_ID_740) ||
11907            (eisa_product_id == ASC_EISA_ID_750)) {
11908            if (AscFindSignature(iop_base)) {
11909                inpw(iop_base + 4);
11910                return (iop_base);
11911            }
11912        }
11913        if (iop_base == ASC_EISA_MAX_IOP_ADDR)
11914            return (0);
11915        if ((iop_base & 0x0050) == 0x0050) {
11916            iop_base += ASC_EISA_BIG_IOP_GAP;
11917        } else {
11918            iop_base += ASC_EISA_SMALL_IOP_GAP;
11919        }
11920    }
11921    return (0);
11922}
11923#endif /* CONFIG_ISA */
11924
11925STATIC int
11926AscStartChip(
11927                PortAddr iop_base
11928)
11929{
11930    AscSetChipControl(iop_base, 0);
11931    if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
11932        return (0);
11933    }
11934    return (1);
11935}
11936
11937STATIC int
11938AscStopChip(
11939               PortAddr iop_base
11940)
11941{
11942    uchar               cc_val;
11943
11944    cc_val = AscGetChipControl(iop_base) & (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
11945    AscSetChipControl(iop_base, (uchar) (cc_val | CC_HALT));
11946    AscSetChipIH(iop_base, INS_HALT);
11947    AscSetChipIH(iop_base, INS_RFLAG_WTM);
11948    if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
11949        return (0);
11950    }
11951    return (1);
11952}
11953
11954STATIC int
11955AscIsChipHalted(
11956                   PortAddr iop_base
11957)
11958{
11959    if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
11960        if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
11961            return (1);
11962        }
11963    }
11964    return (0);
11965}
11966
11967STATIC void
11968AscSetChipIH(
11969                PortAddr iop_base,
11970                ushort ins_code
11971)
11972{
11973    AscSetBank(iop_base, 1);
11974    AscWriteChipIH(iop_base, ins_code);
11975    AscSetBank(iop_base, 0);
11976    return;
11977}
11978
11979STATIC void
11980AscAckInterrupt(
11981                   PortAddr iop_base
11982)
11983{
11984    uchar               host_flag;
11985    uchar               risc_flag;
11986    ushort              loop;
11987
11988    loop = 0;
11989    do {
11990        risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
11991        if (loop++ > 0x7FFF) {
11992            break;
11993        }
11994    } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
11995    host_flag = AscReadLramByte(iop_base, ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
11996    AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
11997                     (uchar) (host_flag | ASC_HOST_FLAG_ACK_INT));
11998    AscSetChipStatus(iop_base, CIW_INT_ACK);
11999    loop = 0;
12000    while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
12001        AscSetChipStatus(iop_base, CIW_INT_ACK);
12002        if (loop++ > 3) {
12003            break;
12004        }
12005    }
12006    AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
12007    return;
12008}
12009
12010STATIC void
12011AscDisableInterrupt(
12012                       PortAddr iop_base
12013)
12014{
12015    ushort              cfg;
12016
12017    cfg = AscGetChipCfgLsw(iop_base);
12018    AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
12019    return;
12020}
12021
12022STATIC void
12023AscEnableInterrupt(
12024                      PortAddr iop_base
12025)
12026{
12027    ushort              cfg;
12028
12029    cfg = AscGetChipCfgLsw(iop_base);
12030    AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
12031    return;
12032}
12033
12034
12035
12036STATIC void
12037AscSetBank(
12038              PortAddr iop_base,
12039              uchar bank
12040)
12041{
12042    uchar               val;
12043
12044    val = AscGetChipControl(iop_base) &
12045      (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET | CC_CHIP_RESET));
12046    if (bank == 1) {
12047        val |= CC_BANK_ONE;
12048    } else if (bank == 2) {
12049        val |= CC_DIAG | CC_BANK_ONE;
12050    } else {
12051        val &= ~CC_BANK_ONE;
12052    }
12053    AscSetChipControl(iop_base, val);
12054    return;
12055}
12056
12057STATIC int
12058AscResetChipAndScsiBus(
12059                          ASC_DVC_VAR *asc_dvc
12060)
12061{
12062    PortAddr    iop_base;
12063    int         i = 10;
12064
12065    iop_base = asc_dvc->iop_base;
12066    while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) && (i-- > 0))
12067    {
12068          DvcSleepMilliSecond(100);
12069    }
12070    AscStopChip(iop_base);
12071    AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
12072    DvcDelayNanoSecond(asc_dvc, 60000);
12073    AscSetChipIH(iop_base, INS_RFLAG_WTM);
12074    AscSetChipIH(iop_base, INS_HALT);
12075    AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
12076    AscSetChipControl(iop_base, CC_HALT);
12077    DvcSleepMilliSecond(200);
12078    AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
12079    AscSetChipStatus(iop_base, 0);
12080    return (AscIsChipHalted(iop_base));
12081}
12082
12083ASC_INITFUNC(
12084STATIC ASC_DCNT,
12085AscGetMaxDmaCount(
12086                     ushort bus_type
12087)
12088)
12089{
12090    if (bus_type & ASC_IS_ISA)
12091        return (ASC_MAX_ISA_DMA_COUNT);
12092    else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
12093        return (ASC_MAX_VL_DMA_COUNT);
12094    return (ASC_MAX_PCI_DMA_COUNT);
12095}
12096
12097#ifdef CONFIG_ISA
12098ASC_INITFUNC(
12099STATIC ushort,
12100AscGetIsaDmaChannel(
12101                       PortAddr iop_base
12102)
12103)
12104{
12105    ushort              channel;
12106
12107    channel = AscGetChipCfgLsw(iop_base) & 0x0003;
12108    if (channel == 0x03)
12109        return (0);
12110    else if (channel == 0x00)
12111        return (7);
12112    return (channel + 4);
12113}
12114
12115ASC_INITFUNC(
12116STATIC ushort,
12117AscSetIsaDmaChannel(
12118                       PortAddr iop_base,
12119                       ushort dma_channel
12120)
12121)
12122{
12123    ushort              cfg_lsw;
12124    uchar               value;
12125
12126    if ((dma_channel >= 5) && (dma_channel <= 7)) {
12127        if (dma_channel == 7)
12128            value = 0x00;
12129        else
12130            value = dma_channel - 4;
12131        cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
12132        cfg_lsw |= value;
12133        AscSetChipCfgLsw(iop_base, cfg_lsw);
12134        return (AscGetIsaDmaChannel(iop_base));
12135    }
12136    return (0);
12137}
12138
12139ASC_INITFUNC(
12140STATIC uchar,
12141AscSetIsaDmaSpeed(
12142                     PortAddr iop_base,
12143                     uchar speed_value
12144)
12145)
12146{
12147    speed_value &= 0x07;
12148    AscSetBank(iop_base, 1);
12149    AscWriteChipDmaSpeed(iop_base, speed_value);
12150    AscSetBank(iop_base, 0);
12151    return (AscGetIsaDmaSpeed(iop_base));
12152}
12153
12154ASC_INITFUNC(
12155STATIC uchar,
12156AscGetIsaDmaSpeed(
12157                     PortAddr iop_base
12158)
12159)
12160{
12161    uchar               speed_value;
12162
12163    AscSetBank(iop_base, 1);
12164    speed_value = AscReadChipDmaSpeed(iop_base);
12165    speed_value &= 0x07;
12166    AscSetBank(iop_base, 0);
12167    return (speed_value);
12168}
12169#endif /* CONFIG_ISA */
12170
12171ASC_INITFUNC(
12172STATIC ushort,
12173AscReadPCIConfigWord(
12174    ASC_DVC_VAR *asc_dvc,
12175    ushort pci_config_offset)
12176)
12177{
12178    uchar       lsb, msb;
12179
12180    lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset);
12181    msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1);
12182    return ((ushort) ((msb << 8) | lsb));
12183}
12184
12185ASC_INITFUNC(
12186STATIC ushort,
12187AscInitGetConfig(
12188        ASC_DVC_VAR *asc_dvc
12189)
12190)
12191{
12192    ushort              warn_code;
12193    PortAddr            iop_base;
12194    ushort              PCIDeviceID;
12195    ushort              PCIVendorID;
12196    uchar               PCIRevisionID;
12197    uchar               prevCmdRegBits;
12198
12199    warn_code = 0;
12200    iop_base = asc_dvc->iop_base;
12201    asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
12202    if (asc_dvc->err_code != 0) {
12203        return (UW_ERR);
12204    }
12205    if (asc_dvc->bus_type == ASC_IS_PCI) {
12206        PCIVendorID = AscReadPCIConfigWord(asc_dvc,
12207                                    AscPCIConfigVendorIDRegister);
12208
12209        PCIDeviceID = AscReadPCIConfigWord(asc_dvc,
12210                                    AscPCIConfigDeviceIDRegister);
12211
12212        PCIRevisionID = DvcReadPCIConfigByte(asc_dvc,
12213                                    AscPCIConfigRevisionIDRegister);
12214
12215        if (PCIVendorID != ASC_PCI_VENDORID) {
12216            warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
12217        }
12218        prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc,
12219                                    AscPCIConfigCommandRegister);
12220
12221        if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster) !=
12222            AscPCICmdRegBits_IOMemBusMaster) {
12223            DvcWritePCIConfigByte(asc_dvc,
12224                            AscPCIConfigCommandRegister,
12225                            (prevCmdRegBits |
12226                             AscPCICmdRegBits_IOMemBusMaster));
12227
12228            if ((DvcReadPCIConfigByte(asc_dvc,
12229                                AscPCIConfigCommandRegister)
12230                 & AscPCICmdRegBits_IOMemBusMaster)
12231                != AscPCICmdRegBits_IOMemBusMaster) {
12232                warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
12233            }
12234        }
12235        if ((PCIDeviceID == ASC_PCI_DEVICEID_1200A) ||
12236            (PCIDeviceID == ASC_PCI_DEVICEID_1200B)) {
12237            DvcWritePCIConfigByte(asc_dvc,
12238                            AscPCIConfigLatencyTimer, 0x00);
12239            if (DvcReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer)
12240                != 0x00) {
12241                warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
12242            }
12243        } else if (PCIDeviceID == ASC_PCI_DEVICEID_ULTRA) {
12244            if (DvcReadPCIConfigByte(asc_dvc,
12245                                AscPCIConfigLatencyTimer) < 0x20) {
12246                DvcWritePCIConfigByte(asc_dvc,
12247                                    AscPCIConfigLatencyTimer, 0x20);
12248
12249                if (DvcReadPCIConfigByte(asc_dvc,
12250                                    AscPCIConfigLatencyTimer) < 0x20) {
12251                    warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
12252                }
12253            }
12254        }
12255    }
12256
12257    if (AscFindSignature(iop_base)) {
12258        warn_code |= AscInitAscDvcVar(asc_dvc);
12259        warn_code |= AscInitFromEEP(asc_dvc);
12260        asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
12261        if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) {
12262            asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
12263        }
12264    } else {
12265        asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
12266    }
12267    return(warn_code);
12268}
12269
12270ASC_INITFUNC(
12271STATIC ushort,
12272AscInitSetConfig(
12273                    ASC_DVC_VAR *asc_dvc
12274)
12275)
12276{
12277    ushort              warn_code = 0;
12278
12279    asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
12280    if (asc_dvc->err_code != 0)
12281        return (UW_ERR);
12282    if (AscFindSignature(asc_dvc->iop_base)) {
12283        warn_code |= AscInitFromAscDvcVar(asc_dvc);
12284        asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
12285    } else {
12286        asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
12287    }
12288    return (warn_code);
12289}
12290
12291ASC_INITFUNC(
12292STATIC ushort,
12293AscInitFromAscDvcVar(
12294                        ASC_DVC_VAR *asc_dvc
12295)
12296)
12297{
12298    PortAddr            iop_base;
12299    ushort              cfg_msw;
12300    ushort              warn_code;
12301    ushort              pci_device_id;
12302
12303    iop_base = asc_dvc->iop_base;
12304    pci_device_id = asc_dvc->cfg->pci_dev->device;
12305    warn_code = 0;
12306    cfg_msw = AscGetChipCfgMsw(iop_base);
12307    if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
12308        cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
12309        warn_code |= ASC_WARN_CFG_MSW_RECOVER;
12310        AscSetChipCfgMsw(iop_base, cfg_msw);
12311    }
12312    if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
12313        asc_dvc->cfg->cmd_qng_enabled) {
12314        asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
12315        warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
12316    }
12317    if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
12318        warn_code |= ASC_WARN_AUTO_CONFIG;
12319    }
12320    if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
12321        if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
12322            != asc_dvc->irq_no) {
12323            asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
12324        }
12325    }
12326    if (asc_dvc->bus_type & ASC_IS_PCI) {
12327        cfg_msw &= 0xFFC0;
12328        AscSetChipCfgMsw(iop_base, cfg_msw);
12329        if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
12330        } else {
12331            if ((pci_device_id == ASC_PCI_DEVICE_ID_REV_A) ||
12332                (pci_device_id == ASC_PCI_DEVICE_ID_REV_B)) {
12333                asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
12334                asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
12335            }
12336        }
12337    } else if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
12338        if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
12339            == ASC_CHIP_VER_ASYN_BUG) {
12340            asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
12341        }
12342    }
12343    if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
12344        asc_dvc->cfg->chip_scsi_id) {
12345        asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
12346    }
12347#ifdef CONFIG_ISA
12348    if (asc_dvc->bus_type & ASC_IS_ISA) {
12349        AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
12350        AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
12351    }
12352#endif /* CONFIG_ISA */
12353    return (warn_code);
12354}
12355
12356STATIC ushort
12357AscInitAsc1000Driver(
12358                        ASC_DVC_VAR *asc_dvc
12359)
12360{
12361    ushort              warn_code;
12362    PortAddr            iop_base;
12363
12364    iop_base = asc_dvc->iop_base;
12365    warn_code = 0;
12366    if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
12367        !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
12368        AscResetChipAndScsiBus(asc_dvc);
12369        DvcSleepMilliSecond((ASC_DCNT)
12370            ((ushort) asc_dvc->scsi_reset_wait * 1000));
12371    }
12372    asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
12373    if (asc_dvc->err_code != 0)
12374        return (UW_ERR);
12375    if (!AscFindSignature(asc_dvc->iop_base)) {
12376        asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
12377        return (warn_code);
12378    }
12379    AscDisableInterrupt(iop_base);
12380    warn_code |= AscInitLram(asc_dvc);
12381    if (asc_dvc->err_code != 0)
12382        return (UW_ERR);
12383    ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
12384        (ulong) _asc_mcode_chksum);
12385    if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
12386                         _asc_mcode_size) != _asc_mcode_chksum) {
12387        asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
12388        return (warn_code);
12389    }
12390    warn_code |= AscInitMicroCodeVar(asc_dvc);
12391    asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
12392    AscEnableInterrupt(iop_base);
12393    return (warn_code);
12394}
12395
12396ASC_INITFUNC(
12397STATIC ushort,
12398AscInitAscDvcVar(
12399                    ASC_DVC_VAR *asc_dvc
12400)
12401)
12402{
12403    int                 i;
12404    PortAddr            iop_base;
12405    ushort              warn_code;
12406    uchar               chip_version;
12407
12408    iop_base = asc_dvc->iop_base;
12409    warn_code = 0;
12410    asc_dvc->err_code = 0;
12411    if ((asc_dvc->bus_type &
12412         (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
12413        asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
12414    }
12415    AscSetChipControl(iop_base, CC_HALT);
12416    AscSetChipStatus(iop_base, 0);
12417    asc_dvc->bug_fix_cntl = 0;
12418    asc_dvc->pci_fix_asyn_xfer = 0;
12419    asc_dvc->pci_fix_asyn_xfer_always = 0;
12420    /* asc_dvc->init_state initalized in AscInitGetConfig(). */
12421    asc_dvc->sdtr_done = 0;
12422    asc_dvc->cur_total_qng = 0;
12423    asc_dvc->is_in_int = 0;
12424    asc_dvc->in_critical_cnt = 0;
12425    asc_dvc->last_q_shortage = 0;
12426    asc_dvc->use_tagged_qng = 0;
12427    asc_dvc->no_scam = 0;
12428    asc_dvc->unit_not_ready = 0;
12429    asc_dvc->queue_full_or_busy = 0;
12430    asc_dvc->redo_scam = 0;
12431    asc_dvc->res2 = 0;
12432    asc_dvc->host_init_sdtr_index = 0;
12433    asc_dvc->cfg->can_tagged_qng = 0;
12434    asc_dvc->cfg->cmd_qng_enabled = 0;
12435    asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
12436    asc_dvc->init_sdtr = 0;
12437    asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
12438    asc_dvc->scsi_reset_wait = 3;
12439    asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
12440    asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
12441    asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
12442    asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
12443    asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
12444    asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
12445    asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
12446      ASC_LIB_VERSION_MINOR;
12447    chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
12448    asc_dvc->cfg->chip_version = chip_version;
12449    asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
12450    asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
12451    asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
12452    asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
12453    asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
12454    asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
12455    asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
12456    asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
12457    asc_dvc->max_sdtr_index = 7;
12458    if ((asc_dvc->bus_type & ASC_IS_PCI) &&
12459        (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
12460        asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
12461        asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
12462        asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
12463        asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
12464        asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
12465        asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
12466        asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
12467        asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
12468        asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
12469        asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
12470        asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
12471        asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
12472        asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
12473        asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
12474        asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
12475        asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
12476        asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
12477        asc_dvc->max_sdtr_index = 15;
12478        if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150)
12479        {
12480            AscSetExtraControl(iop_base,
12481                (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
12482        } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
12483            AscSetExtraControl(iop_base,
12484                (SEC_ACTIVE_NEGATE | SEC_ENABLE_FILTER));
12485        }
12486    }
12487    if (asc_dvc->bus_type == ASC_IS_PCI) {
12488           AscSetExtraControl(iop_base, (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
12489    }
12490
12491    asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
12492    if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
12493        AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
12494        asc_dvc->bus_type = ASC_IS_ISAPNP;
12495    }
12496#ifdef CONFIG_ISA
12497    if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
12498        asc_dvc->cfg->isa_dma_channel = (uchar) AscGetIsaDmaChannel(iop_base);
12499    }
12500#endif /* CONFIG_ISA */
12501    for (i = 0; i <= ASC_MAX_TID; i++) {
12502        asc_dvc->cur_dvc_qng[i] = 0;
12503        asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
12504        asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *) 0L;
12505        asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *) 0L;
12506        asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
12507    }
12508    return (warn_code);
12509}
12510
12511ASC_INITFUNC(
12512STATIC ushort,
12513AscInitFromEEP(
12514                  ASC_DVC_VAR *asc_dvc
12515)
12516)
12517{
12518    ASCEEP_CONFIG       eep_config_buf;
12519    ASCEEP_CONFIG       *eep_config;
12520    PortAddr            iop_base;
12521    ushort              chksum;
12522    ushort              warn_code;
12523    ushort              cfg_msw, cfg_lsw;
12524    int                 i;
12525    int                 write_eep = 0;
12526
12527    iop_base = asc_dvc->iop_base;
12528    warn_code = 0;
12529    AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
12530    AscStopQueueExe(iop_base);
12531    if ((AscStopChip(iop_base) == FALSE) ||
12532        (AscGetChipScsiCtrl(iop_base) != 0)) {
12533        asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
12534        AscResetChipAndScsiBus(asc_dvc);
12535        DvcSleepMilliSecond((ASC_DCNT)
12536            ((ushort) asc_dvc->scsi_reset_wait * 1000));
12537    }
12538    if (AscIsChipHalted(iop_base) == FALSE) {
12539        asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
12540        return (warn_code);
12541    }
12542    AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
12543    if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
12544        asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
12545        return (warn_code);
12546    }
12547    eep_config = (ASCEEP_CONFIG *) &eep_config_buf;
12548    cfg_msw = AscGetChipCfgMsw(iop_base);
12549    cfg_lsw = AscGetChipCfgLsw(iop_base);
12550    if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
12551        cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
12552        warn_code |= ASC_WARN_CFG_MSW_RECOVER;
12553        AscSetChipCfgMsw(iop_base, cfg_msw);
12554    }
12555    chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
12556    ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
12557    if (chksum == 0) {
12558        chksum = 0xaa55;
12559    }
12560    if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
12561        warn_code |= ASC_WARN_AUTO_CONFIG;
12562        if (asc_dvc->cfg->chip_version == 3) {
12563            if (eep_config->cfg_lsw != cfg_lsw) {
12564                warn_code |= ASC_WARN_EEPROM_RECOVER;
12565                eep_config->cfg_lsw = AscGetChipCfgLsw(iop_base);
12566            }
12567            if (eep_config->cfg_msw != cfg_msw) {
12568                warn_code |= ASC_WARN_EEPROM_RECOVER;
12569                eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
12570            }
12571        }
12572    }
12573    eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
12574    eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
12575    ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
12576        eep_config->chksum);
12577    if (chksum != eep_config->chksum) {
12578            if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
12579                    ASC_CHIP_VER_PCI_ULTRA_3050 )
12580            {
12581                ASC_DBG(1,
12582"AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
12583                eep_config->init_sdtr = 0xFF;
12584                eep_config->disc_enable = 0xFF;
12585                eep_config->start_motor = 0xFF;
12586                eep_config->use_cmd_qng = 0;
12587                eep_config->max_total_qng = 0xF0;
12588                eep_config->max_tag_qng = 0x20;
12589                eep_config->cntl = 0xBFFF;
12590                ASC_EEP_SET_CHIP_ID(eep_config, 7);
12591                eep_config->no_scam = 0;
12592                eep_config->adapter_info[0] = 0;
12593                eep_config->adapter_info[1] = 0;
12594                eep_config->adapter_info[2] = 0;
12595                eep_config->adapter_info[3] = 0;
12596                eep_config->adapter_info[4] = 0;
12597                /* Indicate EEPROM-less board. */
12598                eep_config->adapter_info[5] = 0xBB;
12599            } else {
12600                ASC_PRINT(
12601"AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
12602                write_eep = 1;
12603                warn_code |= ASC_WARN_EEPROM_CHKSUM;
12604            }
12605    }
12606    asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
12607    asc_dvc->cfg->disc_enable = eep_config->disc_enable;
12608    asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
12609    asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
12610    asc_dvc->start_motor = eep_config->start_motor;
12611    asc_dvc->dvc_cntl = eep_config->cntl;
12612    asc_dvc->no_scam = eep_config->no_scam;
12613    asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
12614    asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
12615    asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
12616    asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
12617    asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
12618    asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
12619    if (!AscTestExternalLram(asc_dvc)) {
12620        if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA)) {
12621            eep_config->max_total_qng = ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
12622            eep_config->max_tag_qng = ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
12623        } else {
12624            eep_config->cfg_msw |= 0x0800;
12625            cfg_msw |= 0x0800;
12626            AscSetChipCfgMsw(iop_base, cfg_msw);
12627            eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
12628            eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
12629        }
12630    } else {
12631    }
12632    if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
12633        eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
12634    }
12635    if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
12636        eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
12637    }
12638    if (eep_config->max_tag_qng > eep_config->max_total_qng) {
12639        eep_config->max_tag_qng = eep_config->max_total_qng;
12640    }
12641    if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
12642        eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
12643    }
12644    asc_dvc->max_total_qng = eep_config->max_total_qng;
12645    if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
12646        eep_config->use_cmd_qng) {
12647        eep_config->disc_enable = eep_config->use_cmd_qng;
12648        warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
12649    }
12650    if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
12651        asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
12652    }
12653    ASC_EEP_SET_CHIP_ID(eep_config, ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
12654    asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
12655    if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
12656        !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
12657        asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
12658    }
12659
12660    for (i = 0; i <= ASC_MAX_TID; i++) {
12661        asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
12662        asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
12663        asc_dvc->cfg->sdtr_period_offset[i] =
12664            (uchar) (ASC_DEF_SDTR_OFFSET |
12665                     (asc_dvc->host_init_sdtr_index << 4));
12666    }
12667    eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
12668    if (write_eep) {
12669        if ((i = AscSetEEPConfig(iop_base, eep_config, asc_dvc->bus_type)) !=
12670             0) {
12671                ASC_PRINT1(
12672"AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n", i);
12673        } else {
12674                ASC_PRINT("AscInitFromEEP: Succesfully re-wrote EEPROM.");
12675        }
12676    }
12677    return (warn_code);
12678}
12679
12680STATIC ushort
12681AscInitMicroCodeVar(
12682                       ASC_DVC_VAR *asc_dvc
12683)
12684{
12685    int                 i;
12686    ushort              warn_code;
12687    PortAddr            iop_base;
12688    ASC_PADDR           phy_addr;
12689    ASC_DCNT            phy_size;
12690
12691    iop_base = asc_dvc->iop_base;
12692    warn_code = 0;
12693    for (i = 0; i <= ASC_MAX_TID; i++) {
12694        AscPutMCodeInitSDTRAtID(iop_base, i,
12695                                asc_dvc->cfg->sdtr_period_offset[i]
12696);
12697    }
12698
12699    AscInitQLinkVar(asc_dvc);
12700    AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
12701                     asc_dvc->cfg->disc_enable);
12702    AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
12703                     ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
12704
12705    /* Align overrun buffer on an 8 byte boundary. */
12706    phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
12707    phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
12708    AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
12709        (uchar *) &phy_addr, 1);
12710    phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
12711    AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
12712        (uchar *) &phy_size, 1);
12713
12714    asc_dvc->cfg->mcode_date =
12715        AscReadLramWord(iop_base, (ushort) ASCV_MC_DATE_W);
12716    asc_dvc->cfg->mcode_version =
12717        AscReadLramWord(iop_base, (ushort) ASCV_MC_VER_W);
12718
12719    AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
12720    if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
12721        asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
12722        return (warn_code);
12723    }
12724    if (AscStartChip(iop_base) != 1) {
12725        asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
12726        return (warn_code);
12727    }
12728
12729    return (warn_code);
12730}
12731
12732ASC_INITFUNC(
12733STATIC int,
12734AscTestExternalLram(
12735                       ASC_DVC_VAR *asc_dvc
12736)
12737)
12738{
12739    PortAddr            iop_base;
12740    ushort              q_addr;
12741    ushort              saved_word;
12742    int                 sta;
12743
12744    iop_base = asc_dvc->iop_base;
12745    sta = 0;
12746    q_addr = ASC_QNO_TO_QADDR(241);
12747    saved_word = AscReadLramWord(iop_base, q_addr);
12748    AscSetChipLramAddr(iop_base, q_addr);
12749    AscSetChipLramData(iop_base, 0x55AA);
12750    DvcSleepMilliSecond(10);
12751    AscSetChipLramAddr(iop_base, q_addr);
12752    if (AscGetChipLramData(iop_base) == 0x55AA) {
12753        sta = 1;
12754        AscWriteLramWord(iop_base, q_addr, saved_word);
12755    }
12756    return (sta);
12757}
12758
12759ASC_INITFUNC(
12760STATIC int,
12761AscWriteEEPCmdReg(
12762                     PortAddr iop_base,
12763                     uchar cmd_reg
12764)
12765)
12766{
12767    uchar               read_back;
12768    int                 retry;
12769
12770    retry = 0;
12771    while (TRUE) {
12772        AscSetChipEEPCmd(iop_base, cmd_reg);
12773        DvcSleepMilliSecond(1);
12774        read_back = AscGetChipEEPCmd(iop_base);
12775        if (read_back == cmd_reg) {
12776            return (1);
12777        }
12778        if (retry++ > ASC_EEP_MAX_RETRY) {
12779            return (0);
12780        }
12781    }
12782}
12783
12784ASC_INITFUNC(
12785STATIC int,
12786AscWriteEEPDataReg(
12787                      PortAddr iop_base,
12788                      ushort data_reg
12789)
12790)
12791{
12792    ushort              read_back;
12793    int                 retry;
12794
12795    retry = 0;
12796    while (TRUE) {
12797        AscSetChipEEPData(iop_base, data_reg);
12798        DvcSleepMilliSecond(1);
12799        read_back = AscGetChipEEPData(iop_base);
12800        if (read_back == data_reg) {
12801            return (1);
12802        }
12803        if (retry++ > ASC_EEP_MAX_RETRY) {
12804            return (0);
12805        }
12806    }
12807}
12808
12809ASC_INITFUNC(
12810STATIC void,
12811AscWaitEEPRead(
12812                  void
12813)
12814)
12815{
12816    DvcSleepMilliSecond(1);
12817    return;
12818}
12819
12820ASC_INITFUNC(
12821STATIC void,
12822AscWaitEEPWrite(
12823                   void
12824)
12825)
12826{
12827    DvcSleepMilliSecond(20);
12828    return;
12829}
12830
12831ASC_INITFUNC(
12832STATIC ushort,
12833AscReadEEPWord(
12834                  PortAddr iop_base,
12835                  uchar addr
12836)
12837)
12838{
12839    ushort              read_wval;
12840    uchar               cmd_reg;
12841
12842    AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
12843    AscWaitEEPRead();
12844    cmd_reg = addr | ASC_EEP_CMD_READ;
12845    AscWriteEEPCmdReg(iop_base, cmd_reg);
12846    AscWaitEEPRead();
12847    read_wval = AscGetChipEEPData(iop_base);
12848    AscWaitEEPRead();
12849    return (read_wval);
12850}
12851
12852ASC_INITFUNC(
12853STATIC ushort,
12854AscWriteEEPWord(
12855                   PortAddr iop_base,
12856                   uchar addr,
12857                   ushort word_val
12858)
12859)
12860{
12861    ushort              read_wval;
12862
12863    read_wval = AscReadEEPWord(iop_base, addr);
12864    if (read_wval != word_val) {
12865        AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
12866        AscWaitEEPRead();
12867        AscWriteEEPDataReg(iop_base, word_val);
12868        AscWaitEEPRead();
12869        AscWriteEEPCmdReg(iop_base,
12870                          (uchar) ((uchar) ASC_EEP_CMD_WRITE | addr));
12871        AscWaitEEPWrite();
12872        AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
12873        AscWaitEEPRead();
12874        return (AscReadEEPWord(iop_base, addr));
12875    }
12876    return (read_wval);
12877}
12878
12879ASC_INITFUNC(
12880STATIC ushort,
12881AscGetEEPConfig(
12882                   PortAddr iop_base,
12883                   ASCEEP_CONFIG * cfg_buf, ushort bus_type
12884)
12885)
12886{
12887    ushort              wval;
12888    ushort              sum;
12889    ushort              *wbuf;
12890    int                 cfg_beg;
12891    int                 cfg_end;
12892    int                 uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
12893    int                 s_addr;
12894
12895    wbuf = (ushort *) cfg_buf;
12896    sum = 0;
12897    /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
12898    for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
12899        *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
12900        sum += *wbuf;
12901    }
12902    if (bus_type & ASC_IS_VL) {
12903        cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
12904        cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
12905    } else {
12906        cfg_beg = ASC_EEP_DVC_CFG_BEG;
12907        cfg_end = ASC_EEP_MAX_DVC_ADDR;
12908    }
12909    for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
12910        wval = AscReadEEPWord( iop_base, ( uchar )s_addr ) ;
12911        if (s_addr <= uchar_end_in_config) {
12912            /*
12913             * Swap all char fields - must unswap bytes already swapped
12914             * by AscReadEEPWord().
12915             */
12916            *wbuf = le16_to_cpu(wval);
12917        } else {
12918            /* Don't swap word field at the end - cntl field. */
12919            *wbuf = wval;
12920        }
12921        sum += wval; /* Checksum treats all EEPROM data as words. */
12922    }
12923    /*
12924     * Read the checksum word which will be compared against 'sum'
12925     * by the caller. Word field already swapped.
12926     */
12927    *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
12928    return (sum);
12929}
12930
12931ASC_INITFUNC(
12932STATIC int,
12933AscSetEEPConfigOnce(
12934                       PortAddr iop_base,
12935                       ASCEEP_CONFIG * cfg_buf, ushort bus_type
12936)
12937)
12938{
12939    int                 n_error;
12940    ushort              *wbuf;
12941    ushort              word;
12942    ushort              sum;
12943    int                 s_addr;
12944    int                 cfg_beg;
12945    int                 cfg_end;
12946    int                 uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
12947
12948
12949    wbuf = (ushort *) cfg_buf;
12950    n_error = 0;
12951    sum = 0;
12952    /* Write two config words; AscWriteEEPWord() will swap bytes. */
12953    for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
12954        sum += *wbuf;
12955        if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
12956            n_error++;
12957        }
12958    }
12959    if (bus_type & ASC_IS_VL) {
12960        cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
12961        cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
12962    } else {
12963        cfg_beg = ASC_EEP_DVC_CFG_BEG;
12964        cfg_end = ASC_EEP_MAX_DVC_ADDR;
12965    }
12966    for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
12967        if (s_addr <= uchar_end_in_config) {
12968            /*
12969             * This is a char field. Swap char fields before they are
12970             * swapped again by AscWriteEEPWord().
12971             */
12972            word = cpu_to_le16(*wbuf);
12973            if (word != AscWriteEEPWord( iop_base, (uchar) s_addr, word)) {
12974                n_error++;
12975            }
12976        } else {
12977            /* Don't swap word field at the end - cntl field. */
12978            if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
12979                n_error++;
12980            }
12981        }
12982        sum += *wbuf; /* Checksum calculated from word values. */
12983    }
12984    /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
12985    *wbuf = sum;
12986    if (sum != AscWriteEEPWord(iop_base, (uchar) s_addr, sum)) {
12987        n_error++;
12988    }
12989
12990    /* Read EEPROM back again. */
12991    wbuf = (ushort *) cfg_buf;
12992    /*
12993     * Read two config words; Byte-swapping done by AscReadEEPWord().
12994     */
12995    for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
12996        if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
12997            n_error++;
12998        }
12999    }
13000    if (bus_type & ASC_IS_VL) {
13001        cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
13002        cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
13003    } else {
13004        cfg_beg = ASC_EEP_DVC_CFG_BEG;
13005        cfg_end = ASC_EEP_MAX_DVC_ADDR;
13006    }
13007    for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
13008        if (s_addr <= uchar_end_in_config) {
13009            /*
13010             * Swap all char fields. Must unswap bytes already swapped
13011             * by AscReadEEPWord().
13012             */
13013            word = le16_to_cpu(AscReadEEPWord(iop_base, (uchar) s_addr));
13014        } else {
13015            /* Don't swap word field at the end - cntl field. */
13016            word = AscReadEEPWord(iop_base, (uchar) s_addr);
13017        }
13018        if (*wbuf != word) {
13019            n_error++;
13020        }
13021    }
13022    /* Read checksum; Byte swapping not needed. */
13023    if (AscReadEEPWord(iop_base, (uchar) s_addr) != sum) {
13024        n_error++;
13025    }
13026    return (n_error);
13027}
13028
13029ASC_INITFUNC(
13030STATIC int,
13031AscSetEEPConfig(
13032                   PortAddr iop_base,
13033                   ASCEEP_CONFIG * cfg_buf, ushort bus_type
13034)
13035)
13036{
13037    int            retry;
13038    int            n_error;
13039
13040    retry = 0;
13041    while (TRUE) {
13042        if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
13043                                           bus_type)) == 0) {
13044            break;
13045        }
13046        if (++retry > ASC_EEP_MAX_RETRY) {
13047            break;
13048        }
13049    }
13050    return (n_error);
13051}
13052
13053STATIC void
13054AscAsyncFix(
13055               ASC_DVC_VAR *asc_dvc,
13056               uchar tid_no,
13057               ASC_SCSI_INQUIRY *inq)
13058{
13059    uchar                       dvc_type;
13060    ASC_SCSI_BIT_ID_TYPE        tid_bits;
13061
13062    dvc_type = ASC_INQ_DVC_TYPE(inq);
13063    tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
13064
13065    if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN)
13066    {
13067        if (!(asc_dvc->init_sdtr & tid_bits))
13068        {
13069            if ((dvc_type == SCSI_TYPE_CDROM) &&
13070                (AscCompareString((uchar *) inq->vendor_id,
13071                    (uchar *) "HP ", 3) == 0))
13072            {
13073                asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
13074            }
13075            asc_dvc->pci_fix_asyn_xfer |= tid_bits;
13076            if ((dvc_type == SCSI_TYPE_PROC) ||
13077                (dvc_type == SCSI_TYPE_SCANNER) ||
13078                (dvc_type == SCSI_TYPE_CDROM) ||
13079                (dvc_type == SCSI_TYPE_SASD))
13080            {
13081                asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
13082            }
13083
13084            if (asc_dvc->pci_fix_asyn_xfer & tid_bits)
13085            {
13086                AscSetRunChipSynRegAtID(asc_dvc->iop_base, tid_no,
13087                    ASYN_SDTR_DATA_FIX_PCI_REV_AB);
13088            }
13089        }
13090    }
13091    return;
13092}
13093
13094STATIC int
13095AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq)
13096{
13097    if ((inq->add_len >= 32) &&
13098        (AscCompareString((uchar *) inq->vendor_id,
13099            (uchar *) "QUANTUM XP34301", 15) == 0) &&
13100        (AscCompareString((uchar *) inq->product_rev_level,
13101            (uchar *) "1071", 4) == 0))
13102    {
13103        return 0;
13104    }
13105    return 1;
13106}
13107
13108STATIC void
13109AscInquiryHandling(ASC_DVC_VAR *asc_dvc,
13110                   uchar tid_no, ASC_SCSI_INQUIRY *inq)
13111{
13112    ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no);
13113    ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng;
13114
13115    orig_init_sdtr = asc_dvc->init_sdtr;
13116    orig_use_tagged_qng = asc_dvc->use_tagged_qng;
13117
13118    asc_dvc->init_sdtr &= ~tid_bit;
13119    asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
13120    asc_dvc->use_tagged_qng &= ~tid_bit;
13121
13122    if (ASC_INQ_RESPONSE_FMT(inq) >= 2 || ASC_INQ_ANSI_VER(inq) >= 2) {
13123        if ((asc_dvc->cfg->sdtr_enable & tid_bit) && ASC_INQ_SYNC(inq)) {
13124            asc_dvc->init_sdtr |= tid_bit;
13125        }
13126        if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) &&
13127             ASC_INQ_CMD_QUEUE(inq)) {
13128            if (AscTagQueuingSafe(inq)) {
13129                asc_dvc->use_tagged_qng |= tid_bit;
13130                asc_dvc->cfg->can_tagged_qng |= tid_bit;
13131            }
13132        }
13133    }
13134    if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) {
13135        AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
13136                         asc_dvc->cfg->disc_enable);
13137        AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
13138                         asc_dvc->use_tagged_qng);
13139        AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
13140                         asc_dvc->cfg->can_tagged_qng);
13141
13142        asc_dvc->max_dvc_qng[tid_no] =
13143          asc_dvc->cfg->max_tag_qng[tid_no];
13144        AscWriteLramByte(asc_dvc->iop_base,
13145                         (ushort) (ASCV_MAX_DVC_QNG_BEG + tid_no),
13146                         asc_dvc->max_dvc_qng[tid_no]);
13147    }
13148    if (orig_init_sdtr != asc_dvc->init_sdtr) {
13149        AscAsyncFix(asc_dvc, tid_no, inq);
13150    }
13151    return;
13152}
13153
13154STATIC int
13155AscCompareString(
13156                    uchar *str1,
13157                    uchar *str2,
13158                    int len
13159)
13160{
13161    int                 i;
13162    int                 diff;
13163
13164    for (i = 0; i < len; i++) {
13165        diff = (int) (str1[i] - str2[i]);
13166        if (diff != 0)
13167            return (diff);
13168    }
13169    return (0);
13170}
13171
13172STATIC uchar
13173AscReadLramByte(
13174                   PortAddr iop_base,
13175                   ushort addr
13176)
13177{
13178    uchar               byte_data;
13179    ushort              word_data;
13180
13181    if (isodd_word(addr)) {
13182        AscSetChipLramAddr(iop_base, addr - 1);
13183        word_data = AscGetChipLramData(iop_base);
13184        byte_data = (uchar) ((word_data >> 8) & 0xFF);
13185    } else {
13186        AscSetChipLramAddr(iop_base, addr);
13187        word_data = AscGetChipLramData(iop_base);
13188        byte_data = (uchar) (word_data & 0xFF);
13189    }
13190    return (byte_data);
13191}
13192STATIC ushort
13193AscReadLramWord(
13194                   PortAddr iop_base,
13195                   ushort addr
13196)
13197{
13198    ushort              word_data;
13199
13200    AscSetChipLramAddr(iop_base, addr);
13201    word_data = AscGetChipLramData(iop_base);
13202    return (word_data);
13203}
13204
13205#if CC_VERY_LONG_SG_LIST
13206STATIC ASC_DCNT
13207AscReadLramDWord(
13208                    PortAddr iop_base,
13209                    ushort addr
13210)
13211{
13212    ushort              val_low, val_high;
13213    ASC_DCNT            dword_data;
13214
13215    AscSetChipLramAddr(iop_base, addr);
13216    val_low = AscGetChipLramData(iop_base);
13217    val_high = AscGetChipLramData(iop_base);
13218    dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
13219    return (dword_data);
13220}
13221#endif /* CC_VERY_LONG_SG_LIST */
13222
13223STATIC void
13224AscWriteLramWord(
13225                    PortAddr iop_base,
13226                    ushort addr,
13227                    ushort word_val
13228)
13229{
13230    AscSetChipLramAddr(iop_base, addr);
13231    AscSetChipLramData(iop_base, word_val);
13232    return;
13233}
13234
13235STATIC void
13236AscWriteLramByte(
13237                    PortAddr iop_base,
13238                    ushort addr,
13239                    uchar byte_val
13240)
13241{
13242    ushort              word_data;
13243
13244    if (isodd_word(addr)) {
13245        addr--;
13246        word_data = AscReadLramWord(iop_base, addr);
13247        word_data &= 0x00FF;
13248        word_data |= (((ushort) byte_val << 8) & 0xFF00);
13249    } else {
13250        word_data = AscReadLramWord(iop_base, addr);
13251        word_data &= 0xFF00;
13252        word_data |= ((ushort) byte_val & 0x00FF);
13253    }
13254    AscWriteLramWord(iop_base, addr, word_data);
13255    return;
13256}
13257
13258/*
13259 * Copy 2 bytes to LRAM.
13260 *
13261 * The source data is assumed to be in little-endian order in memory
13262 * and is maintained in little-endian order when written to LRAM.
13263 */
13264STATIC void
13265AscMemWordCopyPtrToLram(
13266                        PortAddr iop_base,
13267                        ushort s_addr,
13268                        uchar *s_buffer,
13269                        int words
13270)
13271{
13272    int    i;
13273
13274    AscSetChipLramAddr(iop_base, s_addr);
13275    for (i = 0; i < 2 * words; i += 2) {
13276        /*
13277         * On a little-endian system the second argument below
13278         * produces a little-endian ushort which is written to
13279         * LRAM in little-endian order. On a big-endian system
13280         * the second argument produces a big-endian ushort which
13281         * is "transparently" byte-swapped by outpw() and written
13282         * in little-endian order to LRAM.
13283         */
13284        outpw(iop_base + IOP_RAM_DATA,
13285            ((ushort) s_buffer[i + 1] << 8) | s_buffer[i]);
13286    }
13287    return;
13288}
13289
13290/*
13291 * Copy 4 bytes to LRAM.
13292 *
13293 * The source data is assumed to be in little-endian order in memory
13294 * and is maintained in little-endian order when writen to LRAM.
13295 */
13296STATIC void
13297AscMemDWordCopyPtrToLram(
13298                         PortAddr iop_base,
13299                         ushort s_addr,
13300                         uchar *s_buffer,
13301                         int dwords
13302)
13303{
13304    int       i;
13305
13306    AscSetChipLramAddr(iop_base, s_addr);
13307    for (i = 0; i < 4 * dwords; i += 4) {
13308        outpw(iop_base + IOP_RAM_DATA,
13309            ((ushort) s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
13310        outpw(iop_base + IOP_RAM_DATA,
13311            ((ushort) s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
13312    }
13313    return;
13314}
13315
13316/*
13317 * Copy 2 bytes from LRAM.
13318 *
13319 * The source data is assumed to be in little-endian order in LRAM
13320 * and is maintained in little-endian order when written to memory.
13321 */
13322STATIC void
13323AscMemWordCopyPtrFromLram(
13324                          PortAddr iop_base,
13325                          ushort s_addr,
13326                          uchar *d_buffer,
13327                          int words
13328)
13329{
13330    int i;
13331    ushort word;
13332
13333    AscSetChipLramAddr(iop_base, s_addr);
13334    for (i = 0; i < 2 * words; i += 2) {
13335        word = inpw(iop_base + IOP_RAM_DATA);
13336        d_buffer[i] = word & 0xff;
13337        d_buffer[i + 1] = (word >> 8) & 0xff;
13338    }
13339    return;
13340}
13341
13342STATIC ASC_DCNT
13343AscMemSumLramWord(
13344                     PortAddr iop_base,
13345                     ushort s_addr,
13346                     int words
13347)
13348{
13349    ASC_DCNT         sum;
13350    int              i;
13351
13352    sum = 0L;
13353    for (i = 0; i < words; i++, s_addr += 2) {
13354        sum += AscReadLramWord(iop_base, s_addr);
13355    }
13356    return (sum);
13357}
13358
13359STATIC void
13360AscMemWordSetLram(
13361                     PortAddr iop_base,
13362                     ushort s_addr,
13363                     ushort set_wval,
13364                     int words
13365)
13366{
13367    int             i;
13368
13369    AscSetChipLramAddr(iop_base, s_addr);
13370    for (i = 0; i < words; i++) {
13371        AscSetChipLramData(iop_base, set_wval);
13372    }
13373    return;
13374}
13375
13376
13377/*
13378 * --- Adv Library Functions
13379 */
13380
13381/* a_mcode.h */
13382
13383/* Microcode buffer is kept after initialization for error recovery. */
13384STATIC unsigned char _adv_asc3550_buf[] = {
13385  0x00,  0x00,  0x00,  0xf2,  0x00,  0xf0,  0x00,  0x16,  0x18,  0xe4,  0x00,  0xfc,  0x01,  0x00,  0x48,  0xe4,
13386  0xbe,  0x18,  0x18,  0x80,  0x03,  0xf6,  0x02,  0x00,  0x00,  0xfa,  0xff,  0xff,  0x28,  0x0e,  0x9e,  0xe7,
13387  0xff,  0x00,  0x82,  0xe7,  0x00,  0xea,  0x00,  0xf6,  0x01,  0xe6,  0x09,  0xe7,  0x55,  0xf0,  0x01,  0xf6,
13388  0x01,  0xfa,  0x08,  0x00,  0x03,  0x00,  0x04,  0x00,  0x18,  0xf4,  0x10,  0x00,  0x00,  0xec,  0x85,  0xf0,
13389  0xbc,  0x00,  0xd5,  0xf0,  0x8e,  0x0c,  0x38,  0x54,  0x00,  0xe6,  0x1e,  0xf0,  0x86,  0xf0,  0xb4,  0x00,
13390  0x98,  0x57,  0xd0,  0x01,  0x0c,  0x1c,  0x3e,  0x1c,  0x0c,  0x00,  0xbb,  0x00,  0xaa,  0x18,  0x02,  0x80,
13391  0x32,  0xf0,  0x01,  0xfc,  0x88,  0x0c,  0xc6,  0x12,  0x02,  0x13,  0x18,  0x40,  0x00,  0x57,  0x01,  0xea,
13392  0x3c,  0x00,  0x6c,  0x01,  0x6e,  0x01,  0x04,  0x12,  0x3e,  0x57,  0x00,  0x80,  0x03,  0xe6,  0xb6,  0x00,
13393  0xc0,  0x00,  0x01,  0x01,  0x3e,  0x01,  0xda,  0x0f,  0x22,  0x10,  0x08,  0x12,  0x02,  0x4a,  0xb9,  0x54,
13394  0x03,  0x58,  0x1b,  0x80,  0x30,  0xe4,  0x4b,  0xe4,  0x20,  0x00,  0x32,  0x00,  0x3e,  0x00,  0x80,  0x00,
13395  0x24,  0x01,  0x3c,  0x01,  0x68,  0x01,  0x6a,  0x01,  0x70,  0x01,  0x72,  0x01,  0x74,  0x01,  0x76,  0x01,
13396  0x78,  0x01,  0x62,  0x0a,  0x92,  0x0c,  0x2c,  0x10,  0x2e,  0x10,  0x06,  0x13,  0x4c,  0x1c,  0xbb,  0x55,
13397  0x3c,  0x56,  0x04,  0x80,  0x4a,  0xe4,  0x02,  0xee,  0x5b,  0xf0,  0xb1,  0xf0,  0x03,  0xf7,  0x06,  0xf7,
13398  0x03,  0xfc,  0x0f,  0x00,  0x40,  0x00,  0xbe,  0x00,  0x00,  0x01,  0xb0,  0x08,  0x30,  0x13,  0x64,  0x15,
13399  0x32,  0x1c,  0x38,  0x1c,  0x4e,  0x1c,  0x10,  0x44,  0x02,  0x48,  0x00,  0x4c,  0x04,  0xea,  0x5d,  0xf0,
13400  0x04,  0xf6,  0x02,  0xfc,  0x05,  0x00,  0x34,  0x00,  0x36,  0x00,  0x98,  0x00,  0xcc,  0x00,  0x20,  0x01,
13401  0x4e,  0x01,  0x4e,  0x0b,  0x1e,  0x0e,  0x0c,  0x10,  0x0a,  0x12,  0x04,  0x13,  0x40,  0x13,  0x30,  0x1c,
13402  0x00,  0x4e,  0xbd,  0x56,  0x06,  0x83,  0x00,  0xdc,  0x05,  0xf0,  0x09,  0xf0,  0x59,  0xf0,  0xa7,  0xf0,
13403  0xb8,  0xf0,  0x0e,  0xf7,  0x06,  0x00,  0x19,  0x00,  0x33,  0x00,  0x9b,  0x00,  0xa4,  0x00,  0xb5,  0x00,
13404  0xba,  0x00,  0xd0,  0x00,  0xe1,  0x00,  0xe7,  0x00,  0xde,  0x03,  0x56,  0x0a,  0x14,  0x0e,  0x02,  0x10,
13405  0x04,  0x10,  0x0a,  0x10,  0x36,  0x10,  0x0a,  0x13,  0x12,  0x13,  0x52,  0x13,  0x10,  0x15,  0x14,  0x15,
13406  0xac,  0x16,  0x20,  0x1c,  0x34,  0x1c,  0x36,  0x1c,  0x08,  0x44,  0x38,  0x44,  0x91,  0x44,  0x0a,  0x45,
13407  0x48,  0x46,  0x01,  0x48,  0x68,  0x54,  0x83,  0x55,  0xb0,  0x57,  0x01,  0x58,  0x83,  0x59,  0x05,  0xe6,
13408  0x0b,  0xf0,  0x0c,  0xf0,  0x5c,  0xf0,  0x4b,  0xf4,  0x04,  0xf8,  0x05,  0xf8,  0x02,  0xfa,  0x03,  0xfa,
13409  0x04,  0xfc,  0x05,  0xfc,  0x07,  0x00,  0x0a,  0x00,  0x0d,  0x00,  0x1c,  0x00,  0x9e,  0x00,  0xa8,  0x00,
13410  0xaa,  0x00,  0xb9,  0x00,  0xe0,  0x00,  0x22,  0x01,  0x26,  0x01,  0x79,  0x01,  0x7a,  0x01,  0xc0,  0x01,
13411  0xc2,  0x01,  0x7c,  0x02,  0x5a,  0x03,  0xea,  0x04,  0xe8,  0x07,  0x68,  0x08,  0x69,  0x08,  0xba,  0x08,
13412  0xe9,  0x09,  0x06,  0x0b,  0x3a,  0x0e,  0x00,  0x10,  0x1a,  0x10,  0xed,  0x10,  0xf1,  0x10,  0x06,  0x12,
13413  0x0c,  0x13,  0x16,  0x13,  0x1e,  0x13,  0x82,  0x13,  0x42,  0x14,  0xd6,  0x14,  0x8a,  0x15,  0xc6,  0x17,
13414  0xd2,  0x17,  0x6b,  0x18,  0x12,  0x1c,  0x46,  0x1c,  0x9c,  0x32,  0x00,  0x40,  0x0e,  0x47,  0x48,  0x47,
13415  0x41,  0x48,  0x89,  0x48,  0x80,  0x4c,  0x00,  0x54,  0x44,  0x55,  0xe5,  0x55,  0x14,  0x56,  0x77,  0x57,
13416  0xbf,  0x57,  0x40,  0x5c,  0x06,  0x80,  0x08,  0x90,  0x03,  0xa1,  0xfe,  0x9c,  0xf0,  0x29,  0x02,  0xfe,
13417  0xb8,  0x0c,  0xff,  0x10,  0x00,  0x00,  0xd0,  0xfe,  0xcc,  0x18,  0x00,  0xcf,  0xfe,  0x80,  0x01,  0xff,
13418  0x03,  0x00,  0x00,  0xfe,  0x93,  0x15,  0xfe,  0x0f,  0x05,  0xff,  0x38,  0x00,  0x00,  0xfe,  0x57,  0x24,
13419  0x00,  0xfe,  0x48,  0x00,  0x4f,  0xff,  0x04,  0x00,  0x00,  0x10,  0xff,  0x09,  0x00,  0x00,  0xff,  0x08,
13420  0x01,  0x01,  0xff,  0x08,  0xff,  0xff,  0xff,  0x27,  0x00,  0x00,  0xff,  0x10,  0xff,  0xff,  0xff,  0x0f,
13421  0x00,  0x00,  0xfe,  0x78,  0x56,  0xfe,  0x34,  0x12,  0xff,  0x21,  0x00,  0x00,  0xfe,  0x04,  0xf7,  0xcf,
13422  0x2a,  0x67,  0x0b,  0x01,  0xfe,  0xce,  0x0e,  0xfe,  0x04,  0xf7,  0xcf,  0x67,  0x0b,  0x3c,  0x2a,  0xfe,
13423  0x3d,  0xf0,  0xfe,  0x02,  0x02,  0xfe,  0x20,  0xf0,  0x9c,  0xfe,  0x91,  0xf0,  0xfe,  0xf0,  0x01,  0xfe,
13424  0x90,  0xf0,  0xfe,  0xf0,  0x01,  0xfe,  0x8f,  0xf0,  0x9c,  0x05,  0x51,  0x3b,  0x02,  0xfe,  0xd4,  0x0c,
13425  0x01,  0xfe,  0x44,  0x0d,  0xfe,  0xdd,  0x12,  0xfe,  0xfc,  0x10,  0xfe,  0x28,  0x1c,  0x05,  0xfe,  0xa6,
13426  0x00,  0xfe,  0xd3,  0x12,  0x47,  0x18,  0xfe,  0xa6,  0x00,  0xb5,  0xfe,  0x48,  0xf0,  0xfe,  0x86,  0x02,
13427  0xfe,  0x49,  0xf0,  0xfe,  0xa0,  0x02,  0xfe,  0x4a,  0xf0,  0xfe,  0xbe,  0x02,  0xfe,  0x46,  0xf0,  0xfe,
13428  0x50,  0x02,  0xfe,  0x47,  0xf0,  0xfe,  0x56,  0x02,  0xfe,  0x43,  0xf0,  0xfe,  0x44,  0x02,  0xfe,  0x44,
13429  0xf0,  0xfe,  0x48,  0x02,  0xfe,  0x45,  0xf0,  0xfe,  0x4c,  0x02,  0x17,  0x0b,  0xa0,  0x17,  0x06,  0x18,
13430  0x96,  0x02,  0x29,  0xfe,  0x00,  0x1c,  0xde,  0xfe,  0x02,  0x1c,  0xdd,  0xfe,  0x1e,  0x1c,  0xfe,  0xe9,
13431  0x10,  0x01,  0xfe,  0x20,  0x17,  0xfe,  0xe7,  0x10,  0xfe,  0x06,  0xfc,  0xc7,  0x0a,  0x6b,  0x01,  0x9e,
13432  0x02,  0x29,  0x14,  0x4d,  0x37,  0x97,  0x01,  0xfe,  0x64,  0x0f,  0x0a,  0x6b,  0x01,  0x82,  0xfe,  0xbd,
13433  0x10,  0x0a,  0x6b,  0x01,  0x82,  0xfe,  0xad,  0x10,  0xfe,  0x16,  0x1c,  0xfe,  0x58,  0x1c,  0x17,  0x06,
13434  0x18,  0x96,  0x2a,  0x25,  0x29,  0xfe,  0x3d,  0xf0,  0xfe,  0x02,  0x02,  0x21,  0xfe,  0x94,  0x02,  0xfe,
13435  0x5a,  0x1c,  0xea,  0xfe,  0x14,  0x1c,  0x14,  0xfe,  0x30,  0x00,  0x37,  0x97,  0x01,  0xfe,  0x54,  0x0f,
13436  0x17,  0x06,  0x18,  0x96,  0x02,  0xd0,  0x1e,  0x20,  0x07,  0x10,  0x34,  0xfe,  0x69,  0x10,  0x17,  0x06,
13437  0x18,  0x96,  0xfe,  0x04,  0xec,  0x20,  0x46,  0x3d,  0x12,  0x20,  0xfe,  0x05,  0xf6,  0xc7,  0x01,  0xfe,
13438  0x52,  0x16,  0x09,  0x4a,  0x4c,  0x35,  0x11,  0x2d,  0x3c,  0x8a,  0x01,  0xe6,  0x02,  0x29,  0x0a,  0x40,
13439  0x01,  0x0e,  0x07,  0x00,  0x5d,  0x01,  0x6f,  0xfe,  0x18,  0x10,  0xfe,  0x41,  0x58,  0x0a,  0x99,  0x01,
13440  0x0e,  0xfe,  0xc8,  0x54,  0x64,  0xfe,  0x0c,  0x03,  0x01,  0xe6,  0x02,  0x29,  0x2a,  0x46,  0xfe,  0x02,
13441  0xe8,  0x27,  0xf8,  0xfe,  0x9e,  0x43,  0xf7,  0xfe,  0x27,  0xf0,  0xfe,  0xdc,  0x01,  0xfe,  0x07,  0x4b,
13442  0xfe,  0x20,  0xf0,  0x9c,  0xfe,  0x40,  0x1c,  0x25,  0xd2,  0xfe,  0x26,  0xf0,  0xfe,  0x56,  0x03,  0xfe,
13443  0xa0,  0xf0,  0xfe,  0x44,  0x03,  0xfe,  0x11,  0xf0,  0x9c,  0xfe,  0xef,  0x10,  0xfe,  0x9f,  0xf0,  0xfe,
13444  0x64,  0x03,  0xeb,  0x0f,  0xfe,  0x11,  0x00,  0x02,  0x5a,  0x2a,  0xfe,  0x48,  0x1c,  0xeb,  0x09,  0x04,
13445  0x1d,  0xfe,  0x18,  0x13,  0x23,  0x1e,  0x98,  0xac,  0x12,  0x98,  0x0a,  0x40,  0x01,  0x0e,  0xac,  0x75,
13446  0x01,  0xfe,  0xbc,  0x15,  0x11,  0xca,  0x25,  0xd2,  0xfe,  0x01,  0xf0,  0xd2,  0xfe,  0x82,  0xf0,  0xfe,
13447  0x92,  0x03,  0xec,  0x11,  0xfe,  0xe4,  0x00,  0x65,  0xfe,  0xa4,  0x03,  0x25,  0x32,  0x1f,  0xfe,  0xb4,
13448  0x03,  0x01,  0x43,  0xfe,  0x06,  0xf0,  0xfe,  0xc4,  0x03,  0x8d,  0x81,  0xfe,  0x0a,  0xf0,  0xfe,  0x7a,
13449  0x06,  0x02,  0x22,  0x05,  0x6b,  0x28,  0x16,  0xfe,  0xf6,  0x04,  0x14,  0x2c,  0x01,  0x33,  0x8f,  0xfe,
13450  0x66,  0x02,  0x02,  0xd1,  0xeb,  0x2a,  0x67,  0x1a,  0xfe,  0x67,  0x1b,  0xf8,  0xf7,  0xfe,  0x48,  0x1c,
13451  0x70,  0x01,  0x6e,  0x87,  0x0a,  0x40,  0x01,  0x0e,  0x07,  0x00,  0x16,  0xd3,  0x0a,  0xca,  0x01,  0x0e,
13452  0x74,  0x60,  0x59,  0x76,  0x27,  0x05,  0x6b,  0x28,  0xfe,  0x10,  0x12,  0x14,  0x2c,  0x01,  0x33,  0x8f,
13453  0xfe,  0x66,  0x02,  0x02,  0xd1,  0xbc,  0x7d,  0xbd,  0x7f,  0x25,  0x22,  0x65,  0xfe,  0x3c,  0x04,  0x1f,
13454  0xfe,  0x38,  0x04,  0x68,  0xfe,  0xa0,  0x00,  0xfe,  0x9b,  0x57,  0xfe,  0x4e,  0x12,  0x2b,  0xff,  0x02,
13455  0x00,  0x10,  0x01,  0x08,  0x1f,  0xfe,  0xe0,  0x04,  0x2b,  0x01,  0x08,  0x1f,  0x22,  0x30,  0x2e,  0xd5,
13456  0xfe,  0x4c,  0x44,  0xfe,  0x4c,  0x12,  0x60,  0xfe,  0x44,  0x48,  0x13,  0x2c,  0xfe,  0x4c,  0x54,  0x64,
13457  0xd3,  0x46,  0x76,  0x27,  0xfa,  0xef,  0xfe,  0x62,  0x13,  0x09,  0x04,  0x1d,  0xfe,  0x2a,  0x13,  0x2f,
13458  0x07,  0x7e,  0xa5,  0xfe,  0x20,  0x10,  0x13,  0x2c,  0xfe,  0x4c,  0x54,  0x64,  0xd3,  0xfa,  0xef,  0x86,
13459  0x09,  0x04,  0x1d,  0xfe,  0x08,  0x13,  0x2f,  0x07,  0x7e,  0x6e,  0x09,  0x04,  0x1d,  0xfe,  0x1c,  0x12,
13460  0x14,  0x92,  0x09,  0x04,  0x06,  0x3b,  0x14,  0xc4,  0x01,  0x33,  0x8f,  0xfe,  0x70,  0x0c,  0x02,  0x22,
13461  0x2b,  0x11,  0xfe,  0xe6,  0x00,  0xfe,  0x1c,  0x90,  0xf9,  0x03,  0x14,  0x92,  0x01,  0x33,  0x02,  0x29,
13462  0xfe,  0x42,  0x5b,  0x67,  0x1a,  0xfe,  0x46,  0x59,  0xf8,  0xf7,  0xfe,  0x87,  0x80,  0xfe,  0x31,  0xe4,
13463  0x4f,  0x09,  0x04,  0x0b,  0xfe,  0x78,  0x13,  0xfe,  0x20,  0x80,  0x07,  0x1a,  0xfe,  0x70,  0x12,  0x49,
13464  0x04,  0x06,  0xfe,  0x60,  0x13,  0x05,  0xfe,  0xa2,  0x00,  0x28,  0x16,  0xfe,  0x80,  0x05,  0xfe,  0x31,
13465  0xe4,  0x6a,  0x49,  0x04,  0x0b,  0xfe,  0x4a,  0x13,  0x05,  0xfe,  0xa0,  0x00,  0x28,  0xfe,  0x42,  0x12,
13466  0x5e,  0x01,  0x08,  0x25,  0x32,  0xf1,  0x01,  0x08,  0x26,  0xfe,  0x98,  0x05,  0x11,  0xfe,  0xe3,  0x00,
13467  0x23,  0x49,  0xfe,  0x4a,  0xf0,  0xfe,  0x6a,  0x05,  0xfe,  0x49,  0xf0,  0xfe,  0x64,  0x05,  0x83,  0x24,
13468  0xfe,  0x21,  0x00,  0xa1,  0x24,  0xfe,  0x22,  0x00,  0xa0,  0x24,  0x4c,  0xfe,  0x09,  0x48,  0x01,  0x08,
13469  0x26,  0xfe,  0x98,  0x05,  0xfe,  0xe2,  0x08,  0x49,  0x04,  0xc5,  0x3b,  0x01,  0x86,  0x24,  0x06,  0x12,
13470  0xcc,  0x37,  0xfe,  0x27,  0x01,  0x09,  0x04,  0x1d,  0xfe,  0x22,  0x12,  0x47,  0x01,  0xa7,  0x14,  0x92,
13471  0x09,  0x04,  0x06,  0x3b,  0x14,  0xc4,  0x01,  0x33,  0x8f,  0xfe,  0x70,  0x0c,  0x02,  0x22,  0x05,  0xfe,
13472  0x9c,  0x00,  0x28,  0xfe,  0x3e,  0x12,  0x05,  0x50,  0x28,  0xfe,  0x36,  0x13,  0x47,  0x01,  0xa7,  0x26,
13473  0xfe,  0x08,  0x06,  0x0a,  0x06,  0x49,  0x04,  0x19,  0xfe,  0x02,  0x12,  0x5f,  0x01,  0xfe,  0xaa,  0x14,
13474  0x1f,  0xfe,  0xfe,  0x05,  0x11,  0x9a,  0x01,  0x43,  0x11,  0xfe,  0xe5,  0x00,  0x05,  0x50,  0xb4,  0x0c,
13475  0x50,  0x05,  0xc6,  0x28,  0xfe,  0x62,  0x12,  0x05,  0x3f,  0x28,  0xfe,  0x5a,  0x13,  0x01,  0xfe,  0x14,
13476  0x18,  0x01,  0xfe,  0x66,  0x18,  0xfe,  0x43,  0x48,  0xb7,  0x19,  0x13,  0x6c,  0xff,  0x02,  0x00,  0x57,
13477  0x48,  0x8b,  0x1c,  0x3d,  0x85,  0xb7,  0x69,  0x47,  0x01,  0xa7,  0x26,  0xfe,  0x72,  0x06,  0x49,  0x04,
13478  0x1b,  0xdf,  0x89,  0x0a,  0x4d,  0x01,  0xfe,  0xd8,  0x14,  0x1f,  0xfe,  0x68,  0x06,  0x11,  0x9a,  0x01,
13479  0x43,  0x11,  0xfe,  0xe5,  0x00,  0x05,  0x3f,  0xb4,  0x0c,  0x3f,  0x17,  0x06,  0x01,  0xa7,  0xec,  0x72,
13480  0x70,  0x01,  0x6e,  0x87,  0x11,  0xfe,  0xe2,  0x00,  0x01,  0x08,  0x25,  0x32,  0xfe,  0x0a,  0xf0,  0xfe,
13481  0xa6,  0x06,  0x8c,  0xfe,  0x5c,  0x07,  0xfe,  0x06,  0xf0,  0xfe,  0x64,  0x07,  0x8d,  0x81,  0x02,  0x22,
13482  0x09,  0x04,  0x0b,  0xfe,  0x2e,  0x12,  0x15,  0x1a,  0x01,  0x08,  0x15,  0x00,  0x01,  0x08,  0x15,  0x00,
13483  0x01,  0x08,  0x15,  0x00,  0x01,  0x08,  0xfe,  0x99,  0xa4,  0x01,  0x08,  0x15,  0x00,  0x02,  0xfe,  0x32,
13484  0x08,  0x61,  0x04,  0x1b,  0xfe,  0x38,  0x12,  0x09,  0x04,  0x1b,  0x6e,  0x15,  0xfe,  0x1b,  0x00,  0x01,
13485  0x08,  0x15,  0x00,  0x01,  0x08,  0x15,  0x00,  0x01,  0x08,  0x15,  0x00,  0x01,  0x08,  0x15,  0x06,  0x01,
13486  0x08,  0x15,  0x00,  0x02,  0xd9,  0x66,  0x4c,  0xfe,  0x3a,  0x55,  0x5f,  0xfe,  0x9a,  0x81,  0x4b,  0x1d,
13487  0xba,  0xfe,  0x32,  0x07,  0x0a,  0x1d,  0xfe,  0x09,  0x6f,  0xaf,  0xfe,  0xca,  0x45,  0xfe,  0x32,  0x12,
13488  0x62,  0x2c,  0x85,  0x66,  0x7b,  0x01,  0x08,  0x25,  0x32,  0xfe,  0x0a,  0xf0,  0xfe,  0x32,  0x07,  0x8d,
13489  0x81,  0x8c,  0xfe,  0x5c,  0x07,  0x02,  0x22,  0x01,  0x43,  0x02,  0xfe,  0x8a,  0x06,  0x15,  0x19,  0x02,
13490  0xfe,  0x8a,  0x06,  0xfe,  0x9c,  0xf7,  0xd4,  0xfe,  0x2c,  0x90,  0xfe,  0xae,  0x90,  0x77,  0xfe,  0xca,
13491  0x07,  0x0c,  0x54,  0x18,  0x55,  0x09,  0x4a,  0x6a,  0x35,  0x1e,  0x20,  0x07,  0x10,  0xfe,  0x0e,  0x12,
13492  0x74,  0xfe,  0x80,  0x80,  0x37,  0x20,  0x63,  0x27,  0xfe,  0x06,  0x10,  0xfe,  0x83,  0xe7,  0xc4,  0xa1,
13493  0xfe,  0x03,  0x40,  0x09,  0x4a,  0x4f,  0x35,  0x01,  0xa8,  0xad,  0xfe,  0x1f,  0x40,  0x12,  0x58,  0x01,
13494  0xa5,  0xfe,  0x08,  0x50,  0xfe,  0x8a,  0x50,  0xfe,  0x44,  0x51,  0xfe,  0xc6,  0x51,  0x83,  0xfb,  0xfe,
13495  0x8a,  0x90,  0x0c,  0x52,  0x18,  0x53,  0xfe,  0x0c,  0x90,  0xfe,  0x8e,  0x90,  0xfe,  0x40,  0x50,  0xfe,
13496  0xc2,  0x50,  0x0c,  0x39,  0x18,  0x3a,  0xfe,  0x4a,  0x10,  0x09,  0x04,  0x6a,  0xfe,  0x2a,  0x12,  0xfe,
13497  0x2c,  0x90,  0xfe,  0xae,  0x90,  0x0c,  0x54,  0x18,  0x55,  0x09,  0x04,  0x4f,  0x85,  0x01,  0xa8,  0xfe,
13498  0x1f,  0x80,  0x12,  0x58,  0xfe,  0x44,  0x90,  0xfe,  0xc6,  0x90,  0x0c,  0x56,  0x18,  0x57,  0xfb,  0xfe,
13499  0x8a,  0x90,  0x0c,  0x52,  0x18,  0x53,  0xfe,  0x40,  0x90,  0xfe,  0xc2,  0x90,  0x0c,  0x39,  0x18,  0x3a,
13500  0x0c,  0x38,  0x18,  0x4e,  0x09,  0x4a,  0x19,  0x35,  0x2a,  0x13,  0xfe,  0x4e,  0x11,  0x65,  0xfe,  0x48,
13501  0x08,  0xfe,  0x9e,  0xf0,  0xfe,  0x5c,  0x08,  0xb1,  0x16,  0x32,  0x2a,  0x73,  0xdd,  0xb8,  0xfe,  0x80,
13502  0x08,  0xb9,  0xfe,  0x9e,  0x08,  0x8c,  0xfe,  0x74,  0x08,  0xfe,  0x06,  0xf0,  0xfe,  0x7a,  0x08,  0x8d,
13503  0x81,  0x02,  0x22,  0x01,  0x43,  0xfe,  0xc9,  0x10,  0x15,  0x19,  0xfe,  0xc9,  0x10,  0x61,  0x04,  0x06,
13504  0xfe,  0x10,  0x12,  0x61,  0x04,  0x0b,  0x45,  0x09,  0x04,  0x0b,  0xfe,  0x68,  0x12,  0xfe,  0x2e,  0x1c,
13505  0x02,  0xfe,  0x24,  0x0a,  0x61,  0x04,  0x06,  0x45,  0x61,  0x04,  0x0b,  0xfe,  0x52,  0x12,  0xfe,  0x2c,
13506  0x1c,  0xfe,  0xaa,  0xf0,  0xfe,  0x1e,  0x09,  0xfe,  0xac,  0xf0,  0xfe,  0xbe,  0x08,  0xfe,  0x8a,  0x10,
13507  0xaa,  0xfe,  0xf3,  0x10,  0xfe,  0xad,  0xf0,  0xfe,  0xca,  0x08,  0x02,  0xfe,  0x24,  0x0a,  0xab,  0xfe,
13508  0xe7,  0x10,  0xfe,  0x2b,  0xf0,  0x9d,  0xe9,  0x1c,  0xfe,  0x00,  0xfe,  0xfe,  0x1c,  0x12,  0xb5,  0xfe,
13509  0xd2,  0xf0,  0x9d,  0xfe,  0x76,  0x18,  0x1c,  0x1a,  0x16,  0x9d,  0x05,  0xcb,  0x1c,  0x06,  0x16,  0x9d,
13510  0xb8,  0x6d,  0xb9,  0x6d,  0xaa,  0xab,  0xfe,  0xb1,  0x10,  0x70,  0x5e,  0x2b,  0x14,  0x92,  0x01,  0x33,
13511  0x0f,  0xfe,  0x35,  0x00,  0xfe,  0x01,  0xf0,  0x5a,  0x0f,  0x7c,  0x02,  0x5a,  0xfe,  0x74,  0x18,  0x1c,
13512  0xfe,  0x00,  0xf8,  0x16,  0x6d,  0x67,  0x1b,  0x01,  0xfe,  0x44,  0x0d,  0x3b,  0x01,  0xe6,  0x1e,  0x27,
13513  0x74,  0x67,  0x1a,  0x02,  0x6d,  0x09,  0x04,  0x0b,  0x21,  0xfe,  0x06,  0x0a,  0x09,  0x04,  0x6a,  0xfe,
13514  0x82,  0x12,  0x09,  0x04,  0x19,  0xfe,  0x66,  0x13,  0x1e,  0x58,  0xac,  0xfc,  0xfe,  0x83,  0x80,  0xfe,
13515  0xc8,  0x44,  0xfe,  0x2e,  0x13,  0xfe,  0x04,  0x91,  0xfe,  0x86,  0x91,  0x63,  0x27,  0xfe,  0x40,  0x59,
13516  0xfe,  0xc1,  0x59,  0x77,  0xd7,  0x05,  0x54,  0x31,  0x55,  0x0c,  0x7b,  0x18,  0x7c,  0xbe,  0x54,  0xbf,
13517  0x55,  0x01,  0xa8,  0xad,  0x63,  0x27,  0x12,  0x58,  0xc0,  0x38,  0xc1,  0x4e,  0x79,  0x56,  0x68,  0x57,
13518  0xf4,  0xf5,  0xfe,  0x04,  0xfa,  0x38,  0xfe,  0x05,  0xfa,  0x4e,  0x01,  0xa5,  0xa2,  0x23,  0x0c,  0x7b,
13519  0x0c,  0x7c,  0x79,  0x56,  0x68,  0x57,  0xfe,  0x12,  0x10,  0x09,  0x04,  0x19,  0x16,  0xd7,  0x79,  0x39,
13520  0x68,  0x3a,  0x09,  0x04,  0xfe,  0xf7,  0x00,  0x35,  0x05,  0x52,  0x31,  0x53,  0xfe,  0x10,  0x58,  0xfe,
13521  0x91,  0x58,  0xfe,  0x14,  0x59,  0xfe,  0x95,  0x59,  0x02,  0x6d,  0x09,  0x04,  0x19,  0x16,  0xd7,  0x09,
13522  0x04,  0xfe,  0xf7,  0x00,  0x35,  0xfe,  0x3a,  0x55,  0xfe,  0x19,  0x81,  0x5f,  0xfe,  0x10,  0x90,  0xfe,
13523  0x92,  0x90,  0xfe,  0xd7,  0x10,  0x2f,  0x07,  0x9b,  0x16,  0xfe,  0xc6,  0x08,  0x11,  0x9b,  0x09,  0x04,
13524  0x0b,  0xfe,  0x14,  0x13,  0x05,  0x39,  0x31,  0x3a,  0x77,  0xfe,  0xc6,  0x08,  0xfe,  0x0c,  0x58,  0xfe,
13525  0x8d,  0x58,  0x02,  0x6d,  0x23,  0x47,  0xfe,  0x19,  0x80,  0xde,  0x09,  0x04,  0x0b,  0xfe,  0x1a,  0x12,
13526  0xfe,  0x6c,  0x19,  0xfe,  0x19,  0x41,  0xe9,  0xb5,  0xfe,  0xd1,  0xf0,  0xd9,  0x14,  0x7a,  0x01,  0x33,
13527  0x0f,  0xfe,  0x44,  0x00,  0xfe,  0x8e,  0x10,  0xfe,  0x6c,  0x19,  0xbe,  0x39,  0xfe,  0xed,  0x19,  0xbf,
13528  0x3a,  0xfe,  0x0c,  0x51,  0xfe,  0x8e,  0x51,  0xe9,  0x1c,  0xfe,  0x00,  0xff,  0x34,  0xfe,  0x74,  0x10,
13529  0xb5,  0xfe,  0xd2,  0xf0,  0xfe,  0xb2,  0x0a,  0xfe,  0x76,  0x18,  0x1c,  0x1a,  0x84,  0x05,  0xcb,  0x1c,
13530  0x06,  0xfe,  0x08,  0x13,  0x0f,  0xfe,  0x16,  0x00,  0x02,  0x5a,  0xfe,  0xd1,  0xf0,  0xfe,  0xc4,  0x0a,
13531  0x14,  0x7a,  0x01,  0x33,  0x0f,  0xfe,  0x17,  0x00,  0xfe,  0x42,  0x10,  0xfe,  0xce,  0xf0,  0xfe,  0xca,
13532  0x0a,  0xfe,  0x3c,  0x10,  0xfe,  0xcd,  0xf0,  0xfe,  0xd6,  0x0a,  0x0f,  0xfe,  0x22,  0x00,  0x02,  0x5a,
13533  0xfe,  0xcb,  0xf0,  0xfe,  0xe2,  0x0a,  0x0f,  0xfe,  0x24,  0x00,  0x02,  0x5a,  0xfe,  0xd0,  0xf0,  0xfe,
13534  0xec,  0x0a,  0x0f,  0x93,  0xdc,  0xfe,  0xcf,  0xf0,  0xfe,  0xf6,  0x0a,  0x0f,  0x4c,  0xfe,  0x10,  0x10,
13535  0xfe,  0xcc,  0xf0,  0xd9,  0x61,  0x04,  0x19,  0x3b,  0x0f,  0xfe,  0x12,  0x00,  0x2a,  0x13,  0xfe,  0x4e,
13536  0x11,  0x65,  0xfe,  0x0c,  0x0b,  0xfe,  0x9e,  0xf0,  0xfe,  0x20,  0x0b,  0xb1,  0x16,  0x32,  0x2a,  0x73,
13537  0xdd,  0xb8,  0x22,  0xb9,  0x22,  0x2a,  0xec,  0x65,  0xfe,  0x2c,  0x0b,  0x25,  0x32,  0x8c,  0xfe,  0x48,
13538  0x0b,  0x8d,  0x81,  0xb8,  0xd4,  0xb9,  0xd4,  0x02,  0x22,  0x01,  0x43,  0xfe,  0xdb,  0x10,  0x11,  0xfe,
13539  0xe8,  0x00,  0xaa,  0xab,  0x70,  0xbc,  0x7d,  0xbd,  0x7f,  0xfe,  0x89,  0xf0,  0x22,  0x30,  0x2e,  0xd8,
13540  0xbc,  0x7d,  0xbd,  0x7f,  0x01,  0x08,  0x1f,  0x22,  0x30,  0x2e,  0xd6,  0xb1,  0x45,  0x0f,  0xfe,  0x42,
13541  0x00,  0x02,  0x5a,  0x78,  0x06,  0xfe,  0x81,  0x49,  0x16,  0xfe,  0x38,  0x0c,  0x09,  0x04,  0x0b,  0xfe,
13542  0x44,  0x13,  0x0f,  0x00,  0x4b,  0x0b,  0xfe,  0x54,  0x12,  0x4b,  0xfe,  0x28,  0x00,  0x21,  0xfe,  0xa6,
13543  0x0c,  0x0a,  0x40,  0x01,  0x0e,  0x07,  0x00,  0x5d,  0x3e,  0xfe,  0x28,  0x00,  0xfe,  0xe2,  0x10,  0x01,
13544  0xe7,  0x01,  0xe8,  0x0a,  0x99,  0x01,  0xfe,  0x32,  0x0e,  0x59,  0x11,  0x2d,  0x01,  0x6f,  0x02,  0x29,
13545  0x0f,  0xfe,  0x44,  0x00,  0x4b,  0x0b,  0xdf,  0x3e,  0x0b,  0xfe,  0xb4,  0x10,  0x01,  0x86,  0x3e,  0x0b,
13546  0xfe,  0xaa,  0x10,  0x01,  0x86,  0xfe,  0x19,  0x82,  0xfe,  0x34,  0x46,  0xa3,  0x3e,  0x0b,  0x0f,  0xfe,
13547  0x43,  0x00,  0xfe,  0x96,  0x10,  0x09,  0x4a,  0x0b,  0x35,  0x01,  0xe7,  0x01,  0xe8,  0x59,  0x11,  0x2d,
13548  0x01,  0x6f,  0x67,  0x0b,  0x59,  0x3c,  0x8a,  0x02,  0xfe,  0x2a,  0x03,  0x09,  0x04,  0x0b,  0x84,  0x3e,
13549  0x0b,  0x0f,  0x00,  0xfe,  0x5c,  0x10,  0x61,  0x04,  0x1b,  0xfe,  0x58,  0x12,  0x09,  0x04,  0x1b,  0xfe,
13550  0x50,  0x13,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,  0x5c,  0x0c,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,
13551  0xf0,  0xfe,  0x62,  0x0c,  0x09,  0x4a,  0x1b,  0x35,  0xfe,  0xa9,  0x10,  0x0f,  0xfe,  0x15,  0x00,  0xfe,
13552  0x04,  0xe6,  0x0b,  0x5f,  0x5c,  0x0f,  0xfe,  0x13,  0x00,  0xfe,  0x10,  0x10,  0x0f,  0xfe,  0x47,  0x00,
13553  0xa1,  0x0f,  0xfe,  0x41,  0x00,  0xa0,  0x0f,  0xfe,  0x24,  0x00,  0x87,  0xaa,  0xab,  0x70,  0x05,  0x6b,
13554  0x28,  0x21,  0xd1,  0x5f,  0xfe,  0x04,  0xe6,  0x1b,  0xfe,  0x9d,  0x41,  0xfe,  0x1c,  0x42,  0x59,  0x01,
13555  0xda,  0x02,  0x29,  0xea,  0x14,  0x0b,  0x37,  0x95,  0xa9,  0x14,  0xfe,  0x31,  0x00,  0x37,  0x97,  0x01,
13556  0xfe,  0x54,  0x0f,  0x02,  0xd0,  0x3c,  0xfe,  0x06,  0xec,  0xc9,  0xee,  0x3e,  0x1d,  0xfe,  0xce,  0x45,
13557  0x34,  0x3c,  0xfe,  0x06,  0xea,  0xc9,  0xfe,  0x47,  0x4b,  0x89,  0xfe,  0x75,  0x57,  0x05,  0x51,  0xfe,
13558  0x98,  0x56,  0xfe,  0x38,  0x12,  0x0a,  0x42,  0x01,  0x0e,  0xfe,  0x44,  0x48,  0x46,  0x09,  0x04,  0x1d,
13559  0xfe,  0x1a,  0x13,  0x0a,  0x40,  0x01,  0x0e,  0x47,  0xfe,  0x41,  0x58,  0x0a,  0x99,  0x01,  0x0e,  0xfe,
13560  0x49,  0x54,  0x8e,  0xfe,  0x2a,  0x0d,  0x02,  0xfe,  0x2a,  0x03,  0x0a,  0x51,  0xfe,  0xee,  0x14,  0xee,
13561  0x3e,  0x1d,  0xfe,  0xce,  0x45,  0x34,  0x3c,  0xfe,  0xce,  0x47,  0xfe,  0xad,  0x13,  0x02,  0x29,  0x1e,
13562  0x20,  0x07,  0x10,  0xfe,  0x9e,  0x12,  0x23,  0x12,  0x4d,  0x12,  0x94,  0x12,  0xce,  0x1e,  0x2d,  0x47,
13563  0x37,  0x2d,  0xb1,  0xe0,  0xfe,  0xbc,  0xf0,  0xfe,  0xec,  0x0d,  0x13,  0x06,  0x12,  0x4d,  0x01,  0xfe,
13564  0xe2,  0x15,  0x05,  0xfe,  0x38,  0x01,  0x31,  0xfe,  0x3a,  0x01,  0x77,  0xfe,  0xf0,  0x0d,  0xfe,  0x02,
13565  0xec,  0xce,  0x62,  0x00,  0x5d,  0xfe,  0x04,  0xec,  0x20,  0x46,  0xfe,  0x05,  0xf6,  0xfe,  0x34,  0x01,
13566  0x01,  0xfe,  0x52,  0x16,  0xfb,  0xfe,  0x48,  0xf4,  0x0d,  0xfe,  0x18,  0x13,  0xaf,  0xfe,  0x02,  0xea,
13567  0xce,  0x62,  0x7a,  0xfe,  0xc5,  0x13,  0x14,  0x1b,  0x37,  0x95,  0xa9,  0x5c,  0x05,  0xfe,  0x38,  0x01,
13568  0x1c,  0xfe,  0xf0,  0xff,  0x0c,  0xfe,  0x60,  0x01,  0x05,  0xfe,  0x3a,  0x01,  0x0c,  0xfe,  0x62,  0x01,
13569  0x3d,  0x12,  0x20,  0x24,  0x06,  0x12,  0x2d,  0x11,  0x2d,  0x8a,  0x13,  0x06,  0x03,  0x23,  0x03,  0x1e,
13570  0x4d,  0xfe,  0xf7,  0x12,  0x1e,  0x94,  0xac,  0x12,  0x94,  0x07,  0x7a,  0xfe,  0x71,  0x13,  0xfe,  0x24,
13571  0x1c,  0x14,  0x1a,  0x37,  0x95,  0xa9,  0xfe,  0xd9,  0x10,  0xb6,  0xfe,  0x03,  0xdc,  0xfe,  0x73,  0x57,
13572  0xfe,  0x80,  0x5d,  0x03,  0xb6,  0xfe,  0x03,  0xdc,  0xfe,  0x5b,  0x57,  0xfe,  0x80,  0x5d,  0x03,  0xfe,
13573  0x03,  0x57,  0xb6,  0x23,  0xfe,  0x00,  0xcc,  0x03,  0xfe,  0x03,  0x57,  0xb6,  0x75,  0x03,  0x09,  0x04,
13574  0x4c,  0xfe,  0x22,  0x13,  0xfe,  0x1c,  0x80,  0x07,  0x06,  0xfe,  0x1a,  0x13,  0xfe,  0x1e,  0x80,  0xe1,
13575  0xfe,  0x1d,  0x80,  0xa4,  0xfe,  0x0c,  0x90,  0xfe,  0x0e,  0x13,  0xfe,  0x0e,  0x90,  0xa3,  0xfe,  0x3c,
13576  0x90,  0xfe,  0x30,  0xf4,  0x0b,  0xfe,  0x3c,  0x50,  0xa0,  0x01,  0xfe,  0x82,  0x16,  0x2f,  0x07,  0x2d,
13577  0xe0,  0x01,  0xfe,  0xbc,  0x15,  0x09,  0x04,  0x1d,  0x45,  0x01,  0xe7,  0x01,  0xe8,  0x11,  0xfe,  0xe9,
13578  0x00,  0x09,  0x04,  0x4c,  0xfe,  0x2c,  0x13,  0x01,  0xfe,  0x14,  0x16,  0xfe,  0x1e,  0x1c,  0xfe,  0x14,
13579  0x90,  0xfe,  0x96,  0x90,  0x0c,  0xfe,  0x64,  0x01,  0x18,  0xfe,  0x66,  0x01,  0x09,  0x04,  0x4f,  0xfe,
13580  0x12,  0x12,  0xfe,  0x03,  0x80,  0x74,  0xfe,  0x01,  0xec,  0x20,  0xfe,  0x80,  0x40,  0x12,  0x20,  0x63,
13581  0x27,  0x11,  0xc8,  0x59,  0x1e,  0x20,  0xed,  0x76,  0x20,  0x03,  0xfe,  0x08,  0x1c,  0x05,  0xfe,  0xac,
13582  0x00,  0xfe,  0x06,  0x58,  0x05,  0xfe,  0xae,  0x00,  0xfe,  0x07,  0x58,  0x05,  0xfe,  0xb0,  0x00,  0xfe,
13583  0x08,  0x58,  0x05,  0xfe,  0xb2,  0x00,  0xfe,  0x09,  0x58,  0xfe,  0x0a,  0x1c,  0x24,  0x69,  0x12,  0xc9,
13584  0x23,  0x0c,  0x50,  0x0c,  0x3f,  0x13,  0x40,  0x48,  0x5f,  0x17,  0x1d,  0xfe,  0x90,  0x4d,  0xfe,  0x91,
13585  0x54,  0x21,  0xfe,  0x08,  0x0f,  0x3e,  0x10,  0x13,  0x42,  0x48,  0x17,  0x4c,  0xfe,  0x90,  0x4d,  0xfe,
13586  0x91,  0x54,  0x21,  0xfe,  0x1e,  0x0f,  0x24,  0x10,  0x12,  0x20,  0x78,  0x2c,  0x46,  0x1e,  0x20,  0xed,
13587  0x76,  0x20,  0x11,  0xc8,  0xf6,  0xfe,  0xd6,  0xf0,  0xfe,  0x32,  0x0f,  0xea,  0x70,  0xfe,  0x14,  0x1c,
13588  0xfe,  0x10,  0x1c,  0xfe,  0x18,  0x1c,  0x03,  0x3c,  0xfe,  0x0c,  0x14,  0xee,  0xfe,  0x07,  0xe6,  0x1d,
13589  0xfe,  0xce,  0x47,  0xfe,  0xf5,  0x13,  0x03,  0x01,  0x86,  0x78,  0x2c,  0x46,  0xfa,  0xef,  0xfe,  0x42,
13590  0x13,  0x2f,  0x07,  0x2d,  0xfe,  0x34,  0x13,  0x0a,  0x42,  0x01,  0x0e,  0xb0,  0xfe,  0x36,  0x12,  0xf0,
13591  0xfe,  0x45,  0x48,  0x01,  0xe3,  0xfe,  0x00,  0xcc,  0xb0,  0xfe,  0xf3,  0x13,  0x3d,  0x75,  0x07,  0x10,
13592  0xa3,  0x0a,  0x80,  0x01,  0x0e,  0xfe,  0x80,  0x5c,  0x01,  0x6f,  0xfe,  0x0e,  0x10,  0x07,  0x7e,  0x45,
13593  0xf6,  0xfe,  0xd6,  0xf0,  0xfe,  0x6c,  0x0f,  0x03,  0xfe,  0x44,  0x58,  0x74,  0xfe,  0x01,  0xec,  0x97,
13594  0xfe,  0x9e,  0x40,  0xfe,  0x9d,  0xe7,  0x00,  0xfe,  0x9c,  0xe7,  0x1b,  0x76,  0x27,  0x01,  0xda,  0xfe,
13595  0xdd,  0x10,  0x2a,  0xbc,  0x7d,  0xbd,  0x7f,  0x30,  0x2e,  0xd5,  0x07,  0x1b,  0xfe,  0x48,  0x12,  0x07,
13596  0x0b,  0xfe,  0x56,  0x12,  0x07,  0x1a,  0xfe,  0x30,  0x12,  0x07,  0xc2,  0x16,  0xfe,  0x3e,  0x11,  0x07,
13597  0xfe,  0x23,  0x00,  0x16,  0xfe,  0x4a,  0x11,  0x07,  0x06,  0x16,  0xfe,  0xa8,  0x11,  0x07,  0x19,  0xfe,
13598  0x12,  0x12,  0x07,  0x00,  0x16,  0x22,  0x14,  0xc2,  0x01,  0x33,  0x9f,  0x2b,  0x01,  0x08,  0x8c,  0x43,
13599  0x03,  0x2b,  0xfe,  0x62,  0x08,  0x0a,  0xca,  0x01,  0xfe,  0x32,  0x0e,  0x11,  0x7e,  0x02,  0x29,  0x2b,
13600  0x2f,  0x07,  0x9b,  0xfe,  0xd9,  0x13,  0x79,  0x39,  0x68,  0x3a,  0x77,  0xfe,  0xfc,  0x10,  0x09,  0x04,
13601  0x6a,  0xfe,  0x72,  0x12,  0xc0,  0x38,  0xc1,  0x4e,  0xf4,  0xf5,  0x8e,  0xfe,  0xc6,  0x10,  0x1e,  0x58,
13602  0xfe,  0x26,  0x13,  0x05,  0x7b,  0x31,  0x7c,  0x77,  0xfe,  0x82,  0x0c,  0x0c,  0x54,  0x18,  0x55,  0x23,
13603  0x0c,  0x7b,  0x0c,  0x7c,  0x01,  0xa8,  0x24,  0x69,  0x73,  0x12,  0x58,  0x01,  0xa5,  0xc0,  0x38,  0xc1,
13604  0x4e,  0xfe,  0x04,  0x55,  0xfe,  0xa5,  0x55,  0xfe,  0x04,  0xfa,  0x38,  0xfe,  0x05,  0xfa,  0x4e,  0xfe,
13605  0x91,  0x10,  0x05,  0x56,  0x31,  0x57,  0xfe,  0x40,  0x56,  0xfe,  0xe1,  0x56,  0x0c,  0x56,  0x18,  0x57,
13606  0x83,  0xc0,  0x38,  0xc1,  0x4e,  0xf4,  0xf5,  0x05,  0x52,  0x31,  0x53,  0xfe,  0x00,  0x56,  0xfe,  0xa1,
13607  0x56,  0x0c,  0x52,  0x18,  0x53,  0x09,  0x04,  0x6a,  0xfe,  0x1e,  0x12,  0x1e,  0x58,  0xfe,  0x1f,  0x40,
13608  0x05,  0x54,  0x31,  0x55,  0xfe,  0x2c,  0x50,  0xfe,  0xae,  0x50,  0x05,  0x56,  0x31,  0x57,  0xfe,  0x44,
13609  0x50,  0xfe,  0xc6,  0x50,  0x05,  0x52,  0x31,  0x53,  0xfe,  0x08,  0x50,  0xfe,  0x8a,  0x50,  0x05,  0x39,
13610  0x31,  0x3a,  0xfe,  0x40,  0x50,  0xfe,  0xc2,  0x50,  0x02,  0x5c,  0x24,  0x06,  0x12,  0xcd,  0x02,  0x5b,
13611  0x2b,  0x01,  0x08,  0x1f,  0x44,  0x30,  0x2e,  0xd5,  0x07,  0x06,  0x21,  0x44,  0x2f,  0x07,  0x9b,  0x21,
13612  0x5b,  0x01,  0x6e,  0x1c,  0x3d,  0x16,  0x44,  0x09,  0x04,  0x0b,  0xe2,  0x79,  0x39,  0x68,  0x3a,  0xfe,
13613  0x0a,  0x55,  0x34,  0xfe,  0x8b,  0x55,  0xbe,  0x39,  0xbf,  0x3a,  0xfe,  0x0c,  0x51,  0xfe,  0x8e,  0x51,
13614  0x02,  0x5b,  0xfe,  0x19,  0x81,  0xaf,  0xfe,  0x19,  0x41,  0x02,  0x5b,  0x2b,  0x01,  0x08,  0x25,  0x32,
13615  0x1f,  0xa2,  0x30,  0x2e,  0xd8,  0x4b,  0x1a,  0xfe,  0xa6,  0x12,  0x4b,  0x0b,  0x3b,  0x02,  0x44,  0x01,
13616  0x08,  0x25,  0x32,  0x1f,  0xa2,  0x30,  0x2e,  0xd6,  0x07,  0x1a,  0x21,  0x44,  0x01,  0x08,  0x1f,  0xa2,
13617  0x30,  0x2e,  0xfe,  0xe8,  0x09,  0xfe,  0xc2,  0x49,  0x60,  0x05,  0xfe,  0x9c,  0x00,  0x28,  0x84,  0x49,
13618  0x04,  0x19,  0x34,  0x9f,  0xfe,  0xbb,  0x45,  0x4b,  0x00,  0x45,  0x3e,  0x06,  0x78,  0x3d,  0xfe,  0xda,
13619  0x14,  0x01,  0x6e,  0x87,  0xfe,  0x4b,  0x45,  0xe2,  0x2f,  0x07,  0x9a,  0xe1,  0x05,  0xc6,  0x28,  0x84,
13620  0x05,  0x3f,  0x28,  0x34,  0x5e,  0x02,  0x5b,  0xfe,  0xc0,  0x5d,  0xfe,  0xf8,  0x14,  0xfe,  0x03,  0x17,
13621  0x05,  0x50,  0xb4,  0x0c,  0x50,  0x5e,  0x2b,  0x01,  0x08,  0x26,  0x5c,  0x01,  0xfe,  0xaa,  0x14,  0x02,
13622  0x5c,  0x01,  0x08,  0x25,  0x32,  0x1f,  0x44,  0x30,  0x2e,  0xd6,  0x07,  0x06,  0x21,  0x44,  0x01,  0xfe,
13623  0x8e,  0x13,  0xfe,  0x42,  0x58,  0xfe,  0x82,  0x14,  0xfe,  0xa4,  0x14,  0x87,  0xfe,  0x4a,  0xf4,  0x0b,
13624  0x16,  0x44,  0xfe,  0x4a,  0xf4,  0x06,  0xfe,  0x0c,  0x12,  0x2f,  0x07,  0x9a,  0x85,  0x02,  0x5b,  0x05,
13625  0x3f,  0xb4,  0x0c,  0x3f,  0x5e,  0x2b,  0x01,  0x08,  0x26,  0x5c,  0x01,  0xfe,  0xd8,  0x14,  0x02,  0x5c,
13626  0x13,  0x06,  0x65,  0xfe,  0xca,  0x12,  0x26,  0xfe,  0xe0,  0x12,  0x72,  0xf1,  0x01,  0x08,  0x23,  0x72,
13627  0x03,  0x8f,  0xfe,  0xdc,  0x12,  0x25,  0xfe,  0xdc,  0x12,  0x1f,  0xfe,  0xca,  0x12,  0x5e,  0x2b,  0x01,
13628  0x08,  0xfe,  0xd5,  0x10,  0x13,  0x6c,  0xff,  0x02,  0x00,  0x57,  0x48,  0x8b,  0x1c,  0xfe,  0xff,  0x7f,
13629  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x03,  0x13,  0x6c,  0xff,  0x02,  0x00,  0x57,  0x48,  0x8b,  0x1c,
13630  0x3d,  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x03,  0x13,  0x6c,  0xff,  0x02,  0x00,  0x57,  0x48,  0x8b,
13631  0x03,  0x13,  0x6c,  0xff,  0x02,  0x00,  0x57,  0x48,  0x8b,  0xfe,  0x0b,  0x58,  0x03,  0x0a,  0x50,  0x01,
13632  0x82,  0x0a,  0x3f,  0x01,  0x82,  0x03,  0xfc,  0x1c,  0x10,  0xff,  0x03,  0x00,  0x54,  0xfe,  0x00,  0xf4,
13633  0x19,  0x48,  0xfe,  0x00,  0x7d,  0xfe,  0x01,  0x7d,  0xfe,  0x02,  0x7d,  0xfe,  0x03,  0x7c,  0x63,  0x27,
13634  0x0c,  0x52,  0x18,  0x53,  0xbe,  0x56,  0xbf,  0x57,  0x03,  0xfe,  0x62,  0x08,  0xfe,  0x82,  0x4a,  0xfe,
13635  0xe1,  0x1a,  0xfe,  0x83,  0x5a,  0x74,  0x03,  0x01,  0xfe,  0x14,  0x18,  0xfe,  0x42,  0x48,  0x5f,  0x60,
13636  0x89,  0x01,  0x08,  0x1f,  0xfe,  0xa2,  0x14,  0x30,  0x2e,  0xd8,  0x01,  0x08,  0x1f,  0xfe,  0xa2,  0x14,
13637  0x30,  0x2e,  0xfe,  0xe8,  0x0a,  0xfe,  0xc1,  0x59,  0x05,  0xc6,  0x28,  0xfe,  0xcc,  0x12,  0x49,  0x04,
13638  0x1b,  0xfe,  0xc4,  0x13,  0x23,  0x62,  0x1b,  0xe2,  0x4b,  0xc3,  0x64,  0xfe,  0xe8,  0x13,  0x3b,  0x13,
13639  0x06,  0x17,  0xc3,  0x78,  0xdb,  0xfe,  0x78,  0x10,  0xff,  0x02,  0x83,  0x55,  0xa1,  0xff,  0x02,  0x83,
13640  0x55,  0x62,  0x1a,  0xa4,  0xbb,  0xfe,  0x30,  0x00,  0x8e,  0xe4,  0x17,  0x2c,  0x13,  0x06,  0xfe,  0x56,
13641  0x10,  0x62,  0x0b,  0xe1,  0xbb,  0xfe,  0x64,  0x00,  0x8e,  0xe4,  0x0a,  0xfe,  0x64,  0x00,  0x17,  0x93,
13642  0x13,  0x06,  0xfe,  0x28,  0x10,  0x62,  0x06,  0xfe,  0x60,  0x13,  0xbb,  0xfe,  0xc8,  0x00,  0x8e,  0xe4,
13643  0x0a,  0xfe,  0xc8,  0x00,  0x17,  0x4d,  0x13,  0x06,  0x83,  0xbb,  0xfe,  0x90,  0x01,  0xba,  0xfe,  0x4e,
13644  0x14,  0x89,  0xfe,  0x12,  0x10,  0xfe,  0x43,  0xf4,  0x94,  0xfe,  0x56,  0xf0,  0xfe,  0x60,  0x14,  0xfe,
13645  0x04,  0xf4,  0x6c,  0xfe,  0x43,  0xf4,  0x93,  0xfe,  0xf3,  0x10,  0xf9,  0x01,  0xfe,  0x22,  0x13,  0x1c,
13646  0x3d,  0xfe,  0x10,  0x13,  0xfe,  0x00,  0x17,  0xfe,  0x4d,  0xe4,  0x69,  0xba,  0xfe,  0x9c,  0x14,  0xb7,
13647  0x69,  0xfe,  0x1c,  0x10,  0xfe,  0x00,  0x17,  0xfe,  0x4d,  0xe4,  0x19,  0xba,  0xfe,  0x9c,  0x14,  0xb7,
13648  0x19,  0x83,  0x60,  0x23,  0xfe,  0x4d,  0xf4,  0x00,  0xdf,  0x89,  0x13,  0x06,  0xfe,  0xb4,  0x56,  0xfe,
13649  0xc3,  0x58,  0x03,  0x60,  0x13,  0x0b,  0x03,  0x15,  0x06,  0x01,  0x08,  0x26,  0xe5,  0x15,  0x0b,  0x01,
13650  0x08,  0x26,  0xe5,  0x15,  0x1a,  0x01,  0x08,  0x26,  0xe5,  0x72,  0xfe,  0x89,  0x49,  0x01,  0x08,  0x03,
13651  0x15,  0x06,  0x01,  0x08,  0x26,  0xa6,  0x15,  0x1a,  0x01,  0x08,  0x26,  0xa6,  0x15,  0x06,  0x01,  0x08,
13652  0x26,  0xa6,  0xfe,  0x89,  0x49,  0x01,  0x08,  0x26,  0xa6,  0x72,  0xfe,  0x89,  0x4a,  0x01,  0x08,  0x03,
13653  0x60,  0x03,  0x1e,  0xcc,  0x07,  0x06,  0xfe,  0x44,  0x13,  0xad,  0x12,  0xcc,  0xfe,  0x49,  0xf4,  0x00,
13654  0x3b,  0x72,  0x9f,  0x5e,  0xfe,  0x01,  0xec,  0xfe,  0x27,  0x01,  0xf1,  0x01,  0x08,  0x2f,  0x07,  0xfe,
13655  0xe3,  0x00,  0xfe,  0x20,  0x13,  0x1f,  0xfe,  0x5a,  0x15,  0x23,  0x12,  0xcd,  0x01,  0x43,  0x1e,  0xcd,
13656  0x07,  0x06,  0x45,  0x09,  0x4a,  0x06,  0x35,  0x03,  0x0a,  0x42,  0x01,  0x0e,  0xed,  0x88,  0x07,  0x10,
13657  0xa4,  0x0a,  0x80,  0x01,  0x0e,  0x88,  0x0a,  0x51,  0x01,  0x9e,  0x03,  0x0a,  0x80,  0x01,  0x0e,  0x88,
13658  0xfe,  0x80,  0xe7,  0x10,  0x07,  0x10,  0x84,  0xfe,  0x45,  0x58,  0x01,  0xe3,  0x88,  0x03,  0x0a,  0x42,
13659  0x01,  0x0e,  0x88,  0x0a,  0x51,  0x01,  0x9e,  0x03,  0x0a,  0x42,  0x01,  0x0e,  0xfe,  0x80,  0x80,  0xf2,
13660  0xfe,  0x49,  0xe4,  0x10,  0xa4,  0x0a,  0x80,  0x01,  0x0e,  0xf2,  0x0a,  0x51,  0x01,  0x82,  0x03,  0x17,
13661  0x10,  0x71,  0x66,  0xfe,  0x60,  0x01,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,  0x24,  0x1c,  0xfe,
13662  0x1d,  0xf7,  0x1d,  0x90,  0xfe,  0xf6,  0x15,  0x01,  0xfe,  0xfc,  0x16,  0xe0,  0x91,  0x1d,  0x66,  0xfe,
13663  0x2c,  0x01,  0xfe,  0x2f,  0x19,  0x03,  0xae,  0x21,  0xfe,  0xe6,  0x15,  0xfe,  0xda,  0x10,  0x17,  0x10,
13664  0x71,  0x05,  0xfe,  0x64,  0x01,  0xfe,  0x00,  0xf4,  0x19,  0xfe,  0x18,  0x58,  0x05,  0xfe,  0x66,  0x01,
13665  0xfe,  0x19,  0x58,  0x91,  0x19,  0xfe,  0x3c,  0x90,  0xfe,  0x30,  0xf4,  0x06,  0xfe,  0x3c,  0x50,  0x66,
13666  0xfe,  0x38,  0x00,  0xfe,  0x0f,  0x79,  0xfe,  0x1c,  0xf7,  0x19,  0x90,  0xfe,  0x40,  0x16,  0xfe,  0xb6,
13667  0x14,  0x34,  0x03,  0xae,  0x21,  0xfe,  0x18,  0x16,  0xfe,  0x9c,  0x10,  0x17,  0x10,  0x71,  0xfe,  0x83,
13668  0x5a,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,  0x1d,  0xf7,  0x38,  0x90,  0xfe,  0x62,  0x16,  0xfe,
13669  0x94,  0x14,  0xfe,  0x10,  0x13,  0x91,  0x38,  0x66,  0x1b,  0xfe,  0xaf,  0x19,  0xfe,  0x98,  0xe7,  0x00,
13670  0x03,  0xae,  0x21,  0xfe,  0x56,  0x16,  0xfe,  0x6c,  0x10,  0x17,  0x10,  0x71,  0xfe,  0x30,  0xbc,  0xfe,
13671  0xb2,  0xbc,  0x91,  0xc5,  0x66,  0x1b,  0xfe,  0x0f,  0x79,  0xfe,  0x1c,  0xf7,  0xc5,  0x90,  0xfe,  0x9a,
13672  0x16,  0xfe,  0x5c,  0x14,  0x34,  0x03,  0xae,  0x21,  0xfe,  0x86,  0x16,  0xfe,  0x42,  0x10,  0xfe,  0x02,
13673  0xf6,  0x10,  0x71,  0xfe,  0x18,  0xfe,  0x54,  0xfe,  0x19,  0xfe,  0x55,  0xfc,  0xfe,  0x1d,  0xf7,  0x4f,
13674  0x90,  0xfe,  0xc0,  0x16,  0xfe,  0x36,  0x14,  0xfe,  0x1c,  0x13,  0x91,  0x4f,  0x47,  0xfe,  0x83,  0x58,
13675  0xfe,  0xaf,  0x19,  0xfe,  0x80,  0xe7,  0x10,  0xfe,  0x81,  0xe7,  0x10,  0x11,  0xfe,  0xdd,  0x00,  0x63,
13676  0x27,  0x03,  0x63,  0x27,  0xfe,  0x12,  0x45,  0x21,  0xfe,  0xb0,  0x16,  0x14,  0x06,  0x37,  0x95,  0xa9,
13677  0x02,  0x29,  0xfe,  0x39,  0xf0,  0xfe,  0x04,  0x17,  0x23,  0x03,  0xfe,  0x7e,  0x18,  0x1c,  0x1a,  0x5d,
13678  0x13,  0x0d,  0x03,  0x71,  0x05,  0xcb,  0x1c,  0x06,  0xfe,  0xef,  0x12,  0xfe,  0xe1,  0x10,  0x78,  0x2c,
13679  0x46,  0x2f,  0x07,  0x2d,  0xfe,  0x3c,  0x13,  0xfe,  0x82,  0x14,  0xfe,  0x42,  0x13,  0x3c,  0x8a,  0x0a,
13680  0x42,  0x01,  0x0e,  0xb0,  0xfe,  0x3e,  0x12,  0xf0,  0xfe,  0x45,  0x48,  0x01,  0xe3,  0xfe,  0x00,  0xcc,
13681  0xb0,  0xfe,  0xf3,  0x13,  0x3d,  0x75,  0x07,  0x10,  0xa3,  0x0a,  0x80,  0x01,  0x0e,  0xf2,  0x01,  0x6f,
13682  0xfe,  0x16,  0x10,  0x07,  0x7e,  0x85,  0xfe,  0x40,  0x14,  0xfe,  0x24,  0x12,  0xf6,  0xfe,  0xd6,  0xf0,
13683  0xfe,  0x24,  0x17,  0x17,  0x0b,  0x03,  0xfe,  0x9c,  0xe7,  0x0b,  0x0f,  0xfe,  0x15,  0x00,  0x59,  0x76,
13684  0x27,  0x01,  0xda,  0x17,  0x06,  0x03,  0x3c,  0x8a,  0x09,  0x4a,  0x1d,  0x35,  0x11,  0x2d,  0x01,  0x6f,
13685  0x17,  0x06,  0x03,  0xfe,  0x38,  0x90,  0xfe,  0xba,  0x90,  0x79,  0xc7,  0x68,  0xc8,  0xfe,  0x48,  0x55,
13686  0x34,  0xfe,  0xc9,  0x55,  0x03,  0x1e,  0x98,  0x73,  0x12,  0x98,  0x03,  0x0a,  0x99,  0x01,  0x0e,  0xf0,
13687  0x0a,  0x40,  0x01,  0x0e,  0xfe,  0x49,  0x44,  0x16,  0xfe,  0xf0,  0x17,  0x73,  0x75,  0x03,  0x0a,  0x42,
13688  0x01,  0x0e,  0x07,  0x10,  0x45,  0x0a,  0x51,  0x01,  0x9e,  0x0a,  0x40,  0x01,  0x0e,  0x73,  0x75,  0x03,
13689  0xfe,  0x4e,  0xe4,  0x1a,  0x64,  0xfe,  0x24,  0x18,  0x05,  0xfe,  0x90,  0x00,  0xfe,  0x3a,  0x45,  0x5b,
13690  0xfe,  0x4e,  0xe4,  0xc2,  0x64,  0xfe,  0x36,  0x18,  0x05,  0xfe,  0x92,  0x00,  0xfe,  0x02,  0xe6,  0x1b,
13691  0xdc,  0xfe,  0x4e,  0xe4,  0xfe,  0x0b,  0x00,  0x64,  0xfe,  0x48,  0x18,  0x05,  0xfe,  0x94,  0x00,  0xfe,
13692  0x02,  0xe6,  0x19,  0xfe,  0x08,  0x10,  0x05,  0xfe,  0x96,  0x00,  0xfe,  0x02,  0xe6,  0x2c,  0xfe,  0x4e,
13693  0x45,  0xfe,  0x0c,  0x12,  0xaf,  0xff,  0x04,  0x68,  0x54,  0xde,  0x1c,  0x69,  0x03,  0x07,  0x7a,  0xfe,
13694  0x5a,  0xf0,  0xfe,  0x74,  0x18,  0x24,  0xfe,  0x09,  0x00,  0xfe,  0x34,  0x10,  0x07,  0x1b,  0xfe,  0x5a,
13695  0xf0,  0xfe,  0x82,  0x18,  0x24,  0xc3,  0xfe,  0x26,  0x10,  0x07,  0x1a,  0x5d,  0x24,  0x2c,  0xdc,  0x07,
13696  0x0b,  0x5d,  0x24,  0x93,  0xfe,  0x0e,  0x10,  0x07,  0x06,  0x5d,  0x24,  0x4d,  0x9f,  0xad,  0x03,  0x14,
13697  0xfe,  0x09,  0x00,  0x01,  0x33,  0xfe,  0x04,  0xfe,  0x7d,  0x05,  0x7f,  0xf9,  0x03,  0x25,  0xfe,  0xca,
13698  0x18,  0xfe,  0x14,  0xf0,  0x08,  0x65,  0xfe,  0xc6,  0x18,  0x03,  0xff,  0x1a,  0x00,  0x00,
13699};
13700
13701STATIC unsigned short _adv_asc3550_size =
13702        sizeof(_adv_asc3550_buf); /* 0x13AD */
13703STATIC ADV_DCNT _adv_asc3550_chksum =
13704        0x04D52DDDUL; /* Expanded little-endian checksum. */
13705
13706/* Microcode buffer is kept after initialization for error recovery. */
13707STATIC unsigned char _adv_asc38C0800_buf[] = {
13708  0x00,  0x00,  0x00,  0xf2,  0x00,  0xf0,  0x00,  0xfc,  0x00,  0x16,  0x18,  0xe4,  0x01,  0x00,  0x48,  0xe4,
13709  0x18,  0x80,  0x03,  0xf6,  0x02,  0x00,  0xce,  0x19,  0x00,  0xfa,  0xff,  0xff,  0x1c,  0x0f,  0x00,  0xf6,
13710  0x9e,  0xe7,  0xff,  0x00,  0x82,  0xe7,  0x00,  0xea,  0x01,  0xfa,  0x01,  0xe6,  0x09,  0xe7,  0x55,  0xf0,
13711  0x01,  0xf6,  0x03,  0x00,  0x04,  0x00,  0x10,  0x00,  0x1e,  0xf0,  0x85,  0xf0,  0x18,  0xf4,  0x08,  0x00,
13712  0xbc,  0x00,  0x38,  0x54,  0x00,  0xec,  0xd5,  0xf0,  0x82,  0x0d,  0x00,  0xe6,  0x86,  0xf0,  0xb1,  0xf0,
13713  0x98,  0x57,  0x01,  0xfc,  0xb4,  0x00,  0xd4,  0x01,  0x0c,  0x1c,  0x3e,  0x1c,  0x3c,  0x00,  0xbb,  0x00,
13714  0x00,  0x10,  0xba,  0x19,  0x02,  0x80,  0x32,  0xf0,  0x7c,  0x0d,  0x02,  0x13,  0xba,  0x13,  0x18,  0x40,
13715  0x00,  0x57,  0x01,  0xea,  0x02,  0xfc,  0x03,  0xfc,  0x3e,  0x00,  0x6c,  0x01,  0x6e,  0x01,  0x74,  0x01,
13716  0x76,  0x01,  0xb9,  0x54,  0x3e,  0x57,  0x00,  0x80,  0x03,  0xe6,  0xb6,  0x00,  0xc0,  0x00,  0x01,  0x01,
13717  0x3e,  0x01,  0x7a,  0x01,  0xca,  0x08,  0xce,  0x10,  0x16,  0x11,  0x04,  0x12,  0x08,  0x12,  0x02,  0x4a,
13718  0xbb,  0x55,  0x3c,  0x56,  0x03,  0x58,  0x1b,  0x80,  0x30,  0xe4,  0x4b,  0xe4,  0x5d,  0xf0,  0x02,  0xfa,
13719  0x20,  0x00,  0x32,  0x00,  0x40,  0x00,  0x80,  0x00,  0x24,  0x01,  0x3c,  0x01,  0x68,  0x01,  0x6a,  0x01,
13720  0x70,  0x01,  0x72,  0x01,  0x78,  0x01,  0x7c,  0x01,  0x62,  0x0a,  0x86,  0x0d,  0x06,  0x13,  0x4c,  0x1c,
13721  0x04,  0x80,  0x4a,  0xe4,  0x02,  0xee,  0x5b,  0xf0,  0x03,  0xf7,  0x0c,  0x00,  0x0f,  0x00,  0x47,  0x00,
13722  0xbe,  0x00,  0x00,  0x01,  0x20,  0x11,  0x5c,  0x16,  0x32,  0x1c,  0x38,  0x1c,  0x4e,  0x1c,  0x10,  0x44,
13723  0x00,  0x4c,  0x04,  0xea,  0x5c,  0xf0,  0xa7,  0xf0,  0x04,  0xf6,  0x03,  0xfa,  0x05,  0x00,  0x34,  0x00,
13724  0x36,  0x00,  0x98,  0x00,  0xcc,  0x00,  0x20,  0x01,  0x4e,  0x01,  0x4a,  0x0b,  0x42,  0x0c,  0x12,  0x0f,
13725  0x0c,  0x10,  0x22,  0x11,  0x0a,  0x12,  0x04,  0x13,  0x30,  0x1c,  0x02,  0x48,  0x00,  0x4e,  0x42,  0x54,
13726  0x44,  0x55,  0xbd,  0x56,  0x06,  0x83,  0x00,  0xdc,  0x05,  0xf0,  0x09,  0xf0,  0x59,  0xf0,  0xb8,  0xf0,
13727  0x4b,  0xf4,  0x06,  0xf7,  0x0e,  0xf7,  0x04,  0xfc,  0x05,  0xfc,  0x06,  0x00,  0x19,  0x00,  0x33,  0x00,
13728  0x9b,  0x00,  0xa4,  0x00,  0xb5,  0x00,  0xba,  0x00,  0xd0,  0x00,  0xe1,  0x00,  0xe7,  0x00,  0xe2,  0x03,
13729  0x08,  0x0f,  0x02,  0x10,  0x04,  0x10,  0x0a,  0x10,  0x0a,  0x13,  0x0c,  0x13,  0x12,  0x13,  0x24,  0x14,
13730  0x34,  0x14,  0x04,  0x16,  0x08,  0x16,  0xa4,  0x17,  0x20,  0x1c,  0x34,  0x1c,  0x36,  0x1c,  0x08,  0x44,
13731  0x38,  0x44,  0x91,  0x44,  0x0a,  0x45,  0x48,  0x46,  0x01,  0x48,  0x68,  0x54,  0x3a,  0x55,  0x83,  0x55,
13732  0xe5,  0x55,  0xb0,  0x57,  0x01,  0x58,  0x83,  0x59,  0x05,  0xe6,  0x0b,  0xf0,  0x0c,  0xf0,  0x04,  0xf8,
13733  0x05,  0xf8,  0x07,  0x00,  0x0a,  0x00,  0x1c,  0x00,  0x1e,  0x00,  0x9e,  0x00,  0xa8,  0x00,  0xaa,  0x00,
13734  0xb9,  0x00,  0xe0,  0x00,  0x22,  0x01,  0x26,  0x01,  0x79,  0x01,  0x7e,  0x01,  0xc4,  0x01,  0xc6,  0x01,
13735  0x80,  0x02,  0x5e,  0x03,  0xee,  0x04,  0x9a,  0x06,  0xf8,  0x07,  0x62,  0x08,  0x68,  0x08,  0x69,  0x08,
13736  0xd6,  0x08,  0xe9,  0x09,  0xfa,  0x0b,  0x2e,  0x0f,  0x12,  0x10,  0x1a,  0x10,  0xed,  0x10,  0xf1,  0x10,
13737  0x2a,  0x11,  0x06,  0x12,  0x0c,  0x12,  0x3e,  0x12,  0x10,  0x13,  0x16,  0x13,  0x1e,  0x13,  0x46,  0x14,
13738  0x76,  0x14,  0x82,  0x14,  0x36,  0x15,  0xca,  0x15,  0x6b,  0x18,  0xbe,  0x18,  0xca,  0x18,  0xe6,  0x19,
13739  0x12,  0x1c,  0x46,  0x1c,  0x9c,  0x32,  0x00,  0x40,  0x0e,  0x47,  0xfe,  0x9c,  0xf0,  0x2b,  0x02,  0xfe,
13740  0xac,  0x0d,  0xff,  0x10,  0x00,  0x00,  0xd7,  0xfe,  0xe8,  0x19,  0x00,  0xd6,  0xfe,  0x84,  0x01,  0xff,
13741  0x03,  0x00,  0x00,  0xfe,  0x93,  0x15,  0xfe,  0x0f,  0x05,  0xff,  0x38,  0x00,  0x00,  0xfe,  0x57,  0x24,
13742  0x00,  0xfe,  0x4c,  0x00,  0x5b,  0xff,  0x04,  0x00,  0x00,  0x11,  0xff,  0x09,  0x00,  0x00,  0xff,  0x08,
13743  0x01,  0x01,  0xff,  0x08,  0xff,  0xff,  0xff,  0x27,  0x00,  0x00,  0xff,  0x10,  0xff,  0xff,  0xff,  0x11,
13744  0x00,  0x00,  0xfe,  0x78,  0x56,  0xfe,  0x34,  0x12,  0xff,  0x21,  0x00,  0x00,  0xfe,  0x04,  0xf7,  0xd6,
13745  0x2c,  0x99,  0x0a,  0x01,  0xfe,  0xc2,  0x0f,  0xfe,  0x04,  0xf7,  0xd6,  0x99,  0x0a,  0x42,  0x2c,  0xfe,
13746  0x3d,  0xf0,  0xfe,  0x06,  0x02,  0xfe,  0x20,  0xf0,  0xa7,  0xfe,  0x91,  0xf0,  0xfe,  0xf4,  0x01,  0xfe,
13747  0x90,  0xf0,  0xfe,  0xf4,  0x01,  0xfe,  0x8f,  0xf0,  0xa7,  0x03,  0x5d,  0x4d,  0x02,  0xfe,  0xc8,  0x0d,
13748  0x01,  0xfe,  0x38,  0x0e,  0xfe,  0xdd,  0x12,  0xfe,  0xfc,  0x10,  0xfe,  0x28,  0x1c,  0x03,  0xfe,  0xa6,
13749  0x00,  0xfe,  0xd3,  0x12,  0x41,  0x14,  0xfe,  0xa6,  0x00,  0xc2,  0xfe,  0x48,  0xf0,  0xfe,  0x8a,  0x02,
13750  0xfe,  0x49,  0xf0,  0xfe,  0xa4,  0x02,  0xfe,  0x4a,  0xf0,  0xfe,  0xc2,  0x02,  0xfe,  0x46,  0xf0,  0xfe,
13751  0x54,  0x02,  0xfe,  0x47,  0xf0,  0xfe,  0x5a,  0x02,  0xfe,  0x43,  0xf0,  0xfe,  0x48,  0x02,  0xfe,  0x44,
13752  0xf0,  0xfe,  0x4c,  0x02,  0xfe,  0x45,  0xf0,  0xfe,  0x50,  0x02,  0x18,  0x0a,  0xaa,  0x18,  0x06,  0x14,
13753  0xa1,  0x02,  0x2b,  0xfe,  0x00,  0x1c,  0xe7,  0xfe,  0x02,  0x1c,  0xe6,  0xfe,  0x1e,  0x1c,  0xfe,  0xe9,
13754  0x10,  0x01,  0xfe,  0x18,  0x18,  0xfe,  0xe7,  0x10,  0xfe,  0x06,  0xfc,  0xce,  0x09,  0x70,  0x01,  0xa8,
13755  0x02,  0x2b,  0x15,  0x59,  0x39,  0xa2,  0x01,  0xfe,  0x58,  0x10,  0x09,  0x70,  0x01,  0x87,  0xfe,  0xbd,
13756  0x10,  0x09,  0x70,  0x01,  0x87,  0xfe,  0xad,  0x10,  0xfe,  0x16,  0x1c,  0xfe,  0x58,  0x1c,  0x18,  0x06,
13757  0x14,  0xa1,  0x2c,  0x1c,  0x2b,  0xfe,  0x3d,  0xf0,  0xfe,  0x06,  0x02,  0x23,  0xfe,  0x98,  0x02,  0xfe,
13758  0x5a,  0x1c,  0xf8,  0xfe,  0x14,  0x1c,  0x15,  0xfe,  0x30,  0x00,  0x39,  0xa2,  0x01,  0xfe,  0x48,  0x10,
13759  0x18,  0x06,  0x14,  0xa1,  0x02,  0xd7,  0x22,  0x20,  0x07,  0x11,  0x35,  0xfe,  0x69,  0x10,  0x18,  0x06,
13760  0x14,  0xa1,  0xfe,  0x04,  0xec,  0x20,  0x4f,  0x43,  0x13,  0x20,  0xfe,  0x05,  0xf6,  0xce,  0x01,  0xfe,
13761  0x4a,  0x17,  0x08,  0x54,  0x58,  0x37,  0x12,  0x2f,  0x42,  0x92,  0x01,  0xfe,  0x82,  0x16,  0x02,  0x2b,
13762  0x09,  0x46,  0x01,  0x0e,  0x07,  0x00,  0x66,  0x01,  0x73,  0xfe,  0x18,  0x10,  0xfe,  0x41,  0x58,  0x09,
13763  0xa4,  0x01,  0x0e,  0xfe,  0xc8,  0x54,  0x6b,  0xfe,  0x10,  0x03,  0x01,  0xfe,  0x82,  0x16,  0x02,  0x2b,
13764  0x2c,  0x4f,  0xfe,  0x02,  0xe8,  0x2a,  0xfe,  0xbf,  0x57,  0xfe,  0x9e,  0x43,  0xfe,  0x77,  0x57,  0xfe,
13765  0x27,  0xf0,  0xfe,  0xe0,  0x01,  0xfe,  0x07,  0x4b,  0xfe,  0x20,  0xf0,  0xa7,  0xfe,  0x40,  0x1c,  0x1c,
13766  0xd9,  0xfe,  0x26,  0xf0,  0xfe,  0x5a,  0x03,  0xfe,  0xa0,  0xf0,  0xfe,  0x48,  0x03,  0xfe,  0x11,  0xf0,
13767  0xa7,  0xfe,  0xef,  0x10,  0xfe,  0x9f,  0xf0,  0xfe,  0x68,  0x03,  0xf9,  0x10,  0xfe,  0x11,  0x00,  0x02,
13768  0x65,  0x2c,  0xfe,  0x48,  0x1c,  0xf9,  0x08,  0x05,  0x1b,  0xfe,  0x18,  0x13,  0x21,  0x22,  0xa3,  0xb7,
13769  0x13,  0xa3,  0x09,  0x46,  0x01,  0x0e,  0xb7,  0x78,  0x01,  0xfe,  0xb4,  0x16,  0x12,  0xd1,  0x1c,  0xd9,
13770  0xfe,  0x01,  0xf0,  0xd9,  0xfe,  0x82,  0xf0,  0xfe,  0x96,  0x03,  0xfa,  0x12,  0xfe,  0xe4,  0x00,  0x27,
13771  0xfe,  0xa8,  0x03,  0x1c,  0x34,  0x1d,  0xfe,  0xb8,  0x03,  0x01,  0x4b,  0xfe,  0x06,  0xf0,  0xfe,  0xc8,
13772  0x03,  0x95,  0x86,  0xfe,  0x0a,  0xf0,  0xfe,  0x8a,  0x06,  0x02,  0x24,  0x03,  0x70,  0x28,  0x17,  0xfe,
13773  0xfa,  0x04,  0x15,  0x6d,  0x01,  0x36,  0x7b,  0xfe,  0x6a,  0x02,  0x02,  0xd8,  0xf9,  0x2c,  0x99,  0x19,
13774  0xfe,  0x67,  0x1b,  0xfe,  0xbf,  0x57,  0xfe,  0x77,  0x57,  0xfe,  0x48,  0x1c,  0x74,  0x01,  0xaf,  0x8c,
13775  0x09,  0x46,  0x01,  0x0e,  0x07,  0x00,  0x17,  0xda,  0x09,  0xd1,  0x01,  0x0e,  0x8d,  0x51,  0x64,  0x79,
13776  0x2a,  0x03,  0x70,  0x28,  0xfe,  0x10,  0x12,  0x15,  0x6d,  0x01,  0x36,  0x7b,  0xfe,  0x6a,  0x02,  0x02,
13777  0xd8,  0xc7,  0x81,  0xc8,  0x83,  0x1c,  0x24,  0x27,  0xfe,  0x40,  0x04,  0x1d,  0xfe,  0x3c,  0x04,  0x3b,
13778  0xfe,  0xa0,  0x00,  0xfe,  0x9b,  0x57,  0xfe,  0x4e,  0x12,  0x2d,  0xff,  0x02,  0x00,  0x10,  0x01,  0x0b,
13779  0x1d,  0xfe,  0xe4,  0x04,  0x2d,  0x01,  0x0b,  0x1d,  0x24,  0x33,  0x31,  0xde,  0xfe,  0x4c,  0x44,  0xfe,
13780  0x4c,  0x12,  0x51,  0xfe,  0x44,  0x48,  0x0f,  0x6f,  0xfe,  0x4c,  0x54,  0x6b,  0xda,  0x4f,  0x79,  0x2a,
13781  0xfe,  0x06,  0x80,  0xfe,  0x48,  0x47,  0xfe,  0x62,  0x13,  0x08,  0x05,  0x1b,  0xfe,  0x2a,  0x13,  0x32,
13782  0x07,  0x82,  0xfe,  0x52,  0x13,  0xfe,  0x20,  0x10,  0x0f,  0x6f,  0xfe,  0x4c,  0x54,  0x6b,  0xda,  0xfe,
13783  0x06,  0x80,  0xfe,  0x48,  0x47,  0xfe,  0x40,  0x13,  0x08,  0x05,  0x1b,  0xfe,  0x08,  0x13,  0x32,  0x07,
13784  0x82,  0xfe,  0x30,  0x13,  0x08,  0x05,  0x1b,  0xfe,  0x1c,  0x12,  0x15,  0x9d,  0x08,  0x05,  0x06,  0x4d,
13785  0x15,  0xfe,  0x0d,  0x00,  0x01,  0x36,  0x7b,  0xfe,  0x64,  0x0d,  0x02,  0x24,  0x2d,  0x12,  0xfe,  0xe6,
13786  0x00,  0xfe,  0x1c,  0x90,  0xfe,  0x40,  0x5c,  0x04,  0x15,  0x9d,  0x01,  0x36,  0x02,  0x2b,  0xfe,  0x42,
13787  0x5b,  0x99,  0x19,  0xfe,  0x46,  0x59,  0xfe,  0xbf,  0x57,  0xfe,  0x77,  0x57,  0xfe,  0x87,  0x80,  0xfe,
13788  0x31,  0xe4,  0x5b,  0x08,  0x05,  0x0a,  0xfe,  0x84,  0x13,  0xfe,  0x20,  0x80,  0x07,  0x19,  0xfe,  0x7c,
13789  0x12,  0x53,  0x05,  0x06,  0xfe,  0x6c,  0x13,  0x03,  0xfe,  0xa2,  0x00,  0x28,  0x17,  0xfe,  0x90,  0x05,
13790  0xfe,  0x31,  0xe4,  0x5a,  0x53,  0x05,  0x0a,  0xfe,  0x56,  0x13,  0x03,  0xfe,  0xa0,  0x00,  0x28,  0xfe,
13791  0x4e,  0x12,  0x67,  0xff,  0x02,  0x00,  0x10,  0x27,  0xfe,  0x48,  0x05,  0x1c,  0x34,  0xfe,  0x89,  0x48,
13792  0xff,  0x02,  0x00,  0x10,  0x27,  0xfe,  0x56,  0x05,  0x26,  0xfe,  0xa8,  0x05,  0x12,  0xfe,  0xe3,  0x00,
13793  0x21,  0x53,  0xfe,  0x4a,  0xf0,  0xfe,  0x76,  0x05,  0xfe,  0x49,  0xf0,  0xfe,  0x70,  0x05,  0x88,  0x25,
13794  0xfe,  0x21,  0x00,  0xab,  0x25,  0xfe,  0x22,  0x00,  0xaa,  0x25,  0x58,  0xfe,  0x09,  0x48,  0xff,  0x02,
13795  0x00,  0x10,  0x27,  0xfe,  0x86,  0x05,  0x26,  0xfe,  0xa8,  0x05,  0xfe,  0xe2,  0x08,  0x53,  0x05,  0xcb,
13796  0x4d,  0x01,  0xb0,  0x25,  0x06,  0x13,  0xd3,  0x39,  0xfe,  0x27,  0x01,  0x08,  0x05,  0x1b,  0xfe,  0x22,
13797  0x12,  0x41,  0x01,  0xb2,  0x15,  0x9d,  0x08,  0x05,  0x06,  0x4d,  0x15,  0xfe,  0x0d,  0x00,  0x01,  0x36,
13798  0x7b,  0xfe,  0x64,  0x0d,  0x02,  0x24,  0x03,  0xfe,  0x9c,  0x00,  0x28,  0xeb,  0x03,  0x5c,  0x28,  0xfe,
13799  0x36,  0x13,  0x41,  0x01,  0xb2,  0x26,  0xfe,  0x18,  0x06,  0x09,  0x06,  0x53,  0x05,  0x1f,  0xfe,  0x02,
13800  0x12,  0x50,  0x01,  0xfe,  0x9e,  0x15,  0x1d,  0xfe,  0x0e,  0x06,  0x12,  0xa5,  0x01,  0x4b,  0x12,  0xfe,
13801  0xe5,  0x00,  0x03,  0x5c,  0xc1,  0x0c,  0x5c,  0x03,  0xcd,  0x28,  0xfe,  0x62,  0x12,  0x03,  0x45,  0x28,
13802  0xfe,  0x5a,  0x13,  0x01,  0xfe,  0x0c,  0x19,  0x01,  0xfe,  0x76,  0x19,  0xfe,  0x43,  0x48,  0xc4,  0xcc,
13803  0x0f,  0x71,  0xff,  0x02,  0x00,  0x57,  0x52,  0x93,  0x1e,  0x43,  0x8b,  0xc4,  0x6e,  0x41,  0x01,  0xb2,
13804  0x26,  0xfe,  0x82,  0x06,  0x53,  0x05,  0x1a,  0xe9,  0x91,  0x09,  0x59,  0x01,  0xfe,  0xcc,  0x15,  0x1d,
13805  0xfe,  0x78,  0x06,  0x12,  0xa5,  0x01,  0x4b,  0x12,  0xfe,  0xe5,  0x00,  0x03,  0x45,  0xc1,  0x0c,  0x45,
13806  0x18,  0x06,  0x01,  0xb2,  0xfa,  0x76,  0x74,  0x01,  0xaf,  0x8c,  0x12,  0xfe,  0xe2,  0x00,  0x27,  0xdb,
13807  0x1c,  0x34,  0xfe,  0x0a,  0xf0,  0xfe,  0xb6,  0x06,  0x94,  0xfe,  0x6c,  0x07,  0xfe,  0x06,  0xf0,  0xfe,
13808  0x74,  0x07,  0x95,  0x86,  0x02,  0x24,  0x08,  0x05,  0x0a,  0xfe,  0x2e,  0x12,  0x16,  0x19,  0x01,  0x0b,
13809  0x16,  0x00,  0x01,  0x0b,  0x16,  0x00,  0x01,  0x0b,  0x16,  0x00,  0x01,  0x0b,  0xfe,  0x99,  0xa4,  0x01,
13810  0x0b,  0x16,  0x00,  0x02,  0xfe,  0x42,  0x08,  0x68,  0x05,  0x1a,  0xfe,  0x38,  0x12,  0x08,  0x05,  0x1a,
13811  0xfe,  0x30,  0x13,  0x16,  0xfe,  0x1b,  0x00,  0x01,  0x0b,  0x16,  0x00,  0x01,  0x0b,  0x16,  0x00,  0x01,
13812  0x0b,  0x16,  0x00,  0x01,  0x0b,  0x16,  0x06,  0x01,  0x0b,  0x16,  0x00,  0x02,  0xe2,  0x6c,  0x58,  0xbe,
13813  0x50,  0xfe,  0x9a,  0x81,  0x55,  0x1b,  0x7a,  0xfe,  0x42,  0x07,  0x09,  0x1b,  0xfe,  0x09,  0x6f,  0xba,
13814  0xfe,  0xca,  0x45,  0xfe,  0x32,  0x12,  0x69,  0x6d,  0x8b,  0x6c,  0x7f,  0x27,  0xfe,  0x54,  0x07,  0x1c,
13815  0x34,  0xfe,  0x0a,  0xf0,  0xfe,  0x42,  0x07,  0x95,  0x86,  0x94,  0xfe,  0x6c,  0x07,  0x02,  0x24,  0x01,
13816  0x4b,  0x02,  0xdb,  0x16,  0x1f,  0x02,  0xdb,  0xfe,  0x9c,  0xf7,  0xdc,  0xfe,  0x2c,  0x90,  0xfe,  0xae,
13817  0x90,  0x56,  0xfe,  0xda,  0x07,  0x0c,  0x60,  0x14,  0x61,  0x08,  0x54,  0x5a,  0x37,  0x22,  0x20,  0x07,
13818  0x11,  0xfe,  0x0e,  0x12,  0x8d,  0xfe,  0x80,  0x80,  0x39,  0x20,  0x6a,  0x2a,  0xfe,  0x06,  0x10,  0xfe,
13819  0x83,  0xe7,  0xfe,  0x48,  0x00,  0xab,  0xfe,  0x03,  0x40,  0x08,  0x54,  0x5b,  0x37,  0x01,  0xb3,  0xb8,
13820  0xfe,  0x1f,  0x40,  0x13,  0x62,  0x01,  0xef,  0xfe,  0x08,  0x50,  0xfe,  0x8a,  0x50,  0xfe,  0x44,  0x51,
13821  0xfe,  0xc6,  0x51,  0x88,  0xfe,  0x08,  0x90,  0xfe,  0x8a,  0x90,  0x0c,  0x5e,  0x14,  0x5f,  0xfe,  0x0c,
13822  0x90,  0xfe,  0x8e,  0x90,  0xfe,  0x40,  0x50,  0xfe,  0xc2,  0x50,  0x0c,  0x3d,  0x14,  0x3e,  0xfe,  0x4a,
13823  0x10,  0x08,  0x05,  0x5a,  0xfe,  0x2a,  0x12,  0xfe,  0x2c,  0x90,  0xfe,  0xae,  0x90,  0x0c,  0x60,  0x14,
13824  0x61,  0x08,  0x05,  0x5b,  0x8b,  0x01,  0xb3,  0xfe,  0x1f,  0x80,  0x13,  0x62,  0xfe,  0x44,  0x90,  0xfe,
13825  0xc6,  0x90,  0x0c,  0x3f,  0x14,  0x40,  0xfe,  0x08,  0x90,  0xfe,  0x8a,  0x90,  0x0c,  0x5e,  0x14,  0x5f,
13826  0xfe,  0x40,  0x90,  0xfe,  0xc2,  0x90,  0x0c,  0x3d,  0x14,  0x3e,  0x0c,  0x2e,  0x14,  0x3c,  0x21,  0x0c,
13827  0x49,  0x0c,  0x63,  0x08,  0x54,  0x1f,  0x37,  0x2c,  0x0f,  0xfe,  0x4e,  0x11,  0x27,  0xdd,  0xfe,  0x9e,
13828  0xf0,  0xfe,  0x76,  0x08,  0xbc,  0x17,  0x34,  0x2c,  0x77,  0xe6,  0xc5,  0xfe,  0x9a,  0x08,  0xc6,  0xfe,
13829  0xb8,  0x08,  0x94,  0xfe,  0x8e,  0x08,  0xfe,  0x06,  0xf0,  0xfe,  0x94,  0x08,  0x95,  0x86,  0x02,  0x24,
13830  0x01,  0x4b,  0xfe,  0xc9,  0x10,  0x16,  0x1f,  0xfe,  0xc9,  0x10,  0x68,  0x05,  0x06,  0xfe,  0x10,  0x12,
13831  0x68,  0x05,  0x0a,  0x4e,  0x08,  0x05,  0x0a,  0xfe,  0x90,  0x12,  0xfe,  0x2e,  0x1c,  0x02,  0xfe,  0x18,
13832  0x0b,  0x68,  0x05,  0x06,  0x4e,  0x68,  0x05,  0x0a,  0xfe,  0x7a,  0x12,  0xfe,  0x2c,  0x1c,  0xfe,  0xaa,
13833  0xf0,  0xfe,  0xd2,  0x09,  0xfe,  0xac,  0xf0,  0xfe,  0x00,  0x09,  0x02,  0xfe,  0xde,  0x09,  0xfe,  0xb7,
13834  0xf0,  0xfe,  0xfc,  0x08,  0xfe,  0x02,  0xf6,  0x1a,  0x50,  0xfe,  0x70,  0x18,  0xfe,  0xf1,  0x18,  0xfe,
13835  0x40,  0x55,  0xfe,  0xe1,  0x55,  0xfe,  0x10,  0x58,  0xfe,  0x91,  0x58,  0xfe,  0x14,  0x59,  0xfe,  0x95,
13836  0x59,  0x1c,  0x85,  0xfe,  0x8c,  0xf0,  0xfe,  0xfc,  0x08,  0xfe,  0xac,  0xf0,  0xfe,  0xf0,  0x08,  0xb5,
13837  0xfe,  0xcb,  0x10,  0xfe,  0xad,  0xf0,  0xfe,  0x0c,  0x09,  0x02,  0xfe,  0x18,  0x0b,  0xb6,  0xfe,  0xbf,
13838  0x10,  0xfe,  0x2b,  0xf0,  0x85,  0xf4,  0x1e,  0xfe,  0x00,  0xfe,  0xfe,  0x1c,  0x12,  0xc2,  0xfe,  0xd2,
13839  0xf0,  0x85,  0xfe,  0x76,  0x18,  0x1e,  0x19,  0x17,  0x85,  0x03,  0xd2,  0x1e,  0x06,  0x17,  0x85,  0xc5,
13840  0x4a,  0xc6,  0x4a,  0xb5,  0xb6,  0xfe,  0x89,  0x10,  0x74,  0x67,  0x2d,  0x15,  0x9d,  0x01,  0x36,  0x10,
13841  0xfe,  0x35,  0x00,  0xfe,  0x01,  0xf0,  0x65,  0x10,  0x80,  0x02,  0x65,  0xfe,  0x98,  0x80,  0xfe,  0x19,
13842  0xe4,  0x0a,  0xfe,  0x1a,  0x12,  0x51,  0xfe,  0x19,  0x82,  0xfe,  0x6c,  0x18,  0xfe,  0x44,  0x54,  0xbe,
13843  0xfe,  0x19,  0x81,  0xfe,  0x74,  0x18,  0x8f,  0x90,  0x17,  0xfe,  0xce,  0x08,  0x02,  0x4a,  0x08,  0x05,
13844  0x5a,  0xec,  0x03,  0x2e,  0x29,  0x3c,  0x0c,  0x3f,  0x14,  0x40,  0x9b,  0x2e,  0x9c,  0x3c,  0xfe,  0x6c,
13845  0x18,  0xfe,  0xed,  0x18,  0xfe,  0x44,  0x54,  0xfe,  0xe5,  0x54,  0x3a,  0x3f,  0x3b,  0x40,  0x03,  0x49,
13846  0x29,  0x63,  0x8f,  0xfe,  0xe3,  0x54,  0xfe,  0x74,  0x18,  0xfe,  0xf5,  0x18,  0x8f,  0xfe,  0xe3,  0x54,
13847  0x90,  0xc0,  0x56,  0xfe,  0xce,  0x08,  0x02,  0x4a,  0xfe,  0x37,  0xf0,  0xfe,  0xda,  0x09,  0xfe,  0x8b,
13848  0xf0,  0xfe,  0x60,  0x09,  0x02,  0x4a,  0x08,  0x05,  0x0a,  0x23,  0xfe,  0xfa,  0x0a,  0x3a,  0x49,  0x3b,
13849  0x63,  0x56,  0xfe,  0x3e,  0x0a,  0x0f,  0xfe,  0xc0,  0x07,  0x41,  0x98,  0x00,  0xad,  0xfe,  0x01,  0x59,
13850  0xfe,  0x52,  0xf0,  0xfe,  0x0c,  0x0a,  0x8f,  0x7a,  0xfe,  0x24,  0x0a,  0x3a,  0x49,  0x8f,  0xfe,  0xe3,
13851  0x54,  0x57,  0x49,  0x7d,  0x63,  0xfe,  0x14,  0x58,  0xfe,  0x95,  0x58,  0x02,  0x4a,  0x3a,  0x49,  0x3b,
13852  0x63,  0xfe,  0x14,  0x59,  0xfe,  0x95,  0x59,  0xbe,  0x57,  0x49,  0x57,  0x63,  0x02,  0x4a,  0x08,  0x05,
13853  0x5a,  0xfe,  0x82,  0x12,  0x08,  0x05,  0x1f,  0xfe,  0x66,  0x13,  0x22,  0x62,  0xb7,  0xfe,  0x03,  0xa1,
13854  0xfe,  0x83,  0x80,  0xfe,  0xc8,  0x44,  0xfe,  0x2e,  0x13,  0xfe,  0x04,  0x91,  0xfe,  0x86,  0x91,  0x6a,
13855  0x2a,  0xfe,  0x40,  0x59,  0xfe,  0xc1,  0x59,  0x56,  0xe0,  0x03,  0x60,  0x29,  0x61,  0x0c,  0x7f,  0x14,
13856  0x80,  0x57,  0x60,  0x7d,  0x61,  0x01,  0xb3,  0xb8,  0x6a,  0x2a,  0x13,  0x62,  0x9b,  0x2e,  0x9c,  0x3c,
13857  0x3a,  0x3f,  0x3b,  0x40,  0x90,  0xc0,  0xfe,  0x04,  0xfa,  0x2e,  0xfe,  0x05,  0xfa,  0x3c,  0x01,  0xef,
13858  0xfe,  0x36,  0x10,  0x21,  0x0c,  0x7f,  0x0c,  0x80,  0x3a,  0x3f,  0x3b,  0x40,  0xe4,  0x08,  0x05,  0x1f,
13859  0x17,  0xe0,  0x3a,  0x3d,  0x3b,  0x3e,  0x08,  0x05,  0xfe,  0xf7,  0x00,  0x37,  0x03,  0x5e,  0x29,  0x5f,
13860  0xfe,  0x10,  0x58,  0xfe,  0x91,  0x58,  0x57,  0x49,  0x7d,  0x63,  0x02,  0xfe,  0xf4,  0x09,  0x08,  0x05,
13861  0x1f,  0x17,  0xe0,  0x08,  0x05,  0xfe,  0xf7,  0x00,  0x37,  0xbe,  0xfe,  0x19,  0x81,  0x50,  0xfe,  0x10,
13862  0x90,  0xfe,  0x92,  0x90,  0xfe,  0xd3,  0x10,  0x32,  0x07,  0xa6,  0x17,  0xfe,  0x08,  0x09,  0x12,  0xa6,
13863  0x08,  0x05,  0x0a,  0xfe,  0x14,  0x13,  0x03,  0x3d,  0x29,  0x3e,  0x56,  0xfe,  0x08,  0x09,  0xfe,  0x0c,
13864  0x58,  0xfe,  0x8d,  0x58,  0x02,  0x4a,  0x21,  0x41,  0xfe,  0x19,  0x80,  0xe7,  0x08,  0x05,  0x0a,  0xfe,
13865  0x1a,  0x12,  0xfe,  0x6c,  0x19,  0xfe,  0x19,  0x41,  0xf4,  0xc2,  0xfe,  0xd1,  0xf0,  0xe2,  0x15,  0x7e,
13866  0x01,  0x36,  0x10,  0xfe,  0x44,  0x00,  0xfe,  0x8e,  0x10,  0xfe,  0x6c,  0x19,  0x57,  0x3d,  0xfe,  0xed,
13867  0x19,  0x7d,  0x3e,  0xfe,  0x0c,  0x51,  0xfe,  0x8e,  0x51,  0xf4,  0x1e,  0xfe,  0x00,  0xff,  0x35,  0xfe,
13868  0x74,  0x10,  0xc2,  0xfe,  0xd2,  0xf0,  0xfe,  0xa6,  0x0b,  0xfe,  0x76,  0x18,  0x1e,  0x19,  0x8a,  0x03,
13869  0xd2,  0x1e,  0x06,  0xfe,  0x08,  0x13,  0x10,  0xfe,  0x16,  0x00,  0x02,  0x65,  0xfe,  0xd1,  0xf0,  0xfe,
13870  0xb8,  0x0b,  0x15,  0x7e,  0x01,  0x36,  0x10,  0xfe,  0x17,  0x00,  0xfe,  0x42,  0x10,  0xfe,  0xce,  0xf0,
13871  0xfe,  0xbe,  0x0b,  0xfe,  0x3c,  0x10,  0xfe,  0xcd,  0xf0,  0xfe,  0xca,  0x0b,  0x10,  0xfe,  0x22,  0x00,
13872  0x02,  0x65,  0xfe,  0xcb,  0xf0,  0xfe,  0xd6,  0x0b,  0x10,  0xfe,  0x24,  0x00,  0x02,  0x65,  0xfe,  0xd0,
13873  0xf0,  0xfe,  0xe0,  0x0b,  0x10,  0x9e,  0xe5,  0xfe,  0xcf,  0xf0,  0xfe,  0xea,  0x0b,  0x10,  0x58,  0xfe,
13874  0x10,  0x10,  0xfe,  0xcc,  0xf0,  0xe2,  0x68,  0x05,  0x1f,  0x4d,  0x10,  0xfe,  0x12,  0x00,  0x2c,  0x0f,
13875  0xfe,  0x4e,  0x11,  0x27,  0xfe,  0x00,  0x0c,  0xfe,  0x9e,  0xf0,  0xfe,  0x14,  0x0c,  0xbc,  0x17,  0x34,
13876  0x2c,  0x77,  0xe6,  0xc5,  0x24,  0xc6,  0x24,  0x2c,  0xfa,  0x27,  0xfe,  0x20,  0x0c,  0x1c,  0x34,  0x94,
13877  0xfe,  0x3c,  0x0c,  0x95,  0x86,  0xc5,  0xdc,  0xc6,  0xdc,  0x02,  0x24,  0x01,  0x4b,  0xfe,  0xdb,  0x10,
13878  0x12,  0xfe,  0xe8,  0x00,  0xb5,  0xb6,  0x74,  0xc7,  0x81,  0xc8,  0x83,  0xfe,  0x89,  0xf0,  0x24,  0x33,
13879  0x31,  0xe1,  0xc7,  0x81,  0xc8,  0x83,  0x27,  0xfe,  0x66,  0x0c,  0x1d,  0x24,  0x33,  0x31,  0xdf,  0xbc,
13880  0x4e,  0x10,  0xfe,  0x42,  0x00,  0x02,  0x65,  0x7c,  0x06,  0xfe,  0x81,  0x49,  0x17,  0xfe,  0x2c,  0x0d,
13881  0x08,  0x05,  0x0a,  0xfe,  0x44,  0x13,  0x10,  0x00,  0x55,  0x0a,  0xfe,  0x54,  0x12,  0x55,  0xfe,  0x28,
13882  0x00,  0x23,  0xfe,  0x9a,  0x0d,  0x09,  0x46,  0x01,  0x0e,  0x07,  0x00,  0x66,  0x44,  0xfe,  0x28,  0x00,
13883  0xfe,  0xe2,  0x10,  0x01,  0xf5,  0x01,  0xf6,  0x09,  0xa4,  0x01,  0xfe,  0x26,  0x0f,  0x64,  0x12,  0x2f,
13884  0x01,  0x73,  0x02,  0x2b,  0x10,  0xfe,  0x44,  0x00,  0x55,  0x0a,  0xe9,  0x44,  0x0a,  0xfe,  0xb4,  0x10,
13885  0x01,  0xb0,  0x44,  0x0a,  0xfe,  0xaa,  0x10,  0x01,  0xb0,  0xfe,  0x19,  0x82,  0xfe,  0x34,  0x46,  0xac,
13886  0x44,  0x0a,  0x10,  0xfe,  0x43,  0x00,  0xfe,  0x96,  0x10,  0x08,  0x54,  0x0a,  0x37,  0x01,  0xf5,  0x01,
13887  0xf6,  0x64,  0x12,  0x2f,  0x01,  0x73,  0x99,  0x0a,  0x64,  0x42,  0x92,  0x02,  0xfe,  0x2e,  0x03,  0x08,
13888  0x05,  0x0a,  0x8a,  0x44,  0x0a,  0x10,  0x00,  0xfe,  0x5c,  0x10,  0x68,  0x05,  0x1a,  0xfe,  0x58,  0x12,
13889  0x08,  0x05,  0x1a,  0xfe,  0x50,  0x13,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,  0x50,  0x0d,  0xfe,
13890  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,  0x56,  0x0d,  0x08,  0x54,  0x1a,  0x37,  0xfe,  0xa9,  0x10,  0x10,
13891  0xfe,  0x15,  0x00,  0xfe,  0x04,  0xe6,  0x0a,  0x50,  0xfe,  0x2e,  0x10,  0x10,  0xfe,  0x13,  0x00,  0xfe,
13892  0x10,  0x10,  0x10,  0x6f,  0xab,  0x10,  0xfe,  0x41,  0x00,  0xaa,  0x10,  0xfe,  0x24,  0x00,  0x8c,  0xb5,
13893  0xb6,  0x74,  0x03,  0x70,  0x28,  0x23,  0xd8,  0x50,  0xfe,  0x04,  0xe6,  0x1a,  0xfe,  0x9d,  0x41,  0xfe,
13894  0x1c,  0x42,  0x64,  0x01,  0xe3,  0x02,  0x2b,  0xf8,  0x15,  0x0a,  0x39,  0xa0,  0xb4,  0x15,  0xfe,  0x31,
13895  0x00,  0x39,  0xa2,  0x01,  0xfe,  0x48,  0x10,  0x02,  0xd7,  0x42,  0xfe,  0x06,  0xec,  0xd0,  0xfc,  0x44,
13896  0x1b,  0xfe,  0xce,  0x45,  0x35,  0x42,  0xfe,  0x06,  0xea,  0xd0,  0xfe,  0x47,  0x4b,  0x91,  0xfe,  0x75,
13897  0x57,  0x03,  0x5d,  0xfe,  0x98,  0x56,  0xfe,  0x38,  0x12,  0x09,  0x48,  0x01,  0x0e,  0xfe,  0x44,  0x48,
13898  0x4f,  0x08,  0x05,  0x1b,  0xfe,  0x1a,  0x13,  0x09,  0x46,  0x01,  0x0e,  0x41,  0xfe,  0x41,  0x58,  0x09,
13899  0xa4,  0x01,  0x0e,  0xfe,  0x49,  0x54,  0x96,  0xfe,  0x1e,  0x0e,  0x02,  0xfe,  0x2e,  0x03,  0x09,  0x5d,
13900  0xfe,  0xee,  0x14,  0xfc,  0x44,  0x1b,  0xfe,  0xce,  0x45,  0x35,  0x42,  0xfe,  0xce,  0x47,  0xfe,  0xad,
13901  0x13,  0x02,  0x2b,  0x22,  0x20,  0x07,  0x11,  0xfe,  0x9e,  0x12,  0x21,  0x13,  0x59,  0x13,  0x9f,  0x13,
13902  0xd5,  0x22,  0x2f,  0x41,  0x39,  0x2f,  0xbc,  0xad,  0xfe,  0xbc,  0xf0,  0xfe,  0xe0,  0x0e,  0x0f,  0x06,
13903  0x13,  0x59,  0x01,  0xfe,  0xda,  0x16,  0x03,  0xfe,  0x38,  0x01,  0x29,  0xfe,  0x3a,  0x01,  0x56,  0xfe,
13904  0xe4,  0x0e,  0xfe,  0x02,  0xec,  0xd5,  0x69,  0x00,  0x66,  0xfe,  0x04,  0xec,  0x20,  0x4f,  0xfe,  0x05,
13905  0xf6,  0xfe,  0x34,  0x01,  0x01,  0xfe,  0x4a,  0x17,  0xfe,  0x08,  0x90,  0xfe,  0x48,  0xf4,  0x0d,  0xfe,
13906  0x18,  0x13,  0xba,  0xfe,  0x02,  0xea,  0xd5,  0x69,  0x7e,  0xfe,  0xc5,  0x13,  0x15,  0x1a,  0x39,  0xa0,
13907  0xb4,  0xfe,  0x2e,  0x10,  0x03,  0xfe,  0x38,  0x01,  0x1e,  0xfe,  0xf0,  0xff,  0x0c,  0xfe,  0x60,  0x01,
13908  0x03,  0xfe,  0x3a,  0x01,  0x0c,  0xfe,  0x62,  0x01,  0x43,  0x13,  0x20,  0x25,  0x06,  0x13,  0x2f,  0x12,
13909  0x2f,  0x92,  0x0f,  0x06,  0x04,  0x21,  0x04,  0x22,  0x59,  0xfe,  0xf7,  0x12,  0x22,  0x9f,  0xb7,  0x13,
13910  0x9f,  0x07,  0x7e,  0xfe,  0x71,  0x13,  0xfe,  0x24,  0x1c,  0x15,  0x19,  0x39,  0xa0,  0xb4,  0xfe,  0xd9,
13911  0x10,  0xc3,  0xfe,  0x03,  0xdc,  0xfe,  0x73,  0x57,  0xfe,  0x80,  0x5d,  0x04,  0xc3,  0xfe,  0x03,  0xdc,
13912  0xfe,  0x5b,  0x57,  0xfe,  0x80,  0x5d,  0x04,  0xfe,  0x03,  0x57,  0xc3,  0x21,  0xfe,  0x00,  0xcc,  0x04,
13913  0xfe,  0x03,  0x57,  0xc3,  0x78,  0x04,  0x08,  0x05,  0x58,  0xfe,  0x22,  0x13,  0xfe,  0x1c,  0x80,  0x07,
13914  0x06,  0xfe,  0x1a,  0x13,  0xfe,  0x1e,  0x80,  0xed,  0xfe,  0x1d,  0x80,  0xae,  0xfe,  0x0c,  0x90,  0xfe,
13915  0x0e,  0x13,  0xfe,  0x0e,  0x90,  0xac,  0xfe,  0x3c,  0x90,  0xfe,  0x30,  0xf4,  0x0a,  0xfe,  0x3c,  0x50,
13916  0xaa,  0x01,  0xfe,  0x7a,  0x17,  0x32,  0x07,  0x2f,  0xad,  0x01,  0xfe,  0xb4,  0x16,  0x08,  0x05,  0x1b,
13917  0x4e,  0x01,  0xf5,  0x01,  0xf6,  0x12,  0xfe,  0xe9,  0x00,  0x08,  0x05,  0x58,  0xfe,  0x2c,  0x13,  0x01,
13918  0xfe,  0x0c,  0x17,  0xfe,  0x1e,  0x1c,  0xfe,  0x14,  0x90,  0xfe,  0x96,  0x90,  0x0c,  0xfe,  0x64,  0x01,
13919  0x14,  0xfe,  0x66,  0x01,  0x08,  0x05,  0x5b,  0xfe,  0x12,  0x12,  0xfe,  0x03,  0x80,  0x8d,  0xfe,  0x01,
13920  0xec,  0x20,  0xfe,  0x80,  0x40,  0x13,  0x20,  0x6a,  0x2a,  0x12,  0xcf,  0x64,  0x22,  0x20,  0xfb,  0x79,
13921  0x20,  0x04,  0xfe,  0x08,  0x1c,  0x03,  0xfe,  0xac,  0x00,  0xfe,  0x06,  0x58,  0x03,  0xfe,  0xae,  0x00,
13922
13923  0xfe,  0x07,  0x58,  0x03,  0xfe,  0xb0,  0x00,  0xfe,  0x08,  0x58,  0x03,  0xfe,  0xb2,  0x00,  0xfe,  0x09,
13924  0x58,  0xfe,  0x0a,  0x1c,  0x25,  0x6e,  0x13,  0xd0,  0x21,  0x0c,  0x5c,  0x0c,  0x45,  0x0f,  0x46,  0x52,
13925  0x50,  0x18,  0x1b,  0xfe,  0x90,  0x4d,  0xfe,  0x91,  0x54,  0x23,  0xfe,  0xfc,  0x0f,  0x44,  0x11,  0x0f,
13926  0x48,  0x52,  0x18,  0x58,  0xfe,  0x90,  0x4d,  0xfe,  0x91,  0x54,  0x23,  0xe4,  0x25,  0x11,  0x13,  0x20,
13927  0x7c,  0x6f,  0x4f,  0x22,  0x20,  0xfb,  0x79,  0x20,  0x12,  0xcf,  0xfe,  0x14,  0x56,  0xfe,  0xd6,  0xf0,
13928  0xfe,  0x26,  0x10,  0xf8,  0x74,  0xfe,  0x14,  0x1c,  0xfe,  0x10,  0x1c,  0xfe,  0x18,  0x1c,  0x04,  0x42,
13929  0xfe,  0x0c,  0x14,  0xfc,  0xfe,  0x07,  0xe6,  0x1b,  0xfe,  0xce,  0x47,  0xfe,  0xf5,  0x13,  0x04,  0x01,
13930  0xb0,  0x7c,  0x6f,  0x4f,  0xfe,  0x06,  0x80,  0xfe,  0x48,  0x47,  0xfe,  0x42,  0x13,  0x32,  0x07,  0x2f,
13931  0xfe,  0x34,  0x13,  0x09,  0x48,  0x01,  0x0e,  0xbb,  0xfe,  0x36,  0x12,  0xfe,  0x41,  0x48,  0xfe,  0x45,
13932  0x48,  0x01,  0xf0,  0xfe,  0x00,  0xcc,  0xbb,  0xfe,  0xf3,  0x13,  0x43,  0x78,  0x07,  0x11,  0xac,  0x09,
13933  0x84,  0x01,  0x0e,  0xfe,  0x80,  0x5c,  0x01,  0x73,  0xfe,  0x0e,  0x10,  0x07,  0x82,  0x4e,  0xfe,  0x14,
13934  0x56,  0xfe,  0xd6,  0xf0,  0xfe,  0x60,  0x10,  0x04,  0xfe,  0x44,  0x58,  0x8d,  0xfe,  0x01,  0xec,  0xa2,
13935  0xfe,  0x9e,  0x40,  0xfe,  0x9d,  0xe7,  0x00,  0xfe,  0x9c,  0xe7,  0x1a,  0x79,  0x2a,  0x01,  0xe3,  0xfe,
13936  0xdd,  0x10,  0x2c,  0xc7,  0x81,  0xc8,  0x83,  0x33,  0x31,  0xde,  0x07,  0x1a,  0xfe,  0x48,  0x12,  0x07,
13937  0x0a,  0xfe,  0x56,  0x12,  0x07,  0x19,  0xfe,  0x30,  0x12,  0x07,  0xc9,  0x17,  0xfe,  0x32,  0x12,  0x07,
13938  0xfe,  0x23,  0x00,  0x17,  0xeb,  0x07,  0x06,  0x17,  0xfe,  0x9c,  0x12,  0x07,  0x1f,  0xfe,  0x12,  0x12,
13939  0x07,  0x00,  0x17,  0x24,  0x15,  0xc9,  0x01,  0x36,  0xa9,  0x2d,  0x01,  0x0b,  0x94,  0x4b,  0x04,  0x2d,
13940  0xdd,  0x09,  0xd1,  0x01,  0xfe,  0x26,  0x0f,  0x12,  0x82,  0x02,  0x2b,  0x2d,  0x32,  0x07,  0xa6,  0xfe,
13941  0xd9,  0x13,  0x3a,  0x3d,  0x3b,  0x3e,  0x56,  0xfe,  0xf0,  0x11,  0x08,  0x05,  0x5a,  0xfe,  0x72,  0x12,
13942  0x9b,  0x2e,  0x9c,  0x3c,  0x90,  0xc0,  0x96,  0xfe,  0xba,  0x11,  0x22,  0x62,  0xfe,  0x26,  0x13,  0x03,
13943  0x7f,  0x29,  0x80,  0x56,  0xfe,  0x76,  0x0d,  0x0c,  0x60,  0x14,  0x61,  0x21,  0x0c,  0x7f,  0x0c,  0x80,
13944  0x01,  0xb3,  0x25,  0x6e,  0x77,  0x13,  0x62,  0x01,  0xef,  0x9b,  0x2e,  0x9c,  0x3c,  0xfe,  0x04,  0x55,
13945  0xfe,  0xa5,  0x55,  0xfe,  0x04,  0xfa,  0x2e,  0xfe,  0x05,  0xfa,  0x3c,  0xfe,  0x91,  0x10,  0x03,  0x3f,
13946  0x29,  0x40,  0xfe,  0x40,  0x56,  0xfe,  0xe1,  0x56,  0x0c,  0x3f,  0x14,  0x40,  0x88,  0x9b,  0x2e,  0x9c,
13947  0x3c,  0x90,  0xc0,  0x03,  0x5e,  0x29,  0x5f,  0xfe,  0x00,  0x56,  0xfe,  0xa1,  0x56,  0x0c,  0x5e,  0x14,
13948  0x5f,  0x08,  0x05,  0x5a,  0xfe,  0x1e,  0x12,  0x22,  0x62,  0xfe,  0x1f,  0x40,  0x03,  0x60,  0x29,  0x61,
13949  0xfe,  0x2c,  0x50,  0xfe,  0xae,  0x50,  0x03,  0x3f,  0x29,  0x40,  0xfe,  0x44,  0x50,  0xfe,  0xc6,  0x50,
13950  0x03,  0x5e,  0x29,  0x5f,  0xfe,  0x08,  0x50,  0xfe,  0x8a,  0x50,  0x03,  0x3d,  0x29,  0x3e,  0xfe,  0x40,
13951  0x50,  0xfe,  0xc2,  0x50,  0x02,  0x89,  0x25,  0x06,  0x13,  0xd4,  0x02,  0x72,  0x2d,  0x01,  0x0b,  0x1d,
13952  0x4c,  0x33,  0x31,  0xde,  0x07,  0x06,  0x23,  0x4c,  0x32,  0x07,  0xa6,  0x23,  0x72,  0x01,  0xaf,  0x1e,
13953  0x43,  0x17,  0x4c,  0x08,  0x05,  0x0a,  0xee,  0x3a,  0x3d,  0x3b,  0x3e,  0xfe,  0x0a,  0x55,  0x35,  0xfe,
13954  0x8b,  0x55,  0x57,  0x3d,  0x7d,  0x3e,  0xfe,  0x0c,  0x51,  0xfe,  0x8e,  0x51,  0x02,  0x72,  0xfe,  0x19,
13955  0x81,  0xba,  0xfe,  0x19,  0x41,  0x02,  0x72,  0x2d,  0x01,  0x0b,  0x1c,  0x34,  0x1d,  0xe8,  0x33,  0x31,
13956  0xe1,  0x55,  0x19,  0xfe,  0xa6,  0x12,  0x55,  0x0a,  0x4d,  0x02,  0x4c,  0x01,  0x0b,  0x1c,  0x34,  0x1d,
13957  0xe8,  0x33,  0x31,  0xdf,  0x07,  0x19,  0x23,  0x4c,  0x01,  0x0b,  0x1d,  0xe8,  0x33,  0x31,  0xfe,  0xe8,
13958  0x09,  0xfe,  0xc2,  0x49,  0x51,  0x03,  0xfe,  0x9c,  0x00,  0x28,  0x8a,  0x53,  0x05,  0x1f,  0x35,  0xa9,
13959  0xfe,  0xbb,  0x45,  0x55,  0x00,  0x4e,  0x44,  0x06,  0x7c,  0x43,  0xfe,  0xda,  0x14,  0x01,  0xaf,  0x8c,
13960  0xfe,  0x4b,  0x45,  0xee,  0x32,  0x07,  0xa5,  0xed,  0x03,  0xcd,  0x28,  0x8a,  0x03,  0x45,  0x28,  0x35,
13961  0x67,  0x02,  0x72,  0xfe,  0xc0,  0x5d,  0xfe,  0xf8,  0x14,  0xfe,  0x03,  0x17,  0x03,  0x5c,  0xc1,  0x0c,
13962  0x5c,  0x67,  0x2d,  0x01,  0x0b,  0x26,  0x89,  0x01,  0xfe,  0x9e,  0x15,  0x02,  0x89,  0x01,  0x0b,  0x1c,
13963  0x34,  0x1d,  0x4c,  0x33,  0x31,  0xdf,  0x07,  0x06,  0x23,  0x4c,  0x01,  0xf1,  0xfe,  0x42,  0x58,  0xf1,
13964  0xfe,  0xa4,  0x14,  0x8c,  0xfe,  0x4a,  0xf4,  0x0a,  0x17,  0x4c,  0xfe,  0x4a,  0xf4,  0x06,  0xea,  0x32,
13965  0x07,  0xa5,  0x8b,  0x02,  0x72,  0x03,  0x45,  0xc1,  0x0c,  0x45,  0x67,  0x2d,  0x01,  0x0b,  0x26,  0x89,
13966  0x01,  0xfe,  0xcc,  0x15,  0x02,  0x89,  0x0f,  0x06,  0x27,  0xfe,  0xbe,  0x13,  0x26,  0xfe,  0xd4,  0x13,
13967  0x76,  0xfe,  0x89,  0x48,  0x01,  0x0b,  0x21,  0x76,  0x04,  0x7b,  0xfe,  0xd0,  0x13,  0x1c,  0xfe,  0xd0,
13968  0x13,  0x1d,  0xfe,  0xbe,  0x13,  0x67,  0x2d,  0x01,  0x0b,  0xfe,  0xd5,  0x10,  0x0f,  0x71,  0xff,  0x02,
13969  0x00,  0x57,  0x52,  0x93,  0x1e,  0xfe,  0xff,  0x7f,  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x04,  0x0f,
13970  0x71,  0xff,  0x02,  0x00,  0x57,  0x52,  0x93,  0x1e,  0x43,  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x04,
13971  0x0f,  0x71,  0xff,  0x02,  0x00,  0x57,  0x52,  0x93,  0x04,  0x0f,  0x71,  0xff,  0x02,  0x00,  0x57,  0x52,
13972  0x93,  0xfe,  0x0b,  0x58,  0x04,  0x09,  0x5c,  0x01,  0x87,  0x09,  0x45,  0x01,  0x87,  0x04,  0xfe,  0x03,
13973  0xa1,  0x1e,  0x11,  0xff,  0x03,  0x00,  0x54,  0xfe,  0x00,  0xf4,  0x1f,  0x52,  0xfe,  0x00,  0x7d,  0xfe,
13974  0x01,  0x7d,  0xfe,  0x02,  0x7d,  0xfe,  0x03,  0x7c,  0x6a,  0x2a,  0x0c,  0x5e,  0x14,  0x5f,  0x57,  0x3f,
13975  0x7d,  0x40,  0x04,  0xdd,  0xfe,  0x82,  0x4a,  0xfe,  0xe1,  0x1a,  0xfe,  0x83,  0x5a,  0x8d,  0x04,  0x01,
13976  0xfe,  0x0c,  0x19,  0xfe,  0x42,  0x48,  0x50,  0x51,  0x91,  0x01,  0x0b,  0x1d,  0xfe,  0x96,  0x15,  0x33,
13977  0x31,  0xe1,  0x01,  0x0b,  0x1d,  0xfe,  0x96,  0x15,  0x33,  0x31,  0xfe,  0xe8,  0x0a,  0xfe,  0xc1,  0x59,
13978  0x03,  0xcd,  0x28,  0xfe,  0xcc,  0x12,  0x53,  0x05,  0x1a,  0xfe,  0xc4,  0x13,  0x21,  0x69,  0x1a,  0xee,
13979  0x55,  0xca,  0x6b,  0xfe,  0xdc,  0x14,  0x4d,  0x0f,  0x06,  0x18,  0xca,  0x7c,  0x30,  0xfe,  0x78,  0x10,
13980  0xff,  0x02,  0x83,  0x55,  0xab,  0xff,  0x02,  0x83,  0x55,  0x69,  0x19,  0xae,  0x98,  0xfe,  0x30,  0x00,
13981  0x96,  0xf2,  0x18,  0x6d,  0x0f,  0x06,  0xfe,  0x56,  0x10,  0x69,  0x0a,  0xed,  0x98,  0xfe,  0x64,  0x00,
13982  0x96,  0xf2,  0x09,  0xfe,  0x64,  0x00,  0x18,  0x9e,  0x0f,  0x06,  0xfe,  0x28,  0x10,  0x69,  0x06,  0xfe,
13983  0x60,  0x13,  0x98,  0xfe,  0xc8,  0x00,  0x96,  0xf2,  0x09,  0xfe,  0xc8,  0x00,  0x18,  0x59,  0x0f,  0x06,
13984  0x88,  0x98,  0xfe,  0x90,  0x01,  0x7a,  0xfe,  0x42,  0x15,  0x91,  0xe4,  0xfe,  0x43,  0xf4,  0x9f,  0xfe,
13985  0x56,  0xf0,  0xfe,  0x54,  0x15,  0xfe,  0x04,  0xf4,  0x71,  0xfe,  0x43,  0xf4,  0x9e,  0xfe,  0xf3,  0x10,
13986  0xfe,  0x40,  0x5c,  0x01,  0xfe,  0x16,  0x14,  0x1e,  0x43,  0xec,  0xfe,  0x00,  0x17,  0xfe,  0x4d,  0xe4,
13987  0x6e,  0x7a,  0xfe,  0x90,  0x15,  0xc4,  0x6e,  0xfe,  0x1c,  0x10,  0xfe,  0x00,  0x17,  0xfe,  0x4d,  0xe4,
13988  0xcc,  0x7a,  0xfe,  0x90,  0x15,  0xc4,  0xcc,  0x88,  0x51,  0x21,  0xfe,  0x4d,  0xf4,  0x00,  0xe9,  0x91,
13989  0x0f,  0x06,  0xfe,  0xb4,  0x56,  0xfe,  0xc3,  0x58,  0x04,  0x51,  0x0f,  0x0a,  0x04,  0x16,  0x06,  0x01,
13990  0x0b,  0x26,  0xf3,  0x16,  0x0a,  0x01,  0x0b,  0x26,  0xf3,  0x16,  0x19,  0x01,  0x0b,  0x26,  0xf3,  0x76,
13991  0xfe,  0x89,  0x49,  0x01,  0x0b,  0x04,  0x16,  0x06,  0x01,  0x0b,  0x26,  0xb1,  0x16,  0x19,  0x01,  0x0b,
13992  0x26,  0xb1,  0x16,  0x06,  0x01,  0x0b,  0x26,  0xb1,  0xfe,  0x89,  0x49,  0x01,  0x0b,  0x26,  0xb1,  0x76,
13993  0xfe,  0x89,  0x4a,  0x01,  0x0b,  0x04,  0x51,  0x04,  0x22,  0xd3,  0x07,  0x06,  0xfe,  0x48,  0x13,  0xb8,
13994  0x13,  0xd3,  0xfe,  0x49,  0xf4,  0x00,  0x4d,  0x76,  0xa9,  0x67,  0xfe,  0x01,  0xec,  0xfe,  0x27,  0x01,
13995  0xfe,  0x89,  0x48,  0xff,  0x02,  0x00,  0x10,  0x27,  0xfe,  0x2e,  0x16,  0x32,  0x07,  0xfe,  0xe3,  0x00,
13996  0xfe,  0x20,  0x13,  0x1d,  0xfe,  0x52,  0x16,  0x21,  0x13,  0xd4,  0x01,  0x4b,  0x22,  0xd4,  0x07,  0x06,
13997  0x4e,  0x08,  0x54,  0x06,  0x37,  0x04,  0x09,  0x48,  0x01,  0x0e,  0xfb,  0x8e,  0x07,  0x11,  0xae,  0x09,
13998  0x84,  0x01,  0x0e,  0x8e,  0x09,  0x5d,  0x01,  0xa8,  0x04,  0x09,  0x84,  0x01,  0x0e,  0x8e,  0xfe,  0x80,
13999  0xe7,  0x11,  0x07,  0x11,  0x8a,  0xfe,  0x45,  0x58,  0x01,  0xf0,  0x8e,  0x04,  0x09,  0x48,  0x01,  0x0e,
14000  0x8e,  0x09,  0x5d,  0x01,  0xa8,  0x04,  0x09,  0x48,  0x01,  0x0e,  0xfe,  0x80,  0x80,  0xfe,  0x80,  0x4c,
14001  0xfe,  0x49,  0xe4,  0x11,  0xae,  0x09,  0x84,  0x01,  0x0e,  0xfe,  0x80,  0x4c,  0x09,  0x5d,  0x01,  0x87,
14002  0x04,  0x18,  0x11,  0x75,  0x6c,  0xfe,  0x60,  0x01,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,  0x24,
14003  0x1c,  0xfe,  0x1d,  0xf7,  0x1b,  0x97,  0xfe,  0xee,  0x16,  0x01,  0xfe,  0xf4,  0x17,  0xad,  0x9a,  0x1b,
14004  0x6c,  0xfe,  0x2c,  0x01,  0xfe,  0x2f,  0x19,  0x04,  0xb9,  0x23,  0xfe,  0xde,  0x16,  0xfe,  0xda,  0x10,
14005  0x18,  0x11,  0x75,  0x03,  0xfe,  0x64,  0x01,  0xfe,  0x00,  0xf4,  0x1f,  0xfe,  0x18,  0x58,  0x03,  0xfe,
14006  0x66,  0x01,  0xfe,  0x19,  0x58,  0x9a,  0x1f,  0xfe,  0x3c,  0x90,  0xfe,  0x30,  0xf4,  0x06,  0xfe,  0x3c,
14007  0x50,  0x6c,  0xfe,  0x38,  0x00,  0xfe,  0x0f,  0x79,  0xfe,  0x1c,  0xf7,  0x1f,  0x97,  0xfe,  0x38,  0x17,
14008  0xfe,  0xb6,  0x14,  0x35,  0x04,  0xb9,  0x23,  0xfe,  0x10,  0x17,  0xfe,  0x9c,  0x10,  0x18,  0x11,  0x75,
14009  0xfe,  0x83,  0x5a,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,  0x1d,  0xf7,  0x2e,  0x97,  0xfe,  0x5a,
14010  0x17,  0xfe,  0x94,  0x14,  0xec,  0x9a,  0x2e,  0x6c,  0x1a,  0xfe,  0xaf,  0x19,  0xfe,  0x98,  0xe7,  0x00,
14011  0x04,  0xb9,  0x23,  0xfe,  0x4e,  0x17,  0xfe,  0x6c,  0x10,  0x18,  0x11,  0x75,  0xfe,  0x30,  0xbc,  0xfe,
14012  0xb2,  0xbc,  0x9a,  0xcb,  0x6c,  0x1a,  0xfe,  0x0f,  0x79,  0xfe,  0x1c,  0xf7,  0xcb,  0x97,  0xfe,  0x92,
14013  0x17,  0xfe,  0x5c,  0x14,  0x35,  0x04,  0xb9,  0x23,  0xfe,  0x7e,  0x17,  0xfe,  0x42,  0x10,  0xfe,  0x02,
14014  0xf6,  0x11,  0x75,  0xfe,  0x18,  0xfe,  0x60,  0xfe,  0x19,  0xfe,  0x61,  0xfe,  0x03,  0xa1,  0xfe,  0x1d,
14015  0xf7,  0x5b,  0x97,  0xfe,  0xb8,  0x17,  0xfe,  0x36,  0x14,  0xfe,  0x1c,  0x13,  0x9a,  0x5b,  0x41,  0xfe,
14016  0x83,  0x58,  0xfe,  0xaf,  0x19,  0xfe,  0x80,  0xe7,  0x11,  0xfe,  0x81,  0xe7,  0x11,  0x12,  0xfe,  0xdd,
14017  0x00,  0x6a,  0x2a,  0x04,  0x6a,  0x2a,  0xfe,  0x12,  0x45,  0x23,  0xfe,  0xa8,  0x17,  0x15,  0x06,  0x39,
14018  0xa0,  0xb4,  0x02,  0x2b,  0xfe,  0x39,  0xf0,  0xfe,  0xfc,  0x17,  0x21,  0x04,  0xfe,  0x7e,  0x18,  0x1e,
14019  0x19,  0x66,  0x0f,  0x0d,  0x04,  0x75,  0x03,  0xd2,  0x1e,  0x06,  0xfe,  0xef,  0x12,  0xfe,  0xe1,  0x10,
14020  0x7c,  0x6f,  0x4f,  0x32,  0x07,  0x2f,  0xfe,  0x3c,  0x13,  0xf1,  0xfe,  0x42,  0x13,  0x42,  0x92,  0x09,
14021  0x48,  0x01,  0x0e,  0xbb,  0xeb,  0xfe,  0x41,  0x48,  0xfe,  0x45,  0x48,  0x01,  0xf0,  0xfe,  0x00,  0xcc,
14022  0xbb,  0xfe,  0xf3,  0x13,  0x43,  0x78,  0x07,  0x11,  0xac,  0x09,  0x84,  0x01,  0x0e,  0xfe,  0x80,  0x4c,
14023  0x01,  0x73,  0xfe,  0x16,  0x10,  0x07,  0x82,  0x8b,  0xfe,  0x40,  0x14,  0xfe,  0x24,  0x12,  0xfe,  0x14,
14024  0x56,  0xfe,  0xd6,  0xf0,  0xfe,  0x1c,  0x18,  0x18,  0x0a,  0x04,  0xfe,  0x9c,  0xe7,  0x0a,  0x10,  0xfe,
14025  0x15,  0x00,  0x64,  0x79,  0x2a,  0x01,  0xe3,  0x18,  0x06,  0x04,  0x42,  0x92,  0x08,  0x54,  0x1b,  0x37,
14026  0x12,  0x2f,  0x01,  0x73,  0x18,  0x06,  0x04,  0xfe,  0x38,  0x90,  0xfe,  0xba,  0x90,  0x3a,  0xce,  0x3b,
14027  0xcf,  0xfe,  0x48,  0x55,  0x35,  0xfe,  0xc9,  0x55,  0x04,  0x22,  0xa3,  0x77,  0x13,  0xa3,  0x04,  0x09,
14028  0xa4,  0x01,  0x0e,  0xfe,  0x41,  0x48,  0x09,  0x46,  0x01,  0x0e,  0xfe,  0x49,  0x44,  0x17,  0xfe,  0xe8,
14029  0x18,  0x77,  0x78,  0x04,  0x09,  0x48,  0x01,  0x0e,  0x07,  0x11,  0x4e,  0x09,  0x5d,  0x01,  0xa8,  0x09,
14030  0x46,  0x01,  0x0e,  0x77,  0x78,  0x04,  0xfe,  0x4e,  0xe4,  0x19,  0x6b,  0xfe,  0x1c,  0x19,  0x03,  0xfe,
14031  0x90,  0x00,  0xfe,  0x3a,  0x45,  0xfe,  0x2c,  0x10,  0xfe,  0x4e,  0xe4,  0xc9,  0x6b,  0xfe,  0x2e,  0x19,
14032  0x03,  0xfe,  0x92,  0x00,  0xfe,  0x02,  0xe6,  0x1a,  0xe5,  0xfe,  0x4e,  0xe4,  0xfe,  0x0b,  0x00,  0x6b,
14033  0xfe,  0x40,  0x19,  0x03,  0xfe,  0x94,  0x00,  0xfe,  0x02,  0xe6,  0x1f,  0xfe,  0x08,  0x10,  0x03,  0xfe,
14034  0x96,  0x00,  0xfe,  0x02,  0xe6,  0x6d,  0xfe,  0x4e,  0x45,  0xea,  0xba,  0xff,  0x04,  0x68,  0x54,  0xe7,
14035  0x1e,  0x6e,  0xfe,  0x08,  0x1c,  0xfe,  0x67,  0x19,  0xfe,  0x0a,  0x1c,  0xfe,  0x1a,  0xf4,  0xfe,  0x00,
14036  0x04,  0xea,  0xfe,  0x48,  0xf4,  0x19,  0x7a,  0xfe,  0x74,  0x19,  0x0f,  0x19,  0x04,  0x07,  0x7e,  0xfe,
14037  0x5a,  0xf0,  0xfe,  0x84,  0x19,  0x25,  0xfe,  0x09,  0x00,  0xfe,  0x34,  0x10,  0x07,  0x1a,  0xfe,  0x5a,
14038  0xf0,  0xfe,  0x92,  0x19,  0x25,  0xca,  0xfe,  0x26,  0x10,  0x07,  0x19,  0x66,  0x25,  0x6d,  0xe5,  0x07,
14039  0x0a,  0x66,  0x25,  0x9e,  0xfe,  0x0e,  0x10,  0x07,  0x06,  0x66,  0x25,  0x59,  0xa9,  0xb8,  0x04,  0x15,
14040  0xfe,  0x09,  0x00,  0x01,  0x36,  0xfe,  0x04,  0xfe,  0x81,  0x03,  0x83,  0xfe,  0x40,  0x5c,  0x04,  0x1c,
14041  0xf7,  0xfe,  0x14,  0xf0,  0x0b,  0x27,  0xfe,  0xd6,  0x19,  0x1c,  0xf7,  0x7b,  0xf7,  0xfe,  0x82,  0xf0,
14042  0xfe,  0xda,  0x19,  0x04,  0xff,  0xcc,  0x00,  0x00,
14043};
14044
14045STATIC unsigned short _adv_asc38C0800_size =
14046        sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
14047STATIC ADV_DCNT _adv_asc38C0800_chksum =
14048        0x050D3FD8UL; /* Expanded little-endian checksum. */
14049
14050/* Microcode buffer is kept after initialization for error recovery. */
14051STATIC unsigned char _adv_asc38C1600_buf[] = {
14052  0x00,  0x00,  0x00,  0xf2,  0x00,  0x16,  0x00,  0xfc,  0x00,  0x10,  0x00,  0xf0,  0x18,  0xe4,  0x01,  0x00,
14053  0x04,  0x1e,  0x48,  0xe4,  0x03,  0xf6,  0xf7,  0x13,  0x2e,  0x1e,  0x02,  0x00,  0x07,  0x17,  0xc0,  0x5f,
14054  0x00,  0xfa,  0xff,  0xff,  0x04,  0x00,  0x00,  0xf6,  0x09,  0xe7,  0x82,  0xe7,  0x85,  0xf0,  0x86,  0xf0,
14055  0x4e,  0x10,  0x9e,  0xe7,  0xff,  0x00,  0x55,  0xf0,  0x01,  0xf6,  0x03,  0x00,  0x98,  0x57,  0x01,  0xe6,
14056  0x00,  0xea,  0x00,  0xec,  0x01,  0xfa,  0x18,  0xf4,  0x08,  0x00,  0xf0,  0x1d,  0x38,  0x54,  0x32,  0xf0,
14057  0x10,  0x00,  0xc2,  0x0e,  0x1e,  0xf0,  0xd5,  0xf0,  0xbc,  0x00,  0x4b,  0xe4,  0x00,  0xe6,  0xb1,  0xf0,
14058  0xb4,  0x00,  0x02,  0x13,  0x3e,  0x1c,  0xc8,  0x47,  0x3e,  0x00,  0xd8,  0x01,  0x06,  0x13,  0x0c,  0x1c,
14059  0x5e,  0x1e,  0x00,  0x57,  0xc8,  0x57,  0x01,  0xfc,  0xbc,  0x0e,  0xa2,  0x12,  0xb9,  0x54,  0x00,  0x80,
14060  0x62,  0x0a,  0x5a,  0x12,  0xc8,  0x15,  0x3e,  0x1e,  0x18,  0x40,  0xbd,  0x56,  0x03,  0xe6,  0x01,  0xea,
14061  0x5c,  0xf0,  0x0f,  0x00,  0x20,  0x00,  0x6c,  0x01,  0x6e,  0x01,  0x04,  0x12,  0x04,  0x13,  0xbb,  0x55,
14062  0x3c,  0x56,  0x3e,  0x57,  0x03,  0x58,  0x4a,  0xe4,  0x40,  0x00,  0xb6,  0x00,  0xbb,  0x00,  0xc0,  0x00,
14063  0x00,  0x01,  0x01,  0x01,  0x3e,  0x01,  0x58,  0x0a,  0x44,  0x10,  0x0a,  0x12,  0x4c,  0x1c,  0x4e,  0x1c,
14064  0x02,  0x4a,  0x30,  0xe4,  0x05,  0xe6,  0x0c,  0x00,  0x3c,  0x00,  0x80,  0x00,  0x24,  0x01,  0x3c,  0x01,
14065  0x68,  0x01,  0x6a,  0x01,  0x70,  0x01,  0x72,  0x01,  0x74,  0x01,  0x76,  0x01,  0x78,  0x01,  0x7c,  0x01,
14066  0xc6,  0x0e,  0x0c,  0x10,  0xac,  0x12,  0xae,  0x12,  0x16,  0x1a,  0x32,  0x1c,  0x6e,  0x1e,  0x02,  0x48,
14067  0x3a,  0x55,  0xc9,  0x57,  0x02,  0xee,  0x5b,  0xf0,  0x03,  0xf7,  0x06,  0xf7,  0x03,  0xfc,  0x06,  0x00,
14068  0x1e,  0x00,  0xbe,  0x00,  0xe1,  0x00,  0x0c,  0x12,  0x18,  0x1a,  0x70,  0x1a,  0x30,  0x1c,  0x38,  0x1c,
14069  0x10,  0x44,  0x00,  0x4c,  0xb0,  0x57,  0x40,  0x5c,  0x4d,  0xe4,  0x04,  0xea,  0x5d,  0xf0,  0xa7,  0xf0,
14070  0x04,  0xf6,  0x02,  0xfc,  0x05,  0x00,  0x09,  0x00,  0x19,  0x00,  0x32,  0x00,  0x33,  0x00,  0x34,  0x00,
14071  0x36,  0x00,  0x98,  0x00,  0x9e,  0x00,  0xcc,  0x00,  0x20,  0x01,  0x4e,  0x01,  0x79,  0x01,  0x3c,  0x09,
14072  0x68,  0x0d,  0x02,  0x10,  0x04,  0x10,  0x3a,  0x10,  0x08,  0x12,  0x0a,  0x13,  0x40,  0x16,  0x50,  0x16,
14073  0x00,  0x17,  0x4a,  0x19,  0x00,  0x4e,  0x00,  0x54,  0x01,  0x58,  0x00,  0xdc,  0x05,  0xf0,  0x09,  0xf0,
14074  0x59,  0xf0,  0xb8,  0xf0,  0x48,  0xf4,  0x0e,  0xf7,  0x0a,  0x00,  0x9b,  0x00,  0x9c,  0x00,  0xa4,  0x00,
14075  0xb5,  0x00,  0xba,  0x00,  0xd0,  0x00,  0xe7,  0x00,  0xf0,  0x03,  0x69,  0x08,  0xe9,  0x09,  0x5c,  0x0c,
14076  0xb6,  0x12,  0xbc,  0x19,  0xd8,  0x1b,  0x20,  0x1c,  0x34,  0x1c,  0x36,  0x1c,  0x42,  0x1d,  0x08,  0x44,
14077  0x38,  0x44,  0x91,  0x44,  0x0a,  0x45,  0x48,  0x46,  0x89,  0x48,  0x68,  0x54,  0x83,  0x55,  0x83,  0x59,
14078  0x31,  0xe4,  0x02,  0xe6,  0x07,  0xf0,  0x08,  0xf0,  0x0b,  0xf0,  0x0c,  0xf0,  0x4b,  0xf4,  0x04,  0xf8,
14079  0x05,  0xf8,  0x02,  0xfa,  0x03,  0xfa,  0x04,  0xfc,  0x05,  0xfc,  0x07,  0x00,  0xa8,  0x00,  0xaa,  0x00,
14080  0xb9,  0x00,  0xe0,  0x00,  0xe5,  0x00,  0x22,  0x01,  0x26,  0x01,  0x60,  0x01,  0x7a,  0x01,  0x82,  0x01,
14081  0xc8,  0x01,  0xca,  0x01,  0x86,  0x02,  0x6a,  0x03,  0x18,  0x05,  0xb2,  0x07,  0x68,  0x08,  0x10,  0x0d,
14082  0x06,  0x10,  0x0a,  0x10,  0x0e,  0x10,  0x12,  0x10,  0x60,  0x10,  0xed,  0x10,  0xf3,  0x10,  0x06,  0x12,
14083  0x10,  0x12,  0x1e,  0x12,  0x0c,  0x13,  0x0e,  0x13,  0x10,  0x13,  0xfe,  0x9c,  0xf0,  0x35,  0x05,  0xfe,
14084  0xec,  0x0e,  0xff,  0x10,  0x00,  0x00,  0xe9,  0xfe,  0x34,  0x1f,  0x00,  0xe8,  0xfe,  0x88,  0x01,  0xff,
14085  0x03,  0x00,  0x00,  0xfe,  0x93,  0x15,  0xfe,  0x0f,  0x05,  0xff,  0x38,  0x00,  0x00,  0xfe,  0x57,  0x24,
14086  0x00,  0xfe,  0x4c,  0x00,  0x65,  0xff,  0x04,  0x00,  0x00,  0x1a,  0xff,  0x09,  0x00,  0x00,  0xff,  0x08,
14087  0x01,  0x01,  0xff,  0x08,  0xff,  0xff,  0xff,  0x27,  0x00,  0x00,  0xff,  0x10,  0xff,  0xff,  0xff,  0x13,
14088  0x00,  0x00,  0xfe,  0x78,  0x56,  0xfe,  0x34,  0x12,  0xff,  0x21,  0x00,  0x00,  0xfe,  0x04,  0xf7,  0xe8,
14089  0x37,  0x7d,  0x0d,  0x01,  0xfe,  0x4a,  0x11,  0xfe,  0x04,  0xf7,  0xe8,  0x7d,  0x0d,  0x51,  0x37,  0xfe,
14090  0x3d,  0xf0,  0xfe,  0x0c,  0x02,  0xfe,  0x20,  0xf0,  0xbc,  0xfe,  0x91,  0xf0,  0xfe,  0xf8,  0x01,  0xfe,
14091  0x90,  0xf0,  0xfe,  0xf8,  0x01,  0xfe,  0x8f,  0xf0,  0xbc,  0x03,  0x67,  0x4d,  0x05,  0xfe,  0x08,  0x0f,
14092  0x01,  0xfe,  0x78,  0x0f,  0xfe,  0xdd,  0x12,  0x05,  0xfe,  0x0e,  0x03,  0xfe,  0x28,  0x1c,  0x03,  0xfe,
14093  0xa6,  0x00,  0xfe,  0xd1,  0x12,  0x3e,  0x22,  0xfe,  0xa6,  0x00,  0xac,  0xfe,  0x48,  0xf0,  0xfe,  0x90,
14094  0x02,  0xfe,  0x49,  0xf0,  0xfe,  0xaa,  0x02,  0xfe,  0x4a,  0xf0,  0xfe,  0xc8,  0x02,  0xfe,  0x46,  0xf0,
14095  0xfe,  0x5a,  0x02,  0xfe,  0x47,  0xf0,  0xfe,  0x60,  0x02,  0xfe,  0x43,  0xf0,  0xfe,  0x4e,  0x02,  0xfe,
14096  0x44,  0xf0,  0xfe,  0x52,  0x02,  0xfe,  0x45,  0xf0,  0xfe,  0x56,  0x02,  0x1c,  0x0d,  0xa2,  0x1c,  0x07,
14097  0x22,  0xb7,  0x05,  0x35,  0xfe,  0x00,  0x1c,  0xfe,  0xf1,  0x10,  0xfe,  0x02,  0x1c,  0xf5,  0xfe,  0x1e,
14098  0x1c,  0xfe,  0xe9,  0x10,  0x01,  0x5f,  0xfe,  0xe7,  0x10,  0xfe,  0x06,  0xfc,  0xde,  0x0a,  0x81,  0x01,
14099  0xa3,  0x05,  0x35,  0x1f,  0x95,  0x47,  0xb8,  0x01,  0xfe,  0xe4,  0x11,  0x0a,  0x81,  0x01,  0x5c,  0xfe,
14100  0xbd,  0x10,  0x0a,  0x81,  0x01,  0x5c,  0xfe,  0xad,  0x10,  0xfe,  0x16,  0x1c,  0xfe,  0x58,  0x1c,  0x1c,
14101  0x07,  0x22,  0xb7,  0x37,  0x2a,  0x35,  0xfe,  0x3d,  0xf0,  0xfe,  0x0c,  0x02,  0x2b,  0xfe,  0x9e,  0x02,
14102  0xfe,  0x5a,  0x1c,  0xfe,  0x12,  0x1c,  0xfe,  0x14,  0x1c,  0x1f,  0xfe,  0x30,  0x00,  0x47,  0xb8,  0x01,
14103  0xfe,  0xd4,  0x11,  0x1c,  0x07,  0x22,  0xb7,  0x05,  0xe9,  0x21,  0x2c,  0x09,  0x1a,  0x31,  0xfe,  0x69,
14104  0x10,  0x1c,  0x07,  0x22,  0xb7,  0xfe,  0x04,  0xec,  0x2c,  0x60,  0x01,  0xfe,  0x1e,  0x1e,  0x20,  0x2c,
14105  0xfe,  0x05,  0xf6,  0xde,  0x01,  0xfe,  0x62,  0x1b,  0x01,  0x0c,  0x61,  0x4a,  0x44,  0x15,  0x56,  0x51,
14106  0x01,  0xfe,  0x9e,  0x1e,  0x01,  0xfe,  0x96,  0x1a,  0x05,  0x35,  0x0a,  0x57,  0x01,  0x18,  0x09,  0x00,
14107  0x36,  0x01,  0x85,  0xfe,  0x18,  0x10,  0xfe,  0x41,  0x58,  0x0a,  0xba,  0x01,  0x18,  0xfe,  0xc8,  0x54,
14108  0x7b,  0xfe,  0x1c,  0x03,  0x01,  0xfe,  0x96,  0x1a,  0x05,  0x35,  0x37,  0x60,  0xfe,  0x02,  0xe8,  0x30,
14109  0xfe,  0xbf,  0x57,  0xfe,  0x9e,  0x43,  0xfe,  0x77,  0x57,  0xfe,  0x27,  0xf0,  0xfe,  0xe4,  0x01,  0xfe,
14110  0x07,  0x4b,  0xfe,  0x20,  0xf0,  0xbc,  0xfe,  0x40,  0x1c,  0x2a,  0xeb,  0xfe,  0x26,  0xf0,  0xfe,  0x66,
14111  0x03,  0xfe,  0xa0,  0xf0,  0xfe,  0x54,  0x03,  0xfe,  0x11,  0xf0,  0xbc,  0xfe,  0xef,  0x10,  0xfe,  0x9f,
14112  0xf0,  0xfe,  0x74,  0x03,  0xfe,  0x46,  0x1c,  0x19,  0xfe,  0x11,  0x00,  0x05,  0x70,  0x37,  0xfe,  0x48,
14113  0x1c,  0xfe,  0x46,  0x1c,  0x01,  0x0c,  0x06,  0x28,  0xfe,  0x18,  0x13,  0x26,  0x21,  0xb9,  0xc7,  0x20,
14114  0xb9,  0x0a,  0x57,  0x01,  0x18,  0xc7,  0x89,  0x01,  0xfe,  0xc8,  0x1a,  0x15,  0xe1,  0x2a,  0xeb,  0xfe,
14115  0x01,  0xf0,  0xeb,  0xfe,  0x82,  0xf0,  0xfe,  0xa4,  0x03,  0xfe,  0x9c,  0x32,  0x15,  0xfe,  0xe4,  0x00,
14116  0x2f,  0xfe,  0xb6,  0x03,  0x2a,  0x3c,  0x16,  0xfe,  0xc6,  0x03,  0x01,  0x41,  0xfe,  0x06,  0xf0,  0xfe,
14117  0xd6,  0x03,  0xaf,  0xa0,  0xfe,  0x0a,  0xf0,  0xfe,  0xa2,  0x07,  0x05,  0x29,  0x03,  0x81,  0x1e,  0x1b,
14118  0xfe,  0x24,  0x05,  0x1f,  0x63,  0x01,  0x42,  0x8f,  0xfe,  0x70,  0x02,  0x05,  0xea,  0xfe,  0x46,  0x1c,
14119  0x37,  0x7d,  0x1d,  0xfe,  0x67,  0x1b,  0xfe,  0xbf,  0x57,  0xfe,  0x77,  0x57,  0xfe,  0x48,  0x1c,  0x75,
14120  0x01,  0xa6,  0x86,  0x0a,  0x57,  0x01,  0x18,  0x09,  0x00,  0x1b,  0xec,  0x0a,  0xe1,  0x01,  0x18,  0x77,
14121  0x50,  0x40,  0x8d,  0x30,  0x03,  0x81,  0x1e,  0xf8,  0x1f,  0x63,  0x01,  0x42,  0x8f,  0xfe,  0x70,  0x02,
14122  0x05,  0xea,  0xd7,  0x99,  0xd8,  0x9c,  0x2a,  0x29,  0x2f,  0xfe,  0x4e,  0x04,  0x16,  0xfe,  0x4a,  0x04,
14123  0x7e,  0xfe,  0xa0,  0x00,  0xfe,  0x9b,  0x57,  0xfe,  0x54,  0x12,  0x32,  0xff,  0x02,  0x00,  0x10,  0x01,
14124  0x08,  0x16,  0xfe,  0x02,  0x05,  0x32,  0x01,  0x08,  0x16,  0x29,  0x27,  0x25,  0xee,  0xfe,  0x4c,  0x44,
14125  0xfe,  0x58,  0x12,  0x50,  0xfe,  0x44,  0x48,  0x13,  0x34,  0xfe,  0x4c,  0x54,  0x7b,  0xec,  0x60,  0x8d,
14126  0x30,  0x01,  0xfe,  0x4e,  0x1e,  0xfe,  0x48,  0x47,  0xfe,  0x7c,  0x13,  0x01,  0x0c,  0x06,  0x28,  0xfe,
14127  0x32,  0x13,  0x01,  0x43,  0x09,  0x9b,  0xfe,  0x68,  0x13,  0xfe,  0x26,  0x10,  0x13,  0x34,  0xfe,  0x4c,
14128  0x54,  0x7b,  0xec,  0x01,  0xfe,  0x4e,  0x1e,  0xfe,  0x48,  0x47,  0xfe,  0x54,  0x13,  0x01,  0x0c,  0x06,
14129  0x28,  0xa5,  0x01,  0x43,  0x09,  0x9b,  0xfe,  0x40,  0x13,  0x01,  0x0c,  0x06,  0x28,  0xf9,  0x1f,  0x7f,
14130  0x01,  0x0c,  0x06,  0x07,  0x4d,  0x1f,  0xfe,  0x0d,  0x00,  0x01,  0x42,  0x8f,  0xfe,  0xa4,  0x0e,  0x05,
14131  0x29,  0x32,  0x15,  0xfe,  0xe6,  0x00,  0x0f,  0xfe,  0x1c,  0x90,  0x04,  0xfe,  0x9c,  0x93,  0x3a,  0x0b,
14132  0x0e,  0x8b,  0x02,  0x1f,  0x7f,  0x01,  0x42,  0x05,  0x35,  0xfe,  0x42,  0x5b,  0x7d,  0x1d,  0xfe,  0x46,
14133  0x59,  0xfe,  0xbf,  0x57,  0xfe,  0x77,  0x57,  0x0f,  0xfe,  0x87,  0x80,  0x04,  0xfe,  0x87,  0x83,  0xfe,
14134  0xc9,  0x47,  0x0b,  0x0e,  0xd0,  0x65,  0x01,  0x0c,  0x06,  0x0d,  0xfe,  0x98,  0x13,  0x0f,  0xfe,  0x20,
14135  0x80,  0x04,  0xfe,  0xa0,  0x83,  0x33,  0x0b,  0x0e,  0x09,  0x1d,  0xfe,  0x84,  0x12,  0x01,  0x38,  0x06,
14136  0x07,  0xfe,  0x70,  0x13,  0x03,  0xfe,  0xa2,  0x00,  0x1e,  0x1b,  0xfe,  0xda,  0x05,  0xd0,  0x54,  0x01,
14137  0x38,  0x06,  0x0d,  0xfe,  0x58,  0x13,  0x03,  0xfe,  0xa0,  0x00,  0x1e,  0xfe,  0x50,  0x12,  0x5e,  0xff,
14138  0x02,  0x00,  0x10,  0x2f,  0xfe,  0x90,  0x05,  0x2a,  0x3c,  0xcc,  0xff,  0x02,  0x00,  0x10,  0x2f,  0xfe,
14139  0x9e,  0x05,  0x17,  0xfe,  0xf4,  0x05,  0x15,  0xfe,  0xe3,  0x00,  0x26,  0x01,  0x38,  0xfe,  0x4a,  0xf0,
14140  0xfe,  0xc0,  0x05,  0xfe,  0x49,  0xf0,  0xfe,  0xba,  0x05,  0x71,  0x2e,  0xfe,  0x21,  0x00,  0xf1,  0x2e,
14141  0xfe,  0x22,  0x00,  0xa2,  0x2e,  0x4a,  0xfe,  0x09,  0x48,  0xff,  0x02,  0x00,  0x10,  0x2f,  0xfe,  0xd0,
14142  0x05,  0x17,  0xfe,  0xf4,  0x05,  0xfe,  0xe2,  0x08,  0x01,  0x38,  0x06,  0xfe,  0x1c,  0x00,  0x4d,  0x01,
14143  0xa7,  0x2e,  0x07,  0x20,  0xe4,  0x47,  0xfe,  0x27,  0x01,  0x01,  0x0c,  0x06,  0x28,  0xfe,  0x24,  0x12,
14144  0x3e,  0x01,  0x84,  0x1f,  0x7f,  0x01,  0x0c,  0x06,  0x07,  0x4d,  0x1f,  0xfe,  0x0d,  0x00,  0x01,  0x42,
14145  0x8f,  0xfe,  0xa4,  0x0e,  0x05,  0x29,  0x03,  0xe6,  0x1e,  0xfe,  0xca,  0x13,  0x03,  0xb6,  0x1e,  0xfe,
14146  0x40,  0x12,  0x03,  0x66,  0x1e,  0xfe,  0x38,  0x13,  0x3e,  0x01,  0x84,  0x17,  0xfe,  0x72,  0x06,  0x0a,
14147  0x07,  0x01,  0x38,  0x06,  0x24,  0xfe,  0x02,  0x12,  0x4f,  0x01,  0xfe,  0x56,  0x19,  0x16,  0xfe,  0x68,
14148  0x06,  0x15,  0x82,  0x01,  0x41,  0x15,  0xe2,  0x03,  0x66,  0x8a,  0x10,  0x66,  0x03,  0x9a,  0x1e,  0xfe,
14149  0x70,  0x12,  0x03,  0x55,  0x1e,  0xfe,  0x68,  0x13,  0x01,  0xc6,  0x09,  0x12,  0x48,  0xfe,  0x92,  0x06,
14150  0x2e,  0x12,  0x01,  0xfe,  0xac,  0x1d,  0xfe,  0x43,  0x48,  0x62,  0x80,  0x13,  0x58,  0xff,  0x02,  0x00,
14151  0x57,  0x52,  0xad,  0x23,  0x3f,  0x4e,  0x62,  0x49,  0x3e,  0x01,  0x84,  0x17,  0xfe,  0xea,  0x06,  0x01,
14152  0x38,  0x06,  0x12,  0xf7,  0x45,  0x0a,  0x95,  0x01,  0xfe,  0x84,  0x19,  0x16,  0xfe,  0xe0,  0x06,  0x15,
14153  0x82,  0x01,  0x41,  0x15,  0xe2,  0x03,  0x55,  0x8a,  0x10,  0x55,  0x1c,  0x07,  0x01,  0x84,  0xfe,  0xae,
14154  0x10,  0x03,  0x6f,  0x1e,  0xfe,  0x9e,  0x13,  0x3e,  0x01,  0x84,  0x03,  0x9a,  0x1e,  0xfe,  0x1a,  0x12,
14155  0x01,  0x38,  0x06,  0x12,  0xfc,  0x01,  0xc6,  0x01,  0xfe,  0xac,  0x1d,  0xfe,  0x43,  0x48,  0x62,  0x80,
14156  0xf0,  0x45,  0x0a,  0x95,  0x03,  0xb6,  0x1e,  0xf8,  0x01,  0x38,  0x06,  0x24,  0x36,  0xfe,  0x02,  0xf6,
14157  0x07,  0x71,  0x78,  0x8c,  0x00,  0x4d,  0x62,  0x49,  0x3e,  0x2d,  0x93,  0x4e,  0xd0,  0x0d,  0x17,  0xfe,
14158  0x9a,  0x07,  0x01,  0xfe,  0xc0,  0x19,  0x16,  0xfe,  0x90,  0x07,  0x26,  0x20,  0x9e,  0x15,  0x82,  0x01,
14159  0x41,  0x15,  0xe2,  0x21,  0x9e,  0x09,  0x07,  0xfb,  0x03,  0xe6,  0xfe,  0x58,  0x57,  0x10,  0xe6,  0x05,
14160  0xfe,  0x2a,  0x06,  0x03,  0x6f,  0x8a,  0x10,  0x6f,  0x1c,  0x07,  0x01,  0x84,  0xfe,  0x9c,  0x32,  0x5f,
14161  0x75,  0x01,  0xa6,  0x86,  0x15,  0xfe,  0xe2,  0x00,  0x2f,  0xed,  0x2a,  0x3c,  0xfe,  0x0a,  0xf0,  0xfe,
14162  0xce,  0x07,  0xae,  0xfe,  0x96,  0x08,  0xfe,  0x06,  0xf0,  0xfe,  0x9e,  0x08,  0xaf,  0xa0,  0x05,  0x29,
14163  0x01,  0x0c,  0x06,  0x0d,  0xfe,  0x2e,  0x12,  0x14,  0x1d,  0x01,  0x08,  0x14,  0x00,  0x01,  0x08,  0x14,
14164  0x00,  0x01,  0x08,  0x14,  0x00,  0x01,  0x08,  0xfe,  0x99,  0xa4,  0x01,  0x08,  0x14,  0x00,  0x05,  0xfe,
14165  0xc6,  0x09,  0x01,  0x76,  0x06,  0x12,  0xfe,  0x3a,  0x12,  0x01,  0x0c,  0x06,  0x12,  0xfe,  0x30,  0x13,
14166  0x14,  0xfe,  0x1b,  0x00,  0x01,  0x08,  0x14,  0x00,  0x01,  0x08,  0x14,  0x00,  0x01,  0x08,  0x14,  0x00,
14167  0x01,  0x08,  0x14,  0x07,  0x01,  0x08,  0x14,  0x00,  0x05,  0xef,  0x7c,  0x4a,  0x78,  0x4f,  0x0f,  0xfe,
14168  0x9a,  0x81,  0x04,  0xfe,  0x9a,  0x83,  0xfe,  0xcb,  0x47,  0x0b,  0x0e,  0x2d,  0x28,  0x48,  0xfe,  0x6c,
14169  0x08,  0x0a,  0x28,  0xfe,  0x09,  0x6f,  0xca,  0xfe,  0xca,  0x45,  0xfe,  0x32,  0x12,  0x53,  0x63,  0x4e,
14170  0x7c,  0x97,  0x2f,  0xfe,  0x7e,  0x08,  0x2a,  0x3c,  0xfe,  0x0a,  0xf0,  0xfe,  0x6c,  0x08,  0xaf,  0xa0,
14171  0xae,  0xfe,  0x96,  0x08,  0x05,  0x29,  0x01,  0x41,  0x05,  0xed,  0x14,  0x24,  0x05,  0xed,  0xfe,  0x9c,
14172  0xf7,  0x9f,  0x01,  0xfe,  0xae,  0x1e,  0xfe,  0x18,  0x58,  0x01,  0xfe,  0xbe,  0x1e,  0xfe,  0x99,  0x58,
14173  0xfe,  0x78,  0x18,  0xfe,  0xf9,  0x18,  0x8e,  0xfe,  0x16,  0x09,  0x10,  0x6a,  0x22,  0x6b,  0x01,  0x0c,
14174  0x61,  0x54,  0x44,  0x21,  0x2c,  0x09,  0x1a,  0xf8,  0x77,  0x01,  0xfe,  0x7e,  0x1e,  0x47,  0x2c,  0x7a,
14175  0x30,  0xf0,  0xfe,  0x83,  0xe7,  0xfe,  0x3f,  0x00,  0x71,  0xfe,  0x03,  0x40,  0x01,  0x0c,  0x61,  0x65,
14176  0x44,  0x01,  0xc2,  0xc8,  0xfe,  0x1f,  0x40,  0x20,  0x6e,  0x01,  0xfe,  0x6a,  0x16,  0xfe,  0x08,  0x50,
14177  0xfe,  0x8a,  0x50,  0xfe,  0x44,  0x51,  0xfe,  0xc6,  0x51,  0xfe,  0x10,  0x10,  0x01,  0xfe,  0xce,  0x1e,
14178  0x01,  0xfe,  0xde,  0x1e,  0x10,  0x68,  0x22,  0x69,  0x01,  0xfe,  0xee,  0x1e,  0x01,  0xfe,  0xfe,  0x1e,
14179  0xfe,  0x40,  0x50,  0xfe,  0xc2,  0x50,  0x10,  0x4b,  0x22,  0x4c,  0xfe,  0x8a,  0x10,  0x01,  0x0c,  0x06,
14180  0x54,  0xfe,  0x50,  0x12,  0x01,  0xfe,  0xae,  0x1e,  0x01,  0xfe,  0xbe,  0x1e,  0x10,  0x6a,  0x22,  0x6b,
14181  0x01,  0x0c,  0x06,  0x65,  0x4e,  0x01,  0xc2,  0x0f,  0xfe,  0x1f,  0x80,  0x04,  0xfe,  0x9f,  0x83,  0x33,
14182  0x0b,  0x0e,  0x20,  0x6e,  0x0f,  0xfe,  0x44,  0x90,  0x04,  0xfe,  0xc4,  0x93,  0x3a,  0x0b,  0xfe,  0xc6,
14183  0x90,  0x04,  0xfe,  0xc6,  0x93,  0x79,  0x0b,  0x0e,  0x10,  0x6c,  0x22,  0x6d,  0x01,  0xfe,  0xce,  0x1e,
14184  0x01,  0xfe,  0xde,  0x1e,  0x10,  0x68,  0x22,  0x69,  0x0f,  0xfe,  0x40,  0x90,  0x04,  0xfe,  0xc0,  0x93,
14185  0x3a,  0x0b,  0xfe,  0xc2,  0x90,  0x04,  0xfe,  0xc2,  0x93,  0x79,  0x0b,  0x0e,  0x10,  0x4b,  0x22,  0x4c,
14186  0x10,  0x64,  0x22,  0x34,  0x01,  0x0c,  0x61,  0x24,  0x44,  0x37,  0x13,  0xfe,  0x4e,  0x11,  0x2f,  0xfe,
14187  0xde,  0x09,  0xfe,  0x9e,  0xf0,  0xfe,  0xf2,  0x09,  0xfe,  0x01,  0x48,  0x1b,  0x3c,  0x37,  0x88,  0xf5,
14188  0xd4,  0xfe,  0x1e,  0x0a,  0xd5,  0xfe,  0x42,  0x0a,  0xd2,  0xfe,  0x1e,  0x0a,  0xd3,  0xfe,  0x42,  0x0a,
14189  0xae,  0xfe,  0x12,  0x0a,  0xfe,  0x06,  0xf0,  0xfe,  0x18,  0x0a,  0xaf,  0xa0,  0x05,  0x29,  0x01,  0x41,
14190  0xfe,  0xc1,  0x10,  0x14,  0x24,  0xfe,  0xc1,  0x10,  0x01,  0x76,  0x06,  0x07,  0xfe,  0x14,  0x12,  0x01,
14191  0x76,  0x06,  0x0d,  0x5d,  0x01,  0x0c,  0x06,  0x0d,  0xfe,  0x74,  0x12,  0xfe,  0x2e,  0x1c,  0x05,  0xfe,
14192  0x1a,  0x0c,  0x01,  0x76,  0x06,  0x07,  0x5d,  0x01,  0x76,  0x06,  0x0d,  0x41,  0xfe,  0x2c,  0x1c,  0xfe,
14193  0xaa,  0xf0,  0xfe,  0xce,  0x0a,  0xfe,  0xac,  0xf0,  0xfe,  0x66,  0x0a,  0xfe,  0x92,  0x10,  0xc4,  0xf6,
14194  0xfe,  0xad,  0xf0,  0xfe,  0x72,  0x0a,  0x05,  0xfe,  0x1a,  0x0c,  0xc5,  0xfe,  0xe7,  0x10,  0xfe,  0x2b,
14195  0xf0,  0xbf,  0xfe,  0x6b,  0x18,  0x23,  0xfe,  0x00,  0xfe,  0xfe,  0x1c,  0x12,  0xac,  0xfe,  0xd2,  0xf0,
14196  0xbf,  0xfe,  0x76,  0x18,  0x23,  0x1d,  0x1b,  0xbf,  0x03,  0xe3,  0x23,  0x07,  0x1b,  0xbf,  0xd4,  0x5b,
14197  0xd5,  0x5b,  0xd2,  0x5b,  0xd3,  0x5b,  0xc4,  0xc5,  0xfe,  0xa9,  0x10,  0x75,  0x5e,  0x32,  0x1f,  0x7f,
14198  0x01,  0x42,  0x19,  0xfe,  0x35,  0x00,  0xfe,  0x01,  0xf0,  0x70,  0x19,  0x98,  0x05,  0x70,  0xfe,  0x74,
14199  0x18,  0x23,  0xfe,  0x00,  0xf8,  0x1b,  0x5b,  0x7d,  0x12,  0x01,  0xfe,  0x78,  0x0f,  0x4d,  0x01,  0xfe,
14200  0x96,  0x1a,  0x21,  0x30,  0x77,  0x7d,  0x1d,  0x05,  0x5b,  0x01,  0x0c,  0x06,  0x0d,  0x2b,  0xfe,  0xe2,
14201  0x0b,  0x01,  0x0c,  0x06,  0x54,  0xfe,  0xa6,  0x12,  0x01,  0x0c,  0x06,  0x24,  0xfe,  0x88,  0x13,  0x21,
14202  0x6e,  0xc7,  0x01,  0xfe,  0x1e,  0x1f,  0x0f,  0xfe,  0x83,  0x80,  0x04,  0xfe,  0x83,  0x83,  0xfe,  0xc9,
14203  0x47,  0x0b,  0x0e,  0xfe,  0xc8,  0x44,  0xfe,  0x42,  0x13,  0x0f,  0xfe,  0x04,  0x91,  0x04,  0xfe,  0x84,
14204  0x93,  0xfe,  0xca,  0x57,  0x0b,  0xfe,  0x86,  0x91,  0x04,  0xfe,  0x86,  0x93,  0xfe,  0xcb,  0x57,  0x0b,
14205  0x0e,  0x7a,  0x30,  0xfe,  0x40,  0x59,  0xfe,  0xc1,  0x59,  0x8e,  0x40,  0x03,  0x6a,  0x3b,  0x6b,  0x10,
14206  0x97,  0x22,  0x98,  0xd9,  0x6a,  0xda,  0x6b,  0x01,  0xc2,  0xc8,  0x7a,  0x30,  0x20,  0x6e,  0xdb,  0x64,
14207  0xdc,  0x34,  0x91,  0x6c,  0x7e,  0x6d,  0xfe,  0x44,  0x55,  0xfe,  0xe5,  0x55,  0xfe,  0x04,  0xfa,  0x64,
14208  0xfe,  0x05,  0xfa,  0x34,  0x01,  0xfe,  0x6a,  0x16,  0xa3,  0x26,  0x10,  0x97,  0x10,  0x98,  0x91,  0x6c,
14209  0x7e,  0x6d,  0xfe,  0x14,  0x10,  0x01,  0x0c,  0x06,  0x24,  0x1b,  0x40,  0x91,  0x4b,  0x7e,  0x4c,  0x01,
14210  0x0c,  0x06,  0xfe,  0xf7,  0x00,  0x44,  0x03,  0x68,  0x3b,  0x69,  0xfe,  0x10,  0x58,  0xfe,  0x91,  0x58,
14211  0xfe,  0x14,  0x59,  0xfe,  0x95,  0x59,  0x05,  0x5b,  0x01,  0x0c,  0x06,  0x24,  0x1b,  0x40,  0x01,  0x0c,
14212  0x06,  0xfe,  0xf7,  0x00,  0x44,  0x78,  0x01,  0xfe,  0x8e,  0x1e,  0x4f,  0x0f,  0xfe,  0x10,  0x90,  0x04,
14213  0xfe,  0x90,  0x93,  0x3a,  0x0b,  0xfe,  0x92,  0x90,  0x04,  0xfe,  0x92,  0x93,  0x79,  0x0b,  0x0e,  0xfe,
14214  0xbd,  0x10,  0x01,  0x43,  0x09,  0xbb,  0x1b,  0xfe,  0x6e,  0x0a,  0x15,  0xbb,  0x01,  0x0c,  0x06,  0x0d,
14215  0xfe,  0x14,  0x13,  0x03,  0x4b,  0x3b,  0x4c,  0x8e,  0xfe,  0x6e,  0x0a,  0xfe,  0x0c,  0x58,  0xfe,  0x8d,
14216  0x58,  0x05,  0x5b,  0x26,  0x3e,  0x0f,  0xfe,  0x19,  0x80,  0x04,  0xfe,  0x99,  0x83,  0x33,  0x0b,  0x0e,
14217  0xfe,  0xe5,  0x10,  0x01,  0x0c,  0x06,  0x0d,  0xfe,  0x1a,  0x12,  0xfe,  0x6c,  0x19,  0xfe,  0x19,  0x41,
14218  0xfe,  0x6b,  0x18,  0xac,  0xfe,  0xd1,  0xf0,  0xef,  0x1f,  0x92,  0x01,  0x42,  0x19,  0xfe,  0x44,  0x00,
14219  0xfe,  0x90,  0x10,  0xfe,  0x6c,  0x19,  0xd9,  0x4b,  0xfe,  0xed,  0x19,  0xda,  0x4c,  0xfe,  0x0c,  0x51,
14220  0xfe,  0x8e,  0x51,  0xfe,  0x6b,  0x18,  0x23,  0xfe,  0x00,  0xff,  0x31,  0xfe,  0x76,  0x10,  0xac,  0xfe,
14221  0xd2,  0xf0,  0xfe,  0xba,  0x0c,  0xfe,  0x76,  0x18,  0x23,  0x1d,  0x5d,  0x03,  0xe3,  0x23,  0x07,  0xfe,
14222  0x08,  0x13,  0x19,  0xfe,  0x16,  0x00,  0x05,  0x70,  0xfe,  0xd1,  0xf0,  0xfe,  0xcc,  0x0c,  0x1f,  0x92,
14223  0x01,  0x42,  0x19,  0xfe,  0x17,  0x00,  0x5c,  0xfe,  0xce,  0xf0,  0xfe,  0xd2,  0x0c,  0xfe,  0x3e,  0x10,
14224  0xfe,  0xcd,  0xf0,  0xfe,  0xde,  0x0c,  0x19,  0xfe,  0x22,  0x00,  0x05,  0x70,  0xfe,  0xcb,  0xf0,  0xfe,
14225  0xea,  0x0c,  0x19,  0xfe,  0x24,  0x00,  0x05,  0x70,  0xfe,  0xd0,  0xf0,  0xfe,  0xf4,  0x0c,  0x19,  0x94,
14226  0xfe,  0x1c,  0x10,  0xfe,  0xcf,  0xf0,  0xfe,  0xfe,  0x0c,  0x19,  0x4a,  0xf3,  0xfe,  0xcc,  0xf0,  0xef,
14227  0x01,  0x76,  0x06,  0x24,  0x4d,  0x19,  0xfe,  0x12,  0x00,  0x37,  0x13,  0xfe,  0x4e,  0x11,  0x2f,  0xfe,
14228  0x16,  0x0d,  0xfe,  0x9e,  0xf0,  0xfe,  0x2a,  0x0d,  0xfe,  0x01,  0x48,  0x1b,  0x3c,  0x37,  0x88,  0xf5,
14229  0xd4,  0x29,  0xd5,  0x29,  0xd2,  0x29,  0xd3,  0x29,  0x37,  0xfe,  0x9c,  0x32,  0x2f,  0xfe,  0x3e,  0x0d,
14230  0x2a,  0x3c,  0xae,  0xfe,  0x62,  0x0d,  0xaf,  0xa0,  0xd4,  0x9f,  0xd5,  0x9f,  0xd2,  0x9f,  0xd3,  0x9f,
14231  0x05,  0x29,  0x01,  0x41,  0xfe,  0xd3,  0x10,  0x15,  0xfe,  0xe8,  0x00,  0xc4,  0xc5,  0x75,  0xd7,  0x99,
14232  0xd8,  0x9c,  0xfe,  0x89,  0xf0,  0x29,  0x27,  0x25,  0xbe,  0xd7,  0x99,  0xd8,  0x9c,  0x2f,  0xfe,  0x8c,
14233  0x0d,  0x16,  0x29,  0x27,  0x25,  0xbd,  0xfe,  0x01,  0x48,  0xa4,  0x19,  0xfe,  0x42,  0x00,  0x05,  0x70,
14234  0x90,  0x07,  0xfe,  0x81,  0x49,  0x1b,  0xfe,  0x64,  0x0e,  0x01,  0x0c,  0x06,  0x0d,  0xfe,  0x44,  0x13,
14235  0x19,  0x00,  0x2d,  0x0d,  0xfe,  0x54,  0x12,  0x2d,  0xfe,  0x28,  0x00,  0x2b,  0xfe,  0xda,  0x0e,  0x0a,
14236  0x57,  0x01,  0x18,  0x09,  0x00,  0x36,  0x46,  0xfe,  0x28,  0x00,  0xfe,  0xfa,  0x10,  0x01,  0xfe,  0xf4,
14237  0x1c,  0x01,  0xfe,  0x00,  0x1d,  0x0a,  0xba,  0x01,  0xfe,  0x58,  0x10,  0x40,  0x15,  0x56,  0x01,  0x85,
14238  0x05,  0x35,  0x19,  0xfe,  0x44,  0x00,  0x2d,  0x0d,  0xf7,  0x46,  0x0d,  0xfe,  0xcc,  0x10,  0x01,  0xa7,
14239  0x46,  0x0d,  0xfe,  0xc2,  0x10,  0x01,  0xa7,  0x0f,  0xfe,  0x19,  0x82,  0x04,  0xfe,  0x99,  0x83,  0xfe,
14240  0xcc,  0x47,  0x0b,  0x0e,  0xfe,  0x34,  0x46,  0xa5,  0x46,  0x0d,  0x19,  0xfe,  0x43,  0x00,  0xfe,  0xa2,
14241  0x10,  0x01,  0x0c,  0x61,  0x0d,  0x44,  0x01,  0xfe,  0xf4,  0x1c,  0x01,  0xfe,  0x00,  0x1d,  0x40,  0x15,
14242  0x56,  0x01,  0x85,  0x7d,  0x0d,  0x40,  0x51,  0x01,  0xfe,  0x9e,  0x1e,  0x05,  0xfe,  0x3a,  0x03,  0x01,
14243  0x0c,  0x06,  0x0d,  0x5d,  0x46,  0x0d,  0x19,  0x00,  0xfe,  0x62,  0x10,  0x01,  0x76,  0x06,  0x12,  0xfe,
14244  0x5c,  0x12,  0x01,  0x0c,  0x06,  0x12,  0xfe,  0x52,  0x13,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,
14245  0x8e,  0x0e,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,  0x94,  0x0e,  0x01,  0x0c,  0x61,  0x12,  0x44,
14246  0xfe,  0x9f,  0x10,  0x19,  0xfe,  0x15,  0x00,  0xfe,  0x04,  0xe6,  0x0d,  0x4f,  0xfe,  0x2e,  0x10,  0x19,
14247  0xfe,  0x13,  0x00,  0xfe,  0x10,  0x10,  0x19,  0xfe,  0x47,  0x00,  0xf1,  0x19,  0xfe,  0x41,  0x00,  0xa2,
14248  0x19,  0xfe,  0x24,  0x00,  0x86,  0xc4,  0xc5,  0x75,  0x03,  0x81,  0x1e,  0x2b,  0xea,  0x4f,  0xfe,  0x04,
14249  0xe6,  0x12,  0xfe,  0x9d,  0x41,  0xfe,  0x1c,  0x42,  0x40,  0x01,  0xf4,  0x05,  0x35,  0xfe,  0x12,  0x1c,
14250  0x1f,  0x0d,  0x47,  0xb5,  0xc3,  0x1f,  0xfe,  0x31,  0x00,  0x47,  0xb8,  0x01,  0xfe,  0xd4,  0x11,  0x05,
14251  0xe9,  0x51,  0xfe,  0x06,  0xec,  0xe0,  0xfe,  0x0e,  0x47,  0x46,  0x28,  0xfe,  0xce,  0x45,  0x31,  0x51,
14252  0xfe,  0x06,  0xea,  0xe0,  0xfe,  0x47,  0x4b,  0x45,  0xfe,  0x75,  0x57,  0x03,  0x67,  0xfe,  0x98,  0x56,
14253  0xfe,  0x38,  0x12,  0x0a,  0x5a,  0x01,  0x18,  0xfe,  0x44,  0x48,  0x60,  0x01,  0x0c,  0x06,  0x28,  0xfe,
14254  0x18,  0x13,  0x0a,  0x57,  0x01,  0x18,  0x3e,  0xfe,  0x41,  0x58,  0x0a,  0xba,  0xfe,  0xfa,  0x14,  0xfe,
14255  0x49,  0x54,  0xb0,  0xfe,  0x5e,  0x0f,  0x05,  0xfe,  0x3a,  0x03,  0x0a,  0x67,  0xfe,  0xe0,  0x14,  0xfe,
14256  0x0e,  0x47,  0x46,  0x28,  0xfe,  0xce,  0x45,  0x31,  0x51,  0xfe,  0xce,  0x47,  0xfe,  0xad,  0x13,  0x05,
14257  0x35,  0x21,  0x2c,  0x09,  0x1a,  0xfe,  0x98,  0x12,  0x26,  0x20,  0x96,  0x20,  0xe7,  0xfe,  0x08,  0x1c,
14258  0xfe,  0x7c,  0x19,  0xfe,  0xfd,  0x19,  0xfe,  0x0a,  0x1c,  0x03,  0xe5,  0xfe,  0x48,  0x55,  0xa5,  0x3b,
14259  0xfe,  0x62,  0x01,  0xfe,  0xc9,  0x55,  0x31,  0xfe,  0x74,  0x10,  0x01,  0xfe,  0xf0,  0x1a,  0x03,  0xfe,
14260  0x38,  0x01,  0x3b,  0xfe,  0x3a,  0x01,  0x8e,  0xfe,  0x1e,  0x10,  0xfe,  0x02,  0xec,  0xe7,  0x53,  0x00,
14261  0x36,  0xfe,  0x04,  0xec,  0x2c,  0x60,  0xfe,  0x05,  0xf6,  0xfe,  0x34,  0x01,  0x01,  0xfe,  0x62,  0x1b,
14262  0x01,  0xfe,  0xce,  0x1e,  0xb2,  0x11,  0xfe,  0x18,  0x13,  0xca,  0xfe,  0x02,  0xea,  0xe7,  0x53,  0x92,
14263  0xfe,  0xc3,  0x13,  0x1f,  0x12,  0x47,  0xb5,  0xc3,  0xfe,  0x2a,  0x10,  0x03,  0xfe,  0x38,  0x01,  0x23,
14264  0xfe,  0xf0,  0xff,  0x10,  0xe5,  0x03,  0xfe,  0x3a,  0x01,  0x10,  0xfe,  0x62,  0x01,  0x01,  0xfe,  0x1e,
14265  0x1e,  0x20,  0x2c,  0x15,  0x56,  0x01,  0xfe,  0x9e,  0x1e,  0x13,  0x07,  0x02,  0x26,  0x02,  0x21,  0x96,
14266  0xc7,  0x20,  0x96,  0x09,  0x92,  0xfe,  0x79,  0x13,  0x1f,  0x1d,  0x47,  0xb5,  0xc3,  0xfe,  0xe1,  0x10,
14267  0xcf,  0xfe,  0x03,  0xdc,  0xfe,  0x73,  0x57,  0xfe,  0x80,  0x5d,  0x02,  0xcf,  0xfe,  0x03,  0xdc,  0xfe,
14268  0x5b,  0x57,  0xfe,  0x80,  0x5d,  0x02,  0xfe,  0x03,  0x57,  0xcf,  0x26,  0xfe,  0x00,  0xcc,  0x02,  0xfe,
14269  0x03,  0x57,  0xcf,  0x89,  0x02,  0x01,  0x0c,  0x06,  0x4a,  0xfe,  0x4e,  0x13,  0x0f,  0xfe,  0x1c,  0x80,
14270  0x04,  0xfe,  0x9c,  0x83,  0x33,  0x0b,  0x0e,  0x09,  0x07,  0xfe,  0x3a,  0x13,  0x0f,  0xfe,  0x1e,  0x80,
14271  0x04,  0xfe,  0x9e,  0x83,  0x33,  0x0b,  0x0e,  0xfe,  0x2a,  0x13,  0x0f,  0xfe,  0x1d,  0x80,  0x04,  0xfe,
14272  0x9d,  0x83,  0xfe,  0xf9,  0x13,  0x0e,  0xfe,  0x1c,  0x13,  0x01,  0xfe,  0xee,  0x1e,  0xac,  0xfe,  0x14,
14273  0x13,  0x01,  0xfe,  0xfe,  0x1e,  0xfe,  0x81,  0x58,  0xfa,  0x01,  0xfe,  0x0e,  0x1f,  0xfe,  0x30,  0xf4,
14274  0x0d,  0xfe,  0x3c,  0x50,  0xa2,  0x01,  0xfe,  0x92,  0x1b,  0x01,  0x43,  0x09,  0x56,  0xfb,  0x01,  0xfe,
14275  0xc8,  0x1a,  0x01,  0x0c,  0x06,  0x28,  0xa4,  0x01,  0xfe,  0xf4,  0x1c,  0x01,  0xfe,  0x00,  0x1d,  0x15,
14276  0xfe,  0xe9,  0x00,  0x01,  0x0c,  0x06,  0x4a,  0xfe,  0x4e,  0x13,  0x01,  0xfe,  0x22,  0x1b,  0xfe,  0x1e,
14277  0x1c,  0x0f,  0xfe,  0x14,  0x90,  0x04,  0xfe,  0x94,  0x93,  0x3a,  0x0b,  0xfe,  0x96,  0x90,  0x04,  0xfe,
14278  0x96,  0x93,  0x79,  0x0b,  0x0e,  0x10,  0xfe,  0x64,  0x01,  0x22,  0xfe,  0x66,  0x01,  0x01,  0x0c,  0x06,
14279  0x65,  0xf9,  0x0f,  0xfe,  0x03,  0x80,  0x04,  0xfe,  0x83,  0x83,  0x33,  0x0b,  0x0e,  0x77,  0xfe,  0x01,
14280  0xec,  0x2c,  0xfe,  0x80,  0x40,  0x20,  0x2c,  0x7a,  0x30,  0x15,  0xdf,  0x40,  0x21,  0x2c,  0xfe,  0x00,
14281  0x40,  0x8d,  0x2c,  0x02,  0xfe,  0x08,  0x1c,  0x03,  0xfe,  0xac,  0x00,  0xfe,  0x06,  0x58,  0x03,  0xfe,
14282  0xae,  0x00,  0xfe,  0x07,  0x58,  0x03,  0xfe,  0xb0,  0x00,  0xfe,  0x08,  0x58,  0x03,  0xfe,  0xb2,  0x00,
14283  0xfe,  0x09,  0x58,  0xfe,  0x0a,  0x1c,  0x2e,  0x49,  0x20,  0xe0,  0x26,  0x10,  0x66,  0x10,  0x55,  0x10,
14284  0x6f,  0x13,  0x57,  0x52,  0x4f,  0x1c,  0x28,  0xfe,  0x90,  0x4d,  0xfe,  0x91,  0x54,  0x2b,  0xfe,  0x88,
14285  0x11,  0x46,  0x1a,  0x13,  0x5a,  0x52,  0x1c,  0x4a,  0xfe,  0x90,  0x4d,  0xfe,  0x91,  0x54,  0x2b,  0xfe,
14286  0x9e,  0x11,  0x2e,  0x1a,  0x20,  0x2c,  0x90,  0x34,  0x60,  0x21,  0x2c,  0xfe,  0x00,  0x40,  0x8d,  0x2c,
14287  0x15,  0xdf,  0xfe,  0x14,  0x56,  0xfe,  0xd6,  0xf0,  0xfe,  0xb2,  0x11,  0xfe,  0x12,  0x1c,  0x75,  0xfe,
14288  0x14,  0x1c,  0xfe,  0x10,  0x1c,  0xfe,  0x18,  0x1c,  0x02,  0x51,  0xfe,  0x0c,  0x14,  0xfe,  0x0e,  0x47,
14289  0xfe,  0x07,  0xe6,  0x28,  0xfe,  0xce,  0x47,  0xfe,  0xf5,  0x13,  0x02,  0x01,  0xa7,  0x90,  0x34,  0x60,
14290  0xfe,  0x06,  0x80,  0xfe,  0x48,  0x47,  0xfe,  0x42,  0x13,  0xfe,  0x02,  0x80,  0x09,  0x56,  0xfe,  0x34,
14291  0x13,  0x0a,  0x5a,  0x01,  0x18,  0xcb,  0xfe,  0x36,  0x12,  0xfe,  0x41,  0x48,  0xfe,  0x45,  0x48,  0x01,
14292  0xfe,  0xb2,  0x16,  0xfe,  0x00,  0xcc,  0xcb,  0xfe,  0xf3,  0x13,  0x3f,  0x89,  0x09,  0x1a,  0xa5,  0x0a,
14293  0x9d,  0x01,  0x18,  0xfe,  0x80,  0x5c,  0x01,  0x85,  0xf2,  0x09,  0x9b,  0xa4,  0xfe,  0x14,  0x56,  0xfe,
14294  0xd6,  0xf0,  0xfe,  0xec,  0x11,  0x02,  0xfe,  0x44,  0x58,  0x77,  0xfe,  0x01,  0xec,  0xb8,  0xfe,  0x9e,
14295  0x40,  0xfe,  0x9d,  0xe7,  0x00,  0xfe,  0x9c,  0xe7,  0x12,  0x8d,  0x30,  0x01,  0xf4,  0xfe,  0xdd,  0x10,
14296  0x37,  0xd7,  0x99,  0xd8,  0x9c,  0x27,  0x25,  0xee,  0x09,  0x12,  0xfe,  0x48,  0x12,  0x09,  0x0d,  0xfe,
14297  0x56,  0x12,  0x09,  0x1d,  0xfe,  0x30,  0x12,  0x09,  0xdd,  0x1b,  0xfe,  0xc4,  0x13,  0x09,  0xfe,  0x23,
14298  0x00,  0x1b,  0xfe,  0xd0,  0x13,  0x09,  0x07,  0x1b,  0xfe,  0x34,  0x14,  0x09,  0x24,  0xfe,  0x12,  0x12,
14299  0x09,  0x00,  0x1b,  0x29,  0x1f,  0xdd,  0x01,  0x42,  0xa1,  0x32,  0x01,  0x08,  0xae,  0x41,  0x02,  0x32,
14300  0xfe,  0x62,  0x08,  0x0a,  0xe1,  0x01,  0xfe,  0x58,  0x10,  0x15,  0x9b,  0x05,  0x35,  0x32,  0x01,  0x43,
14301  0x09,  0xbb,  0xfe,  0xd7,  0x13,  0x91,  0x4b,  0x7e,  0x4c,  0x8e,  0xfe,  0x80,  0x13,  0x01,  0x0c,  0x06,
14302  0x54,  0xfe,  0x72,  0x12,  0xdb,  0x64,  0xdc,  0x34,  0xfe,  0x44,  0x55,  0xfe,  0xe5,  0x55,  0xb0,  0xfe,
14303  0x4a,  0x13,  0x21,  0x6e,  0xfe,  0x26,  0x13,  0x03,  0x97,  0x3b,  0x98,  0x8e,  0xfe,  0xb6,  0x0e,  0x10,
14304  0x6a,  0x22,  0x6b,  0x26,  0x10,  0x97,  0x10,  0x98,  0x01,  0xc2,  0x2e,  0x49,  0x88,  0x20,  0x6e,  0x01,
14305  0xfe,  0x6a,  0x16,  0xdb,  0x64,  0xdc,  0x34,  0xfe,  0x04,  0x55,  0xfe,  0xa5,  0x55,  0xfe,  0x04,  0xfa,
14306  0x64,  0xfe,  0x05,  0xfa,  0x34,  0xfe,  0x8f,  0x10,  0x03,  0x6c,  0x3b,  0x6d,  0xfe,  0x40,  0x56,  0xfe,
14307  0xe1,  0x56,  0x10,  0x6c,  0x22,  0x6d,  0x71,  0xdb,  0x64,  0xdc,  0x34,  0xfe,  0x44,  0x55,  0xfe,  0xe5,
14308  0x55,  0x03,  0x68,  0x3b,  0x69,  0xfe,  0x00,  0x56,  0xfe,  0xa1,  0x56,  0x10,  0x68,  0x22,  0x69,  0x01,
14309  0x0c,  0x06,  0x54,  0xf9,  0x21,  0x6e,  0xfe,  0x1f,  0x40,  0x03,  0x6a,  0x3b,  0x6b,  0xfe,  0x2c,  0x50,
14310  0xfe,  0xae,  0x50,  0x03,  0x6c,  0x3b,  0x6d,  0xfe,  0x44,  0x50,  0xfe,  0xc6,  0x50,  0x03,  0x68,  0x3b,
14311  0x69,  0xfe,  0x08,  0x50,  0xfe,  0x8a,  0x50,  0x03,  0x4b,  0x3b,  0x4c,  0xfe,  0x40,  0x50,  0xfe,  0xc2,
14312  0x50,  0x05,  0x73,  0x2e,  0x07,  0x20,  0x9e,  0x05,  0x72,  0x32,  0x01,  0x08,  0x16,  0x3d,  0x27,  0x25,
14313  0xee,  0x09,  0x07,  0x2b,  0x3d,  0x01,  0x43,  0x09,  0xbb,  0x2b,  0x72,  0x01,  0xa6,  0x23,  0x3f,  0x1b,
14314  0x3d,  0x01,  0x0c,  0x06,  0x0d,  0xfe,  0x1e,  0x13,  0x91,  0x4b,  0x7e,  0x4c,  0xfe,  0x0a,  0x55,  0x31,
14315  0xfe,  0x8b,  0x55,  0xd9,  0x4b,  0xda,  0x4c,  0xfe,  0x0c,  0x51,  0xfe,  0x8e,  0x51,  0x05,  0x72,  0x01,
14316  0xfe,  0x8e,  0x1e,  0xca,  0xfe,  0x19,  0x41,  0x05,  0x72,  0x32,  0x01,  0x08,  0x2a,  0x3c,  0x16,  0xc0,
14317  0x27,  0x25,  0xbe,  0x2d,  0x1d,  0xc0,  0x2d,  0x0d,  0x83,  0x2d,  0x7f,  0x1b,  0xfe,  0x66,  0x15,  0x05,
14318  0x3d,  0x01,  0x08,  0x2a,  0x3c,  0x16,  0xc0,  0x27,  0x25,  0xbd,  0x09,  0x1d,  0x2b,  0x3d,  0x01,  0x08,
14319  0x16,  0xc0,  0x27,  0x25,  0xfe,  0xe8,  0x09,  0xfe,  0xc2,  0x49,  0x50,  0x03,  0xb6,  0x1e,  0x83,  0x01,
14320  0x38,  0x06,  0x24,  0x31,  0xa1,  0xfe,  0xbb,  0x45,  0x2d,  0x00,  0xa4,  0x46,  0x07,  0x90,  0x3f,  0x01,
14321  0xfe,  0xf8,  0x15,  0x01,  0xa6,  0x86,  0xfe,  0x4b,  0x45,  0xfe,  0x20,  0x13,  0x01,  0x43,  0x09,  0x82,
14322  0xfe,  0x16,  0x13,  0x03,  0x9a,  0x1e,  0x5d,  0x03,  0x55,  0x1e,  0x31,  0x5e,  0x05,  0x72,  0xfe,  0xc0,
14323  0x5d,  0x01,  0xa7,  0xfe,  0x03,  0x17,  0x03,  0x66,  0x8a,  0x10,  0x66,  0x5e,  0x32,  0x01,  0x08,  0x17,
14324  0x73,  0x01,  0xfe,  0x56,  0x19,  0x05,  0x73,  0x01,  0x08,  0x2a,  0x3c,  0x16,  0x3d,  0x27,  0x25,  0xbd,
14325  0x09,  0x07,  0x2b,  0x3d,  0x01,  0xfe,  0xbe,  0x16,  0xfe,  0x42,  0x58,  0xfe,  0xe8,  0x14,  0x01,  0xa6,
14326  0x86,  0xfe,  0x4a,  0xf4,  0x0d,  0x1b,  0x3d,  0xfe,  0x4a,  0xf4,  0x07,  0xfe,  0x0e,  0x12,  0x01,  0x43,
14327  0x09,  0x82,  0x4e,  0x05,  0x72,  0x03,  0x55,  0x8a,  0x10,  0x55,  0x5e,  0x32,  0x01,  0x08,  0x17,  0x73,
14328  0x01,  0xfe,  0x84,  0x19,  0x05,  0x73,  0x01,  0x08,  0x2a,  0x3c,  0x16,  0x3d,  0x27,  0x25,  0xbd,  0x09,
14329  0x12,  0x2b,  0x3d,  0x01,  0xfe,  0xe8,  0x17,  0x8b,  0xfe,  0xaa,  0x14,  0xfe,  0xb6,  0x14,  0x86,  0xa8,
14330  0xb2,  0x0d,  0x1b,  0x3d,  0xb2,  0x07,  0xfe,  0x0e,  0x12,  0x01,  0x43,  0x09,  0x82,  0x4e,  0x05,  0x72,
14331  0x03,  0x6f,  0x8a,  0x10,  0x6f,  0x5e,  0x32,  0x01,  0x08,  0x17,  0x73,  0x01,  0xfe,  0xc0,  0x19,  0x05,
14332  0x73,  0x13,  0x07,  0x2f,  0xfe,  0xcc,  0x15,  0x17,  0xfe,  0xe2,  0x15,  0x5f,  0xcc,  0x01,  0x08,  0x26,
14333  0x5f,  0x02,  0x8f,  0xfe,  0xde,  0x15,  0x2a,  0xfe,  0xde,  0x15,  0x16,  0xfe,  0xcc,  0x15,  0x5e,  0x32,
14334  0x01,  0x08,  0xfe,  0xd5,  0x10,  0x13,  0x58,  0xff,  0x02,  0x00,  0x57,  0x52,  0xad,  0x23,  0xfe,  0xff,
14335  0x7f,  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x02,  0x13,  0x58,  0xff,  0x02,  0x00,  0x57,  0x52,  0xad,
14336  0x23,  0x3f,  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x02,  0x13,  0x58,  0xff,  0x02,  0x00,  0x57,  0x52,
14337  0xad,  0x02,  0x13,  0x58,  0xff,  0x02,  0x00,  0x57,  0x52,  0xfe,  0x00,  0x5e,  0x02,  0x13,  0x58,  0xff,
14338  0x02,  0x00,  0x57,  0x52,  0xad,  0xfe,  0x0b,  0x58,  0x02,  0x0a,  0x66,  0x01,  0x5c,  0x0a,  0x55,  0x01,
14339  0x5c,  0x0a,  0x6f,  0x01,  0x5c,  0x02,  0x01,  0xfe,  0x1e,  0x1f,  0x23,  0x1a,  0xff,  0x03,  0x00,  0x54,
14340  0xfe,  0x00,  0xf4,  0x24,  0x52,  0x0f,  0xfe,  0x00,  0x7c,  0x04,  0xfe,  0x07,  0x7c,  0x3a,  0x0b,  0x0e,
14341  0xfe,  0x00,  0x71,  0xfe,  0xf9,  0x18,  0xfe,  0x7a,  0x19,  0xfe,  0xfb,  0x19,  0xfe,  0x1a,  0xf7,  0x00,
14342  0xfe,  0x1b,  0xf7,  0x00,  0x7a,  0x30,  0x10,  0x68,  0x22,  0x69,  0xd9,  0x6c,  0xda,  0x6d,  0x02,  0xfe,
14343  0x62,  0x08,  0xfe,  0x82,  0x4a,  0xfe,  0xe1,  0x1a,  0xfe,  0x83,  0x5a,  0x77,  0x02,  0x01,  0xc6,  0xfe,
14344  0x42,  0x48,  0x4f,  0x50,  0x45,  0x01,  0x08,  0x16,  0xfe,  0xe0,  0x17,  0x27,  0x25,  0xbe,  0x01,  0x08,
14345  0x16,  0xfe,  0xe0,  0x17,  0x27,  0x25,  0xfe,  0xe8,  0x0a,  0xfe,  0xc1,  0x59,  0x03,  0x9a,  0x1e,  0xfe,
14346  0xda,  0x12,  0x01,  0x38,  0x06,  0x12,  0xfe,  0xd0,  0x13,  0x26,  0x53,  0x12,  0x48,  0xfe,  0x08,  0x17,
14347  0xd1,  0x12,  0x53,  0x12,  0xfe,  0x1e,  0x13,  0x2d,  0xb4,  0x7b,  0xfe,  0x26,  0x17,  0x4d,  0x13,  0x07,
14348  0x1c,  0xb4,  0x90,  0x04,  0xfe,  0x78,  0x10,  0xff,  0x02,  0x83,  0x55,  0xf1,  0xff,  0x02,  0x83,  0x55,
14349  0x53,  0x1d,  0xfe,  0x12,  0x13,  0xd6,  0xfe,  0x30,  0x00,  0xb0,  0xfe,  0x80,  0x17,  0x1c,  0x63,  0x13,
14350  0x07,  0xfe,  0x56,  0x10,  0x53,  0x0d,  0xfe,  0x16,  0x13,  0xd6,  0xfe,  0x64,  0x00,  0xb0,  0xfe,  0x80,
14351  0x17,  0x0a,  0xfe,  0x64,  0x00,  0x1c,  0x94,  0x13,  0x07,  0xfe,  0x28,  0x10,  0x53,  0x07,  0xfe,  0x60,
14352  0x13,  0xd6,  0xfe,  0xc8,  0x00,  0xb0,  0xfe,  0x80,  0x17,  0x0a,  0xfe,  0xc8,  0x00,  0x1c,  0x95,  0x13,
14353  0x07,  0x71,  0xd6,  0xfe,  0x90,  0x01,  0x48,  0xfe,  0x8c,  0x17,  0x45,  0xf3,  0xfe,  0x43,  0xf4,  0x96,
14354  0xfe,  0x56,  0xf0,  0xfe,  0x9e,  0x17,  0xfe,  0x04,  0xf4,  0x58,  0xfe,  0x43,  0xf4,  0x94,  0xf6,  0x8b,
14355  0x01,  0xfe,  0x24,  0x16,  0x23,  0x3f,  0xfc,  0xa8,  0x8c,  0x49,  0x48,  0xfe,  0xda,  0x17,  0x62,  0x49,
14356  0xfe,  0x1c,  0x10,  0xa8,  0x8c,  0x80,  0x48,  0xfe,  0xda,  0x17,  0x62,  0x80,  0x71,  0x50,  0x26,  0xfe,
14357  0x4d,  0xf4,  0x00,  0xf7,  0x45,  0x13,  0x07,  0xfe,  0xb4,  0x56,  0xfe,  0xc3,  0x58,  0x02,  0x50,  0x13,
14358  0x0d,  0x02,  0x50,  0x3e,  0x78,  0x4f,  0x45,  0x01,  0x08,  0x16,  0xa9,  0x27,  0x25,  0xbe,  0xfe,  0x03,
14359  0xea,  0xfe,  0x7e,  0x01,  0x01,  0x08,  0x16,  0xa9,  0x27,  0x25,  0xfe,  0xe9,  0x0a,  0x01,  0x08,  0x16,
14360  0xa9,  0x27,  0x25,  0xfe,  0xe9,  0x0a,  0xfe,  0x05,  0xea,  0xfe,  0x7f,  0x01,  0x01,  0x08,  0x16,  0xa9,
14361  0x27,  0x25,  0xfe,  0x69,  0x09,  0xfe,  0x02,  0xea,  0xfe,  0x80,  0x01,  0x01,  0x08,  0x16,  0xa9,  0x27,
14362  0x25,  0xfe,  0xe8,  0x08,  0x47,  0xfe,  0x81,  0x01,  0x03,  0xb6,  0x1e,  0x83,  0x01,  0x38,  0x06,  0x24,
14363  0x31,  0xa2,  0x78,  0xf2,  0x53,  0x07,  0x36,  0xfe,  0x34,  0xf4,  0x3f,  0xa1,  0x78,  0x03,  0x9a,  0x1e,
14364  0x83,  0x01,  0x38,  0x06,  0x12,  0x31,  0xf0,  0x4f,  0x45,  0xfe,  0x90,  0x10,  0xfe,  0x40,  0x5a,  0x23,
14365  0x3f,  0xfb,  0x8c,  0x49,  0x48,  0xfe,  0xaa,  0x18,  0x62,  0x49,  0x71,  0x8c,  0x80,  0x48,  0xfe,  0xaa,
14366  0x18,  0x62,  0x80,  0xfe,  0xb4,  0x56,  0xfe,  0x40,  0x5d,  0x01,  0xc6,  0x01,  0xfe,  0xac,  0x1d,  0xfe,
14367  0x02,  0x17,  0xfe,  0xc8,  0x45,  0xfe,  0x5a,  0xf0,  0xfe,  0xc0,  0x18,  0xfe,  0x43,  0x48,  0x2d,  0x93,
14368  0x36,  0xfe,  0x34,  0xf4,  0xfe,  0x00,  0x11,  0xfe,  0x40,  0x10,  0x2d,  0xb4,  0x36,  0xfe,  0x34,  0xf4,
14369  0x04,  0xfe,  0x34,  0x10,  0x2d,  0xfe,  0x0b,  0x00,  0x36,  0x46,  0x63,  0xfe,  0x28,  0x10,  0xfe,  0xc0,
14370  0x49,  0xff,  0x02,  0x00,  0x54,  0xb2,  0xfe,  0x90,  0x01,  0x48,  0xfe,  0xfa,  0x18,  0x45,  0xfe,  0x1c,
14371  0xf4,  0x3f,  0xf3,  0xfe,  0x40,  0xf4,  0x96,  0xfe,  0x56,  0xf0,  0xfe,  0x0c,  0x19,  0xfe,  0x04,  0xf4,
14372  0x58,  0xfe,  0x40,  0xf4,  0x94,  0xf6,  0x3e,  0x2d,  0x93,  0x4e,  0xd0,  0x0d,  0x21,  0xfe,  0x7f,  0x01,
14373  0xfe,  0xc8,  0x46,  0xfe,  0x24,  0x13,  0x8c,  0x00,  0x5d,  0x26,  0x21,  0xfe,  0x7e,  0x01,  0xfe,  0xc8,
14374  0x45,  0xfe,  0x14,  0x13,  0x21,  0xfe,  0x80,  0x01,  0xfe,  0x48,  0x45,  0xfa,  0x21,  0xfe,  0x81,  0x01,
14375  0xfe,  0xc8,  0x44,  0x4e,  0x26,  0x02,  0x13,  0x07,  0x02,  0x78,  0x45,  0x50,  0x13,  0x0d,  0x02,  0x14,
14376  0x07,  0x01,  0x08,  0x17,  0xfe,  0x82,  0x19,  0x14,  0x0d,  0x01,  0x08,  0x17,  0xfe,  0x82,  0x19,  0x14,
14377  0x1d,  0x01,  0x08,  0x17,  0xfe,  0x82,  0x19,  0x5f,  0xfe,  0x89,  0x49,  0x01,  0x08,  0x02,  0x14,  0x07,
14378  0x01,  0x08,  0x17,  0xc1,  0x14,  0x1d,  0x01,  0x08,  0x17,  0xc1,  0x14,  0x07,  0x01,  0x08,  0x17,  0xc1,
14379  0xfe,  0x89,  0x49,  0x01,  0x08,  0x17,  0xc1,  0x5f,  0xfe,  0x89,  0x4a,  0x01,  0x08,  0x02,  0x50,  0x02,
14380  0x14,  0x07,  0x01,  0x08,  0x17,  0x74,  0x14,  0x7f,  0x01,  0x08,  0x17,  0x74,  0x14,  0x12,  0x01,  0x08,
14381  0x17,  0x74,  0xfe,  0x89,  0x49,  0x01,  0x08,  0x17,  0x74,  0x14,  0x00,  0x01,  0x08,  0x17,  0x74,  0xfe,
14382  0x89,  0x4a,  0x01,  0x08,  0x17,  0x74,  0xfe,  0x09,  0x49,  0x01,  0x08,  0x17,  0x74,  0x5f,  0xcc,  0x01,
14383  0x08,  0x02,  0x21,  0xe4,  0x09,  0x07,  0xfe,  0x4c,  0x13,  0xc8,  0x20,  0xe4,  0xfe,  0x49,  0xf4,  0x00,
14384  0x4d,  0x5f,  0xa1,  0x5e,  0xfe,  0x01,  0xec,  0xfe,  0x27,  0x01,  0xcc,  0xff,  0x02,  0x00,  0x10,  0x2f,
14385  0xfe,  0x3e,  0x1a,  0x01,  0x43,  0x09,  0xfe,  0xe3,  0x00,  0xfe,  0x22,  0x13,  0x16,  0xfe,  0x64,  0x1a,
14386  0x26,  0x20,  0x9e,  0x01,  0x41,  0x21,  0x9e,  0x09,  0x07,  0x5d,  0x01,  0x0c,  0x61,  0x07,  0x44,  0x02,
14387  0x0a,  0x5a,  0x01,  0x18,  0xfe,  0x00,  0x40,  0xaa,  0x09,  0x1a,  0xfe,  0x12,  0x13,  0x0a,  0x9d,  0x01,
14388  0x18,  0xaa,  0x0a,  0x67,  0x01,  0xa3,  0x02,  0x0a,  0x9d,  0x01,  0x18,  0xaa,  0xfe,  0x80,  0xe7,  0x1a,
14389  0x09,  0x1a,  0x5d,  0xfe,  0x45,  0x58,  0x01,  0xfe,  0xb2,  0x16,  0xaa,  0x02,  0x0a,  0x5a,  0x01,  0x18,
14390  0xaa,  0x0a,  0x67,  0x01,  0xa3,  0x02,  0x0a,  0x5a,  0x01,  0x18,  0x01,  0xfe,  0x7e,  0x1e,  0xfe,  0x80,
14391  0x4c,  0xfe,  0x49,  0xe4,  0x1a,  0xfe,  0x12,  0x13,  0x0a,  0x9d,  0x01,  0x18,  0xfe,  0x80,  0x4c,  0x0a,
14392  0x67,  0x01,  0x5c,  0x02,  0x1c,  0x1a,  0x87,  0x7c,  0xe5,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,
14393  0x24,  0x1c,  0xfe,  0x1d,  0xf7,  0x28,  0xb1,  0xfe,  0x04,  0x1b,  0x01,  0xfe,  0x2a,  0x1c,  0xfa,  0xb3,
14394  0x28,  0x7c,  0xfe,  0x2c,  0x01,  0xfe,  0x2f,  0x19,  0x02,  0xc9,  0x2b,  0xfe,  0xf4,  0x1a,  0xfe,  0xfa,
14395  0x10,  0x1c,  0x1a,  0x87,  0x03,  0xfe,  0x64,  0x01,  0xfe,  0x00,  0xf4,  0x24,  0xfe,  0x18,  0x58,  0x03,
14396  0xfe,  0x66,  0x01,  0xfe,  0x19,  0x58,  0xb3,  0x24,  0x01,  0xfe,  0x0e,  0x1f,  0xfe,  0x30,  0xf4,  0x07,
14397  0xfe,  0x3c,  0x50,  0x7c,  0xfe,  0x38,  0x00,  0xfe,  0x0f,  0x79,  0xfe,  0x1c,  0xf7,  0x24,  0xb1,  0xfe,
14398  0x50,  0x1b,  0xfe,  0xd4,  0x14,  0x31,  0x02,  0xc9,  0x2b,  0xfe,  0x26,  0x1b,  0xfe,  0xba,  0x10,  0x1c,
14399  0x1a,  0x87,  0xfe,  0x83,  0x5a,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,  0x1d,  0xf7,  0x54,  0xb1,
14400  0xfe,  0x72,  0x1b,  0xfe,  0xb2,  0x14,  0xfc,  0xb3,  0x54,  0x7c,  0x12,  0xfe,  0xaf,  0x19,  0xfe,  0x98,
14401  0xe7,  0x00,  0x02,  0xc9,  0x2b,  0xfe,  0x66,  0x1b,  0xfe,  0x8a,  0x10,  0x1c,  0x1a,  0x87,  0x8b,  0x0f,
14402  0xfe,  0x30,  0x90,  0x04,  0xfe,  0xb0,  0x93,  0x3a,  0x0b,  0xfe,  0x18,  0x58,  0xfe,  0x32,  0x90,  0x04,
14403  0xfe,  0xb2,  0x93,  0x3a,  0x0b,  0xfe,  0x19,  0x58,  0x0e,  0xa8,  0xb3,  0x4a,  0x7c,  0x12,  0xfe,  0x0f,
14404  0x79,  0xfe,  0x1c,  0xf7,  0x4a,  0xb1,  0xfe,  0xc6,  0x1b,  0xfe,  0x5e,  0x14,  0x31,  0x02,  0xc9,  0x2b,
14405  0xfe,  0x96,  0x1b,  0x5c,  0xfe,  0x02,  0xf6,  0x1a,  0x87,  0xfe,  0x18,  0xfe,  0x6a,  0xfe,  0x19,  0xfe,
14406  0x6b,  0x01,  0xfe,  0x1e,  0x1f,  0xfe,  0x1d,  0xf7,  0x65,  0xb1,  0xfe,  0xee,  0x1b,  0xfe,  0x36,  0x14,
14407  0xfe,  0x1c,  0x13,  0xb3,  0x65,  0x3e,  0xfe,  0x83,  0x58,  0xfe,  0xaf,  0x19,  0xfe,  0x80,  0xe7,  0x1a,
14408  0xfe,  0x81,  0xe7,  0x1a,  0x15,  0xfe,  0xdd,  0x00,  0x7a,  0x30,  0x02,  0x7a,  0x30,  0xfe,  0x12,  0x45,
14409  0x2b,  0xfe,  0xdc,  0x1b,  0x1f,  0x07,  0x47,  0xb5,  0xc3,  0x05,  0x35,  0xfe,  0x39,  0xf0,  0x75,  0x26,
14410  0x02,  0xfe,  0x7e,  0x18,  0x23,  0x1d,  0x36,  0x13,  0x11,  0x02,  0x87,  0x03,  0xe3,  0x23,  0x07,  0xfe,
14411  0xef,  0x12,  0xfe,  0xe1,  0x10,  0x90,  0x34,  0x60,  0xfe,  0x02,  0x80,  0x09,  0x56,  0xfe,  0x3c,  0x13,
14412  0xfe,  0x82,  0x14,  0xfe,  0x42,  0x13,  0x51,  0xfe,  0x06,  0x83,  0x0a,  0x5a,  0x01,  0x18,  0xcb,  0xfe,
14413  0x3e,  0x12,  0xfe,  0x41,  0x48,  0xfe,  0x45,  0x48,  0x01,  0xfe,  0xb2,  0x16,  0xfe,  0x00,  0xcc,  0xcb,
14414  0xfe,  0xf3,  0x13,  0x3f,  0x89,  0x09,  0x1a,  0xa5,  0x0a,  0x9d,  0x01,  0x18,  0xfe,  0x80,  0x4c,  0x01,
14415  0x85,  0xfe,  0x16,  0x10,  0x09,  0x9b,  0x4e,  0xfe,  0x40,  0x14,  0xfe,  0x24,  0x12,  0xfe,  0x14,  0x56,
14416  0xfe,  0xd6,  0xf0,  0xfe,  0x52,  0x1c,  0x1c,  0x0d,  0x02,  0xfe,  0x9c,  0xe7,  0x0d,  0x19,  0xfe,  0x15,
14417  0x00,  0x40,  0x8d,  0x30,  0x01,  0xf4,  0x1c,  0x07,  0x02,  0x51,  0xfe,  0x06,  0x83,  0xfe,  0x18,  0x80,
14418  0x61,  0x28,  0x44,  0x15,  0x56,  0x01,  0x85,  0x1c,  0x07,  0x02,  0xfe,  0x38,  0x90,  0xfe,  0xba,  0x90,
14419  0x91,  0xde,  0x7e,  0xdf,  0xfe,  0x48,  0x55,  0x31,  0xfe,  0xc9,  0x55,  0x02,  0x21,  0xb9,  0x88,  0x20,
14420  0xb9,  0x02,  0x0a,  0xba,  0x01,  0x18,  0xfe,  0x41,  0x48,  0x0a,  0x57,  0x01,  0x18,  0xfe,  0x49,  0x44,
14421  0x1b,  0xfe,  0x1e,  0x1d,  0x88,  0x89,  0x02,  0x0a,  0x5a,  0x01,  0x18,  0x09,  0x1a,  0xa4,  0x0a,  0x67,
14422  0x01,  0xa3,  0x0a,  0x57,  0x01,  0x18,  0x88,  0x89,  0x02,  0xfe,  0x4e,  0xe4,  0x1d,  0x7b,  0xfe,  0x52,
14423  0x1d,  0x03,  0xfe,  0x90,  0x00,  0xfe,  0x3a,  0x45,  0xfe,  0x2c,  0x10,  0xfe,  0x4e,  0xe4,  0xdd,  0x7b,
14424  0xfe,  0x64,  0x1d,  0x03,  0xfe,  0x92,  0x00,  0xd1,  0x12,  0xfe,  0x1a,  0x10,  0xfe,  0x4e,  0xe4,  0xfe,
14425  0x0b,  0x00,  0x7b,  0xfe,  0x76,  0x1d,  0x03,  0xfe,  0x94,  0x00,  0xd1,  0x24,  0xfe,  0x08,  0x10,  0x03,
14426  0xfe,  0x96,  0x00,  0xd1,  0x63,  0xfe,  0x4e,  0x45,  0x83,  0xca,  0xff,  0x04,  0x68,  0x54,  0xfe,  0xf1,
14427  0x10,  0x23,  0x49,  0xfe,  0x08,  0x1c,  0xfe,  0x67,  0x19,  0xfe,  0x0a,  0x1c,  0xfe,  0x1a,  0xf4,  0xfe,
14428  0x00,  0x04,  0x83,  0xb2,  0x1d,  0x48,  0xfe,  0xaa,  0x1d,  0x13,  0x1d,  0x02,  0x09,  0x92,  0xfe,  0x5a,
14429  0xf0,  0xfe,  0xba,  0x1d,  0x2e,  0x93,  0xfe,  0x34,  0x10,  0x09,  0x12,  0xfe,  0x5a,  0xf0,  0xfe,  0xc8,
14430  0x1d,  0x2e,  0xb4,  0xfe,  0x26,  0x10,  0x09,  0x1d,  0x36,  0x2e,  0x63,  0xfe,  0x1a,  0x10,  0x09,  0x0d,
14431  0x36,  0x2e,  0x94,  0xf2,  0x09,  0x07,  0x36,  0x2e,  0x95,  0xa1,  0xc8,  0x02,  0x1f,  0x93,  0x01,  0x42,
14432  0xfe,  0x04,  0xfe,  0x99,  0x03,  0x9c,  0x8b,  0x02,  0x2a,  0xfe,  0x1c,  0x1e,  0xfe,  0x14,  0xf0,  0x08,
14433  0x2f,  0xfe,  0x0c,  0x1e,  0x2a,  0xfe,  0x1c,  0x1e,  0x8f,  0xfe,  0x1c,  0x1e,  0xfe,  0x82,  0xf0,  0xfe,
14434  0x10,  0x1e,  0x02,  0x0f,  0x3f,  0x04,  0xfe,  0x80,  0x83,  0x33,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x18,
14435  0x80,  0x04,  0xfe,  0x98,  0x83,  0x33,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x02,  0x80,  0x04,  0xfe,  0x82,
14436  0x83,  0x33,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x06,  0x80,  0x04,  0xfe,  0x86,  0x83,  0x33,  0x0b,  0x0e,
14437  0x02,  0x0f,  0xfe,  0x1b,  0x80,  0x04,  0xfe,  0x9b,  0x83,  0x33,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x04,
14438  0x80,  0x04,  0xfe,  0x84,  0x83,  0x33,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x80,  0x80,  0x04,  0xfe,  0x80,
14439  0x83,  0xfe,  0xc9,  0x47,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x19,  0x81,  0x04,  0xfe,  0x99,  0x83,  0xfe,
14440  0xca,  0x47,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x06,  0x83,  0x04,  0xfe,  0x86,  0x83,  0xfe,  0xce,  0x47,
14441  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x2c,  0x90,  0x04,  0xfe,  0xac,  0x93,  0x3a,  0x0b,  0x0e,  0x02,  0x0f,
14442  0xfe,  0xae,  0x90,  0x04,  0xfe,  0xae,  0x93,  0x79,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x08,  0x90,  0x04,
14443  0xfe,  0x88,  0x93,  0x3a,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x8a,  0x90,  0x04,  0xfe,  0x8a,  0x93,  0x79,
14444  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x0c,  0x90,  0x04,  0xfe,  0x8c,  0x93,  0x3a,  0x0b,  0x0e,  0x02,  0x0f,
14445  0xfe,  0x8e,  0x90,  0x04,  0xfe,  0x8e,  0x93,  0x79,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x3c,  0x90,  0x04,
14446  0xfe,  0xbc,  0x93,  0x3a,  0x0b,  0x0e,  0x02,  0x8b,  0x0f,  0xfe,  0x03,  0x80,  0x04,  0xfe,  0x83,  0x83,
14447  0x33,  0x0b,  0x77,  0x0e,  0xa8,  0x02,  0xff,  0x66,  0x00,  0x00,
14448};
14449
14450STATIC unsigned short _adv_asc38C1600_size =
14451        sizeof(_adv_asc38C1600_buf); /* 0x1673 */
14452STATIC ADV_DCNT _adv_asc38C1600_chksum =
14453        0x0604EF77UL; /* Expanded little-endian checksum. */
14454
14455/* a_init.c */
14456/*
14457 * EEPROM Configuration.
14458 *
14459 * All drivers should use this structure to set the default EEPROM
14460 * configuration. The BIOS now uses this structure when it is built.
14461 * Additional structure information can be found in a_condor.h where
14462 * the structure is defined.
14463 *
14464 * The *_Field_IsChar structs are needed to correct for endianness.
14465 * These values are read from the board 16 bits at a time directly
14466 * into the structs. Because some fields are char, the values will be
14467 * in the wrong order. The *_Field_IsChar tells when to flip the
14468 * bytes. Data read and written to PCI memory is automatically swapped
14469 * on big-endian platforms so char fields read as words are actually being
14470 * unswapped on big-endian platforms.
14471 */
14472STATIC ADVEEP_3550_CONFIG
14473Default_3550_EEPROM_Config ASC_INITDATA = {
14474    ADV_EEPROM_BIOS_ENABLE,     /* cfg_lsw */
14475    0x0000,                     /* cfg_msw */
14476    0xFFFF,                     /* disc_enable */
14477    0xFFFF,                     /* wdtr_able */
14478    0xFFFF,                     /* sdtr_able */
14479    0xFFFF,                     /* start_motor */
14480    0xFFFF,                     /* tagqng_able */
14481    0xFFFF,                     /* bios_scan */
14482    0,                          /* scam_tolerant */
14483    7,                          /* adapter_scsi_id */
14484    0,                          /* bios_boot_delay */
14485    3,                          /* scsi_reset_delay */
14486    0,                          /* bios_id_lun */
14487    0,                          /* termination */
14488    0,                          /* reserved1 */
14489    0xFFE7,                     /* bios_ctrl */
14490    0xFFFF,                     /* ultra_able */
14491    0,                          /* reserved2 */
14492    ASC_DEF_MAX_HOST_QNG,       /* max_host_qng */
14493    ASC_DEF_MAX_DVC_QNG,        /* max_dvc_qng */
14494    0,                          /* dvc_cntl */
14495    0,                          /* bug_fix */
14496    0,                          /* serial_number_word1 */
14497    0,                          /* serial_number_word2 */
14498    0,                          /* serial_number_word3 */
14499    0,                          /* check_sum */
14500    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* oem_name[16] */
14501    0,                          /* dvc_err_code */
14502    0,                          /* adv_err_code */
14503    0,                          /* adv_err_addr */
14504    0,                          /* saved_dvc_err_code */
14505    0,                          /* saved_adv_err_code */
14506    0,                          /* saved_adv_err_addr */
14507    0                           /* num_of_err */
14508};
14509
14510STATIC ADVEEP_3550_CONFIG
14511ADVEEP_3550_Config_Field_IsChar ASC_INITDATA = {
14512    0,                          /* cfg_lsw */
14513    0,                          /* cfg_msw */
14514    0,                          /* -disc_enable */
14515    0,                          /* wdtr_able */
14516    0,                          /* sdtr_able */
14517    0,                          /* start_motor */
14518    0,                          /* tagqng_able */
14519    0,                          /* bios_scan */
14520    0,                          /* scam_tolerant */
14521    1,                          /* adapter_scsi_id */
14522    1,                          /* bios_boot_delay */
14523    1,                          /* scsi_reset_delay */
14524    1,                          /* bios_id_lun */
14525    1,                          /* termination */
14526    1,                          /* reserved1 */
14527    0,                          /* bios_ctrl */
14528    0,                          /* ultra_able */
14529    0,                          /* reserved2 */
14530    1,                          /* max_host_qng */
14531    1,                          /* max_dvc_qng */
14532    0,                          /* dvc_cntl */
14533    0,                          /* bug_fix */
14534    0,                          /* serial_number_word1 */
14535    0,                          /* serial_number_word2 */
14536    0,                          /* serial_number_word3 */
14537    0,                          /* check_sum */
14538    { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* oem_name[16] */
14539    0,                          /* dvc_err_code */
14540    0,                          /* adv_err_code */
14541    0,                          /* adv_err_addr */
14542    0,                          /* saved_dvc_err_code */
14543    0,                          /* saved_adv_err_code */
14544    0,                          /* saved_adv_err_addr */
14545    0                           /* num_of_err */
14546};
14547
14548STATIC ADVEEP_38C0800_CONFIG
14549Default_38C0800_EEPROM_Config ASC_INITDATA = {
14550    ADV_EEPROM_BIOS_ENABLE,     /* 00 cfg_lsw */
14551    0x0000,                     /* 01 cfg_msw */
14552    0xFFFF,                     /* 02 disc_enable */
14553    0xFFFF,                     /* 03 wdtr_able */
14554    0x4444,                     /* 04 sdtr_speed1 */
14555    0xFFFF,                     /* 05 start_motor */
14556    0xFFFF,                     /* 06 tagqng_able */
14557    0xFFFF,                     /* 07 bios_scan */
14558    0,                          /* 08 scam_tolerant */
14559    7,                          /* 09 adapter_scsi_id */
14560    0,                          /*    bios_boot_delay */
14561    3,                          /* 10 scsi_reset_delay */
14562    0,                          /*    bios_id_lun */
14563    0,                          /* 11 termination_se */
14564    0,                          /*    termination_lvd */
14565    0xFFE7,                     /* 12 bios_ctrl */
14566    0x4444,                     /* 13 sdtr_speed2 */
14567    0x4444,                     /* 14 sdtr_speed3 */
14568    ASC_DEF_MAX_HOST_QNG,       /* 15 max_host_qng */
14569    ASC_DEF_MAX_DVC_QNG,        /*    max_dvc_qng */
14570    0,                          /* 16 dvc_cntl */
14571    0x4444,                     /* 17 sdtr_speed4 */
14572    0,                          /* 18 serial_number_word1 */
14573    0,                          /* 19 serial_number_word2 */
14574    0,                          /* 20 serial_number_word3 */
14575    0,                          /* 21 check_sum */
14576    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* 22-29 oem_name[16] */
14577    0,                          /* 30 dvc_err_code */
14578    0,                          /* 31 adv_err_code */
14579    0,                          /* 32 adv_err_addr */
14580    0,                          /* 33 saved_dvc_err_code */
14581    0,                          /* 34 saved_adv_err_code */
14582    0,                          /* 35 saved_adv_err_addr */
14583    0,                          /* 36 reserved */
14584    0,                          /* 37 reserved */
14585    0,                          /* 38 reserved */
14586    0,                          /* 39 reserved */
14587    0,                          /* 40 reserved */
14588    0,                          /* 41 reserved */
14589    0,                          /* 42 reserved */
14590    0,                          /* 43 reserved */
14591    0,                          /* 44 reserved */
14592    0,                          /* 45 reserved */
14593    0,                          /* 46 reserved */
14594    0,                          /* 47 reserved */
14595    0,                          /* 48 reserved */
14596    0,                          /* 49 reserved */
14597    0,                          /* 50 reserved */
14598    0,                          /* 51 reserved */
14599    0,                          /* 52 reserved */
14600    0,                          /* 53 reserved */
14601    0,                          /* 54 reserved */
14602    0,                          /* 55 reserved */
14603    0,                          /* 56 cisptr_lsw */
14604    0,                          /* 57 cisprt_msw */
14605    ADV_PCI_VENDOR_ID,          /* 58 subsysvid */
14606    ADV_PCI_DEVID_38C0800_REV1, /* 59 subsysid */
14607    0,                          /* 60 reserved */
14608    0,                          /* 61 reserved */
14609    0,                          /* 62 reserved */
14610    0                           /* 63 reserved */
14611};
14612
14613STATIC ADVEEP_38C0800_CONFIG
14614ADVEEP_38C0800_Config_Field_IsChar ASC_INITDATA = {
14615    0,                          /* 00 cfg_lsw */
14616    0,                          /* 01 cfg_msw */
14617    0,                          /* 02 disc_enable */
14618    0,                          /* 03 wdtr_able */
14619    0,                          /* 04 sdtr_speed1 */
14620    0,                          /* 05 start_motor */
14621    0,                          /* 06 tagqng_able */
14622    0,                          /* 07 bios_scan */
14623    0,                          /* 08 scam_tolerant */
14624    1,                          /* 09 adapter_scsi_id */
14625    1,                          /*    bios_boot_delay */
14626    1,                          /* 10 scsi_reset_delay */
14627    1,                          /*    bios_id_lun */
14628    1,                          /* 11 termination_se */
14629    1,                          /*    termination_lvd */
14630    0,                          /* 12 bios_ctrl */
14631    0,                          /* 13 sdtr_speed2 */
14632    0,                          /* 14 sdtr_speed3 */
14633    1,                          /* 15 max_host_qng */
14634    1,                          /*    max_dvc_qng */
14635    0,                          /* 16 dvc_cntl */
14636    0,                          /* 17 sdtr_speed4 */
14637    0,                          /* 18 serial_number_word1 */
14638    0,                          /* 19 serial_number_word2 */
14639    0,                          /* 20 serial_number_word3 */
14640    0,                          /* 21 check_sum */
14641    { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* 22-29 oem_name[16] */
14642    0,                          /* 30 dvc_err_code */
14643    0,                          /* 31 adv_err_code */
14644    0,                          /* 32 adv_err_addr */
14645    0,                          /* 33 saved_dvc_err_code */
14646    0,                          /* 34 saved_adv_err_code */
14647    0,                          /* 35 saved_adv_err_addr */
14648    0,                          /* 36 reserved */
14649    0,                          /* 37 reserved */
14650    0,                          /* 38 reserved */
14651    0,                          /* 39 reserved */
14652    0,                          /* 40 reserved */
14653    0,                          /* 41 reserved */
14654    0,                          /* 42 reserved */
14655    0,                          /* 43 reserved */
14656    0,                          /* 44 reserved */
14657    0,                          /* 45 reserved */
14658    0,                          /* 46 reserved */
14659    0,                          /* 47 reserved */
14660    0,                          /* 48 reserved */
14661    0,                          /* 49 reserved */
14662    0,                          /* 50 reserved */
14663    0,                          /* 51 reserved */
14664    0,                          /* 52 reserved */
14665    0,                          /* 53 reserved */
14666    0,                          /* 54 reserved */
14667    0,                          /* 55 reserved */
14668    0,                          /* 56 cisptr_lsw */
14669    0,                          /* 57 cisprt_msw */
14670    0,                          /* 58 subsysvid */
14671    0,                          /* 59 subsysid */
14672    0,                          /* 60 reserved */
14673    0,                          /* 61 reserved */
14674    0,                          /* 62 reserved */
14675    0                           /* 63 reserved */
14676};
14677
14678STATIC ADVEEP_38C1600_CONFIG
14679Default_38C1600_EEPROM_Config ASC_INITDATA = {
14680    ADV_EEPROM_BIOS_ENABLE,     /* 00 cfg_lsw */
14681    0x0000,                     /* 01 cfg_msw */
14682    0xFFFF,                     /* 02 disc_enable */
14683    0xFFFF,                     /* 03 wdtr_able */
14684    0x5555,                     /* 04 sdtr_speed1 */
14685    0xFFFF,                     /* 05 start_motor */
14686    0xFFFF,                     /* 06 tagqng_able */
14687    0xFFFF,                     /* 07 bios_scan */
14688    0,                          /* 08 scam_tolerant */
14689    7,                          /* 09 adapter_scsi_id */
14690    0,                          /*    bios_boot_delay */
14691    3,                          /* 10 scsi_reset_delay */
14692    0,                          /*    bios_id_lun */
14693    0,                          /* 11 termination_se */
14694    0,                          /*    termination_lvd */
14695    0xFFE7,                     /* 12 bios_ctrl */
14696    0x5555,                     /* 13 sdtr_speed2 */
14697    0x5555,                     /* 14 sdtr_speed3 */
14698    ASC_DEF_MAX_HOST_QNG,       /* 15 max_host_qng */
14699    ASC_DEF_MAX_DVC_QNG,        /*    max_dvc_qng */
14700    0,                          /* 16 dvc_cntl */
14701    0x5555,                     /* 17 sdtr_speed4 */
14702    0,                          /* 18 serial_number_word1 */
14703    0,                          /* 19 serial_number_word2 */
14704    0,                          /* 20 serial_number_word3 */
14705    0,                          /* 21 check_sum */
14706    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* 22-29 oem_name[16] */
14707    0,                          /* 30 dvc_err_code */
14708    0,                          /* 31 adv_err_code */
14709    0,                          /* 32 adv_err_addr */
14710    0,                          /* 33 saved_dvc_err_code */
14711    0,                          /* 34 saved_adv_err_code */
14712    0,                          /* 35 saved_adv_err_addr */
14713    0,                          /* 36 reserved */
14714    0,                          /* 37 reserved */
14715    0,                          /* 38 reserved */
14716    0,                          /* 39 reserved */
14717    0,                          /* 40 reserved */
14718    0,                          /* 41 reserved */
14719    0,                          /* 42 reserved */
14720    0,                          /* 43 reserved */
14721    0,                          /* 44 reserved */
14722    0,                          /* 45 reserved */
14723    0,                          /* 46 reserved */
14724    0,                          /* 47 reserved */
14725    0,                          /* 48 reserved */
14726    0,                          /* 49 reserved */
14727    0,                          /* 50 reserved */
14728    0,                          /* 51 reserved */
14729    0,                          /* 52 reserved */
14730    0,                          /* 53 reserved */
14731    0,                          /* 54 reserved */
14732    0,                          /* 55 reserved */
14733    0,                          /* 56 cisptr_lsw */
14734    0,                          /* 57 cisprt_msw */
14735    ADV_PCI_VENDOR_ID,          /* 58 subsysvid */
14736    ADV_PCI_DEVID_38C1600_REV1, /* 59 subsysid */
14737    0,                          /* 60 reserved */
14738    0,                          /* 61 reserved */
14739    0,                          /* 62 reserved */
14740    0                           /* 63 reserved */
14741};
14742
14743STATIC ADVEEP_38C1600_CONFIG
14744ADVEEP_38C1600_Config_Field_IsChar ASC_INITDATA = {
14745    0,                          /* 00 cfg_lsw */
14746    0,                          /* 01 cfg_msw */
14747    0,                          /* 02 disc_enable */
14748    0,                          /* 03 wdtr_able */
14749    0,                          /* 04 sdtr_speed1 */
14750    0,                          /* 05 start_motor */
14751    0,                          /* 06 tagqng_able */
14752    0,                          /* 07 bios_scan */
14753    0,                          /* 08 scam_tolerant */
14754    1,                          /* 09 adapter_scsi_id */
14755    1,                          /*    bios_boot_delay */
14756    1,                          /* 10 scsi_reset_delay */
14757    1,                          /*    bios_id_lun */
14758    1,                          /* 11 termination_se */
14759    1,                          /*    termination_lvd */
14760    0,                          /* 12 bios_ctrl */
14761    0,                          /* 13 sdtr_speed2 */
14762    0,                          /* 14 sdtr_speed3 */
14763    1,                          /* 15 max_host_qng */
14764    1,                          /*    max_dvc_qng */
14765    0,                          /* 16 dvc_cntl */
14766    0,                          /* 17 sdtr_speed4 */
14767    0,                          /* 18 serial_number_word1 */
14768    0,                          /* 19 serial_number_word2 */
14769    0,                          /* 20 serial_number_word3 */
14770    0,                          /* 21 check_sum */
14771    { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* 22-29 oem_name[16] */
14772    0,                          /* 30 dvc_err_code */
14773    0,                          /* 31 adv_err_code */
14774    0,                          /* 32 adv_err_addr */
14775    0,                          /* 33 saved_dvc_err_code */
14776    0,                          /* 34 saved_adv_err_code */
14777    0,                          /* 35 saved_adv_err_addr */
14778    0,                          /* 36 reserved */
14779    0,                          /* 37 reserved */
14780    0,                          /* 38 reserved */
14781    0,                          /* 39 reserved */
14782    0,                          /* 40 reserved */
14783    0,                          /* 41 reserved */
14784    0,                          /* 42 reserved */
14785    0,                          /* 43 reserved */
14786    0,                          /* 44 reserved */
14787    0,                          /* 45 reserved */
14788    0,                          /* 46 reserved */
14789    0,                          /* 47 reserved */
14790    0,                          /* 48 reserved */
14791    0,                          /* 49 reserved */
14792    0,                          /* 50 reserved */
14793    0,                          /* 51 reserved */
14794    0,                          /* 52 reserved */
14795    0,                          /* 53 reserved */
14796    0,                          /* 54 reserved */
14797    0,                          /* 55 reserved */
14798    0,                          /* 56 cisptr_lsw */
14799    0,                          /* 57 cisprt_msw */
14800    0,                          /* 58 subsysvid */
14801    0,                          /* 59 subsysid */
14802    0,                          /* 60 reserved */
14803    0,                          /* 61 reserved */
14804    0,                          /* 62 reserved */
14805    0                           /* 63 reserved */
14806};
14807
14808/*
14809 * Initialize the ADV_DVC_VAR structure.
14810 *
14811 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14812 *
14813 * For a non-fatal error return a warning code. If there are no warnings
14814 * then 0 is returned.
14815 */
14816ASC_INITFUNC(
14817STATIC int,
14818AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
14819)
14820{
14821    ushort      warn_code;
14822    AdvPortAddr iop_base;
14823    uchar       pci_cmd_reg;
14824    int         status;
14825
14826    warn_code = 0;
14827    asc_dvc->err_code = 0;
14828    iop_base = asc_dvc->iop_base;
14829
14830    /*
14831     * PCI Command Register
14832     *
14833     * Note: AscPCICmdRegBits_BusMastering definition (0x0007) includes
14834     * I/O Space Control, Memory Space Control and Bus Master Control bits.
14835     */
14836
14837    if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc,
14838                            AscPCIConfigCommandRegister))
14839         & AscPCICmdRegBits_BusMastering)
14840        != AscPCICmdRegBits_BusMastering)
14841    {
14842        pci_cmd_reg |= AscPCICmdRegBits_BusMastering;
14843
14844        DvcAdvWritePCIConfigByte(asc_dvc,
14845                AscPCIConfigCommandRegister, pci_cmd_reg);
14846
14847        if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister))
14848             & AscPCICmdRegBits_BusMastering)
14849            != AscPCICmdRegBits_BusMastering)
14850        {
14851            warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14852        }
14853    }
14854
14855    /*
14856     * PCI Latency Timer
14857     *
14858     * If the "latency timer" register is 0x20 or above, then we don't need
14859     * to change it.  Otherwise, set it to 0x20 (i.e. set it to 0x20 if it
14860     * comes up less than 0x20).
14861     */
14862    if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) {
14863        DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer, 0x20);
14864        if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20)
14865        {
14866            warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14867        }
14868    }
14869
14870    /*
14871     * Save the state of the PCI Configuration Command Register
14872     * "Parity Error Response Control" Bit. If the bit is clear (0),
14873     * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
14874     * DMA parity errors.
14875     */
14876    asc_dvc->cfg->control_flag = 0;
14877    if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister)
14878         & AscPCICmdRegBits_ParErrRespCtrl)) == 0)
14879    {
14880        asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
14881    }
14882
14883    asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
14884      ADV_LIB_VERSION_MINOR;
14885    asc_dvc->cfg->chip_version =
14886      AdvGetChipVersion(iop_base, asc_dvc->bus_type);
14887
14888    ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
14889        (ushort) AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
14890        (ushort) ADV_CHIP_ID_BYTE);
14891
14892    ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
14893        (ushort) AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
14894        (ushort) ADV_CHIP_ID_WORD);
14895
14896    /*
14897     * Reset the chip to start and allow register writes.
14898     */
14899    if (AdvFindSignature(iop_base) == 0)
14900    {
14901        asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
14902        return ADV_ERROR;
14903    }
14904    else {
14905        /*
14906         * The caller must set 'chip_type' to a valid setting.
14907         */
14908        if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
14909            asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
14910            asc_dvc->chip_type != ADV_CHIP_ASC38C1600)
14911        {
14912            asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
14913            return ADV_ERROR;
14914        }
14915
14916        /*
14917         * Reset Chip.
14918         */
14919        AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
14920            ADV_CTRL_REG_CMD_RESET);
14921        DvcSleepMilliSecond(100);
14922        AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
14923            ADV_CTRL_REG_CMD_WR_IO_REG);
14924
14925        if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
14926        {
14927            if ((status = AdvInitFrom38C1600EEP(asc_dvc)) == ADV_ERROR)
14928            {
14929                return ADV_ERROR;
14930            }
14931        } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
14932        {
14933            if ((status = AdvInitFrom38C0800EEP(asc_dvc)) == ADV_ERROR)
14934            {
14935                return ADV_ERROR;
14936            }
14937        } else
14938        {
14939            if ((status = AdvInitFrom3550EEP(asc_dvc)) == ADV_ERROR)
14940            {
14941                return ADV_ERROR;
14942            }
14943        }
14944        warn_code |= status;
14945    }
14946
14947    return warn_code;
14948}
14949
14950/*
14951 * Initialize the ASC-3550.
14952 *
14953 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14954 *
14955 * For a non-fatal error return a warning code. If there are no warnings
14956 * then 0 is returned.
14957 *
14958 * Needed after initialization for error recovery.
14959 */
14960STATIC int
14961AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
14962{
14963    AdvPortAddr iop_base;
14964    ushort      warn_code;
14965    ADV_DCNT    sum;
14966    int         begin_addr;
14967    int         end_addr;
14968    ushort      code_sum;
14969    int         word;
14970    int         j;
14971    int         adv_asc3550_expanded_size;
14972    ADV_CARR_T  *carrp;
14973    ADV_DCNT    contig_len;
14974    ADV_SDCNT   buf_size;
14975    ADV_PADDR   carr_paddr;
14976    int         i;
14977    ushort      scsi_cfg1;
14978    uchar       tid;
14979    ushort      bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
14980    ushort      wdtr_able = 0, sdtr_able, tagqng_able;
14981    uchar       max_cmd[ADV_MAX_TID + 1];
14982
14983    /* If there is already an error, don't continue. */
14984    if (asc_dvc->err_code != 0)
14985    {
14986        return ADV_ERROR;
14987    }
14988
14989    /*
14990     * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
14991     */
14992    if (asc_dvc->chip_type != ADV_CHIP_ASC3550)
14993    {
14994        asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
14995        return ADV_ERROR;
14996    }
14997
14998    warn_code = 0;
14999    iop_base = asc_dvc->iop_base;
15000
15001    /*
15002     * Save the RISC memory BIOS region before writing the microcode.
15003     * The BIOS may already be loaded and using its RISC LRAM region
15004     * so its region must be saved and restored.
15005     *
15006     * Note: This code makes the assumption, which is currently true,
15007     * that a chip reset does not clear RISC LRAM.
15008     */
15009    for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15010    {
15011        AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15012    }
15013
15014    /*
15015     * Save current per TID negotiated values.
15016     */
15017    if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
15018    {
15019        ushort  bios_version, major, minor;
15020
15021        bios_version = bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM)/2];
15022        major = (bios_version  >> 12) & 0xF;
15023        minor = (bios_version  >> 8) & 0xF;
15024        if (major < 3 || (major == 3 && minor == 1))
15025        {
15026            /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
15027            AdvReadWordLram(iop_base, 0x120, wdtr_able);
15028        } else
15029        {
15030            AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15031        }
15032    }
15033    AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15034    AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15035    for (tid = 0; tid <= ADV_MAX_TID; tid++)
15036    {
15037        AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15038            max_cmd[tid]);
15039    }
15040
15041    /*
15042     * Load the Microcode
15043     *
15044     * Write the microcode image to RISC memory starting at address 0.
15045     */
15046    AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15047    /* Assume the following compressed format of the microcode buffer:
15048     *
15049     *  254 word (508 byte) table indexed by byte code followed
15050     *  by the following byte codes:
15051     *
15052     *    1-Byte Code:
15053     *      00: Emit word 0 in table.
15054     *      01: Emit word 1 in table.
15055     *      .
15056     *      FD: Emit word 253 in table.
15057     *
15058     *    Multi-Byte Code:
15059     *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15060     *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15061     */
15062    word = 0;
15063    for (i = 253 * 2; i < _adv_asc3550_size; i++)
15064    {
15065        if (_adv_asc3550_buf[i] == 0xff)
15066        {
15067            for (j = 0; j < _adv_asc3550_buf[i + 1]; j++)
15068            {
15069                AdvWriteWordAutoIncLram(iop_base, (((ushort)
15070                    _adv_asc3550_buf[i + 3] << 8) |
15071                _adv_asc3550_buf[i + 2]));
15072                word++;
15073            }
15074            i += 3;
15075        } else if (_adv_asc3550_buf[i] == 0xfe)
15076        {
15077            AdvWriteWordAutoIncLram(iop_base, (((ushort)
15078                _adv_asc3550_buf[i + 2] << 8) |
15079                _adv_asc3550_buf[i + 1]));
15080            i += 2;
15081            word++;
15082        } else
15083        {
15084            AdvWriteWordAutoIncLram(iop_base, (((ushort)
15085                _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) |
15086                _adv_asc3550_buf[_adv_asc3550_buf[i] * 2]));
15087            word++;
15088        }
15089    }
15090
15091    /*
15092     * Set 'word' for later use to clear the rest of memory and save
15093     * the expanded mcode size.
15094     */
15095    word *= 2;
15096    adv_asc3550_expanded_size = word;
15097
15098    /*
15099     * Clear the rest of ASC-3550 Internal RAM (8KB).
15100     */
15101    for (; word < ADV_3550_MEMSIZE; word += 2)
15102    {
15103        AdvWriteWordAutoIncLram(iop_base, 0);
15104    }
15105
15106    /*
15107     * Verify the microcode checksum.
15108     */
15109    sum = 0;
15110    AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15111
15112    for (word = 0; word < adv_asc3550_expanded_size; word += 2)
15113    {
15114        sum += AdvReadWordAutoIncLram(iop_base);
15115    }
15116
15117    if (sum != _adv_asc3550_chksum)
15118    {
15119        asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15120        return ADV_ERROR;
15121    }
15122
15123    /*
15124     * Restore the RISC memory BIOS region.
15125     */
15126    for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15127    {
15128        AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15129    }
15130
15131    /*
15132     * Calculate and write the microcode code checksum to the microcode
15133     * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15134     */
15135    AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15136    AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15137    code_sum = 0;
15138    AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15139    for (word = begin_addr; word < end_addr; word += 2)
15140    {
15141        code_sum += AdvReadWordAutoIncLram(iop_base);
15142    }
15143    AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15144
15145    /*
15146     * Read and save microcode version and date.
15147     */
15148    AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
15149    AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
15150
15151    /*
15152     * Set the chip type to indicate the ASC3550.
15153     */
15154    AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
15155
15156    /*
15157     * If the PCI Configuration Command Register "Parity Error Response
15158     * Control" Bit was clear (0), then set the microcode variable
15159     * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15160     * to ignore DMA parity errors.
15161     */
15162    if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
15163    {
15164        AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15165        word |= CONTROL_FLAG_IGNORE_PERR;
15166        AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15167    }
15168
15169    /*
15170     * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
15171     * threshold of 128 bytes. This register is only accessible to the host.
15172     */
15173    AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15174        START_CTL_EMFU | READ_CMD_MRM);
15175
15176    /*
15177     * Microcode operating variables for WDTR, SDTR, and command tag
15178     * queuing will be set in AdvInquiryHandling() based on what a
15179     * device reports it is capable of in Inquiry byte 7.
15180     *
15181     * If SCSI Bus Resets have been disabled, then directly set
15182     * SDTR and WDTR from the EEPROM configuration. This will allow
15183     * the BIOS and warm boot to work without a SCSI bus hang on
15184     * the Inquiry caused by host and target mismatched DTR values.
15185     * Without the SCSI Bus Reset, before an Inquiry a device can't
15186     * be assumed to be in Asynchronous, Narrow mode.
15187     */
15188    if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
15189    {
15190        AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
15191        AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
15192    }
15193
15194    /*
15195     * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
15196     * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
15197     * bitmask. These values determine the maximum SDTR speed negotiated
15198     * with a device.
15199     *
15200     * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15201     * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15202     * without determining here whether the device supports SDTR.
15203     *
15204     * 4-bit speed  SDTR speed name
15205     * ===========  ===============
15206     * 0000b (0x0)  SDTR disabled
15207     * 0001b (0x1)  5 Mhz
15208     * 0010b (0x2)  10 Mhz
15209     * 0011b (0x3)  20 Mhz (Ultra)
15210     * 0100b (0x4)  40 Mhz (LVD/Ultra2)
15211     * 0101b (0x5)  80 Mhz (LVD2/Ultra3)
15212     * 0110b (0x6)  Undefined
15213     * .
15214     * 1111b (0xF)  Undefined
15215     */
15216    word = 0;
15217    for (tid = 0; tid <= ADV_MAX_TID; tid++)
15218    {
15219        if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able)
15220        {
15221            /* Set Ultra speed for TID 'tid'. */
15222            word |= (0x3 << (4 * (tid % 4)));
15223        } else
15224        {
15225            /* Set Fast speed for TID 'tid'. */
15226            word |= (0x2 << (4 * (tid % 4)));
15227        }
15228        if (tid == 3) /* Check if done with sdtr_speed1. */
15229        {
15230            AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
15231            word = 0;
15232        } else if (tid == 7) /* Check if done with sdtr_speed2. */
15233        {
15234            AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
15235            word = 0;
15236        } else if (tid == 11) /* Check if done with sdtr_speed3. */
15237        {
15238            AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
15239            word = 0;
15240        } else if (tid == 15) /* Check if done with sdtr_speed4. */
15241        {
15242            AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
15243            /* End of loop. */
15244        }
15245    }
15246
15247    /*
15248     * Set microcode operating variable for the disconnect per TID bitmask.
15249     */
15250    AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
15251
15252    /*
15253     * Set SCSI_CFG0 Microcode Default Value.
15254     *
15255     * The microcode will set the SCSI_CFG0 register using this value
15256     * after it is started below.
15257     */
15258    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15259        PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15260        asc_dvc->chip_scsi_id);
15261
15262    /*
15263     * Determine SCSI_CFG1 Microcode Default Value.
15264     *
15265     * The microcode will set the SCSI_CFG1 register using this value
15266     * after it is started below.
15267     */
15268
15269    /* Read current SCSI_CFG1 Register value. */
15270    scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15271
15272    /*
15273     * If all three connectors are in use, return an error.
15274     */
15275    if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
15276        (scsi_cfg1 & CABLE_ILLEGAL_B) == 0)
15277    {
15278            asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
15279            return ADV_ERROR;
15280    }
15281
15282    /*
15283     * If the internal narrow cable is reversed all of the SCSI_CTRL
15284     * register signals will be set. Check for and return an error if
15285     * this condition is found.
15286     */
15287    if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
15288    {
15289        asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15290        return ADV_ERROR;
15291    }
15292
15293    /*
15294     * If this is a differential board and a single-ended device
15295     * is attached to one of the connectors, return an error.
15296     */
15297    if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0)
15298    {
15299        asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
15300        return ADV_ERROR;
15301    }
15302
15303    /*
15304     * If automatic termination control is enabled, then set the
15305     * termination value based on a table listed in a_condor.h.
15306     *
15307     * If manual termination was specified with an EEPROM setting
15308     * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
15309     * is ready to be 'ored' into SCSI_CFG1.
15310     */
15311    if (asc_dvc->cfg->termination == 0)
15312    {
15313        /*
15314         * The software always controls termination by setting TERM_CTL_SEL.
15315         * If TERM_CTL_SEL were set to 0, the hardware would set termination.
15316         */
15317        asc_dvc->cfg->termination |= TERM_CTL_SEL;
15318
15319        switch(scsi_cfg1 & CABLE_DETECT)
15320        {
15321            /* TERM_CTL_H: on, TERM_CTL_L: on */
15322            case 0x3: case 0x7: case 0xB: case 0xD: case 0xE: case 0xF:
15323                asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
15324                break;
15325
15326            /* TERM_CTL_H: on, TERM_CTL_L: off */
15327            case 0x1: case 0x5: case 0x9: case 0xA: case 0xC:
15328                asc_dvc->cfg->termination |= TERM_CTL_H;
15329                break;
15330
15331            /* TERM_CTL_H: off, TERM_CTL_L: off */
15332            case 0x2: case 0x6:
15333                break;
15334        }
15335    }
15336
15337    /*
15338     * Clear any set TERM_CTL_H and TERM_CTL_L bits.
15339     */
15340    scsi_cfg1 &= ~TERM_CTL;
15341
15342    /*
15343     * Invert the TERM_CTL_H and TERM_CTL_L bits and then
15344     * set 'scsi_cfg1'. The TERM_POL bit does not need to be
15345     * referenced, because the hardware internally inverts
15346     * the Termination High and Low bits if TERM_POL is set.
15347     */
15348    scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
15349
15350    /*
15351     * Set SCSI_CFG1 Microcode Default Value
15352     *
15353     * Set filter value and possibly modified termination control
15354     * bits in the Microcode SCSI_CFG1 Register Value.
15355     *
15356     * The microcode will set the SCSI_CFG1 register using this value
15357     * after it is started below.
15358     */
15359    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
15360        FLTR_DISABLE | scsi_cfg1);
15361
15362    /*
15363     * Set MEM_CFG Microcode Default Value
15364     *
15365     * The microcode will set the MEM_CFG register using this value
15366     * after it is started below.
15367     *
15368     * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15369     * are defined.
15370     *
15371     * ASC-3550 has 8KB internal memory.
15372     */
15373    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15374        BIOS_EN | RAM_SZ_8KB);
15375
15376    /*
15377     * Set SEL_MASK Microcode Default Value
15378     *
15379     * The microcode will set the SEL_MASK register using this value
15380     * after it is started below.
15381     */
15382    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15383        ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15384
15385    /*
15386     * Build carrier freelist.
15387     *
15388     * Driver must have already allocated memory and set 'carrier_buf'.
15389     */
15390    ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15391
15392    carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15393    asc_dvc->carr_freelist = NULL;
15394    if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
15395    {
15396        buf_size = ADV_CARRIER_BUFSIZE;
15397    } else
15398    {
15399        buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15400    }
15401
15402    do {
15403        /*
15404         * Get physical address of the carrier 'carrp'.
15405         */
15406        contig_len = sizeof(ADV_CARR_T);
15407        carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
15408            (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
15409
15410        buf_size -= sizeof(ADV_CARR_T);
15411
15412        /*
15413         * If the current carrier is not physically contiguous, then
15414         * maybe there was a page crossing. Try the next carrier aligned
15415         * start address.
15416         */
15417        if (contig_len < sizeof(ADV_CARR_T))
15418        {
15419            carrp++;
15420            continue;
15421        }
15422
15423        carrp->carr_pa = carr_paddr;
15424        carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15425
15426        /*
15427         * Insert the carrier at the beginning of the freelist.
15428         */
15429        carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15430        asc_dvc->carr_freelist = carrp;
15431
15432        carrp++;
15433    }
15434    while (buf_size > 0);
15435
15436    /*
15437     * Set-up the Host->RISC Initiator Command Queue (ICQ).
15438     */
15439
15440    if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
15441    {
15442        asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15443        return ADV_ERROR;
15444    }
15445    asc_dvc->carr_freelist = (ADV_CARR_T *)
15446        ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15447
15448    /*
15449     * The first command issued will be placed in the stopper carrier.
15450     */
15451    asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15452
15453    /*
15454     * Set RISC ICQ physical address start value.
15455     */
15456    AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15457
15458    /*
15459     * Set-up the RISC->Host Initiator Response Queue (IRQ).
15460     */
15461    if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
15462    {
15463        asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15464        return ADV_ERROR;
15465    }
15466    asc_dvc->carr_freelist = (ADV_CARR_T *)
15467         ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15468
15469    /*
15470     * The first command completed by the RISC will be placed in
15471     * the stopper.
15472     *
15473     * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15474     * completed the RISC will set the ASC_RQ_STOPPER bit.
15475     */
15476    asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15477
15478    /*
15479     * Set RISC IRQ physical address start value.
15480     */
15481    AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15482    asc_dvc->carr_pending_cnt = 0;
15483
15484    AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15485        (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
15486
15487    AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15488    AdvWriteWordRegister(iop_base, IOPW_PC, word);
15489
15490    /* finally, finally, gentlemen, start your engine */
15491    AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15492
15493    /*
15494     * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15495     * Resets should be performed. The RISC has to be running
15496     * to issue a SCSI Bus Reset.
15497     */
15498    if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
15499    {
15500        /*
15501         * If the BIOS Signature is present in memory, restore the
15502         * BIOS Handshake Configuration Table and do not perform
15503         * a SCSI Bus Reset.
15504         */
15505        if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
15506        {
15507            /*
15508             * Restore per TID negotiated values.
15509             */
15510            AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15511            AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15512            AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15513            for (tid = 0; tid <= ADV_MAX_TID; tid++)
15514            {
15515                AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15516                    max_cmd[tid]);
15517            }
15518        } else
15519        {
15520            if (AdvResetSB(asc_dvc) != ADV_TRUE)
15521            {
15522                warn_code = ASC_WARN_BUSRESET_ERROR;
15523            }
15524        }
15525    }
15526
15527    return warn_code;
15528}
15529
15530/*
15531 * Initialize the ASC-38C0800.
15532 *
15533 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15534 *
15535 * For a non-fatal error return a warning code. If there are no warnings
15536 * then 0 is returned.
15537 *
15538 * Needed after initialization for error recovery.
15539 */
15540STATIC int
15541AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
15542{
15543    AdvPortAddr iop_base;
15544    ushort      warn_code;
15545    ADV_DCNT    sum;
15546    int         begin_addr;
15547    int         end_addr;
15548    ushort      code_sum;
15549    int         word;
15550    int         j;
15551    int         adv_asc38C0800_expanded_size;
15552    ADV_CARR_T  *carrp;
15553    ADV_DCNT    contig_len;
15554    ADV_SDCNT   buf_size;
15555    ADV_PADDR   carr_paddr;
15556    int         i;
15557    ushort      scsi_cfg1;
15558    uchar       byte;
15559    uchar       tid;
15560    ushort      bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
15561    ushort      wdtr_able, sdtr_able, tagqng_able;
15562    uchar       max_cmd[ADV_MAX_TID + 1];
15563
15564    /* If there is already an error, don't continue. */
15565    if (asc_dvc->err_code != 0)
15566    {
15567        return ADV_ERROR;
15568    }
15569
15570    /*
15571     * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
15572     */
15573    if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800)
15574    {
15575        asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
15576        return ADV_ERROR;
15577    }
15578
15579    warn_code = 0;
15580    iop_base = asc_dvc->iop_base;
15581
15582    /*
15583     * Save the RISC memory BIOS region before writing the microcode.
15584     * The BIOS may already be loaded and using its RISC LRAM region
15585     * so its region must be saved and restored.
15586     *
15587     * Note: This code makes the assumption, which is currently true,
15588     * that a chip reset does not clear RISC LRAM.
15589     */
15590    for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15591    {
15592        AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15593    }
15594
15595    /*
15596     * Save current per TID negotiated values.
15597     */
15598    AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15599    AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15600    AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15601    for (tid = 0; tid <= ADV_MAX_TID; tid++)
15602    {
15603        AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15604            max_cmd[tid]);
15605    }
15606
15607    /*
15608     * RAM BIST (RAM Built-In Self Test)
15609     *
15610     * Address : I/O base + offset 0x38h register (byte).
15611     * Function: Bit 7-6(RW) : RAM mode
15612     *                          Normal Mode   : 0x00
15613     *                          Pre-test Mode : 0x40
15614     *                          RAM Test Mode : 0x80
15615     *           Bit 5       : unused
15616     *           Bit 4(RO)   : Done bit
15617     *           Bit 3-0(RO) : Status
15618     *                          Host Error    : 0x08
15619     *                          Int_RAM Error : 0x04
15620     *                          RISC Error    : 0x02
15621     *                          SCSI Error    : 0x01
15622     *                          No Error      : 0x00
15623     *
15624     * Note: RAM BIST code should be put right here, before loading the
15625     * microcode and after saving the RISC memory BIOS region.
15626     */
15627
15628    /*
15629     * LRAM Pre-test
15630     *
15631     * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
15632     * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
15633     * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
15634     * to NORMAL_MODE, return an error too.
15635     */
15636    for (i = 0; i < 2; i++)
15637    {
15638        AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
15639        DvcSleepMilliSecond(10);  /* Wait for 10ms before reading back. */
15640        byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15641        if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE)
15642        {
15643            asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15644            return ADV_ERROR;
15645        }
15646
15647        AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15648        DvcSleepMilliSecond(10);  /* Wait for 10ms before reading back. */
15649        if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
15650            != NORMAL_VALUE)
15651        {
15652            asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15653            return ADV_ERROR;
15654        }
15655    }
15656
15657    /*
15658     * LRAM Test - It takes about 1.5 ms to run through the test.
15659     *
15660     * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
15661     * If Done bit not set or Status not 0, save register byte, set the
15662     * err_code, and return an error.
15663     */
15664    AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
15665    DvcSleepMilliSecond(10);  /* Wait for 10ms before checking status. */
15666
15667    byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15668    if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0)
15669    {
15670        /* Get here if Done bit not set or Status not 0. */
15671        asc_dvc->bist_err_code = byte;  /* for BIOS display message */
15672        asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
15673        return ADV_ERROR;
15674    }
15675
15676    /* We need to reset back to normal mode after LRAM test passes. */
15677    AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15678
15679    /*
15680     * Load the Microcode
15681     *
15682     * Write the microcode image to RISC memory starting at address 0.
15683     *
15684     */
15685    AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15686
15687    /* Assume the following compressed format of the microcode buffer:
15688     *
15689     *  254 word (508 byte) table indexed by byte code followed
15690     *  by the following byte codes:
15691     *
15692     *    1-Byte Code:
15693     *      00: Emit word 0 in table.
15694     *      01: Emit word 1 in table.
15695     *      .
15696     *      FD: Emit word 253 in table.
15697     *
15698     *    Multi-Byte Code:
15699     *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15700     *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15701     */
15702    word = 0;
15703    for (i = 253 * 2; i < _adv_asc38C0800_size; i++)
15704    {
15705        if (_adv_asc38C0800_buf[i] == 0xff)
15706        {
15707            for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++)
15708            {
15709                AdvWriteWordAutoIncLram(iop_base, (((ushort)
15710                    _adv_asc38C0800_buf[i + 3] << 8) |
15711                    _adv_asc38C0800_buf[i + 2]));
15712                word++;
15713            }
15714            i += 3;
15715        } else if (_adv_asc38C0800_buf[i] == 0xfe)
15716        {
15717            AdvWriteWordAutoIncLram(iop_base, (((ushort)
15718                _adv_asc38C0800_buf[i + 2] << 8) |
15719                _adv_asc38C0800_buf[i + 1]));
15720            i += 2;
15721            word++;
15722        } else
15723        {
15724            AdvWriteWordAutoIncLram(iop_base, (((ushort)
15725                _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) |
15726                _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2]));
15727            word++;
15728        }
15729    }
15730
15731    /*
15732     * Set 'word' for later use to clear the rest of memory and save
15733     * the expanded mcode size.
15734     */
15735    word *= 2;
15736    adv_asc38C0800_expanded_size = word;
15737
15738    /*
15739     * Clear the rest of ASC-38C0800 Internal RAM (16KB).
15740     */
15741    for (; word < ADV_38C0800_MEMSIZE; word += 2)
15742    {
15743        AdvWriteWordAutoIncLram(iop_base, 0);
15744    }
15745
15746    /*
15747     * Verify the microcode checksum.
15748     */
15749    sum = 0;
15750    AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15751
15752    for (word = 0; word < adv_asc38C0800_expanded_size; word += 2)
15753    {
15754        sum += AdvReadWordAutoIncLram(iop_base);
15755    }
15756    ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i);
15757
15758    ASC_DBG2(1,
15759        "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n",
15760        (ulong) sum, (ulong) _adv_asc38C0800_chksum);
15761
15762    if (sum != _adv_asc38C0800_chksum)
15763    {
15764        asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15765        return ADV_ERROR;
15766    }
15767
15768    /*
15769     * Restore the RISC memory BIOS region.
15770     */
15771    for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15772    {
15773        AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15774    }
15775
15776    /*
15777     * Calculate and write the microcode code checksum to the microcode
15778     * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15779     */
15780    AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15781    AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15782    code_sum = 0;
15783    AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15784    for (word = begin_addr; word < end_addr; word += 2)
15785    {
15786        code_sum += AdvReadWordAutoIncLram(iop_base);
15787    }
15788    AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15789
15790    /*
15791     * Read microcode version and date.
15792     */
15793    AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
15794    AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
15795
15796    /*
15797     * Set the chip type to indicate the ASC38C0800.
15798     */
15799    AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
15800
15801    /*
15802     * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
15803     * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
15804     * cable detection and then we are able to read C_DET[3:0].
15805     *
15806     * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
15807     * Microcode Default Value' section below.
15808     */
15809    scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15810    AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, scsi_cfg1 | DIS_TERM_DRV);
15811
15812    /*
15813     * If the PCI Configuration Command Register "Parity Error Response
15814     * Control" Bit was clear (0), then set the microcode variable
15815     * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15816     * to ignore DMA parity errors.
15817     */
15818    if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
15819    {
15820        AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15821        word |= CONTROL_FLAG_IGNORE_PERR;
15822        AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15823    }
15824
15825    /*
15826     * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
15827     * bits for the default FIFO threshold.
15828     *
15829     * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
15830     *
15831     * For DMA Errata #4 set the BC_THRESH_ENB bit.
15832     */
15833    AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15834        BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
15835
15836    /*
15837     * Microcode operating variables for WDTR, SDTR, and command tag
15838     * queuing will be set in AdvInquiryHandling() based on what a
15839     * device reports it is capable of in Inquiry byte 7.
15840     *
15841     * If SCSI Bus Resets have been disabled, then directly set
15842     * SDTR and WDTR from the EEPROM configuration. This will allow
15843     * the BIOS and warm boot to work without a SCSI bus hang on
15844     * the Inquiry caused by host and target mismatched DTR values.
15845     * Without the SCSI Bus Reset, before an Inquiry a device can't
15846     * be assumed to be in Asynchronous, Narrow mode.
15847     */
15848    if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
15849    {
15850        AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
15851        AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
15852    }
15853
15854    /*
15855     * Set microcode operating variables for DISC and SDTR_SPEED1,
15856     * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
15857     * configuration values.
15858     *
15859     * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15860     * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15861     * without determining here whether the device supports SDTR.
15862     */
15863    AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
15864    AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
15865    AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
15866    AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
15867    AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
15868
15869    /*
15870     * Set SCSI_CFG0 Microcode Default Value.
15871     *
15872     * The microcode will set the SCSI_CFG0 register using this value
15873     * after it is started below.
15874     */
15875    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15876        PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15877        asc_dvc->chip_scsi_id);
15878
15879    /*
15880     * Determine SCSI_CFG1 Microcode Default Value.
15881     *
15882     * The microcode will set the SCSI_CFG1 register using this value
15883     * after it is started below.
15884     */
15885
15886    /* Read current SCSI_CFG1 Register value. */
15887    scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15888
15889    /*
15890     * If the internal narrow cable is reversed all of the SCSI_CTRL
15891     * register signals will be set. Check for and return an error if
15892     * this condition is found.
15893     */
15894    if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
15895    {
15896        asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15897        return ADV_ERROR;
15898    }
15899
15900    /*
15901     * All kind of combinations of devices attached to one of four connectors
15902     * are acceptable except HVD device attached. For example, LVD device can
15903     * be attached to SE connector while SE device attached to LVD connector.
15904     * If LVD device attached to SE connector, it only runs up to Ultra speed.
15905     *
15906     * If an HVD device is attached to one of LVD connectors, return an error.
15907     * However, there is no way to detect HVD device attached to SE connectors.
15908     */
15909    if (scsi_cfg1 & HVD)
15910    {
15911        asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
15912        return ADV_ERROR;
15913    }
15914
15915    /*
15916     * If either SE or LVD automatic termination control is enabled, then
15917     * set the termination value based on a table listed in a_condor.h.
15918     *
15919     * If manual termination was specified with an EEPROM setting then
15920     * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to
15921     * be 'ored' into SCSI_CFG1.
15922     */
15923    if ((asc_dvc->cfg->termination & TERM_SE) == 0)
15924    {
15925        /* SE automatic termination control is enabled. */
15926        switch(scsi_cfg1 & C_DET_SE)
15927        {
15928            /* TERM_SE_HI: on, TERM_SE_LO: on */
15929            case 0x1: case 0x2: case 0x3:
15930                asc_dvc->cfg->termination |= TERM_SE;
15931                break;
15932
15933            /* TERM_SE_HI: on, TERM_SE_LO: off */
15934            case 0x0:
15935                asc_dvc->cfg->termination |= TERM_SE_HI;
15936                break;
15937        }
15938    }
15939
15940    if ((asc_dvc->cfg->termination & TERM_LVD) == 0)
15941    {
15942        /* LVD automatic termination control is enabled. */
15943        switch(scsi_cfg1 & C_DET_LVD)
15944        {
15945            /* TERM_LVD_HI: on, TERM_LVD_LO: on */
15946            case 0x4: case 0x8: case 0xC:
15947                asc_dvc->cfg->termination |= TERM_LVD;
15948                break;
15949
15950            /* TERM_LVD_HI: off, TERM_LVD_LO: off */
15951            case 0x0:
15952                break;
15953        }
15954    }
15955
15956    /*
15957     * Clear any set TERM_SE and TERM_LVD bits.
15958     */
15959    scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
15960
15961    /*
15962     * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
15963     */
15964    scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
15965
15966    /*
15967     * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits
15968     * and set possibly modified termination control bits in the Microcode
15969     * SCSI_CFG1 Register Value.
15970     */
15971    scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
15972
15973    /*
15974     * Set SCSI_CFG1 Microcode Default Value
15975     *
15976     * Set possibly modified termination control and reset DIS_TERM_DRV
15977     * bits in the Microcode SCSI_CFG1 Register Value.
15978     *
15979     * The microcode will set the SCSI_CFG1 register using this value
15980     * after it is started below.
15981     */
15982    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15983
15984    /*
15985     * Set MEM_CFG Microcode Default Value
15986     *
15987     * The microcode will set the MEM_CFG register using this value
15988     * after it is started below.
15989     *
15990     * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15991     * are defined.
15992     *
15993     * ASC-38C0800 has 16KB internal memory.
15994     */
15995    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15996        BIOS_EN | RAM_SZ_16KB);
15997
15998    /*
15999     * Set SEL_MASK Microcode Default Value
16000     *
16001     * The microcode will set the SEL_MASK register using this value
16002     * after it is started below.
16003     */
16004    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
16005        ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
16006
16007    /*
16008     * Build the carrier freelist.
16009     *
16010     * Driver must have already allocated memory and set 'carrier_buf'.
16011     */
16012    ASC_ASSERT(asc_dvc->carrier_buf != NULL);
16013
16014    carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
16015    asc_dvc->carr_freelist = NULL;
16016    if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
16017    {
16018        buf_size = ADV_CARRIER_BUFSIZE;
16019    } else
16020    {
16021        buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
16022    }
16023
16024    do {
16025        /*
16026         * Get physical address for the carrier 'carrp'.
16027         */
16028        contig_len = sizeof(ADV_CARR_T);
16029        carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
16030            (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
16031
16032        buf_size -= sizeof(ADV_CARR_T);
16033
16034        /*
16035         * If the current carrier is not physically contiguous, then
16036         * maybe there was a page crossing. Try the next carrier aligned
16037         * start address.
16038         */
16039        if (contig_len < sizeof(ADV_CARR_T))
16040        {
16041            carrp++;
16042            continue;
16043        }
16044
16045        carrp->carr_pa = carr_paddr;
16046        carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
16047
16048        /*
16049         * Insert the carrier at the beginning of the freelist.
16050         */
16051        carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
16052        asc_dvc->carr_freelist = carrp;
16053
16054        carrp++;
16055    }
16056    while (buf_size > 0);
16057
16058    /*
16059     * Set-up the Host->RISC Initiator Command Queue (ICQ).
16060     */
16061
16062    if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
16063    {
16064        asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16065        return ADV_ERROR;
16066    }
16067    asc_dvc->carr_freelist = (ADV_CARR_T *)
16068        ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
16069
16070    /*
16071     * The first command issued will be placed in the stopper carrier.
16072     */
16073    asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16074
16075    /*
16076     * Set RISC ICQ physical address start value.
16077     * carr_pa is LE, must be native before write
16078     */
16079    AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
16080
16081    /*
16082     * Set-up the RISC->Host Initiator Response Queue (IRQ).
16083     */
16084    if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
16085    {
16086        asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16087        return ADV_ERROR;
16088    }
16089    asc_dvc->carr_freelist = (ADV_CARR_T *)
16090        ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
16091
16092    /*
16093     * The first command completed by the RISC will be placed in
16094     * the stopper.
16095     *
16096     * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
16097     * completed the RISC will set the ASC_RQ_STOPPER bit.
16098     */
16099    asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16100
16101    /*
16102     * Set RISC IRQ physical address start value.
16103     *
16104     * carr_pa is LE, must be native before write *
16105     */
16106    AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
16107    asc_dvc->carr_pending_cnt = 0;
16108
16109    AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
16110        (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
16111
16112    AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
16113    AdvWriteWordRegister(iop_base, IOPW_PC, word);
16114
16115    /* finally, finally, gentlemen, start your engine */
16116    AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
16117
16118    /*
16119     * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
16120     * Resets should be performed. The RISC has to be running
16121     * to issue a SCSI Bus Reset.
16122     */
16123    if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
16124    {
16125        /*
16126         * If the BIOS Signature is present in memory, restore the
16127         * BIOS Handshake Configuration Table and do not perform
16128         * a SCSI Bus Reset.
16129         */
16130        if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
16131        {
16132            /*
16133             * Restore per TID negotiated values.
16134             */
16135            AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16136            AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16137            AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16138            for (tid = 0; tid <= ADV_MAX_TID; tid++)
16139            {
16140                AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16141                    max_cmd[tid]);
16142            }
16143        } else
16144        {
16145            if (AdvResetSB(asc_dvc) != ADV_TRUE)
16146            {
16147                warn_code = ASC_WARN_BUSRESET_ERROR;
16148            }
16149        }
16150    }
16151
16152    return warn_code;
16153}
16154
16155/*
16156 * Initialize the ASC-38C1600.
16157 *
16158 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
16159 *
16160 * For a non-fatal error return a warning code. If there are no warnings
16161 * then 0 is returned.
16162 *
16163 * Needed after initialization for error recovery.
16164 */
16165STATIC int
16166AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
16167{
16168    AdvPortAddr iop_base;
16169    ushort      warn_code;
16170    ADV_DCNT    sum;
16171    int         begin_addr;
16172    int         end_addr;
16173    ushort      code_sum;
16174    long        word;
16175    int         j;
16176    int         adv_asc38C1600_expanded_size;
16177    ADV_CARR_T  *carrp;
16178    ADV_DCNT    contig_len;
16179    ADV_SDCNT   buf_size;
16180    ADV_PADDR   carr_paddr;
16181    int         i;
16182    ushort      scsi_cfg1;
16183    uchar       byte;
16184    uchar       tid;
16185    ushort      bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
16186    ushort      wdtr_able, sdtr_able, ppr_able, tagqng_able;
16187    uchar       max_cmd[ASC_MAX_TID + 1];
16188
16189    /* If there is already an error, don't continue. */
16190    if (asc_dvc->err_code != 0)
16191    {
16192        return ADV_ERROR;
16193    }
16194
16195    /*
16196     * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
16197     */
16198    if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600)
16199    {
16200        asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
16201        return ADV_ERROR;
16202    }
16203
16204    warn_code = 0;
16205    iop_base = asc_dvc->iop_base;
16206
16207    /*
16208     * Save the RISC memory BIOS region before writing the microcode.
16209     * The BIOS may already be loaded and using its RISC LRAM region
16210     * so its region must be saved and restored.
16211     *
16212     * Note: This code makes the assumption, which is currently true,
16213     * that a chip reset does not clear RISC LRAM.
16214     */
16215    for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
16216    {
16217        AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
16218    }
16219
16220    /*
16221     * Save current per TID negotiated values.
16222     */
16223    AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16224    AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16225    AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16226    AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16227    for (tid = 0; tid <= ASC_MAX_TID; tid++)
16228    {
16229        AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16230            max_cmd[tid]);
16231    }
16232
16233    /*
16234     * RAM BIST (Built-In Self Test)
16235     *
16236     * Address : I/O base + offset 0x38h register (byte).
16237     * Function: Bit 7-6(RW) : RAM mode
16238     *                          Normal Mode   : 0x00
16239     *                          Pre-test Mode : 0x40
16240     *                          RAM Test Mode : 0x80
16241     *           Bit 5       : unused
16242     *           Bit 4(RO)   : Done bit
16243     *           Bit 3-0(RO) : Status
16244     *                          Host Error    : 0x08
16245     *                          Int_RAM Error : 0x04
16246     *                          RISC Error    : 0x02
16247     *                          SCSI Error    : 0x01
16248     *                          No Error      : 0x00
16249     *
16250     * Note: RAM BIST code should be put right here, before loading the
16251     * microcode and after saving the RISC memory BIOS region.
16252     */
16253
16254    /*
16255     * LRAM Pre-test
16256     *
16257     * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
16258     * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
16259     * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
16260     * to NORMAL_MODE, return an error too.
16261     */
16262    for (i = 0; i < 2; i++)
16263    {
16264        AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
16265        DvcSleepMilliSecond(10);  /* Wait for 10ms before reading back. */
16266        byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
16267        if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE)
16268        {
16269            asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
16270            return ADV_ERROR;
16271        }
16272
16273        AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
16274        DvcSleepMilliSecond(10);  /* Wait for 10ms before reading back. */
16275        if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
16276            != NORMAL_VALUE)
16277        {
16278            asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
16279            return ADV_ERROR;
16280        }
16281    }
16282
16283    /*
16284     * LRAM Test - It takes about 1.5 ms to run through the test.
16285     *
16286     * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
16287     * If Done bit not set or Status not 0, save register byte, set the
16288     * err_code, and return an error.
16289     */
16290    AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
16291    DvcSleepMilliSecond(10);  /* Wait for 10ms before checking status. */
16292
16293    byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
16294    if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0)
16295    {
16296        /* Get here if Done bit not set or Status not 0. */
16297        asc_dvc->bist_err_code = byte;  /* for BIOS display message */
16298        asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
16299        return ADV_ERROR;
16300    }
16301
16302    /* We need to reset back to normal mode after LRAM test passes. */
16303    AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
16304
16305    /*
16306     * Load the Microcode
16307     *
16308     * Write the microcode image to RISC memory starting at address 0.
16309     *
16310     */
16311    AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
16312
16313    /*
16314     * Assume the following compressed format of the microcode buffer:
16315     *
16316     *  254 word (508 byte) table indexed by byte code followed
16317     *  by the following byte codes:
16318     *
16319     *    1-Byte Code:
16320     *      00: Emit word 0 in table.
16321     *      01: Emit word 1 in table.
16322     *      .
16323     *      FD: Emit word 253 in table.
16324     *
16325     *    Multi-Byte Code:
16326     *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
16327     *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
16328     */
16329    word = 0;
16330    for (i = 253 * 2; i < _adv_asc38C1600_size; i++)
16331    {
16332        if (_adv_asc38C1600_buf[i] == 0xff)
16333        {
16334            for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++)
16335            {
16336                AdvWriteWordAutoIncLram(iop_base, (((ushort)
16337                     _adv_asc38C1600_buf[i + 3] << 8) |
16338                     _adv_asc38C1600_buf[i + 2]));
16339                word++;
16340            }
16341           i += 3;
16342        } else if (_adv_asc38C1600_buf[i] == 0xfe)
16343        {
16344                AdvWriteWordAutoIncLram(iop_base, (((ushort)
16345                     _adv_asc38C1600_buf[i + 2] << 8) |
16346                     _adv_asc38C1600_buf[i + 1]));
16347            i += 2;
16348            word++;
16349        } else
16350        {
16351            AdvWriteWordAutoIncLram(iop_base, (((ushort)
16352                 _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) |
16353                 _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2]));
16354            word++;
16355        }
16356    }
16357
16358    /*
16359     * Set 'word' for later use to clear the rest of memory and save
16360     * the expanded mcode size.
16361     */
16362    word *= 2;
16363    adv_asc38C1600_expanded_size = word;
16364
16365    /*
16366     * Clear the rest of ASC-38C1600 Internal RAM (32KB).
16367     */
16368    for (; word < ADV_38C1600_MEMSIZE; word += 2)
16369    {
16370        AdvWriteWordAutoIncLram(iop_base, 0);
16371    }
16372
16373    /*
16374     * Verify the microcode checksum.
16375     */
16376    sum = 0;
16377    AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
16378
16379    for (word = 0; word < adv_asc38C1600_expanded_size; word += 2)
16380    {
16381        sum += AdvReadWordAutoIncLram(iop_base);
16382    }
16383
16384    if (sum != _adv_asc38C1600_chksum)
16385    {
16386        asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
16387        return ADV_ERROR;
16388    }
16389
16390    /*
16391     * Restore the RISC memory BIOS region.
16392     */
16393    for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
16394    {
16395        AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
16396    }
16397
16398    /*
16399     * Calculate and write the microcode code checksum to the microcode
16400     * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
16401     */
16402    AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
16403    AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
16404    code_sum = 0;
16405    AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
16406    for (word = begin_addr; word < end_addr; word += 2)
16407    {
16408        code_sum += AdvReadWordAutoIncLram(iop_base);
16409    }
16410    AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
16411
16412    /*
16413     * Read microcode version and date.
16414     */
16415    AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
16416    AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
16417
16418    /*
16419     * Set the chip type to indicate the ASC38C1600.
16420     */
16421    AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
16422
16423    /*
16424     * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
16425     * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
16426     * cable detection and then we are able to read C_DET[3:0].
16427     *
16428     * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
16429     * Microcode Default Value' section below.
16430     */
16431    scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
16432    AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, scsi_cfg1 | DIS_TERM_DRV);
16433
16434    /*
16435     * If the PCI Configuration Command Register "Parity Error Response
16436     * Control" Bit was clear (0), then set the microcode variable
16437     * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
16438     * to ignore DMA parity errors.
16439     */
16440    if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
16441    {
16442        AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16443        word |= CONTROL_FLAG_IGNORE_PERR;
16444        AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16445    }
16446
16447    /*
16448     * If the BIOS control flag AIPP (Asynchronous Information
16449     * Phase Protection) disable bit is not set, then set the firmware
16450     * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
16451     * AIPP checking and encoding.
16452     */
16453    if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0)
16454    {
16455        AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16456        word |= CONTROL_FLAG_ENABLE_AIPP;
16457        AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16458    }
16459
16460    /*
16461     * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
16462     * and START_CTL_TH [3:2].
16463     */
16464    AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
16465        FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
16466
16467    /*
16468     * Microcode operating variables for WDTR, SDTR, and command tag
16469     * queuing will be set in AdvInquiryHandling() based on what a
16470     * device reports it is capable of in Inquiry byte 7.
16471     *
16472     * If SCSI Bus Resets have been disabled, then directly set
16473     * SDTR and WDTR from the EEPROM configuration. This will allow
16474     * the BIOS and warm boot to work without a SCSI bus hang on
16475     * the Inquiry caused by host and target mismatched DTR values.
16476     * Without the SCSI Bus Reset, before an Inquiry a device can't
16477     * be assumed to be in Asynchronous, Narrow mode.
16478     */
16479    if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
16480    {
16481        AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
16482        AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
16483    }
16484
16485    /*
16486     * Set microcode operating variables for DISC and SDTR_SPEED1,
16487     * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
16488     * configuration values.
16489     *
16490     * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
16491     * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
16492     * without determining here whether the device supports SDTR.
16493     */
16494    AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
16495    AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
16496    AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
16497    AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
16498    AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
16499
16500    /*
16501     * Set SCSI_CFG0 Microcode Default Value.
16502     *
16503     * The microcode will set the SCSI_CFG0 register using this value
16504     * after it is started below.
16505     */
16506    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
16507        PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
16508        asc_dvc->chip_scsi_id);
16509
16510    /*
16511     * Calculate SCSI_CFG1 Microcode Default Value.
16512     *
16513     * The microcode will set the SCSI_CFG1 register using this value
16514     * after it is started below.
16515     *
16516     * Each ASC-38C1600 function has only two cable detect bits.
16517     * The bus mode override bits are in IOPB_SOFT_OVER_WR.
16518     */
16519    scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
16520
16521    /*
16522     * If the cable is reversed all of the SCSI_CTRL register signals
16523     * will be set. Check for and return an error if this condition is
16524     * found.
16525     */
16526    if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
16527    {
16528        asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
16529        return ADV_ERROR;
16530    }
16531
16532    /*
16533     * Each ASC-38C1600 function has two connectors. Only an HVD device
16534     * can not be connected to either connector. An LVD device or SE device
16535     * may be connected to either connecor. If an SE device is connected,
16536     * then at most Ultra speed (20 Mhz) can be used on both connectors.
16537     *
16538     * If an HVD device is attached, return an error.
16539     */
16540    if (scsi_cfg1 & HVD)
16541    {
16542        asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
16543        return ADV_ERROR;
16544    }
16545
16546    /*
16547     * Each function in the ASC-38C1600 uses only the SE cable detect and
16548     * termination because there are two connectors for each function. Each
16549     * function may use either LVD or SE mode. Corresponding the SE automatic
16550     * termination control EEPROM bits are used for each function. Each
16551     * function has its own EEPROM. If SE automatic control is enabled for
16552     * the function, then set the termination value based on a table listed
16553     * in a_condor.h.
16554     *
16555     * If manual termination is specified in the EEPROM for the function,
16556     * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
16557     * ready to be 'ored' into SCSI_CFG1.
16558     */
16559    if ((asc_dvc->cfg->termination & TERM_SE) == 0)
16560    {
16561        /* SE automatic termination control is enabled. */
16562        switch(scsi_cfg1 & C_DET_SE)
16563        {
16564            /* TERM_SE_HI: on, TERM_SE_LO: on */
16565            case 0x1: case 0x2: case 0x3:
16566                asc_dvc->cfg->termination |= TERM_SE;
16567                break;
16568
16569            case 0x0:
16570                if (ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) == 0)
16571                {
16572                    /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
16573                }
16574                else
16575                {
16576                    /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
16577                    asc_dvc->cfg->termination |= TERM_SE_HI;
16578                }
16579                break;
16580        }
16581    }
16582
16583    /*
16584     * Clear any set TERM_SE bits.
16585     */
16586    scsi_cfg1 &= ~TERM_SE;
16587
16588    /*
16589     * Invert the TERM_SE bits and then set 'scsi_cfg1'.
16590     */
16591    scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
16592
16593    /*
16594     * Clear Big Endian and Terminator Polarity bits and set possibly
16595     * modified termination control bits in the Microcode SCSI_CFG1
16596     * Register Value.
16597     *
16598     * Big Endian bit is not used even on big endian machines.
16599     */
16600    scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
16601
16602    /*
16603     * Set SCSI_CFG1 Microcode Default Value
16604     *
16605     * Set possibly modified termination control bits in the Microcode
16606     * SCSI_CFG1 Register Value.
16607     *
16608     * The microcode will set the SCSI_CFG1 register using this value
16609     * after it is started below.
16610     */
16611    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
16612
16613    /*
16614     * Set MEM_CFG Microcode Default Value
16615     *
16616     * The microcode will set the MEM_CFG register using this value
16617     * after it is started below.
16618     *
16619     * MEM_CFG may be accessed as a word or byte, but only bits 0-7
16620     * are defined.
16621     *
16622     * ASC-38C1600 has 32KB internal memory.
16623     *
16624     * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
16625     * out a special 16K Adv Library and Microcode version. After the issue
16626     * resolved, we should turn back to the 32K support. Both a_condor.h and
16627     * mcode.sas files also need to be updated.
16628     *
16629     * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
16630     *  BIOS_EN | RAM_SZ_32KB);
16631     */
16632     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, BIOS_EN | RAM_SZ_16KB);
16633
16634    /*
16635     * Set SEL_MASK Microcode Default Value
16636     *
16637     * The microcode will set the SEL_MASK register using this value
16638     * after it is started below.
16639     */
16640    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
16641        ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
16642
16643    /*
16644     * Build the carrier freelist.
16645     *
16646     * Driver must have already allocated memory and set 'carrier_buf'.
16647     */
16648
16649    ASC_ASSERT(asc_dvc->carrier_buf != NULL);
16650
16651    carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
16652    asc_dvc->carr_freelist = NULL;
16653    if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
16654    {
16655        buf_size = ADV_CARRIER_BUFSIZE;
16656    } else
16657    {
16658        buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
16659    }
16660
16661    do {
16662        /*
16663         * Get physical address for the carrier 'carrp'.
16664         */
16665        contig_len = sizeof(ADV_CARR_T);
16666        carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
16667            (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
16668
16669        buf_size -= sizeof(ADV_CARR_T);
16670
16671        /*
16672         * If the current carrier is not physically contiguous, then
16673         * maybe there was a page crossing. Try the next carrier aligned
16674         * start address.
16675         */
16676        if (contig_len < sizeof(ADV_CARR_T))
16677        {
16678            carrp++;
16679            continue;
16680        }
16681
16682        carrp->carr_pa = carr_paddr;
16683        carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
16684
16685        /*
16686         * Insert the carrier at the beginning of the freelist.
16687         */
16688        carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
16689        asc_dvc->carr_freelist = carrp;
16690
16691        carrp++;
16692    }
16693    while (buf_size > 0);
16694
16695    /*
16696     * Set-up the Host->RISC Initiator Command Queue (ICQ).
16697     */
16698    if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
16699    {
16700        asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16701        return ADV_ERROR;
16702    }
16703    asc_dvc->carr_freelist = (ADV_CARR_T *)
16704        ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
16705
16706    /*
16707     * The first command issued will be placed in the stopper carrier.
16708     */
16709    asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16710
16711    /*
16712     * Set RISC ICQ physical address start value. Initialize the
16713     * COMMA register to the same value otherwise the RISC will
16714     * prematurely detect a command is available.
16715     */
16716    AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
16717    AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
16718        le32_to_cpu(asc_dvc->icq_sp->carr_pa));
16719
16720    /*
16721     * Set-up the RISC->Host Initiator Response Queue (IRQ).
16722     */
16723    if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
16724    {
16725        asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16726        return ADV_ERROR;
16727    }
16728    asc_dvc->carr_freelist = (ADV_CARR_T *)
16729        ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
16730
16731    /*
16732     * The first command completed by the RISC will be placed in
16733     * the stopper.
16734     *
16735     * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
16736     * completed the RISC will set the ASC_RQ_STOPPER bit.
16737     */
16738    asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16739
16740    /*
16741     * Set RISC IRQ physical address start value.
16742     */
16743    AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
16744    asc_dvc->carr_pending_cnt = 0;
16745
16746    AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
16747        (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
16748    AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
16749    AdvWriteWordRegister(iop_base, IOPW_PC, word);
16750
16751    /* finally, finally, gentlemen, start your engine */
16752    AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
16753
16754    /*
16755     * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
16756     * Resets should be performed. The RISC has to be running
16757     * to issue a SCSI Bus Reset.
16758     */
16759    if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
16760    {
16761        /*
16762         * If the BIOS Signature is present in memory, restore the
16763         * per TID microcode operating variables.
16764         */
16765        if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
16766        {
16767            /*
16768             * Restore per TID negotiated values.
16769             */
16770            AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16771            AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16772            AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16773            AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16774            for (tid = 0; tid <= ASC_MAX_TID; tid++)
16775            {
16776                AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16777                    max_cmd[tid]);
16778            }
16779        } else
16780        {
16781            if (AdvResetSB(asc_dvc) != ADV_TRUE)
16782            {
16783                warn_code = ASC_WARN_BUSRESET_ERROR;
16784            }
16785        }
16786    }
16787
16788    return warn_code;
16789}
16790
16791/*
16792 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
16793 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
16794 * all of this is done.
16795 *
16796 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
16797 *
16798 * For a non-fatal error return a warning code. If there are no warnings
16799 * then 0 is returned.
16800 *
16801 * Note: Chip is stopped on entry.
16802 */
16803ASC_INITFUNC(
16804STATIC int,
16805AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
16806)
16807{
16808    AdvPortAddr         iop_base;
16809    ushort              warn_code;
16810    ADVEEP_3550_CONFIG  eep_config;
16811    int                 i;
16812
16813    iop_base = asc_dvc->iop_base;
16814
16815    warn_code = 0;
16816
16817    /*
16818     * Read the board's EEPROM configuration.
16819     *
16820     * Set default values if a bad checksum is found.
16821     */
16822    if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
16823    {
16824        warn_code |= ASC_WARN_EEPROM_CHKSUM;
16825
16826        /*
16827         * Set EEPROM default values.
16828         */
16829        for (i = 0; i < sizeof(ADVEEP_3550_CONFIG); i++)
16830        {
16831            *((uchar *) &eep_config + i) =
16832                *((uchar *) &Default_3550_EEPROM_Config + i);
16833        }
16834
16835        /*
16836         * Assume the 6 byte board serial number that was read
16837         * from EEPROM is correct even if the EEPROM checksum
16838         * failed.
16839         */
16840        eep_config.serial_number_word3 =
16841            AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16842
16843        eep_config.serial_number_word2 =
16844            AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16845
16846        eep_config.serial_number_word1 =
16847            AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16848
16849        AdvSet3550EEPConfig(iop_base, &eep_config);
16850    }
16851    /*
16852     * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
16853     * EEPROM configuration that was read.
16854     *
16855     * This is the mapping of EEPROM fields to Adv Library fields.
16856     */
16857    asc_dvc->wdtr_able = eep_config.wdtr_able;
16858    asc_dvc->sdtr_able = eep_config.sdtr_able;
16859    asc_dvc->ultra_able = eep_config.ultra_able;
16860    asc_dvc->tagqng_able = eep_config.tagqng_able;
16861    asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16862    asc_dvc->max_host_qng = eep_config.max_host_qng;
16863    asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16864    asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
16865    asc_dvc->start_motor = eep_config.start_motor;
16866    asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16867    asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16868    asc_dvc->no_scam = eep_config.scam_tolerant;
16869    asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
16870    asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
16871    asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
16872
16873    /*
16874     * Set the host maximum queuing (max. 253, min. 16) and the per device
16875     * maximum queuing (max. 63, min. 4).
16876     */
16877    if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
16878    {
16879        eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16880    } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
16881    {
16882        /* If the value is zero, assume it is uninitialized. */
16883        if (eep_config.max_host_qng == 0)
16884        {
16885            eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16886        } else
16887        {
16888            eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16889        }
16890    }
16891
16892    if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
16893    {
16894        eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16895    } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
16896    {
16897        /* If the value is zero, assume it is uninitialized. */
16898        if (eep_config.max_dvc_qng == 0)
16899        {
16900            eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16901        } else
16902        {
16903            eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16904        }
16905    }
16906
16907    /*
16908     * If 'max_dvc_qng' is greater than 'max_host_qng', then
16909     * set 'max_dvc_qng' to 'max_host_qng'.
16910     */
16911    if (eep_config.max_dvc_qng > eep_config.max_host_qng)
16912    {
16913        eep_config.max_dvc_qng = eep_config.max_host_qng;
16914    }
16915
16916    /*
16917     * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
16918     * values based on possibly adjusted EEPROM values.
16919     */
16920    asc_dvc->max_host_qng = eep_config.max_host_qng;
16921    asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16922
16923
16924    /*
16925     * If the EEPROM 'termination' field is set to automatic (0), then set
16926     * the ADV_DVC_CFG 'termination' field to automatic also.
16927     *
16928     * If the termination is specified with a non-zero 'termination'
16929     * value check that a legal value is set and set the ADV_DVC_CFG
16930     * 'termination' field appropriately.
16931     */
16932    if (eep_config.termination == 0)
16933    {
16934        asc_dvc->cfg->termination = 0;    /* auto termination */
16935    } else
16936    {
16937        /* Enable manual control with low off / high off. */
16938        if (eep_config.termination == 1)
16939        {
16940            asc_dvc->cfg->termination = TERM_CTL_SEL;
16941
16942        /* Enable manual control with low off / high on. */
16943        } else if (eep_config.termination == 2)
16944        {
16945            asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
16946
16947        /* Enable manual control with low on / high on. */
16948        } else if (eep_config.termination == 3)
16949        {
16950            asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
16951        } else
16952        {
16953            /*
16954             * The EEPROM 'termination' field contains a bad value. Use
16955             * automatic termination instead.
16956             */
16957            asc_dvc->cfg->termination = 0;
16958            warn_code |= ASC_WARN_EEPROM_TERMINATION;
16959        }
16960    }
16961
16962    return warn_code;
16963}
16964
16965/*
16966 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
16967 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
16968 * all of this is done.
16969 *
16970 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
16971 *
16972 * For a non-fatal error return a warning code. If there are no warnings
16973 * then 0 is returned.
16974 *
16975 * Note: Chip is stopped on entry.
16976 */
16977ASC_INITFUNC(
16978STATIC int,
16979AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
16980)
16981{
16982    AdvPortAddr              iop_base;
16983    ushort                   warn_code;
16984    ADVEEP_38C0800_CONFIG    eep_config;
16985    int                      i;
16986    uchar                    tid, termination;
16987    ushort                   sdtr_speed = 0;
16988
16989    iop_base = asc_dvc->iop_base;
16990
16991    warn_code = 0;
16992
16993    /*
16994     * Read the board's EEPROM configuration.
16995     *
16996     * Set default values if a bad checksum is found.
16997     */
16998    if (AdvGet38C0800EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
16999    {
17000        warn_code |= ASC_WARN_EEPROM_CHKSUM;
17001
17002        /*
17003         * Set EEPROM default values.
17004         */
17005        for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++)
17006        {
17007            *((uchar *) &eep_config + i) =
17008                *((uchar *) &Default_38C0800_EEPROM_Config + i);
17009        }
17010
17011        /*
17012         * Assume the 6 byte board serial number that was read
17013         * from EEPROM is correct even if the EEPROM checksum
17014         * failed.
17015         */
17016        eep_config.serial_number_word3 =
17017            AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
17018
17019        eep_config.serial_number_word2 =
17020            AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
17021
17022        eep_config.serial_number_word1 =
17023            AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
17024
17025        AdvSet38C0800EEPConfig(iop_base, &eep_config);
17026    }
17027    /*
17028     * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
17029     * EEPROM configuration that was read.
17030     *
17031     * This is the mapping of EEPROM fields to Adv Library fields.
17032     */
17033    asc_dvc->wdtr_able = eep_config.wdtr_able;
17034    asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
17035    asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
17036    asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
17037    asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
17038    asc_dvc->tagqng_able = eep_config.tagqng_able;
17039    asc_dvc->cfg->disc_enable = eep_config.disc_enable;
17040    asc_dvc->max_host_qng = eep_config.max_host_qng;
17041    asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
17042    asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
17043    asc_dvc->start_motor = eep_config.start_motor;
17044    asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
17045    asc_dvc->bios_ctrl = eep_config.bios_ctrl;
17046    asc_dvc->no_scam = eep_config.scam_tolerant;
17047    asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
17048    asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
17049    asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
17050
17051    /*
17052     * For every Target ID if any of its 'sdtr_speed[1234]' bits
17053     * are set, then set an 'sdtr_able' bit for it.
17054     */
17055    asc_dvc->sdtr_able = 0;
17056    for (tid = 0; tid <= ADV_MAX_TID; tid++)
17057    {
17058        if (tid == 0)
17059        {
17060            sdtr_speed = asc_dvc->sdtr_speed1;
17061        } else if (tid == 4)
17062        {
17063            sdtr_speed = asc_dvc->sdtr_speed2;
17064        } else if (tid == 8)
17065        {
17066            sdtr_speed = asc_dvc->sdtr_speed3;
17067        } else if (tid == 12)
17068        {
17069            sdtr_speed = asc_dvc->sdtr_speed4;
17070        }
17071        if (sdtr_speed & ADV_MAX_TID)
17072        {
17073            asc_dvc->sdtr_able |= (1 << tid);
17074        }
17075        sdtr_speed >>= 4;
17076    }
17077
17078    /*
17079     * Set the host maximum queuing (max. 253, min. 16) and the per device
17080     * maximum queuing (max. 63, min. 4).
17081     */
17082    if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
17083    {
17084        eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
17085    } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
17086    {
17087        /* If the value is zero, assume it is uninitialized. */
17088        if (eep_config.max_host_qng == 0)
17089        {
17090            eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
17091        } else
17092        {
17093            eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
17094        }
17095    }
17096
17097    if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
17098    {
17099        eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17100    } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
17101    {
17102        /* If the value is zero, assume it is uninitialized. */
17103        if (eep_config.max_dvc_qng == 0)
17104        {
17105            eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17106        } else
17107        {
17108            eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
17109        }
17110    }
17111
17112    /*
17113     * If 'max_dvc_qng' is greater than 'max_host_qng', then
17114     * set 'max_dvc_qng' to 'max_host_qng'.
17115     */
17116    if (eep_config.max_dvc_qng > eep_config.max_host_qng)
17117    {
17118        eep_config.max_dvc_qng = eep_config.max_host_qng;
17119    }
17120
17121    /*
17122     * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
17123     * values based on possibly adjusted EEPROM values.
17124     */
17125    asc_dvc->max_host_qng = eep_config.max_host_qng;
17126    asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
17127
17128    /*
17129     * If the EEPROM 'termination' field is set to automatic (0), then set
17130     * the ADV_DVC_CFG 'termination' field to automatic also.
17131     *
17132     * If the termination is specified with a non-zero 'termination'
17133     * value check that a legal value is set and set the ADV_DVC_CFG
17134     * 'termination' field appropriately.
17135     */
17136    if (eep_config.termination_se == 0)
17137    {
17138        termination = 0;                         /* auto termination for SE */
17139    } else
17140    {
17141        /* Enable manual control with low off / high off. */
17142        if (eep_config.termination_se == 1)
17143        {
17144            termination = 0;
17145
17146        /* Enable manual control with low off / high on. */
17147        } else if (eep_config.termination_se == 2)
17148        {
17149            termination = TERM_SE_HI;
17150
17151        /* Enable manual control with low on / high on. */
17152        } else if (eep_config.termination_se == 3)
17153        {
17154            termination = TERM_SE;
17155        } else
17156        {
17157            /*
17158             * The EEPROM 'termination_se' field contains a bad value.
17159             * Use automatic termination instead.
17160             */
17161            termination = 0;
17162            warn_code |= ASC_WARN_EEPROM_TERMINATION;
17163        }
17164    }
17165
17166    if (eep_config.termination_lvd == 0)
17167    {
17168        asc_dvc->cfg->termination = termination; /* auto termination for LVD */
17169    } else
17170    {
17171        /* Enable manual control with low off / high off. */
17172        if (eep_config.termination_lvd == 1)
17173        {
17174            asc_dvc->cfg->termination = termination;
17175
17176        /* Enable manual control with low off / high on. */
17177        } else if (eep_config.termination_lvd == 2)
17178        {
17179            asc_dvc->cfg->termination = termination | TERM_LVD_HI;
17180
17181        /* Enable manual control with low on / high on. */
17182        } else if (eep_config.termination_lvd == 3)
17183        {
17184            asc_dvc->cfg->termination =
17185                termination | TERM_LVD;
17186        } else
17187        {
17188            /*
17189             * The EEPROM 'termination_lvd' field contains a bad value.
17190             * Use automatic termination instead.
17191             */
17192            asc_dvc->cfg->termination = termination;
17193            warn_code |= ASC_WARN_EEPROM_TERMINATION;
17194        }
17195    }
17196
17197    return warn_code;
17198}
17199
17200/*
17201 * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
17202 * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
17203 * all of this is done.
17204 *
17205 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
17206 *
17207 * For a non-fatal error return a warning code. If there are no warnings
17208 * then 0 is returned.
17209 *
17210 * Note: Chip is stopped on entry.
17211 */
17212ASC_INITFUNC(
17213STATIC int,
17214AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
17215)
17216{
17217    AdvPortAddr              iop_base;
17218    ushort                   warn_code;
17219    ADVEEP_38C1600_CONFIG    eep_config;
17220    int                      i;
17221    uchar                    tid, termination;
17222    ushort                   sdtr_speed = 0;
17223
17224    iop_base = asc_dvc->iop_base;
17225
17226    warn_code = 0;
17227
17228    /*
17229     * Read the board's EEPROM configuration.
17230     *
17231     * Set default values if a bad checksum is found.
17232     */
17233    if (AdvGet38C1600EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
17234    {
17235        warn_code |= ASC_WARN_EEPROM_CHKSUM;
17236
17237        /*
17238         * Set EEPROM default values.
17239         */
17240        for (i = 0; i < sizeof(ADVEEP_38C1600_CONFIG); i++)
17241        {
17242            if (i == 1 && ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) != 0)
17243            {
17244                /*
17245                 * Set Function 1 EEPROM Word 0 MSB
17246                 *
17247                 * Clear the BIOS_ENABLE (bit 14) and INTAB (bit 11)
17248                 * EEPROM bits.
17249                 *
17250                 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 and
17251                 * old Mac system booting problem. The Expansion ROM must
17252                 * be disabled in Function 1 for these systems.
17253                 *
17254                 */
17255                *((uchar *) &eep_config + i) =
17256                ((*((uchar *) &Default_38C1600_EEPROM_Config + i)) &
17257                    (~(((ADV_EEPROM_BIOS_ENABLE | ADV_EEPROM_INTAB) >> 8) &
17258                     0xFF)));
17259
17260                /*
17261                 * Set the INTAB (bit 11) if the GPIO 0 input indicates
17262                 * the Function 1 interrupt line is wired to INTA.
17263                 *
17264                 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
17265                 *   1 - Function 1 interrupt line wired to INT A.
17266                 *   0 - Function 1 interrupt line wired to INT B.
17267                 *
17268                 * Note: Adapter boards always have Function 0 wired to INTA.
17269                 * Put all 5 GPIO bits in input mode and then read
17270                 * their input values.
17271                 */
17272                AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0);
17273                if (AdvReadByteRegister(iop_base, IOPB_GPIO_DATA) & 0x01)
17274                {
17275                    /* Function 1 interrupt wired to INTA; Set EEPROM bit. */
17276                *((uchar *) &eep_config + i) |=
17277                    ((ADV_EEPROM_INTAB >> 8) & 0xFF);
17278                }
17279            }
17280            else
17281            {
17282                *((uchar *) &eep_config + i) =
17283                *((uchar *) &Default_38C1600_EEPROM_Config + i);
17284            }
17285        }
17286
17287        /*
17288         * Assume the 6 byte board serial number that was read
17289         * from EEPROM is correct even if the EEPROM checksum
17290         * failed.
17291         */
17292        eep_config.serial_number_word3 =
17293            AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
17294
17295        eep_config.serial_number_word2 =
17296            AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
17297
17298        eep_config.serial_number_word1 =
17299            AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
17300
17301        AdvSet38C1600EEPConfig(iop_base, &eep_config);
17302    }
17303
17304    /*
17305     * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
17306     * EEPROM configuration that was read.
17307     *
17308     * This is the mapping of EEPROM fields to Adv Library fields.
17309     */
17310    asc_dvc->wdtr_able = eep_config.wdtr_able;
17311    asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
17312    asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
17313    asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
17314    asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
17315    asc_dvc->ppr_able = 0;
17316    asc_dvc->tagqng_able = eep_config.tagqng_able;
17317    asc_dvc->cfg->disc_enable = eep_config.disc_enable;
17318    asc_dvc->max_host_qng = eep_config.max_host_qng;
17319    asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
17320    asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
17321    asc_dvc->start_motor = eep_config.start_motor;
17322    asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
17323    asc_dvc->bios_ctrl = eep_config.bios_ctrl;
17324    asc_dvc->no_scam = eep_config.scam_tolerant;
17325
17326    /*
17327     * For every Target ID if any of its 'sdtr_speed[1234]' bits
17328     * are set, then set an 'sdtr_able' bit for it.
17329     */
17330    asc_dvc->sdtr_able = 0;
17331    for (tid = 0; tid <= ASC_MAX_TID; tid++)
17332    {
17333        if (tid == 0)
17334        {
17335            sdtr_speed = asc_dvc->sdtr_speed1;
17336        } else if (tid == 4)
17337        {
17338            sdtr_speed = asc_dvc->sdtr_speed2;
17339        } else if (tid == 8)
17340        {
17341            sdtr_speed = asc_dvc->sdtr_speed3;
17342        } else if (tid == 12)
17343        {
17344            sdtr_speed = asc_dvc->sdtr_speed4;
17345        }
17346        if (sdtr_speed & ASC_MAX_TID)
17347        {
17348            asc_dvc->sdtr_able |= (1 << tid);
17349        }
17350        sdtr_speed >>= 4;
17351    }
17352
17353    /*
17354     * Set the host maximum queuing (max. 253, min. 16) and the per device
17355     * maximum queuing (max. 63, min. 4).
17356     */
17357    if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
17358    {
17359        eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
17360    } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
17361    {
17362        /* If the value is zero, assume it is uninitialized. */
17363        if (eep_config.max_host_qng == 0)
17364        {
17365            eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
17366        } else
17367        {
17368            eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
17369        }
17370    }
17371
17372    if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
17373    {
17374        eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17375    } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
17376    {
17377        /* If the value is zero, assume it is uninitialized. */
17378        if (eep_config.max_dvc_qng == 0)
17379        {
17380            eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17381        } else
17382        {
17383            eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
17384        }
17385    }
17386
17387    /*
17388     * If 'max_dvc_qng' is greater than 'max_host_qng', then
17389     * set 'max_dvc_qng' to 'max_host_qng'.
17390     */
17391    if (eep_config.max_dvc_qng > eep_config.max_host_qng)
17392    {
17393        eep_config.max_dvc_qng = eep_config.max_host_qng;
17394    }
17395
17396    /*
17397     * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
17398     * values based on possibly adjusted EEPROM values.
17399     */
17400    asc_dvc->max_host_qng = eep_config.max_host_qng;
17401    asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
17402
17403    /*
17404     * If the EEPROM 'termination' field is set to automatic (0), then set
17405     * the ASC_DVC_CFG 'termination' field to automatic also.
17406     *
17407     * If the termination is specified with a non-zero 'termination'
17408     * value check that a legal value is set and set the ASC_DVC_CFG
17409     * 'termination' field appropriately.
17410     */
17411    if (eep_config.termination_se == 0)
17412    {
17413        termination = 0;                         /* auto termination for SE */
17414    } else
17415    {
17416        /* Enable manual control with low off / high off. */
17417        if (eep_config.termination_se == 1)
17418        {
17419            termination = 0;
17420
17421        /* Enable manual control with low off / high on. */
17422        } else if (eep_config.termination_se == 2)
17423        {
17424            termination = TERM_SE_HI;
17425
17426        /* Enable manual control with low on / high on. */
17427        } else if (eep_config.termination_se == 3)
17428        {
17429            termination = TERM_SE;
17430        } else
17431        {
17432            /*
17433             * The EEPROM 'termination_se' field contains a bad value.
17434             * Use automatic termination instead.
17435             */
17436            termination = 0;
17437            warn_code |= ASC_WARN_EEPROM_TERMINATION;
17438        }
17439    }
17440
17441    if (eep_config.termination_lvd == 0)
17442    {
17443        asc_dvc->cfg->termination = termination; /* auto termination for LVD */
17444    } else
17445    {
17446        /* Enable manual control with low off / high off. */
17447        if (eep_config.termination_lvd == 1)
17448        {
17449            asc_dvc->cfg->termination = termination;
17450
17451        /* Enable manual control with low off / high on. */
17452        } else if (eep_config.termination_lvd == 2)
17453        {
17454            asc_dvc->cfg->termination = termination | TERM_LVD_HI;
17455
17456        /* Enable manual control with low on / high on. */
17457        } else if (eep_config.termination_lvd == 3)
17458        {
17459            asc_dvc->cfg->termination =
17460                termination | TERM_LVD;
17461        } else
17462        {
17463            /*
17464             * The EEPROM 'termination_lvd' field contains a bad value.
17465             * Use automatic termination instead.
17466             */
17467            asc_dvc->cfg->termination = termination;
17468            warn_code |= ASC_WARN_EEPROM_TERMINATION;
17469        }
17470    }
17471
17472    return warn_code;
17473}
17474
17475/*
17476 * Read EEPROM configuration into the specified buffer.
17477 *
17478 * Return a checksum based on the EEPROM configuration read.
17479 */
17480ASC_INITFUNC(
17481STATIC ushort,
17482AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
17483)
17484{
17485    ushort              wval, chksum;
17486    ushort              *wbuf;
17487    int                 eep_addr;
17488    ushort              *charfields;
17489
17490    charfields = (ushort *) &ADVEEP_3550_Config_Field_IsChar;
17491    wbuf = (ushort *) cfg_buf;
17492    chksum = 0;
17493
17494    for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
17495         eep_addr < ADV_EEP_DVC_CFG_END;
17496         eep_addr++, wbuf++)
17497    {
17498        wval = AdvReadEEPWord(iop_base, eep_addr);
17499        chksum += wval; /* Checksum is calculated from word values. */
17500        if (*charfields++) {
17501            *wbuf = le16_to_cpu(wval);
17502        } else {
17503            *wbuf = wval;
17504        }
17505    }
17506    /* Read checksum word. */
17507    *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17508    wbuf++; charfields++;
17509
17510    /* Read rest of EEPROM not covered by the checksum. */
17511    for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
17512         eep_addr < ADV_EEP_MAX_WORD_ADDR;
17513         eep_addr++, wbuf++)
17514    {
17515        *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17516        if (*charfields++) {
17517            *wbuf = le16_to_cpu(*wbuf);
17518        }
17519    }
17520    return chksum;
17521}
17522
17523/*
17524 * Read EEPROM configuration into the specified buffer.
17525 *
17526 * Return a checksum based on the EEPROM configuration read.
17527 */
17528ASC_INITFUNC(
17529STATIC ushort,
17530AdvGet38C0800EEPConfig(AdvPortAddr iop_base,
17531                       ADVEEP_38C0800_CONFIG *cfg_buf)
17532)
17533{
17534    ushort              wval, chksum;
17535    ushort              *wbuf;
17536    int                 eep_addr;
17537    ushort              *charfields;
17538
17539    charfields = (ushort *) &ADVEEP_38C0800_Config_Field_IsChar;
17540    wbuf = (ushort *) cfg_buf;
17541    chksum = 0;
17542
17543    for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
17544         eep_addr < ADV_EEP_DVC_CFG_END;
17545         eep_addr++, wbuf++)
17546    {
17547        wval = AdvReadEEPWord(iop_base, eep_addr);
17548        chksum += wval; /* Checksum is calculated from word values. */
17549        if (*charfields++) {
17550            *wbuf = le16_to_cpu(wval);
17551        } else {
17552            *wbuf = wval;
17553        }
17554    }
17555    /* Read checksum word. */
17556    *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17557    wbuf++; charfields++;
17558
17559    /* Read rest of EEPROM not covered by the checksum. */
17560    for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
17561         eep_addr < ADV_EEP_MAX_WORD_ADDR;
17562         eep_addr++, wbuf++)
17563    {
17564        *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17565        if (*charfields++) {
17566            *wbuf = le16_to_cpu(*wbuf);
17567        }
17568    }
17569    return chksum;
17570}
17571
17572/*
17573 * Read EEPROM configuration into the specified buffer.
17574 *
17575 * Return a checksum based on the EEPROM configuration read.
17576 */
17577ASC_INITFUNC(
17578STATIC ushort,
17579AdvGet38C1600EEPConfig(AdvPortAddr iop_base,
17580                       ADVEEP_38C1600_CONFIG *cfg_buf)
17581)
17582{
17583    ushort              wval, chksum;
17584    ushort              *wbuf;
17585    int                 eep_addr;
17586    ushort              *charfields;
17587
17588    charfields = (ushort*) &ADVEEP_38C1600_Config_Field_IsChar;
17589    wbuf = (ushort *) cfg_buf;
17590    chksum = 0;
17591
17592    for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
17593         eep_addr < ADV_EEP_DVC_CFG_END;
17594         eep_addr++, wbuf++)
17595    {
17596        wval = AdvReadEEPWord(iop_base, eep_addr);
17597        chksum += wval; /* Checksum is calculated from word values. */
17598        if (*charfields++) {
17599            *wbuf = le16_to_cpu(wval);
17600        } else {
17601            *wbuf = wval;
17602        }
17603    }
17604    /* Read checksum word. */
17605    *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17606    wbuf++; charfields++;
17607
17608    /* Read rest of EEPROM not covered by the checksum. */
17609    for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
17610         eep_addr < ADV_EEP_MAX_WORD_ADDR;
17611         eep_addr++, wbuf++)
17612    {
17613        *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17614        if (*charfields++) {
17615            *wbuf = le16_to_cpu(*wbuf);
17616        }
17617    }
17618    return chksum;
17619}
17620
17621/*
17622 * Read the EEPROM from specified location
17623 */
17624ASC_INITFUNC(
17625STATIC ushort,
17626AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
17627)
17628{
17629    AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
17630        ASC_EEP_CMD_READ | eep_word_addr);
17631    AdvWaitEEPCmd(iop_base);
17632    return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
17633}
17634
17635/*
17636 * Wait for EEPROM command to complete
17637 */
17638ASC_INITFUNC(
17639STATIC void,
17640AdvWaitEEPCmd(AdvPortAddr iop_base)
17641)
17642{
17643    int eep_delay_ms;
17644
17645    for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++)
17646    {
17647        if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE)
17648        {
17649            break;
17650        }
17651        DvcSleepMilliSecond(1);
17652    }
17653    if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) == 0)
17654    {
17655        ASC_ASSERT(0);
17656    }
17657    return;
17658}
17659
17660/*
17661 * Write the EEPROM from 'cfg_buf'.
17662 */
17663void
17664AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
17665{
17666    ushort *wbuf;
17667    ushort addr, chksum;
17668    ushort *charfields;
17669
17670    wbuf = (ushort *) cfg_buf;
17671    charfields = (ushort *) &ADVEEP_3550_Config_Field_IsChar;
17672    chksum = 0;
17673
17674    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17675    AdvWaitEEPCmd(iop_base);
17676
17677    /*
17678     * Write EEPROM from word 0 to word 20.
17679     */
17680    for (addr = ADV_EEP_DVC_CFG_BEGIN;
17681         addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
17682    {
17683        ushort word;
17684
17685        if (*charfields++) {
17686            word = cpu_to_le16(*wbuf);
17687        } else {
17688            word = *wbuf;
17689        }
17690        chksum += *wbuf; /* Checksum is calculated from word values. */
17691        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17692        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17693        AdvWaitEEPCmd(iop_base);
17694        DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
17695    }
17696
17697    /*
17698     * Write EEPROM checksum at word 21.
17699     */
17700    AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17701    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17702    AdvWaitEEPCmd(iop_base);
17703    wbuf++; charfields++;
17704
17705    /*
17706     * Write EEPROM OEM name at words 22 to 29.
17707     */
17708    for (addr = ADV_EEP_DVC_CTL_BEGIN;
17709         addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17710    {
17711        ushort word;
17712
17713        if (*charfields++) {
17714            word = cpu_to_le16(*wbuf);
17715        } else {
17716            word = *wbuf;
17717        }
17718        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17719        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17720        AdvWaitEEPCmd(iop_base);
17721    }
17722    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17723    AdvWaitEEPCmd(iop_base);
17724    return;
17725}
17726
17727/*
17728 * Write the EEPROM from 'cfg_buf'.
17729 */
17730void
17731AdvSet38C0800EEPConfig(AdvPortAddr iop_base,
17732                       ADVEEP_38C0800_CONFIG *cfg_buf)
17733{
17734    ushort *wbuf;
17735    ushort *charfields;
17736    ushort addr, chksum;
17737
17738    wbuf = (ushort *) cfg_buf;
17739    charfields = (ushort *) &ADVEEP_38C0800_Config_Field_IsChar;
17740    chksum = 0;
17741
17742    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17743    AdvWaitEEPCmd(iop_base);
17744
17745    /*
17746     * Write EEPROM from word 0 to word 20.
17747     */
17748    for (addr = ADV_EEP_DVC_CFG_BEGIN;
17749         addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
17750    {
17751        ushort word;
17752
17753        if (*charfields++) {
17754            word = cpu_to_le16(*wbuf);
17755        } else {
17756            word = *wbuf;
17757        }
17758        chksum += *wbuf; /* Checksum is calculated from word values. */
17759        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17760        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17761        AdvWaitEEPCmd(iop_base);
17762        DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
17763    }
17764
17765    /*
17766     * Write EEPROM checksum at word 21.
17767     */
17768    AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17769    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17770    AdvWaitEEPCmd(iop_base);
17771    wbuf++; charfields++;
17772
17773    /*
17774     * Write EEPROM OEM name at words 22 to 29.
17775     */
17776    for (addr = ADV_EEP_DVC_CTL_BEGIN;
17777         addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17778    {
17779        ushort word;
17780
17781        if (*charfields++) {
17782            word = cpu_to_le16(*wbuf);
17783        } else {
17784            word = *wbuf;
17785        }
17786        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17787        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17788        AdvWaitEEPCmd(iop_base);
17789    }
17790    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17791    AdvWaitEEPCmd(iop_base);
17792    return;
17793}
17794
17795/*
17796 * Write the EEPROM from 'cfg_buf'.
17797 */
17798void
17799AdvSet38C1600EEPConfig(AdvPortAddr iop_base,
17800                       ADVEEP_38C1600_CONFIG *cfg_buf)
17801{
17802    ushort              *wbuf;
17803    ushort              *charfields;
17804    ushort              addr, chksum;
17805
17806    wbuf = (ushort *) cfg_buf;
17807    charfields = (ushort *) &ADVEEP_38C1600_Config_Field_IsChar;
17808    chksum = 0;
17809
17810    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17811    AdvWaitEEPCmd(iop_base);
17812
17813    /*
17814     * Write EEPROM from word 0 to word 20.
17815     */
17816    for (addr = ADV_EEP_DVC_CFG_BEGIN;
17817         addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
17818    {
17819        ushort word;
17820
17821        if (*charfields++) {
17822            word = cpu_to_le16(*wbuf);
17823        } else {
17824            word = *wbuf;
17825        }
17826        chksum += *wbuf; /* Checksum is calculated from word values. */
17827        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17828        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17829        AdvWaitEEPCmd(iop_base);
17830        DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
17831    }
17832
17833    /*
17834     * Write EEPROM checksum at word 21.
17835     */
17836    AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17837    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17838    AdvWaitEEPCmd(iop_base);
17839    wbuf++; charfields++;
17840
17841    /*
17842     * Write EEPROM OEM name at words 22 to 29.
17843     */
17844    for (addr = ADV_EEP_DVC_CTL_BEGIN;
17845         addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17846    {
17847        ushort word;
17848
17849        if (*charfields++) {
17850            word = cpu_to_le16(*wbuf);
17851        } else {
17852            word = *wbuf;
17853        }
17854        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17855        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17856        AdvWaitEEPCmd(iop_base);
17857    }
17858    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17859    AdvWaitEEPCmd(iop_base);
17860    return;
17861}
17862
17863/* a_advlib.c */
17864/*
17865 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
17866 *
17867 *   Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
17868 *   add the carrier to the ICQ (Initiator Command Queue), and tickle the
17869 *   RISC to notify it a new command is ready to be executed.
17870 *
17871 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
17872 * set to SCSI_MAX_RETRY.
17873 *
17874 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
17875 * for DMA addresses or math operations are byte swapped to little-endian
17876 * order.
17877 *
17878 * Return:
17879 *      ADV_SUCCESS(1) - The request was successfully queued.
17880 *      ADV_BUSY(0) -    Resource unavailable; Retry again after pending
17881 *                       request completes.
17882 *      ADV_ERROR(-1) -  Invalid ADV_SCSI_REQ_Q request structure
17883 *                       host IC error.
17884 */
17885STATIC int
17886AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc,
17887                ADV_SCSI_REQ_Q *scsiq)
17888{
17889    ulong                  last_int_level;
17890    AdvPortAddr            iop_base;
17891    ADV_DCNT               req_size;
17892    ADV_PADDR              req_paddr;
17893    ADV_CARR_T             *new_carrp;
17894
17895    ASC_ASSERT(scsiq != NULL); /* 'scsiq' should never be NULL. */
17896
17897    /*
17898     * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
17899     */
17900    if (scsiq->target_id > ADV_MAX_TID)
17901    {
17902        scsiq->host_status = QHSTA_M_INVALID_DEVICE;
17903        scsiq->done_status = QD_WITH_ERROR;
17904        return ADV_ERROR;
17905    }
17906
17907    iop_base = asc_dvc->iop_base;
17908
17909    last_int_level = DvcEnterCritical();
17910
17911    /*
17912     * Allocate a carrier ensuring at least one carrier always
17913     * remains on the freelist and initialize fields.
17914     */
17915    if ((new_carrp = asc_dvc->carr_freelist) == NULL)
17916    {
17917       DvcLeaveCritical(last_int_level);
17918       return ADV_BUSY;
17919    }
17920    asc_dvc->carr_freelist = (ADV_CARR_T *)
17921        ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
17922    asc_dvc->carr_pending_cnt++;
17923
17924    /*
17925     * Set the carrier to be a stopper by setting 'next_vpa'
17926     * to the stopper value. The current stopper will be changed
17927     * below to point to the new stopper.
17928     */
17929    new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
17930
17931    /*
17932     * Clear the ADV_SCSI_REQ_Q done flag.
17933     */
17934    scsiq->a_flag &= ~ADV_SCSIQ_DONE;
17935
17936    req_size = sizeof(ADV_SCSI_REQ_Q);
17937    req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *) scsiq,
17938        (ADV_SDCNT *) &req_size, ADV_IS_SCSIQ_FLAG);
17939
17940    ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr);
17941    ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
17942
17943    /* Wait for assertion before making little-endian */
17944    req_paddr = cpu_to_le32(req_paddr);
17945
17946    /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
17947    scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
17948    scsiq->scsiq_rptr = req_paddr;
17949
17950    scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
17951    /*
17952     * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
17953     * order during initialization.
17954     */
17955    scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
17956
17957   /*
17958    * Use the current stopper to send the ADV_SCSI_REQ_Q command to
17959    * the microcode. The newly allocated stopper will become the new
17960    * stopper.
17961    */
17962    asc_dvc->icq_sp->areq_vpa = req_paddr;
17963
17964    /*
17965     * Set the 'next_vpa' pointer for the old stopper to be the
17966     * physical address of the new stopper. The RISC can only
17967     * follow physical addresses.
17968     */
17969    asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
17970
17971    /*
17972     * Set the host adapter stopper pointer to point to the new carrier.
17973     */
17974    asc_dvc->icq_sp = new_carrp;
17975
17976    if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
17977        asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
17978    {
17979        /*
17980         * Tickle the RISC to tell it to read its Command Queue Head pointer.
17981         */
17982        AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
17983        if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
17984        {
17985            /*
17986             * Clear the tickle value. In the ASC-3550 the RISC flag
17987             * command 'clr_tickle_a' does not work unless the host
17988             * value is cleared.
17989             */
17990            AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
17991        }
17992    } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
17993    {
17994        /*
17995         * Notify the RISC a carrier is ready by writing the physical
17996         * address of the new carrier stopper to the COMMA register.
17997         */
17998        AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
17999                le32_to_cpu(new_carrp->carr_pa));
18000    }
18001
18002    DvcLeaveCritical(last_int_level);
18003
18004    return ADV_SUCCESS;
18005}
18006
18007/*
18008 * Reset SCSI Bus and purge all outstanding requests.
18009 *
18010 * Return Value:
18011 *      ADV_TRUE(1) -   All requests are purged and SCSI Bus is reset.
18012 *      ADV_FALSE(0) -  Microcode command failed.
18013 *      ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
18014 *                      may be hung which requires driver recovery.
18015 */
18016STATIC int
18017AdvResetSB(ADV_DVC_VAR *asc_dvc)
18018{
18019    int         status;
18020
18021    /*
18022     * Send the SCSI Bus Reset idle start idle command which asserts
18023     * the SCSI Bus Reset signal.
18024     */
18025    status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET_START, 0L);
18026    if (status != ADV_TRUE)
18027    {
18028        return status;
18029    }
18030
18031    /*
18032     * Delay for the specified SCSI Bus Reset hold time.
18033     *
18034     * The hold time delay is done on the host because the RISC has no
18035     * microsecond accurate timer.
18036     */
18037    DvcDelayMicroSecond(asc_dvc, (ushort) ASC_SCSI_RESET_HOLD_TIME_US);
18038
18039    /*
18040     * Send the SCSI Bus Reset end idle command which de-asserts
18041     * the SCSI Bus Reset signal and purges any pending requests.
18042     */
18043    status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET_END, 0L);
18044    if (status != ADV_TRUE)
18045    {
18046        return status;
18047    }
18048
18049    DvcSleepMilliSecond((ADV_DCNT) asc_dvc->scsi_reset_wait * 1000);
18050
18051    return status;
18052}
18053
18054/*
18055 * Reset chip and SCSI Bus.
18056 *
18057 * Return Value:
18058 *      ADV_TRUE(1) -   Chip re-initialization and SCSI Bus Reset successful.
18059 *      ADV_FALSE(0) -  Chip re-initialization and SCSI Bus Reset failure.
18060 */
18061STATIC int
18062AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
18063{
18064    int         status;
18065    ushort      wdtr_able, sdtr_able, tagqng_able;
18066    ushort      ppr_able = 0;
18067    uchar       tid, max_cmd[ADV_MAX_TID + 1];
18068    AdvPortAddr iop_base;
18069    ushort      bios_sig;
18070
18071    iop_base = asc_dvc->iop_base;
18072
18073    /*
18074     * Save current per TID negotiated values.
18075     */
18076    AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
18077    AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
18078    if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
18079    {
18080        AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
18081    }
18082    AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
18083    for (tid = 0; tid <= ADV_MAX_TID; tid++)
18084    {
18085        AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
18086            max_cmd[tid]);
18087    }
18088
18089    /*
18090     * Force the AdvInitAsc3550/38C0800Driver() function to
18091     * perform a SCSI Bus Reset by clearing the BIOS signature word.
18092     * The initialization functions assumes a SCSI Bus Reset is not
18093     * needed if the BIOS signature word is present.
18094     */
18095    AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
18096    AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
18097
18098    /*
18099     * Stop chip and reset it.
18100     */
18101    AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
18102    AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
18103    DvcSleepMilliSecond(100);
18104    AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_WR_IO_REG);
18105
18106    /*
18107     * Reset Adv Library error code, if any, and try
18108     * re-initializing the chip.
18109     */
18110    asc_dvc->err_code = 0;
18111    if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
18112    {
18113        status = AdvInitAsc38C1600Driver(asc_dvc);
18114    }
18115    else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
18116    {
18117        status = AdvInitAsc38C0800Driver(asc_dvc);
18118    } else
18119    {
18120        status = AdvInitAsc3550Driver(asc_dvc);
18121    }
18122
18123    /* Translate initialization return value to status value. */
18124    if (status == 0)
18125    {
18126        status = ADV_TRUE;
18127    } else
18128    {
18129        status = ADV_FALSE;
18130    }
18131
18132    /*
18133     * Restore the BIOS signature word.
18134     */
18135    AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
18136
18137    /*
18138     * Restore per TID negotiated values.
18139     */
18140    AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
18141    AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
18142    if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
18143    {
18144        AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
18145    }
18146    AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
18147    for (tid = 0; tid <= ADV_MAX_TID; tid++)
18148    {
18149        AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
18150            max_cmd[tid]);
18151    }
18152
18153    return status;
18154}
18155
18156/*
18157 * Adv Library Interrupt Service Routine
18158 *
18159 *  This function is called by a driver's interrupt service routine.
18160 *  The function disables and re-enables interrupts.
18161 *
18162 *  When a microcode idle command is completed, the ADV_DVC_VAR
18163 *  'idle_cmd_done' field is set to ADV_TRUE.
18164 *
18165 *  Note: AdvISR() can be called when interrupts are disabled or even
18166 *  when there is no hardware interrupt condition present. It will
18167 *  always check for completed idle commands and microcode requests.
18168 *  This is an important feature that shouldn't be changed because it
18169 *  allows commands to be completed from polling mode loops.
18170 *
18171 * Return:
18172 *   ADV_TRUE(1) - interrupt was pending
18173 *   ADV_FALSE(0) - no interrupt was pending
18174 */
18175STATIC int
18176AdvISR(ADV_DVC_VAR *asc_dvc)
18177{
18178    AdvPortAddr                 iop_base;
18179    uchar                       int_stat;
18180    ushort                      target_bit;
18181    ADV_CARR_T                  *free_carrp;
18182    ADV_VADDR                   irq_next_vpa;
18183    int                         flags;
18184    ADV_SCSI_REQ_Q              *scsiq;
18185
18186    flags = DvcEnterCritical();
18187
18188    iop_base = asc_dvc->iop_base;
18189
18190    /* Reading the register clears the interrupt. */
18191    int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
18192
18193    if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
18194         ADV_INTR_STATUS_INTRC)) == 0)
18195    {
18196        DvcLeaveCritical(flags);
18197        return ADV_FALSE;
18198    }
18199
18200    /*
18201     * Notify the driver of an asynchronous microcode condition by
18202     * calling the ADV_DVC_VAR.async_callback function. The function
18203     * is passed the microcode ASC_MC_INTRB_CODE byte value.
18204     */
18205    if (int_stat & ADV_INTR_STATUS_INTRB)
18206    {
18207        uchar intrb_code;
18208
18209        AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
18210
18211        if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
18212            asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
18213        {
18214            if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
18215                asc_dvc->carr_pending_cnt != 0)
18216            {
18217                AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
18218                if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
18219                {
18220                    AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
18221                }
18222            }
18223        }
18224
18225        if (asc_dvc->async_callback != 0)
18226        {
18227            (*asc_dvc->async_callback)(asc_dvc, intrb_code);
18228        }
18229    }
18230
18231    /*
18232     * Check if the IRQ stopper carrier contains a completed request.
18233     */
18234    while (((irq_next_vpa =
18235             le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0)
18236    {
18237        /*
18238         * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
18239         * The RISC will have set 'areq_vpa' to a virtual address.
18240         *
18241         * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
18242         * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
18243         * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
18244         * in AdvExeScsiQueue().
18245         */
18246        scsiq = (ADV_SCSI_REQ_Q *)
18247            ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
18248
18249        /*
18250         * Request finished with good status and the queue was not
18251         * DMAed to host memory by the firmware. Set all status fields
18252         * to indicate good status.
18253         */
18254        if ((irq_next_vpa & ASC_RQ_GOOD) != 0)
18255        {
18256            scsiq->done_status = QD_NO_ERROR;
18257            scsiq->host_status = scsiq->scsi_status = 0;
18258            scsiq->data_cnt = 0L;
18259        }
18260
18261        /*
18262         * Advance the stopper pointer to the next carrier
18263         * ignoring the lower four bits. Free the previous
18264         * stopper carrier.
18265         */
18266        free_carrp = asc_dvc->irq_sp;
18267        asc_dvc->irq_sp = (ADV_CARR_T *)
18268            ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
18269
18270        free_carrp->next_vpa =
18271                cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
18272        asc_dvc->carr_freelist = free_carrp;
18273        asc_dvc->carr_pending_cnt--;
18274
18275        ASC_ASSERT(scsiq != NULL);
18276        target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
18277
18278        /*
18279         * Clear request microcode control flag.
18280         */
18281        scsiq->cntl = 0;
18282
18283        /*
18284         * If the command that completed was a SCSI INQUIRY and
18285         * LUN 0 was sent the command, then process the INQUIRY
18286         * command information for the device.
18287         *
18288         * Note: If data returned were either VPD or CmdDt data,
18289         * don't process the INQUIRY command information for
18290         * the device, otherwise may erroneously set *_able bits.
18291         */
18292        if (scsiq->done_status == QD_NO_ERROR &&
18293            scsiq->cdb[0] == SCSICMD_Inquiry &&
18294            scsiq->target_lun == 0 &&
18295            (scsiq->cdb[1] & ADV_INQ_RTN_VPD_AND_CMDDT)
18296                == ADV_INQ_RTN_STD_INQUIRY_DATA)
18297        {
18298            AdvInquiryHandling(asc_dvc, scsiq);
18299        }
18300
18301        /*
18302         * Notify the driver of the completed request by passing
18303         * the ADV_SCSI_REQ_Q pointer to its callback function.
18304         */
18305        scsiq->a_flag |= ADV_SCSIQ_DONE;
18306        (*asc_dvc->isr_callback)(asc_dvc, scsiq);
18307        /*
18308         * Note: After the driver callback function is called, 'scsiq'
18309         * can no longer be referenced.
18310         *
18311         * Fall through and continue processing other completed
18312         * requests...
18313         */
18314
18315        /*
18316         * Disable interrupts again in case the driver inadvertently
18317         * enabled interrupts in its callback function.
18318         *
18319         * The DvcEnterCritical() return value is ignored, because
18320         * the 'flags' saved when AdvISR() was first entered will be
18321         * used to restore the interrupt flag on exit.
18322         */
18323        (void) DvcEnterCritical();
18324    }
18325    DvcLeaveCritical(flags);
18326    return ADV_TRUE;
18327}
18328
18329/*
18330 * Send an idle command to the chip and wait for completion.
18331 *
18332 * Command completion is polled for once per microsecond.
18333 *
18334 * The function can be called from anywhere including an interrupt handler.
18335 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
18336 * functions to prevent reentrancy.
18337 *
18338 * Return Values:
18339 *   ADV_TRUE - command completed successfully
18340 *   ADV_FALSE - command failed
18341 *   ADV_ERROR - command timed out
18342 */
18343STATIC int
18344AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
18345               ushort idle_cmd,
18346               ADV_DCNT idle_cmd_parameter)
18347{
18348    ulong       last_int_level;
18349    int         result;
18350    ADV_DCNT    i, j;
18351    AdvPortAddr iop_base;
18352
18353    last_int_level = DvcEnterCritical();
18354
18355    iop_base = asc_dvc->iop_base;
18356
18357    /*
18358     * Clear the idle command status which is set by the microcode
18359     * to a non-zero value to indicate when the command is completed.
18360     * The non-zero result is one of the IDLE_CMD_STATUS_* values
18361     * defined in a_advlib.h.
18362     */
18363    AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort) 0);
18364
18365    /*
18366     * Write the idle command value after the idle command parameter
18367     * has been written to avoid a race condition. If the order is not
18368     * followed, the microcode may process the idle command before the
18369     * parameters have been written to LRAM.
18370     */
18371    AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
18372        cpu_to_le32(idle_cmd_parameter));
18373    AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
18374
18375    /*
18376     * Tickle the RISC to tell it to process the idle command.
18377     */
18378    AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
18379    if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
18380    {
18381        /*
18382         * Clear the tickle value. In the ASC-3550 the RISC flag
18383         * command 'clr_tickle_b' does not work unless the host
18384         * value is cleared.
18385         */
18386        AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
18387    }
18388
18389    /* Wait for up to 100 millisecond for the idle command to timeout. */
18390    for (i = 0; i < SCSI_WAIT_100_MSEC; i++)
18391    {
18392        /* Poll once each microsecond for command completion. */
18393        for (j = 0; j < SCSI_US_PER_MSEC; j++)
18394        {
18395            AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, result);
18396            if (result != 0)
18397            {
18398                DvcLeaveCritical(last_int_level);
18399                return result;
18400            }
18401            DvcDelayMicroSecond(asc_dvc, (ushort) 1);
18402        }
18403    }
18404
18405    ASC_ASSERT(0); /* The idle command should never timeout. */
18406    DvcLeaveCritical(last_int_level);
18407    return ADV_ERROR;
18408}
18409
18410/*
18411 * Inquiry Information Byte 7 Handling
18412 *
18413 * Handle SCSI Inquiry Command information for a device by setting
18414 * microcode operating variables that affect WDTR, SDTR, and Tag
18415 * Queuing.
18416 */
18417STATIC void
18418AdvInquiryHandling(
18419    ADV_DVC_VAR                 *asc_dvc,
18420    ADV_SCSI_REQ_Q              *scsiq)
18421{
18422    AdvPortAddr                 iop_base;
18423    uchar                       tid;
18424    ADV_SCSI_INQUIRY            *inq;
18425    ushort                      tidmask;
18426    ushort                      cfg_word;
18427
18428    /*
18429     * AdvInquiryHandling() requires up to INQUIRY information Byte 7
18430     * to be available.
18431     *
18432     * If less than 8 bytes of INQUIRY information were requested or less
18433     * than 8 bytes were transferred, then return. cdb[4] is the request
18434     * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the
18435     * microcode to the transfer residual count.
18436     */
18437
18438    if (scsiq->cdb[4] < 8 ||
18439        (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) < 8)
18440    {
18441        return;
18442    }
18443
18444    iop_base = asc_dvc->iop_base;
18445    tid = scsiq->target_id;
18446
18447    inq = (ADV_SCSI_INQUIRY *) scsiq->vdata_addr;
18448
18449    /*
18450     * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
18451     */
18452    if (ADV_INQ_RESPONSE_FMT(inq) < 2 && ADV_INQ_ANSI_VER(inq) < 2)
18453    {
18454        return;
18455    } else
18456    {
18457        /*
18458         * INQUIRY Byte 7 Handling
18459         *
18460         * Use a device's INQUIRY byte 7 to determine whether it
18461         * supports WDTR, SDTR, and Tag Queuing. If the feature
18462         * is enabled in the EEPROM and the device supports the
18463         * feature, then enable it in the microcode.
18464         */
18465
18466        tidmask = ADV_TID_TO_TIDMASK(tid);
18467
18468        /*
18469         * Wide Transfers
18470         *
18471         * If the EEPROM enabled WDTR for the device and the device
18472         * supports wide bus (16 bit) transfers, then turn on the
18473         * device's 'wdtr_able' bit and write the new value to the
18474         * microcode.
18475         */
18476        if ((asc_dvc->wdtr_able & tidmask) && ADV_INQ_WIDE16(inq))
18477        {
18478            AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
18479            if ((cfg_word & tidmask) == 0)
18480            {
18481                cfg_word |= tidmask;
18482                AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
18483
18484                /*
18485                 * Clear the microcode "SDTR negotiation" and "WDTR
18486                 * negotiation" done indicators for the target to cause
18487                 * it to negotiate with the new setting set above.
18488                 * WDTR when accepted causes the target to enter
18489                 * asynchronous mode, so SDTR must be negotiated.
18490                 */
18491                AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18492                cfg_word &= ~tidmask;
18493                AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18494                AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
18495                cfg_word &= ~tidmask;
18496                AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
18497            }
18498        }
18499
18500        /*
18501         * Synchronous Transfers
18502         *
18503         * If the EEPROM enabled SDTR for the device and the device
18504         * supports synchronous transfers, then turn on the device's
18505         * 'sdtr_able' bit. Write the new value to the microcode.
18506         */
18507        if ((asc_dvc->sdtr_able & tidmask) && ADV_INQ_SYNC(inq))
18508        {
18509            AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
18510            if ((cfg_word & tidmask) == 0)
18511            {
18512                cfg_word |= tidmask;
18513                AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
18514
18515                /*
18516                 * Clear the microcode "SDTR negotiation" done indicator
18517                 * for the target to cause it to negotiate with the new
18518                 * setting set above.
18519                 */
18520                AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18521                cfg_word &= ~tidmask;
18522                AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18523            }
18524        }
18525        /*
18526         * If the Inquiry data included enough space for the SPI-3
18527         * Clocking field, then check if DT mode is supported.
18528         */
18529        if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600 &&
18530            (scsiq->cdb[4] >= 57 ||
18531            (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) >= 57))
18532        {
18533            /*
18534             * PPR (Parallel Protocol Request) Capable
18535             *
18536             * If the device supports DT mode, then it must be PPR capable.
18537             * The PPR message will be used in place of the SDTR and WDTR
18538             * messages to negotiate synchronous speed and offset, transfer
18539             * width, and protocol options.
18540             */
18541            if (ADV_INQ_CLOCKING(inq) & ADV_INQ_CLOCKING_DT_ONLY)
18542            {
18543                AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, asc_dvc->ppr_able);
18544                asc_dvc->ppr_able |= tidmask;
18545                AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, asc_dvc->ppr_able);
18546            }
18547        }
18548
18549        /*
18550         * If the EEPROM enabled Tag Queuing for the device and the
18551         * device supports Tag Queueing, then turn on the device's
18552         * 'tagqng_enable' bit in the microcode and set the microcode
18553         * maximum command count to the ADV_DVC_VAR 'max_dvc_qng'
18554         * value.
18555         *
18556         * Tag Queuing is disabled for the BIOS which runs in polled
18557         * mode and would see no benefit from Tag Queuing. Also by
18558         * disabling Tag Queuing in the BIOS devices with Tag Queuing
18559         * bugs will at least work with the BIOS.
18560         */
18561        if ((asc_dvc->tagqng_able & tidmask) && ADV_INQ_CMD_QUEUE(inq))
18562        {
18563            AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
18564            cfg_word |= tidmask;
18565            AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
18566
18567            AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
18568                asc_dvc->max_dvc_qng);
18569        }
18570    }
18571}
18572MODULE_LICENSE("Dual BSD/GPL");
18573
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.