]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/scsi/advansys.c
[SCSI] advansys: use memcpy instead of open-coded loop
[karo-tx-linux.git] / drivers / scsi / advansys.c
1 #define ASC_VERSION "3.4"       /* 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  * Copyright (c) 2007 Matthew Wilcox <matthew@wil.cx>
9  * All Rights Reserved.
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  */
16
17 /*
18  * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
19  * changed its name to ConnectCom Solutions, Inc.
20  * On June 18, 2001 Initio Corp. acquired ConnectCom's SCSI assets
21  */
22
23 /*
24
25   Documentation for the AdvanSys Driver
26
27   A. Linux Kernels Supported by this Driver
28   B. Adapters Supported by this Driver
29   C. Linux source files modified by AdvanSys Driver
30   D. Source Comments
31   E. Driver Compile Time Options and Debugging
32   F. Driver LILO Option
33   G. Tests to run before releasing new driver
34   H. Release History
35   I. Known Problems/Fix List
36   J. Credits (Chronological Order)
37
38   A. Linux Kernels Supported by this Driver
39
40      This driver has been tested in the following Linux kernels: v2.2.18
41      v2.4.0. The driver is supported on v2.2 and v2.4 kernels and on x86,
42      alpha, and PowerPC platforms.
43
44   B. Adapters Supported by this Driver
45
46      AdvanSys (Advanced System Products, Inc.) manufactures the following
47      RISC-based, Bus-Mastering, Fast (10 Mhz) and Ultra (20 Mhz) Narrow
48      (8-bit transfer) SCSI Host Adapters for the ISA, EISA, VL, and PCI
49      buses and RISC-based, Bus-Mastering, Ultra (20 Mhz) Wide (16-bit
50      transfer) SCSI Host Adapters for the PCI bus.
51
52      The CDB counts below indicate the number of SCSI CDB (Command
53      Descriptor Block) requests that can be stored in the RISC chip
54      cache and board LRAM. A CDB is a single SCSI command. The driver
55      detect routine will display the number of CDBs available for each
56      adapter detected. The number of CDBs used by the driver can be
57      lowered in the BIOS by changing the 'Host Queue Size' adapter setting.
58
59      Laptop Products:
60         ABP-480 - Bus-Master CardBus (16 CDB) (2.4 kernel and greater)
61
62      Connectivity Products:
63         ABP510/5150 - Bus-Master ISA (240 CDB)
64         ABP5140 - Bus-Master ISA PnP (16 CDB)
65         ABP5142 - Bus-Master ISA PnP with floppy (16 CDB)
66         ABP902/3902 - Bus-Master PCI (16 CDB)
67         ABP3905 - Bus-Master PCI (16 CDB)
68         ABP915 - Bus-Master PCI (16 CDB)
69         ABP920 - Bus-Master PCI (16 CDB)
70         ABP3922 - Bus-Master PCI (16 CDB)
71         ABP3925 - Bus-Master PCI (16 CDB)
72         ABP930 - Bus-Master PCI (16 CDB)
73         ABP930U - Bus-Master PCI Ultra (16 CDB)
74         ABP930UA - Bus-Master PCI Ultra (16 CDB)
75         ABP960 - Bus-Master PCI MAC/PC (16 CDB)
76         ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB)
77
78      Single Channel Products:
79         ABP542 - Bus-Master ISA with floppy (240 CDB)
80         ABP742 - Bus-Master EISA (240 CDB)
81         ABP842 - Bus-Master VL (240 CDB)
82         ABP940 - Bus-Master PCI (240 CDB)
83         ABP940U - Bus-Master PCI Ultra (240 CDB)
84         ABP940UA/3940UA - Bus-Master PCI Ultra (240 CDB)
85         ABP970 - Bus-Master PCI MAC/PC (240 CDB)
86         ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB)
87         ABP3960UA - Bus-Master PCI MAC/PC Ultra (240 CDB)
88         ABP940UW/3940UW - Bus-Master PCI Ultra-Wide (253 CDB)
89         ABP970UW - Bus-Master PCI MAC/PC Ultra-Wide (253 CDB)
90         ABP3940U2W - Bus-Master PCI LVD/Ultra2-Wide (253 CDB)
91
92      Multi-Channel Products:
93         ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel)
94         ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel)
95         ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel)
96         ABP950UW - Dual Channel Bus-Master PCI Ultra-Wide (253 CDB Per Channel)
97         ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel)
98         ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel)
99         ABP980UA/3980UA - Four Channel Bus-Master PCI Ultra (16 CDB Per Chan.)
100         ABP3950U2W - Bus-Master PCI LVD/Ultra2-Wide and Ultra-Wide (253 CDB)
101         ABP3950U3W - Bus-Master PCI Dual LVD2/Ultra3-Wide (253 CDB)
102
103   C. Linux source files modified by AdvanSys Driver
104
105      This section for historical purposes documents the changes
106      originally made to the Linux kernel source to add the advansys
107      driver. As Linux has changed some of these files have also
108      been modified.
109
110      1. linux/arch/i386/config.in:
111
112           bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y
113
114      2. linux/drivers/scsi/hosts.c:
115
116           #ifdef CONFIG_SCSI_ADVANSYS
117           #include "advansys.h"
118           #endif
119
120         and after "static struct scsi_host_template builtin_scsi_hosts[] =":
121
122           #ifdef CONFIG_SCSI_ADVANSYS
123           ADVANSYS,
124           #endif
125
126      3. linux/drivers/scsi/Makefile:
127
128           ifdef CONFIG_SCSI_ADVANSYS
129           SCSI_SRCS := $(SCSI_SRCS) advansys.c
130           SCSI_OBJS := $(SCSI_OBJS) advansys.o
131           else
132           SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o
133           endif
134
135      4. linux/init/main.c:
136
137           extern void advansys_setup(char *str, int *ints);
138
139         and add the following lines to the bootsetups[] array.
140
141           #ifdef CONFIG_SCSI_ADVANSYS
142              { "advansys=", advansys_setup },
143           #endif
144
145   D. Source Comments
146
147      1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'.
148
149      2. This driver should be maintained in multiple files. But to make
150         it easier to include with Linux and to follow Linux conventions,
151         the whole driver is maintained in the source files advansys.h and
152         advansys.c. In this file logical sections of the driver begin with
153         a comment that contains '---'. The following are the logical sections
154         of the driver below.
155
156            --- Linux Version
157            --- Linux Include File
158            --- Driver Options
159            --- Debugging Header
160            --- Asc Library Constants and Macros
161            --- Adv Library Constants and Macros
162            --- Driver Constants and Macros
163            --- Driver Structures
164            --- Driver Data
165            --- Driver Function Prototypes
166            --- Linux 'struct scsi_host_template' and advansys_setup() Functions
167            --- Loadable Driver Support
168            --- Miscellaneous Driver Functions
169            --- Functions Required by the Asc Library
170            --- Functions Required by the Adv Library
171            --- Tracing and Debugging Functions
172            --- Asc Library Functions
173            --- Adv Library Functions
174
175      3. The string 'XXX' is used to flag code that needs to be re-written
176         or that contains a problem that needs to be addressed.
177
178      4. I have stripped comments from and reformatted the source for the
179         Asc Library and Adv Library to reduce the size of this file. This
180         source can be found under the following headings. The Asc Library
181         is used to support Narrow Boards. The Adv Library is used to
182         support Wide Boards.
183
184            --- Asc Library Constants and Macros
185            --- Adv Library Constants and Macros
186            --- Asc Library Functions
187            --- Adv Library Functions
188
189   E. Driver Compile Time Options and Debugging
190
191      In this source file the following constants can be defined. They are
192      defined in the source below. Both of these options are enabled by
193      default.
194
195      1. ADVANSYS_ASSERT - Enable driver assertions (Def: Enabled)
196
197         Enabling this option adds assertion logic statements to the
198         driver. If an assertion fails a message will be displayed to
199         the console, but the system will continue to operate. Any
200         assertions encountered should be reported to the person
201         responsible for the driver. Assertion statements may proactively
202         detect problems with the driver and facilitate fixing these
203         problems. Enabling assertions will add a small overhead to the
204         execution of the driver.
205
206      2. ADVANSYS_DEBUG - Enable driver debugging (Def: Disabled)
207
208         Enabling this option adds tracing functions to the driver and
209         the ability to set a driver tracing level at boot time. This
210         option will also export symbols not required outside the driver to
211         the kernel name space. This option is very useful for debugging
212         the driver, but it will add to the size of the driver execution
213         image and add overhead to the execution of the driver.
214
215         The amount of debugging output can be controlled with the global
216         variable 'asc_dbglvl'. The higher the number the more output. By
217         default the debug level is 0.
218
219         If the driver is loaded at boot time and the LILO Driver Option
220         is included in the system, the debug level can be changed by
221         specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The
222         first three hex digits of the pseudo I/O Port must be set to
223         'deb' and the fourth hex digit specifies the debug level: 0 - F.
224         The following command line will look for an adapter at 0x330
225         and set the debug level to 2.
226
227            linux advansys=0x330,0,0,0,0xdeb2
228
229         If the driver is built as a loadable module this variable can be
230         defined when the driver is loaded. The following insmod command
231         will set the debug level to one.
232
233            insmod advansys.o asc_dbglvl=1
234
235         Debugging Message Levels:
236            0: Errors Only
237            1: High-Level Tracing
238            2-N: Verbose Tracing
239
240         To enable debug output to console, please make sure that:
241
242         a. System and kernel logging is enabled (syslogd, klogd running).
243         b. Kernel messages are routed to console output. Check
244            /etc/syslog.conf for an entry similar to this:
245
246                 kern.*                  /dev/console
247
248         c. klogd is started with the appropriate -c parameter
249            (e.g. klogd -c 8)
250
251         This will cause printk() messages to be be displayed on the
252         current console. Refer to the klogd(8) and syslogd(8) man pages
253         for details.
254
255         Alternatively you can enable printk() to console with this
256         program. However, this is not the 'official' way to do this.
257         Debug output is logged in /var/log/messages.
258
259           main()
260           {
261                   syscall(103, 7, 0, 0);
262           }
263
264         Increasing LOG_BUF_LEN in kernel/printk.c to something like
265         40960 allows more debug messages to be buffered in the kernel
266         and written to the console or log file.
267
268      3. ADVANSYS_STATS - Enable statistics (Def: Enabled >= v1.3.0)
269
270         Enabling this option adds statistics collection and display
271         through /proc to the driver. The information is useful for
272         monitoring driver and device performance. It will add to the
273         size of the driver execution image and add minor overhead to
274         the execution of the driver.
275
276         Statistics are maintained on a per adapter basis. Driver entry
277         point call counts and transfer size counts are maintained.
278         Statistics are only available for kernels greater than or equal
279         to v1.3.0 with the CONFIG_PROC_FS (/proc) file system configured.
280
281         AdvanSys SCSI adapter files have the following path name format:
282
283            /proc/scsi/advansys/{0,1,2,3,...}
284
285         This information can be displayed with cat. For example:
286
287            cat /proc/scsi/advansys/0
288
289         When ADVANSYS_STATS is not defined the AdvanSys /proc files only
290         contain adapter and device configuration information.
291
292   F. Driver LILO Option
293
294      If init/main.c is modified as described in the 'Directions for Adding
295      the AdvanSys Driver to Linux' section (B.4.) above, the driver will
296      recognize the 'advansys' LILO command line and /etc/lilo.conf option.
297      This option can be used to either disable I/O port scanning or to limit
298      scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and
299      PCI boards will still be searched for and detected. This option only
300      affects searching for ISA and VL boards.
301
302      Examples:
303        1. Eliminate I/O port scanning:
304             boot: linux advansys=
305               or
306             boot: linux advansys=0x0
307        2. Limit I/O port scanning to one I/O port:
308             boot: linux advansys=0x110
309        3. Limit I/O port scanning to four I/O ports:
310             boot: linux advansys=0x110,0x210,0x230,0x330
311
312      For a loadable module the same effect can be achieved by setting
313      the 'asc_iopflag' variable and 'asc_ioport' array when loading
314      the driver, e.g.
315
316            insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330
317
318      If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_IOPORT_PROBE + 1)
319      I/O Port may be added to specify the driver debug level. Refer to
320      the 'Driver Compile Time Options and Debugging' section above for
321      more information.
322
323   G. Tests to run before releasing new driver
324
325      1. In the supported kernels verify there are no warning or compile
326         errors when the kernel is built as both a driver and as a module
327         and with the following options:
328
329         ADVANSYS_DEBUG - enabled and disabled
330         CONFIG_SMP - enabled and disabled
331         CONFIG_PROC_FS - enabled and disabled
332
333      2. Run tests on an x86, alpha, and PowerPC with at least one narrow
334         card and one wide card attached to a hard disk and CD-ROM drive:
335         fdisk, mkfs, fsck, bonnie, copy/compare test from the
336         CD-ROM to the hard drive.
337
338   H. Release History
339
340      BETA-1.0 (12/23/95):
341          First Release
342
343      BETA-1.1 (12/28/95):
344          1. Prevent advansys_detect() from being called twice.
345          2. Add LILO 0xdeb[0-f] option to set 'asc_dbglvl'.
346
347      1.2 (1/12/96):
348          1. Prevent re-entrancy in the interrupt handler which
349             resulted in the driver hanging Linux.
350          2. Fix problem that prevented ABP-940 cards from being
351             recognized on some PCI motherboards.
352          3. Add support for the ABP-5140 PnP ISA card.
353          4. Fix check condition return status.
354          5. Add conditionally compiled code for Linux v1.3.X.
355
356      1.3 (2/23/96):
357          1. Fix problem in advansys_biosparam() that resulted in the
358             wrong drive geometry being returned for drives > 1GB with
359             extended translation enabled.
360          2. Add additional tracing during device initialization.
361          3. Change code that only applies to ISA PnP adapter.
362          4. Eliminate 'make dep' warning.
363          5. Try to fix problem with handling resets by increasing their
364             timeout value.
365
366      1.4 (5/8/96):
367          1. Change definitions to eliminate conflicts with other subsystems.
368          2. Add versioning code for the shared interrupt changes.
369          3. Eliminate problem in asc_rmqueue() with iterating after removing
370             a request.
371          4. Remove reset request loop problem from the "Known Problems or
372             Issues" section. This problem was isolated and fixed in the
373             mid-level SCSI driver.
374
375      1.5 (8/8/96):
376          1. Add support for ABP-940U (PCI Ultra) adapter.
377          2. Add support for IRQ sharing by setting the IRQF_SHARED flag for
378             request_irq and supplying a dev_id pointer to both request_irq()
379             and free_irq().
380          3. In AscSearchIOPortAddr11() restore a call to check_region() which
381             should be used before I/O port probing.
382          4. Fix bug in asc_prt_hex() which resulted in the displaying
383             the wrong data.
384          5. Incorporate miscellaneous Asc Library bug fixes and new microcode.
385          6. Change driver versioning to be specific to each Linux sub-level.
386          7. Change statistics gathering to be per adapter instead of global
387             to the driver.
388          8. Add more information and statistics to the adapter /proc file:
389             /proc/scsi/advansys[0...].
390          9. Remove 'cmd_per_lun' from the "Known Problems or Issues" list.
391             This problem has been addressed with the SCSI mid-level changes
392             made in v1.3.89. The advansys_select_queue_depths() function
393             was added for the v1.3.89 changes.
394
395      1.6 (9/10/96):
396          1. Incorporate miscellaneous Asc Library bug fixes and new microcode.
397
398      1.7 (9/25/96):
399          1. Enable clustering and optimize the setting of the maximum number
400             of scatter gather elements for any particular board. Clustering
401             increases CPU utilization, but results in a relatively larger
402             increase in I/O throughput.
403          2. Improve the performance of the request queuing functions by
404             adding a last pointer to the queue structure.
405          3. Correct problems with reset and abort request handling that
406             could have hung or crashed Linux.
407          4. Add more information to the adapter /proc file:
408             /proc/scsi/advansys[0...].
409          5. Remove the request timeout issue form the driver issues list.
410          6. Miscellaneous documentation additions and changes.
411
412      1.8 (10/4/96):
413          1. Make changes to handle the new v2.1.0 kernel memory mapping
414             in which a kernel virtual address may not be equivalent to its
415             bus or DMA memory address.
416          2. Change abort and reset request handling to make it yet even
417             more robust.
418          3. Try to mitigate request starvation by sending ordered requests
419             to heavily loaded, tag queuing enabled devices.
420          4. Maintain statistics on request response time.
421          5. Add request response time statistics and other information to
422             the adapter /proc file: /proc/scsi/advansys[0...].
423
424      1.9 (10/21/96):
425          1. Add conditionally compiled code (ASC_QUEUE_FLOW_CONTROL) to
426             make use of mid-level SCSI driver device queue depth flow
427             control mechanism. This will eliminate aborts caused by a
428             device being unable to keep up with requests and eliminate
429             repeat busy or QUEUE FULL status returned by a device.
430          2. Incorporate miscellaneous Asc Library bug fixes.
431          3. To allow the driver to work in kernels with broken module
432             support set 'cmd_per_lun' if the driver is compiled as a
433             module. This change affects kernels v1.3.89 to present.
434          4. Remove PCI BIOS address from the driver banner. The PCI BIOS
435             is relocated by the motherboard BIOS and its new address can
436             not be determined by the driver.
437          5. Add mid-level SCSI queue depth information to the adapter
438             /proc file: /proc/scsi/advansys[0...].
439
440      2.0 (11/14/96):
441          1. Change allocation of global structures used for device
442             initialization to guarantee they are in DMA-able memory.
443             Previously when the driver was loaded as a module these
444             structures might not have been in DMA-able memory, causing
445             device initialization to fail.
446
447      2.1 (12/30/96):
448          1. In advansys_reset(), if the request is a synchronous reset
449             request, even if the request serial number has changed, then
450             complete the request.
451          2. Add Asc Library bug fixes including new microcode.
452          3. Clear inquiry buffer before using it.
453          4. Correct ifdef typo.
454
455      2.2 (1/15/97):
456          1. Add Asc Library bug fixes including new microcode.
457          2. Add synchronous data transfer rate information to the
458             adapter /proc file: /proc/scsi/advansys[0...].
459          3. Change ADVANSYS_DEBUG to be disabled by default. This
460             will reduce the size of the driver image, eliminate execution
461             overhead, and remove unneeded symbols from the kernel symbol
462             space that were previously added by the driver.
463          4. Add new compile-time option ADVANSYS_ASSERT for assertion
464             code that used to be defined within ADVANSYS_DEBUG. This
465             option is enabled by default.
466
467      2.8 (5/26/97):
468          1. Change version number to 2.8 to synchronize the Linux driver
469             version numbering with other AdvanSys drivers.
470          2. Reformat source files without tabs to present the same view
471             of the file to everyone regardless of the editor tab setting
472             being used.
473          3. Add Asc Library bug fixes.
474
475      3.1A (1/8/98):
476          1. Change version number to 3.1 to indicate that support for
477             Ultra-Wide adapters (ABP-940UW) is included in this release.
478          2. Add Asc Library (Narrow Board) bug fixes.
479          3. Report an underrun condition with the host status byte set
480             to DID_UNDERRUN. Currently DID_UNDERRUN is defined to 0 which
481             causes the underrun condition to be ignored. When Linux defines
482             its own DID_UNDERRUN the constant defined in this file can be
483             removed.
484          4. Add patch to AscWaitTixISRDone().
485          5. Add support for up to 16 different AdvanSys host adapter SCSI
486             channels in one system. This allows four cards with four channels
487             to be used in one system.
488
489      3.1B (1/9/98):
490          1. Handle that PCI register base addresses are not always page
491             aligned even though ioremap() requires that the address argument
492             be page aligned.
493
494      3.1C (1/10/98):
495          1. Update latest BIOS version checked for from the /proc file.
496          2. Don't set microcode SDTR variable at initialization. Instead
497             wait until device capabilities have been detected from an Inquiry
498             command.
499
500      3.1D (1/21/98):
501          1. Improve performance when the driver is compiled as module by
502             allowing up to 64 scatter-gather elements instead of 8.
503
504      3.1E (5/1/98):
505          1. Set time delay in AscWaitTixISRDone() to 1000 ms.
506          2. Include SMP locking changes.
507          3. For v2.1.93 and newer kernels use CONFIG_PCI and new PCI BIOS
508             access functions.
509          4. Update board serial number printing.
510          5. Try allocating an IRQ both with and without the IRQF_DISABLED
511             flag set to allow IRQ sharing with drivers that do not set
512             the IRQF_DISABLED flag. Also display a more descriptive error
513             message if request_irq() fails.
514          6. Update to latest Asc and Adv Libraries.
515
516      3.2A (7/22/99):
517          1. Update Adv Library to 4.16 which includes support for
518             the ASC38C0800 (Ultra2/LVD) IC.
519
520      3.2B (8/23/99):
521          1. Correct PCI compile time option for v2.1.93 and greater
522             kernels, advansys_info() string, and debug compile time
523             option.
524          2. Correct DvcSleepMilliSecond() for v2.1.0 and greater
525             kernels. This caused an LVD detection/BIST problem problem
526             among other things.
527          3. Sort PCI cards by PCI Bus, Slot, Function ascending order
528             to be consistent with the BIOS.
529          4. Update to Asc Library S121 and Adv Library 5.2.
530
531      3.2C (8/24/99):
532          1. Correct PCI card detection bug introduced in 3.2B that
533             prevented PCI cards from being detected in kernels older
534             than v2.1.93.
535
536      3.2D (8/26/99):
537          1. Correct /proc device synchronous speed information display.
538             Also when re-negotiation is pending for a target device
539             note this condition with an * and footnote.
540          2. Correct initialization problem with Ultra-Wide cards that
541             have a pre-3.2 BIOS. A microcode variable changed locations
542             in 3.2 and greater BIOSes which caused WDTR to be attempted
543             erroneously with drives that don't support WDTR.
544
545      3.2E (8/30/99):
546          1. Fix compile error caused by v2.3.13 PCI structure change.
547          2. Remove field from ASCEEP_CONFIG that resulted in an EEPROM
548             checksum error for ISA cards.
549          3. Remove ASC_QUEUE_FLOW_CONTROL conditional code. The mid-level
550             SCSI changes that it depended on were never included in Linux.
551
552      3.2F (9/3/99):
553          1. Handle new initial function code added in v2.3.16 for all
554             driver versions.
555
556      3.2G (9/8/99):
557          1. Fix PCI board detection in v2.3.13 and greater kernels.
558          2. Fix comiple errors in v2.3.X with debugging enabled.
559
560      3.2H (9/13/99):
561          1. Add 64-bit address, long support for Alpha and UltraSPARC.
562             The driver has been verified to work on an Alpha system.
563          2. Add partial byte order handling support for Power PC and
564             other big-endian platforms. This support has not yet been
565             completed or verified.
566          3. For wide boards replace block zeroing of request and
567             scatter-gather structures with individual field initialization
568             to improve performance.
569          4. Correct and clarify ROM BIOS version detection.
570
571      3.2I (10/8/99):
572          1. Update to Adv Library 5.4.
573          2. Add v2.3.19 underrun reporting to asc_isr_callback() and
574             adv_isr_callback().  Remove DID_UNDERRUN constant and other
575             no longer needed code that previously documented the lack
576             of underrun handling.
577
578      3.2J (10/14/99):
579          1. Eliminate compile errors for v2.0 and earlier kernels.
580
581      3.2K (11/15/99):
582          1. Correct debug compile error in asc_prt_adv_scsi_req_q().
583          2. Update Adv Library to 5.5.
584          3. Add ifdef handling for /proc changes added in v2.3.28.
585          4. Increase Wide board scatter-gather list maximum length to
586             255 when the driver is compiled into the kernel.
587
588      3.2L (11/18/99):
589          1. Fix bug in adv_get_sglist() that caused an assertion failure
590             at line 7475. The reqp->sgblkp pointer must be initialized
591             to NULL in adv_get_sglist().
592
593      3.2M (11/29/99):
594          1. Really fix bug in adv_get_sglist().
595          2. Incorporate v2.3.29 changes into driver.
596
597      3.2N (4/1/00):
598          1. Add CONFIG_ISA ifdef code.
599          2. Include advansys_interrupts_enabled name change patch.
600          3. For >= v2.3.28 use new SCSI error handling with new function
601             advansys_eh_bus_reset(). Don't include an abort function
602             because of base library limitations.
603          4. For >= v2.3.28 use per board lock instead of io_request_lock.
604          5. For >= v2.3.28 eliminate advansys_command() and
605             advansys_command_done().
606          6. Add some changes for PowerPC (Big Endian) support, but it isn't
607             working yet.
608          7. Fix "nonexistent resource free" problem that occurred on a module
609             unload for boards with an I/O space >= 255. The 'n_io_port' field
610             is only one byte and can not be used to hold an ioport length more
611             than 255.
612
613      3.3A (4/4/00):
614          1. Update to Adv Library 5.8.
615          2. For wide cards add support for CDBs up to 16 bytes.
616          3. Eliminate warnings when CONFIG_PROC_FS is not defined.
617
618      3.3B (5/1/00):
619          1. Support for PowerPC (Big Endian) wide cards. Narrow cards
620             still need work.
621          2. Change bitfields to shift and mask access for endian
622             portability.
623
624      3.3C (10/13/00):
625          1. Update for latest 2.4 kernel.
626          2. Test ABP-480 CardBus support in 2.4 kernel - works!
627          3. Update to Asc Library S123.
628          4. Update to Adv Library 5.12.
629
630      3.3D (11/22/00):
631          1. Update for latest 2.4 kernel.
632          2. Create patches for 2.2 and 2.4 kernels.
633
634      3.3E (1/9/01):
635          1. Now that 2.4 is released remove ifdef code for kernel versions
636             less than 2.2. The driver is now only supported in kernels 2.2,
637             2.4, and greater.
638          2. Add code to release and acquire the io_request_lock in
639             the driver entrypoint functions: advansys_detect and
640             advansys_queuecommand. In kernel 2.4 the SCSI mid-level driver
641             still holds the io_request_lock on entry to SCSI low-level drivers.
642             This was supposed to be removed before 2.4 was released but never
643             happened. When the mid-level SCSI driver is changed all references
644             to the io_request_lock should be removed from the driver.
645          3. Simplify error handling by removing advansys_abort(),
646             AscAbortSRB(), AscResetDevice(). SCSI bus reset requests are
647             now handled by resetting the SCSI bus and fully re-initializing
648             the chip. This simple method of error recovery has proven to work
649             most reliably after attempts at different methods. Also now only
650             support the "new" error handling method and remove the obsolete
651             error handling interface.
652          4. Fix debug build errors.
653
654      3.3F (1/24/01):
655          1. Merge with ConnectCom version from Andy Kellner which
656             updates Adv Library to 5.14.
657          2. Make PowerPC (Big Endian) work for narrow cards and
658             fix problems writing EEPROM for wide cards.
659          3. Remove interrupts_enabled assertion function.
660
661      3.3G (2/16/01):
662          1. Return an error from narrow boards if passed a 16 byte
663             CDB. The wide board can already handle 16 byte CDBs.
664
665      3.3GJ (4/15/02):
666          1. hacks for lk 2.5 series (D. Gilbert)
667
668      3.3GJD (10/14/02):
669          1. change select_queue_depths to slave_configure
670          2. make cmd_per_lun be sane again
671
672      3.3K [2004/06/24]:
673          1. continuing cleanup for lk 2.6 series
674          2. Fix problem in lk 2.6.7-bk2 that broke PCI wide cards
675          3. Fix problem that oopsed ISA cards
676
677   I. Known Problems/Fix List (XXX)
678
679      1. Need to add memory mapping workaround. Test the memory mapping.
680         If it doesn't work revert to I/O port access. Can a test be done
681         safely?
682      2. Handle an interrupt not working. Keep an interrupt counter in
683         the interrupt handler. In the timeout function if the interrupt
684         has not occurred then print a message and run in polled mode.
685      3. Allow bus type scanning order to be changed.
686      4. Need to add support for target mode commands, cf. CAM XPT.
687
688   J. Credits (Chronological Order)
689
690      Bob Frey <bfrey@turbolinux.com.cn> wrote the AdvanSys SCSI driver
691      and maintained it up to 3.3F. He continues to answer questions
692      and help maintain the driver.
693
694      Nathan Hartwell <mage@cdc3.cdc.net> provided the directions and
695      basis for the Linux v1.3.X changes which were included in the
696      1.2 release.
697
698      Thomas E Zerucha <zerucha@shell.portal.com> pointed out a bug
699      in advansys_biosparam() which was fixed in the 1.3 release.
700
701      Erik Ratcliffe <erik@caldera.com> has done testing of the
702      AdvanSys driver in the Caldera releases.
703
704      Rik van Riel <H.H.vanRiel@fys.ruu.nl> provided a patch to
705      AscWaitTixISRDone() which he found necessary to make the
706      driver work with a SCSI-1 disk.
707
708      Mark Moran <mmoran@mmoran.com> has helped test Ultra-Wide
709      support in the 3.1A driver.
710
711      Doug Gilbert <dgilbert@interlog.com> has made changes and
712      suggestions to improve the driver and done a lot of testing.
713
714      Ken Mort <ken@mort.net> reported a DEBUG compile bug fixed
715      in 3.2K.
716
717      Tom Rini <trini@kernel.crashing.org> provided the CONFIG_ISA
718      patch and helped with PowerPC wide and narrow board support.
719
720      Philip Blundell <philb@gnu.org> provided an
721      advansys_interrupts_enabled patch.
722
723      Dave Jones <dave@denial.force9.co.uk> reported the compiler
724      warnings generated when CONFIG_PROC_FS was not defined in
725      the 3.2M driver.
726
727      Jerry Quinn <jlquinn@us.ibm.com> fixed PowerPC support (endian
728      problems) for wide cards.
729
730      Bryan Henderson <bryanh@giraffe-data.com> helped debug narrow
731      card error handling.
732
733      Manuel Veloso <veloso@pobox.com> worked hard on PowerPC narrow
734      board support and fixed a bug in AscGetEEPConfig().
735
736      Arnaldo Carvalho de Melo <acme@conectiva.com.br> made
737      save_flags/restore_flags changes.
738
739      Andy Kellner <AKellner@connectcom.net> continues the Advansys SCSI
740      driver development for ConnectCom (Version > 3.3F).
741
742   K. ConnectCom (AdvanSys) Contact Information
743
744      Mail:                   ConnectCom Solutions, Inc.
745                              1150 Ringwood Court
746                              San Jose, CA 95131
747      Operator/Sales:         1-408-383-9400
748      FAX:                    1-408-383-9612
749      Tech Support:           1-408-467-2930
750      Tech Support E-Mail:    linux@connectcom.net
751      FTP Site:               ftp.connectcom.net (login: anonymous)
752      Web Site:               http://www.connectcom.net
753
754 */
755
756 /*
757  * --- Linux Include Files
758  */
759
760 #include <linux/module.h>
761 #include <linux/string.h>
762 #include <linux/kernel.h>
763 #include <linux/types.h>
764 #include <linux/ioport.h>
765 #include <linux/interrupt.h>
766 #include <linux/delay.h>
767 #include <linux/slab.h>
768 #include <linux/mm.h>
769 #include <linux/proc_fs.h>
770 #include <linux/init.h>
771 #include <linux/blkdev.h>
772 #include <linux/isa.h>
773 #include <linux/eisa.h>
774 #include <linux/pci.h>
775 #include <linux/spinlock.h>
776 #include <linux/dma-mapping.h>
777
778 #include <asm/io.h>
779 #include <asm/system.h>
780 #include <asm/dma.h>
781
782 #include <scsi/scsi_cmnd.h>
783 #include <scsi/scsi_device.h>
784 #include <scsi/scsi_tcq.h>
785 #include <scsi/scsi.h>
786 #include <scsi/scsi_host.h>
787
788 /* FIXME: (by jejb@steeleye.com)
789  *
790  * Although all of the necessary command mapping places have the
791  * appropriate dma_map.. APIs, the driver still processes its internal
792  * queue using bus_to_virt() and virt_to_bus() which are illegal under
793  * the API.  The entire queue processing structure will need to be
794  * altered to fix this.
795  */
796 #warning this driver is still not properly converted to the DMA API
797
798 /*
799  * --- Driver Options
800  */
801
802 /* Enable driver assertions. */
803 #define ADVANSYS_ASSERT
804
805 /* Enable driver /proc statistics. */
806 #define ADVANSYS_STATS
807
808 /* Enable driver tracing. */
809 /* #define ADVANSYS_DEBUG */
810
811 /*
812  * --- Asc Library Constants and Macros
813  */
814
815 #define ASC_LIB_VERSION_MAJOR  1
816 #define ASC_LIB_VERSION_MINOR  24
817 #define ASC_LIB_SERIAL_NUMBER  123
818
819 /*
820  * Portable Data Types
821  *
822  * Any instance where a 32-bit long or pointer type is assumed
823  * for precision or HW defined structures, the following define
824  * types must be used. In Linux the char, short, and int types
825  * are all consistent at 8, 16, and 32 bits respectively. Pointers
826  * and long types are 64 bits on Alpha and UltraSPARC.
827  */
828 #define ASC_PADDR __u32         /* Physical/Bus address data type. */
829 #define ASC_VADDR __u32         /* Virtual address data type. */
830 #define ASC_DCNT  __u32         /* Unsigned Data count type. */
831 #define ASC_SDCNT __s32         /* Signed Data count type. */
832
833 /*
834  * These macros are used to convert a virtual address to a
835  * 32-bit value. This currently can be used on Linux Alpha
836  * which uses 64-bit virtual address but a 32-bit bus address.
837  * This is likely to break in the future, but doing this now
838  * will give us time to change the HW and FW to handle 64-bit
839  * addresses.
840  */
841 #define ASC_VADDR_TO_U32   virt_to_bus
842 #define ASC_U32_TO_VADDR   bus_to_virt
843
844 typedef unsigned char uchar;
845
846 #ifndef TRUE
847 #define TRUE     (1)
848 #endif
849 #ifndef FALSE
850 #define FALSE    (0)
851 #endif
852
853 #define EOF      (-1)
854 #define ERR      (-1)
855 #define UW_ERR   (uint)(0xFFFF)
856 #define isodd_word(val)   ((((uint)val) & (uint)0x0001) != 0)
857
858 #define  ASC_DVCLIB_CALL_DONE     (1)
859 #define  ASC_DVCLIB_CALL_FAILED   (0)
860 #define  ASC_DVCLIB_CALL_ERROR    (-1)
861
862 #define PCI_VENDOR_ID_ASP               0x10cd
863 #define PCI_DEVICE_ID_ASP_1200A         0x1100
864 #define PCI_DEVICE_ID_ASP_ABP940        0x1200
865 #define PCI_DEVICE_ID_ASP_ABP940U       0x1300
866 #define PCI_DEVICE_ID_ASP_ABP940UW      0x2300
867 #define PCI_DEVICE_ID_38C0800_REV1      0x2500
868 #define PCI_DEVICE_ID_38C1600_REV1      0x2700
869
870 /*
871  * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
872  * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
873  * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
874  * SRB structure.
875  */
876 #define CC_VERY_LONG_SG_LIST 0
877 #define ASC_SRB2SCSIQ(srb_ptr)  (srb_ptr)
878
879 #define PortAddr                 unsigned short /* port address size  */
880 #define inp(port)                inb(port)
881 #define outp(port, byte)         outb((byte), (port))
882
883 #define inpw(port)               inw(port)
884 #define outpw(port, word)        outw((word), (port))
885
886 #define ASC_MAX_SG_QUEUE    7
887 #define ASC_MAX_SG_LIST     255
888
889 #define ASC_CS_TYPE  unsigned short
890
891 #define ASC_IS_ISA          (0x0001)
892 #define ASC_IS_ISAPNP       (0x0081)
893 #define ASC_IS_EISA         (0x0002)
894 #define ASC_IS_PCI          (0x0004)
895 #define ASC_IS_PCI_ULTRA    (0x0104)
896 #define ASC_IS_PCMCIA       (0x0008)
897 #define ASC_IS_MCA          (0x0020)
898 #define ASC_IS_VL           (0x0040)
899 #define ASC_ISA_PNP_PORT_ADDR  (0x279)
900 #define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
901 #define ASC_IS_WIDESCSI_16  (0x0100)
902 #define ASC_IS_WIDESCSI_32  (0x0200)
903 #define ASC_IS_BIG_ENDIAN   (0x8000)
904 #define ASC_CHIP_MIN_VER_VL      (0x01)
905 #define ASC_CHIP_MAX_VER_VL      (0x07)
906 #define ASC_CHIP_MIN_VER_PCI     (0x09)
907 #define ASC_CHIP_MAX_VER_PCI     (0x0F)
908 #define ASC_CHIP_VER_PCI_BIT     (0x08)
909 #define ASC_CHIP_MIN_VER_ISA     (0x11)
910 #define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
911 #define ASC_CHIP_MAX_VER_ISA     (0x27)
912 #define ASC_CHIP_VER_ISA_BIT     (0x30)
913 #define ASC_CHIP_VER_ISAPNP_BIT  (0x20)
914 #define ASC_CHIP_VER_ASYN_BUG    (0x21)
915 #define ASC_CHIP_VER_PCI             0x08
916 #define ASC_CHIP_VER_PCI_ULTRA_3150  (ASC_CHIP_VER_PCI | 0x02)
917 #define ASC_CHIP_VER_PCI_ULTRA_3050  (ASC_CHIP_VER_PCI | 0x03)
918 #define ASC_CHIP_MIN_VER_EISA (0x41)
919 #define ASC_CHIP_MAX_VER_EISA (0x47)
920 #define ASC_CHIP_VER_EISA_BIT (0x40)
921 #define ASC_CHIP_LATEST_VER_EISA   ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
922 #define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER   0x21
923 #define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER   0x0A
924 #define ASC_MAX_VL_DMA_ADDR     (0x07FFFFFFL)
925 #define ASC_MAX_VL_DMA_COUNT    (0x07FFFFFFL)
926 #define ASC_MAX_PCI_DMA_ADDR    (0xFFFFFFFFL)
927 #define ASC_MAX_PCI_DMA_COUNT   (0xFFFFFFFFL)
928 #define ASC_MAX_ISA_DMA_ADDR    (0x00FFFFFFL)
929 #define ASC_MAX_ISA_DMA_COUNT   (0x00FFFFFFL)
930 #define ASC_MAX_EISA_DMA_ADDR   (0x07FFFFFFL)
931 #define ASC_MAX_EISA_DMA_COUNT  (0x07FFFFFFL)
932
933 #define ASC_SCSI_ID_BITS  3
934 #define ASC_SCSI_TIX_TYPE     uchar
935 #define ASC_ALL_DEVICE_BIT_SET  0xFF
936 #define ASC_SCSI_BIT_ID_TYPE  uchar
937 #define ASC_MAX_TID       7
938 #define ASC_MAX_LUN       7
939 #define ASC_SCSI_WIDTH_BIT_SET  0xFF
940 #define ASC_MAX_SENSE_LEN   32
941 #define ASC_MIN_SENSE_LEN   14
942 #define ASC_MAX_CDB_LEN     12
943 #define ASC_SCSI_RESET_HOLD_TIME_US  60
944
945 /*
946  * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
947  * and CmdDt (Command Support Data) field bit definitions.
948  */
949 #define ADV_INQ_RTN_VPD_AND_CMDDT           0x3
950 #define ADV_INQ_RTN_CMDDT_FOR_OP_CODE       0x2
951 #define ADV_INQ_RTN_VPD_FOR_PG_CODE         0x1
952 #define ADV_INQ_RTN_STD_INQUIRY_DATA        0x0
953
954 #define ASC_SCSIDIR_NOCHK    0x00
955 #define ASC_SCSIDIR_T2H      0x08
956 #define ASC_SCSIDIR_H2T      0x10
957 #define ASC_SCSIDIR_NODATA   0x18
958 #define SCSI_ASC_NOMEDIA          0x3A
959 #define ASC_SRB_HOST(x)  ((uchar)((uchar)(x) >> 4))
960 #define ASC_SRB_TID(x)   ((uchar)((uchar)(x) & (uchar)0x0F))
961 #define ASC_SRB_LUN(x)   ((uchar)((uint)(x) >> 13))
962 #define PUT_CDB1(x)   ((uchar)((uint)(x) >> 8))
963 #define MS_SDTR_LEN    0x03
964 #define MS_WDTR_LEN    0x02
965
966 #define ASC_SG_LIST_PER_Q   7
967 #define QS_FREE        0x00
968 #define QS_READY       0x01
969 #define QS_DISC1       0x02
970 #define QS_DISC2       0x04
971 #define QS_BUSY        0x08
972 #define QS_ABORTED     0x40
973 #define QS_DONE        0x80
974 #define QC_NO_CALLBACK   0x01
975 #define QC_SG_SWAP_QUEUE 0x02
976 #define QC_SG_HEAD       0x04
977 #define QC_DATA_IN       0x08
978 #define QC_DATA_OUT      0x10
979 #define QC_URGENT        0x20
980 #define QC_MSG_OUT       0x40
981 #define QC_REQ_SENSE     0x80
982 #define QCSG_SG_XFER_LIST  0x02
983 #define QCSG_SG_XFER_MORE  0x04
984 #define QCSG_SG_XFER_END   0x08
985 #define QD_IN_PROGRESS       0x00
986 #define QD_NO_ERROR          0x01
987 #define QD_ABORTED_BY_HOST   0x02
988 #define QD_WITH_ERROR        0x04
989 #define QD_INVALID_REQUEST   0x80
990 #define QD_INVALID_HOST_NUM  0x81
991 #define QD_INVALID_DEVICE    0x82
992 #define QD_ERR_INTERNAL      0xFF
993 #define QHSTA_NO_ERROR               0x00
994 #define QHSTA_M_SEL_TIMEOUT          0x11
995 #define QHSTA_M_DATA_OVER_RUN        0x12
996 #define QHSTA_M_DATA_UNDER_RUN       0x12
997 #define QHSTA_M_UNEXPECTED_BUS_FREE  0x13
998 #define QHSTA_M_BAD_BUS_PHASE_SEQ    0x14
999 #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
1000 #define QHSTA_D_ASC_DVC_ERROR_CODE_SET  0x22
1001 #define QHSTA_D_HOST_ABORT_FAILED       0x23
1002 #define QHSTA_D_EXE_SCSI_Q_FAILED       0x24
1003 #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
1004 #define QHSTA_D_ASPI_NO_BUF_POOL        0x26
1005 #define QHSTA_M_WTM_TIMEOUT         0x41
1006 #define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
1007 #define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
1008 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
1009 #define QHSTA_M_TARGET_STATUS_BUSY  0x45
1010 #define QHSTA_M_BAD_TAG_CODE        0x46
1011 #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY  0x47
1012 #define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
1013 #define QHSTA_D_LRAM_CMP_ERROR        0x81
1014 #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
1015 #define ASC_FLAG_SCSIQ_REQ        0x01
1016 #define ASC_FLAG_BIOS_SCSIQ_REQ   0x02
1017 #define ASC_FLAG_BIOS_ASYNC_IO    0x04
1018 #define ASC_FLAG_SRB_LINEAR_ADDR  0x08
1019 #define ASC_FLAG_WIN16            0x10
1020 #define ASC_FLAG_WIN32            0x20
1021 #define ASC_FLAG_ISA_OVER_16MB    0x40
1022 #define ASC_FLAG_DOS_VM_CALLBACK  0x80
1023 #define ASC_TAG_FLAG_EXTRA_BYTES               0x10
1024 #define ASC_TAG_FLAG_DISABLE_DISCONNECT        0x04
1025 #define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX  0x08
1026 #define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
1027 #define ASC_SCSIQ_CPY_BEG              4
1028 #define ASC_SCSIQ_SGHD_CPY_BEG         2
1029 #define ASC_SCSIQ_B_FWD                0
1030 #define ASC_SCSIQ_B_BWD                1
1031 #define ASC_SCSIQ_B_STATUS             2
1032 #define ASC_SCSIQ_B_QNO                3
1033 #define ASC_SCSIQ_B_CNTL               4
1034 #define ASC_SCSIQ_B_SG_QUEUE_CNT       5
1035 #define ASC_SCSIQ_D_DATA_ADDR          8
1036 #define ASC_SCSIQ_D_DATA_CNT          12
1037 #define ASC_SCSIQ_B_SENSE_LEN         20
1038 #define ASC_SCSIQ_DONE_INFO_BEG       22
1039 #define ASC_SCSIQ_D_SRBPTR            22
1040 #define ASC_SCSIQ_B_TARGET_IX         26
1041 #define ASC_SCSIQ_B_CDB_LEN           28
1042 #define ASC_SCSIQ_B_TAG_CODE          29
1043 #define ASC_SCSIQ_W_VM_ID             30
1044 #define ASC_SCSIQ_DONE_STATUS         32
1045 #define ASC_SCSIQ_HOST_STATUS         33
1046 #define ASC_SCSIQ_SCSI_STATUS         34
1047 #define ASC_SCSIQ_CDB_BEG             36
1048 #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
1049 #define ASC_SCSIQ_DW_REMAIN_XFER_CNT  60
1050 #define ASC_SCSIQ_B_FIRST_SG_WK_QP    48
1051 #define ASC_SCSIQ_B_SG_WK_QP          49
1052 #define ASC_SCSIQ_B_SG_WK_IX          50
1053 #define ASC_SCSIQ_W_ALT_DC1           52
1054 #define ASC_SCSIQ_B_LIST_CNT          6
1055 #define ASC_SCSIQ_B_CUR_LIST_CNT      7
1056 #define ASC_SGQ_B_SG_CNTL             4
1057 #define ASC_SGQ_B_SG_HEAD_QP          5
1058 #define ASC_SGQ_B_SG_LIST_CNT         6
1059 #define ASC_SGQ_B_SG_CUR_LIST_CNT     7
1060 #define ASC_SGQ_LIST_BEG              8
1061 #define ASC_DEF_SCSI1_QNG    4
1062 #define ASC_MAX_SCSI1_QNG    4
1063 #define ASC_DEF_SCSI2_QNG    16
1064 #define ASC_MAX_SCSI2_QNG    32
1065 #define ASC_TAG_CODE_MASK    0x23
1066 #define ASC_STOP_REQ_RISC_STOP      0x01
1067 #define ASC_STOP_ACK_RISC_STOP      0x03
1068 #define ASC_STOP_CLEAN_UP_BUSY_Q    0x10
1069 #define ASC_STOP_CLEAN_UP_DISC_Q    0x20
1070 #define ASC_STOP_HOST_REQ_RISC_HALT 0x40
1071 #define ASC_TIDLUN_TO_IX(tid, lun)  (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
1072 #define ASC_TID_TO_TARGET_ID(tid)   (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
1073 #define ASC_TIX_TO_TARGET_ID(tix)   (0x01 << ((tix) & ASC_MAX_TID))
1074 #define ASC_TIX_TO_TID(tix)         ((tix) & ASC_MAX_TID)
1075 #define ASC_TID_TO_TIX(tid)         ((tid) & ASC_MAX_TID)
1076 #define ASC_TIX_TO_LUN(tix)         (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
1077 #define ASC_QNO_TO_QADDR(q_no)      ((ASC_QADR_BEG)+((int)(q_no) << 6))
1078
1079 typedef struct asc_scsiq_1 {
1080         uchar status;
1081         uchar q_no;
1082         uchar cntl;
1083         uchar sg_queue_cnt;
1084         uchar target_id;
1085         uchar target_lun;
1086         ASC_PADDR data_addr;
1087         ASC_DCNT data_cnt;
1088         ASC_PADDR sense_addr;
1089         uchar sense_len;
1090         uchar extra_bytes;
1091 } ASC_SCSIQ_1;
1092
1093 typedef struct asc_scsiq_2 {
1094         ASC_VADDR srb_ptr;
1095         uchar target_ix;
1096         uchar flag;
1097         uchar cdb_len;
1098         uchar tag_code;
1099         ushort vm_id;
1100 } ASC_SCSIQ_2;
1101
1102 typedef struct asc_scsiq_3 {
1103         uchar done_stat;
1104         uchar host_stat;
1105         uchar scsi_stat;
1106         uchar scsi_msg;
1107 } ASC_SCSIQ_3;
1108
1109 typedef struct asc_scsiq_4 {
1110         uchar cdb[ASC_MAX_CDB_LEN];
1111         uchar y_first_sg_list_qp;
1112         uchar y_working_sg_qp;
1113         uchar y_working_sg_ix;
1114         uchar y_res;
1115         ushort x_req_count;
1116         ushort x_reconnect_rtn;
1117         ASC_PADDR x_saved_data_addr;
1118         ASC_DCNT x_saved_data_cnt;
1119 } ASC_SCSIQ_4;
1120
1121 typedef struct asc_q_done_info {
1122         ASC_SCSIQ_2 d2;
1123         ASC_SCSIQ_3 d3;
1124         uchar q_status;
1125         uchar q_no;
1126         uchar cntl;
1127         uchar sense_len;
1128         uchar extra_bytes;
1129         uchar res;
1130         ASC_DCNT remain_bytes;
1131 } ASC_QDONE_INFO;
1132
1133 typedef struct asc_sg_list {
1134         ASC_PADDR addr;
1135         ASC_DCNT bytes;
1136 } ASC_SG_LIST;
1137
1138 typedef struct asc_sg_head {
1139         ushort entry_cnt;
1140         ushort queue_cnt;
1141         ushort entry_to_copy;
1142         ushort res;
1143         ASC_SG_LIST sg_list[ASC_MAX_SG_LIST];
1144 } ASC_SG_HEAD;
1145
1146 #define ASC_MIN_SG_LIST   2
1147
1148 typedef struct asc_min_sg_head {
1149         ushort entry_cnt;
1150         ushort queue_cnt;
1151         ushort entry_to_copy;
1152         ushort res;
1153         ASC_SG_LIST sg_list[ASC_MIN_SG_LIST];
1154 } ASC_MIN_SG_HEAD;
1155
1156 #define QCX_SORT        (0x0001)
1157 #define QCX_COALEASE    (0x0002)
1158
1159 typedef struct asc_scsi_q {
1160         ASC_SCSIQ_1 q1;
1161         ASC_SCSIQ_2 q2;
1162         uchar *cdbptr;
1163         ASC_SG_HEAD *sg_head;
1164         ushort remain_sg_entry_cnt;
1165         ushort next_sg_index;
1166 } ASC_SCSI_Q;
1167
1168 typedef struct asc_scsi_req_q {
1169         ASC_SCSIQ_1 r1;
1170         ASC_SCSIQ_2 r2;
1171         uchar *cdbptr;
1172         ASC_SG_HEAD *sg_head;
1173         uchar *sense_ptr;
1174         ASC_SCSIQ_3 r3;
1175         uchar cdb[ASC_MAX_CDB_LEN];
1176         uchar sense[ASC_MIN_SENSE_LEN];
1177 } ASC_SCSI_REQ_Q;
1178
1179 typedef struct asc_scsi_bios_req_q {
1180         ASC_SCSIQ_1 r1;
1181         ASC_SCSIQ_2 r2;
1182         uchar *cdbptr;
1183         ASC_SG_HEAD *sg_head;
1184         uchar *sense_ptr;
1185         ASC_SCSIQ_3 r3;
1186         uchar cdb[ASC_MAX_CDB_LEN];
1187         uchar sense[ASC_MIN_SENSE_LEN];
1188 } ASC_SCSI_BIOS_REQ_Q;
1189
1190 typedef struct asc_risc_q {
1191         uchar fwd;
1192         uchar bwd;
1193         ASC_SCSIQ_1 i1;
1194         ASC_SCSIQ_2 i2;
1195         ASC_SCSIQ_3 i3;
1196         ASC_SCSIQ_4 i4;
1197 } ASC_RISC_Q;
1198
1199 typedef struct asc_sg_list_q {
1200         uchar seq_no;
1201         uchar q_no;
1202         uchar cntl;
1203         uchar sg_head_qp;
1204         uchar sg_list_cnt;
1205         uchar sg_cur_list_cnt;
1206 } ASC_SG_LIST_Q;
1207
1208 typedef struct asc_risc_sg_list_q {
1209         uchar fwd;
1210         uchar bwd;
1211         ASC_SG_LIST_Q sg;
1212         ASC_SG_LIST sg_list[7];
1213 } ASC_RISC_SG_LIST_Q;
1214
1215 #define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP  0x1000000UL
1216 #define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP  1024
1217 #define ASCQ_ERR_NO_ERROR             0
1218 #define ASCQ_ERR_IO_NOT_FOUND         1
1219 #define ASCQ_ERR_LOCAL_MEM            2
1220 #define ASCQ_ERR_CHKSUM               3
1221 #define ASCQ_ERR_START_CHIP           4
1222 #define ASCQ_ERR_INT_TARGET_ID        5
1223 #define ASCQ_ERR_INT_LOCAL_MEM        6
1224 #define ASCQ_ERR_HALT_RISC            7
1225 #define ASCQ_ERR_GET_ASPI_ENTRY       8
1226 #define ASCQ_ERR_CLOSE_ASPI           9
1227 #define ASCQ_ERR_HOST_INQUIRY         0x0A
1228 #define ASCQ_ERR_SAVED_SRB_BAD        0x0B
1229 #define ASCQ_ERR_QCNTL_SG_LIST        0x0C
1230 #define ASCQ_ERR_Q_STATUS             0x0D
1231 #define ASCQ_ERR_WR_SCSIQ             0x0E
1232 #define ASCQ_ERR_PC_ADDR              0x0F
1233 #define ASCQ_ERR_SYN_OFFSET           0x10
1234 #define ASCQ_ERR_SYN_XFER_TIME        0x11
1235 #define ASCQ_ERR_LOCK_DMA             0x12
1236 #define ASCQ_ERR_UNLOCK_DMA           0x13
1237 #define ASCQ_ERR_VDS_CHK_INSTALL      0x14
1238 #define ASCQ_ERR_MICRO_CODE_HALT      0x15
1239 #define ASCQ_ERR_SET_LRAM_ADDR        0x16
1240 #define ASCQ_ERR_CUR_QNG              0x17
1241 #define ASCQ_ERR_SG_Q_LINKS           0x18
1242 #define ASCQ_ERR_SCSIQ_PTR            0x19
1243 #define ASCQ_ERR_ISR_RE_ENTRY         0x1A
1244 #define ASCQ_ERR_CRITICAL_RE_ENTRY    0x1B
1245 #define ASCQ_ERR_ISR_ON_CRITICAL      0x1C
1246 #define ASCQ_ERR_SG_LIST_ODD_ADDRESS  0x1D
1247 #define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
1248 #define ASCQ_ERR_SCSIQ_NULL_PTR       0x1F
1249 #define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR   0x20
1250 #define ASCQ_ERR_GET_NUM_OF_FREE_Q    0x21
1251 #define ASCQ_ERR_SEND_SCSI_Q          0x22
1252 #define ASCQ_ERR_HOST_REQ_RISC_HALT   0x23
1253 #define ASCQ_ERR_RESET_SDTR           0x24
1254
1255 /*
1256  * Warning code values are set in ASC_DVC_VAR  'warn_code'.
1257  */
1258 #define ASC_WARN_NO_ERROR             0x0000
1259 #define ASC_WARN_IO_PORT_ROTATE       0x0001
1260 #define ASC_WARN_EEPROM_CHKSUM        0x0002
1261 #define ASC_WARN_IRQ_MODIFIED         0x0004
1262 #define ASC_WARN_AUTO_CONFIG          0x0008
1263 #define ASC_WARN_CMD_QNG_CONFLICT     0x0010
1264 #define ASC_WARN_EEPROM_RECOVER       0x0020
1265 #define ASC_WARN_CFG_MSW_RECOVER      0x0040
1266 #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
1267
1268 /*
1269  * Error code values are set in ASC_DVC_VAR  'err_code'.
1270  */
1271 #define ASC_IERR_WRITE_EEPROM         0x0001
1272 #define ASC_IERR_MCODE_CHKSUM         0x0002
1273 #define ASC_IERR_SET_PC_ADDR          0x0004
1274 #define ASC_IERR_START_STOP_CHIP      0x0008
1275 #define ASC_IERR_IRQ_NO               0x0010
1276 #define ASC_IERR_SET_IRQ_NO           0x0020
1277 #define ASC_IERR_CHIP_VERSION         0x0040
1278 #define ASC_IERR_SET_SCSI_ID          0x0080
1279 #define ASC_IERR_GET_PHY_ADDR         0x0100
1280 #define ASC_IERR_BAD_SIGNATURE        0x0200
1281 #define ASC_IERR_NO_BUS_TYPE          0x0400
1282 #define ASC_IERR_SCAM                 0x0800
1283 #define ASC_IERR_SET_SDTR             0x1000
1284 #define ASC_IERR_RW_LRAM              0x8000
1285
1286 #define ASC_DEF_IRQ_NO  10
1287 #define ASC_MAX_IRQ_NO  15
1288 #define ASC_MIN_IRQ_NO  10
1289 #define ASC_MIN_REMAIN_Q        (0x02)
1290 #define ASC_DEF_MAX_TOTAL_QNG   (0xF0)
1291 #define ASC_MIN_TAG_Q_PER_DVC   (0x04)
1292 #define ASC_DEF_TAG_Q_PER_DVC   (0x04)
1293 #define ASC_MIN_FREE_Q        ASC_MIN_REMAIN_Q
1294 #define ASC_MIN_TOTAL_QNG     ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
1295 #define ASC_MAX_TOTAL_QNG 240
1296 #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
1297 #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG   8
1298 #define ASC_MAX_PCI_INRAM_TOTAL_QNG  20
1299 #define ASC_MAX_INRAM_TAG_QNG   16
1300 #define ASC_IOADR_TABLE_MAX_IX  11
1301 #define ASC_IOADR_GAP   0x10
1302 #define ASC_LIB_SCSIQ_WK_SP        256
1303 #define ASC_MAX_SYN_XFER_NO        16
1304 #define ASC_SYN_MAX_OFFSET         0x0F
1305 #define ASC_DEF_SDTR_OFFSET        0x0F
1306 #define ASC_DEF_SDTR_INDEX         0x00
1307 #define ASC_SDTR_ULTRA_PCI_10MB_INDEX  0x02
1308 #define SYN_XFER_NS_0  25
1309 #define SYN_XFER_NS_1  30
1310 #define SYN_XFER_NS_2  35
1311 #define SYN_XFER_NS_3  40
1312 #define SYN_XFER_NS_4  50
1313 #define SYN_XFER_NS_5  60
1314 #define SYN_XFER_NS_6  70
1315 #define SYN_XFER_NS_7  85
1316 #define SYN_ULTRA_XFER_NS_0    12
1317 #define SYN_ULTRA_XFER_NS_1    19
1318 #define SYN_ULTRA_XFER_NS_2    25
1319 #define SYN_ULTRA_XFER_NS_3    32
1320 #define SYN_ULTRA_XFER_NS_4    38
1321 #define SYN_ULTRA_XFER_NS_5    44
1322 #define SYN_ULTRA_XFER_NS_6    50
1323 #define SYN_ULTRA_XFER_NS_7    57
1324 #define SYN_ULTRA_XFER_NS_8    63
1325 #define SYN_ULTRA_XFER_NS_9    69
1326 #define SYN_ULTRA_XFER_NS_10   75
1327 #define SYN_ULTRA_XFER_NS_11   82
1328 #define SYN_ULTRA_XFER_NS_12   88
1329 #define SYN_ULTRA_XFER_NS_13   94
1330 #define SYN_ULTRA_XFER_NS_14  100
1331 #define SYN_ULTRA_XFER_NS_15  107
1332
1333 typedef struct ext_msg {
1334         uchar msg_type;
1335         uchar msg_len;
1336         uchar msg_req;
1337         union {
1338                 struct {
1339                         uchar sdtr_xfer_period;
1340                         uchar sdtr_req_ack_offset;
1341                 } sdtr;
1342                 struct {
1343                         uchar wdtr_width;
1344                 } wdtr;
1345                 struct {
1346                         uchar mdp_b3;
1347                         uchar mdp_b2;
1348                         uchar mdp_b1;
1349                         uchar mdp_b0;
1350                 } mdp;
1351         } u_ext_msg;
1352         uchar res;
1353 } EXT_MSG;
1354
1355 #define xfer_period     u_ext_msg.sdtr.sdtr_xfer_period
1356 #define req_ack_offset  u_ext_msg.sdtr.sdtr_req_ack_offset
1357 #define wdtr_width      u_ext_msg.wdtr.wdtr_width
1358 #define mdp_b3          u_ext_msg.mdp_b3
1359 #define mdp_b2          u_ext_msg.mdp_b2
1360 #define mdp_b1          u_ext_msg.mdp_b1
1361 #define mdp_b0          u_ext_msg.mdp_b0
1362
1363 typedef struct asc_dvc_cfg {
1364         ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
1365         ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
1366         ASC_SCSI_BIT_ID_TYPE disc_enable;
1367         ASC_SCSI_BIT_ID_TYPE sdtr_enable;
1368         uchar chip_scsi_id;
1369         uchar isa_dma_speed;
1370         uchar isa_dma_channel;
1371         uchar chip_version;
1372         ushort lib_serial_no;
1373         ushort lib_version;
1374         ushort mcode_date;
1375         ushort mcode_version;
1376         uchar max_tag_qng[ASC_MAX_TID + 1];
1377         uchar *overrun_buf;
1378         uchar sdtr_period_offset[ASC_MAX_TID + 1];
1379         uchar adapter_info[6];
1380 } ASC_DVC_CFG;
1381
1382 #define ASC_DEF_DVC_CNTL       0xFFFF
1383 #define ASC_DEF_CHIP_SCSI_ID   7
1384 #define ASC_DEF_ISA_DMA_SPEED  4
1385 #define ASC_INIT_STATE_NULL          0x0000
1386 #define ASC_INIT_STATE_BEG_GET_CFG   0x0001
1387 #define ASC_INIT_STATE_END_GET_CFG   0x0002
1388 #define ASC_INIT_STATE_BEG_SET_CFG   0x0004
1389 #define ASC_INIT_STATE_END_SET_CFG   0x0008
1390 #define ASC_INIT_STATE_BEG_LOAD_MC   0x0010
1391 #define ASC_INIT_STATE_END_LOAD_MC   0x0020
1392 #define ASC_INIT_STATE_BEG_INQUIRY   0x0040
1393 #define ASC_INIT_STATE_END_INQUIRY   0x0080
1394 #define ASC_INIT_RESET_SCSI_DONE     0x0100
1395 #define ASC_INIT_STATE_WITHOUT_EEP   0x8000
1396 #define ASC_BUG_FIX_IF_NOT_DWB       0x0001
1397 #define ASC_BUG_FIX_ASYN_USE_SYN     0x0002
1398 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
1399 #define ASC_MIN_TAGGED_CMD  7
1400 #define ASC_MAX_SCSI_RESET_WAIT      30
1401
1402 struct asc_dvc_var;             /* Forward Declaration. */
1403
1404 typedef struct asc_dvc_var {
1405         PortAddr iop_base;
1406         ushort err_code;
1407         ushort dvc_cntl;
1408         ushort bug_fix_cntl;
1409         ushort bus_type;
1410         ASC_SCSI_BIT_ID_TYPE init_sdtr;
1411         ASC_SCSI_BIT_ID_TYPE sdtr_done;
1412         ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
1413         ASC_SCSI_BIT_ID_TYPE unit_not_ready;
1414         ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
1415         ASC_SCSI_BIT_ID_TYPE start_motor;
1416         uchar scsi_reset_wait;
1417         uchar chip_no;
1418         char is_in_int;
1419         uchar max_total_qng;
1420         uchar cur_total_qng;
1421         uchar in_critical_cnt;
1422         uchar irq_no;
1423         uchar last_q_shortage;
1424         ushort init_state;
1425         uchar cur_dvc_qng[ASC_MAX_TID + 1];
1426         uchar max_dvc_qng[ASC_MAX_TID + 1];
1427         ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
1428         ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
1429         uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
1430         ASC_DVC_CFG *cfg;
1431         ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
1432         char redo_scam;
1433         ushort res2;
1434         uchar dos_int13_table[ASC_MAX_TID + 1];
1435         ASC_DCNT max_dma_count;
1436         ASC_SCSI_BIT_ID_TYPE no_scam;
1437         ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
1438         uchar max_sdtr_index;
1439         uchar host_init_sdtr_index;
1440         struct asc_board *drv_ptr;
1441         ASC_DCNT uc_break;
1442 } ASC_DVC_VAR;
1443
1444 typedef struct asc_dvc_inq_info {
1445         uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1446 } ASC_DVC_INQ_INFO;
1447
1448 typedef struct asc_cap_info {
1449         ASC_DCNT lba;
1450         ASC_DCNT blk_size;
1451 } ASC_CAP_INFO;
1452
1453 typedef struct asc_cap_info_array {
1454         ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1455 } ASC_CAP_INFO_ARRAY;
1456
1457 #define ASC_MCNTL_NO_SEL_TIMEOUT  (ushort)0x0001
1458 #define ASC_MCNTL_NULL_TARGET     (ushort)0x0002
1459 #define ASC_CNTL_INITIATOR         (ushort)0x0001
1460 #define ASC_CNTL_BIOS_GT_1GB       (ushort)0x0002
1461 #define ASC_CNTL_BIOS_GT_2_DISK    (ushort)0x0004
1462 #define ASC_CNTL_BIOS_REMOVABLE    (ushort)0x0008
1463 #define ASC_CNTL_NO_SCAM           (ushort)0x0010
1464 #define ASC_CNTL_INT_MULTI_Q       (ushort)0x0080
1465 #define ASC_CNTL_NO_LUN_SUPPORT    (ushort)0x0040
1466 #define ASC_CNTL_NO_VERIFY_COPY    (ushort)0x0100
1467 #define ASC_CNTL_RESET_SCSI        (ushort)0x0200
1468 #define ASC_CNTL_INIT_INQUIRY      (ushort)0x0400
1469 #define ASC_CNTL_INIT_VERBOSE      (ushort)0x0800
1470 #define ASC_CNTL_SCSI_PARITY       (ushort)0x1000
1471 #define ASC_CNTL_BURST_MODE        (ushort)0x2000
1472 #define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
1473 #define ASC_EEP_DVC_CFG_BEG_VL    2
1474 #define ASC_EEP_MAX_DVC_ADDR_VL   15
1475 #define ASC_EEP_DVC_CFG_BEG      32
1476 #define ASC_EEP_MAX_DVC_ADDR     45
1477 #define ASC_EEP_DEFINED_WORDS    10
1478 #define ASC_EEP_MAX_ADDR         63
1479 #define ASC_EEP_RES_WORDS         0
1480 #define ASC_EEP_MAX_RETRY        20
1481 #define ASC_MAX_INIT_BUSY_RETRY   8
1482 #define ASC_EEP_ISA_PNP_WSIZE    16
1483
1484 /*
1485  * These macros keep the chip SCSI id and ISA DMA speed
1486  * bitfields in board order. C bitfields aren't portable
1487  * between big and little-endian platforms so they are
1488  * not used.
1489  */
1490
1491 #define ASC_EEP_GET_CHIP_ID(cfg)    ((cfg)->id_speed & 0x0f)
1492 #define ASC_EEP_GET_DMA_SPD(cfg)    (((cfg)->id_speed & 0xf0) >> 4)
1493 #define ASC_EEP_SET_CHIP_ID(cfg, sid) \
1494    ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
1495 #define ASC_EEP_SET_DMA_SPD(cfg, spd) \
1496    ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
1497
1498 typedef struct asceep_config {
1499         ushort cfg_lsw;
1500         ushort cfg_msw;
1501         uchar init_sdtr;
1502         uchar disc_enable;
1503         uchar use_cmd_qng;
1504         uchar start_motor;
1505         uchar max_total_qng;
1506         uchar max_tag_qng;
1507         uchar bios_scan;
1508         uchar power_up_wait;
1509         uchar no_scam;
1510         uchar id_speed;         /* low order 4 bits is chip scsi id */
1511         /* high order 4 bits is isa dma speed */
1512         uchar dos_int13_table[ASC_MAX_TID + 1];
1513         uchar adapter_info[6];
1514         ushort cntl;
1515         ushort chksum;
1516 } ASCEEP_CONFIG;
1517
1518 #define ASC_PCI_CFG_LSW_SCSI_PARITY  0x0800
1519 #define ASC_PCI_CFG_LSW_BURST_MODE   0x0080
1520 #define ASC_PCI_CFG_LSW_INTR_ABLE    0x0020
1521
1522 #define ASC_EEP_CMD_READ          0x80
1523 #define ASC_EEP_CMD_WRITE         0x40
1524 #define ASC_EEP_CMD_WRITE_ABLE    0x30
1525 #define ASC_EEP_CMD_WRITE_DISABLE 0x00
1526 #define ASC_OVERRUN_BSIZE  0x00000048UL
1527 #define ASC_CTRL_BREAK_ONCE        0x0001
1528 #define ASC_CTRL_BREAK_STAY_IDLE   0x0002
1529 #define ASCV_MSGOUT_BEG         0x0000
1530 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
1531 #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
1532 #define ASCV_BREAK_SAVED_CODE   (ushort)0x0006
1533 #define ASCV_MSGIN_BEG          (ASCV_MSGOUT_BEG+8)
1534 #define ASCV_MSGIN_SDTR_PERIOD  (ASCV_MSGIN_BEG+3)
1535 #define ASCV_MSGIN_SDTR_OFFSET  (ASCV_MSGIN_BEG+4)
1536 #define ASCV_SDTR_DATA_BEG      (ASCV_MSGIN_BEG+8)
1537 #define ASCV_SDTR_DONE_BEG      (ASCV_SDTR_DATA_BEG+8)
1538 #define ASCV_MAX_DVC_QNG_BEG    (ushort)0x0020
1539 #define ASCV_BREAK_ADDR           (ushort)0x0028
1540 #define ASCV_BREAK_NOTIFY_COUNT   (ushort)0x002A
1541 #define ASCV_BREAK_CONTROL        (ushort)0x002C
1542 #define ASCV_BREAK_HIT_COUNT      (ushort)0x002E
1543
1544 #define ASCV_ASCDVC_ERR_CODE_W  (ushort)0x0030
1545 #define ASCV_MCODE_CHKSUM_W   (ushort)0x0032
1546 #define ASCV_MCODE_SIZE_W     (ushort)0x0034
1547 #define ASCV_STOP_CODE_B      (ushort)0x0036
1548 #define ASCV_DVC_ERR_CODE_B   (ushort)0x0037
1549 #define ASCV_OVERRUN_PADDR_D  (ushort)0x0038
1550 #define ASCV_OVERRUN_BSIZE_D  (ushort)0x003C
1551 #define ASCV_HALTCODE_W       (ushort)0x0040
1552 #define ASCV_CHKSUM_W         (ushort)0x0042
1553 #define ASCV_MC_DATE_W        (ushort)0x0044
1554 #define ASCV_MC_VER_W         (ushort)0x0046
1555 #define ASCV_NEXTRDY_B        (ushort)0x0048
1556 #define ASCV_DONENEXT_B       (ushort)0x0049
1557 #define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
1558 #define ASCV_SCSIBUSY_B       (ushort)0x004B
1559 #define ASCV_Q_DONE_IN_PROGRESS_B  (ushort)0x004C
1560 #define ASCV_CURCDB_B         (ushort)0x004D
1561 #define ASCV_RCLUN_B          (ushort)0x004E
1562 #define ASCV_BUSY_QHEAD_B     (ushort)0x004F
1563 #define ASCV_DISC1_QHEAD_B    (ushort)0x0050
1564 #define ASCV_DISC_ENABLE_B    (ushort)0x0052
1565 #define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
1566 #define ASCV_HOSTSCSI_ID_B    (ushort)0x0055
1567 #define ASCV_MCODE_CNTL_B     (ushort)0x0056
1568 #define ASCV_NULL_TARGET_B    (ushort)0x0057
1569 #define ASCV_FREE_Q_HEAD_W    (ushort)0x0058
1570 #define ASCV_DONE_Q_TAIL_W    (ushort)0x005A
1571 #define ASCV_FREE_Q_HEAD_B    (ushort)(ASCV_FREE_Q_HEAD_W+1)
1572 #define ASCV_DONE_Q_TAIL_B    (ushort)(ASCV_DONE_Q_TAIL_W+1)
1573 #define ASCV_HOST_FLAG_B      (ushort)0x005D
1574 #define ASCV_TOTAL_READY_Q_B  (ushort)0x0064
1575 #define ASCV_VER_SERIAL_B     (ushort)0x0065
1576 #define ASCV_HALTCODE_SAVED_W (ushort)0x0066
1577 #define ASCV_WTM_FLAG_B       (ushort)0x0068
1578 #define ASCV_RISC_FLAG_B      (ushort)0x006A
1579 #define ASCV_REQ_SG_LIST_QP   (ushort)0x006B
1580 #define ASC_HOST_FLAG_IN_ISR        0x01
1581 #define ASC_HOST_FLAG_ACK_INT       0x02
1582 #define ASC_RISC_FLAG_GEN_INT      0x01
1583 #define ASC_RISC_FLAG_REQ_SG_LIST  0x02
1584 #define IOP_CTRL         (0x0F)
1585 #define IOP_STATUS       (0x0E)
1586 #define IOP_INT_ACK      IOP_STATUS
1587 #define IOP_REG_IFC      (0x0D)
1588 #define IOP_SYN_OFFSET    (0x0B)
1589 #define IOP_EXTRA_CONTROL (0x0D)
1590 #define IOP_REG_PC        (0x0C)
1591 #define IOP_RAM_ADDR      (0x0A)
1592 #define IOP_RAM_DATA      (0x08)
1593 #define IOP_EEP_DATA      (0x06)
1594 #define IOP_EEP_CMD       (0x07)
1595 #define IOP_VERSION       (0x03)
1596 #define IOP_CONFIG_HIGH   (0x04)
1597 #define IOP_CONFIG_LOW    (0x02)
1598 #define IOP_SIG_BYTE      (0x01)
1599 #define IOP_SIG_WORD      (0x00)
1600 #define IOP_REG_DC1      (0x0E)
1601 #define IOP_REG_DC0      (0x0C)
1602 #define IOP_REG_SB       (0x0B)
1603 #define IOP_REG_DA1      (0x0A)
1604 #define IOP_REG_DA0      (0x08)
1605 #define IOP_REG_SC       (0x09)
1606 #define IOP_DMA_SPEED    (0x07)
1607 #define IOP_REG_FLAG     (0x07)
1608 #define IOP_FIFO_H       (0x06)
1609 #define IOP_FIFO_L       (0x04)
1610 #define IOP_REG_ID       (0x05)
1611 #define IOP_REG_QP       (0x03)
1612 #define IOP_REG_IH       (0x02)
1613 #define IOP_REG_IX       (0x01)
1614 #define IOP_REG_AX       (0x00)
1615 #define IFC_REG_LOCK      (0x00)
1616 #define IFC_REG_UNLOCK    (0x09)
1617 #define IFC_WR_EN_FILTER  (0x10)
1618 #define IFC_RD_NO_EEPROM  (0x10)
1619 #define IFC_SLEW_RATE     (0x20)
1620 #define IFC_ACT_NEG       (0x40)
1621 #define IFC_INP_FILTER    (0x80)
1622 #define IFC_INIT_DEFAULT  (IFC_ACT_NEG | IFC_REG_UNLOCK)
1623 #define SC_SEL   (uchar)(0x80)
1624 #define SC_BSY   (uchar)(0x40)
1625 #define SC_ACK   (uchar)(0x20)
1626 #define SC_REQ   (uchar)(0x10)
1627 #define SC_ATN   (uchar)(0x08)
1628 #define SC_IO    (uchar)(0x04)
1629 #define SC_CD    (uchar)(0x02)
1630 #define SC_MSG   (uchar)(0x01)
1631 #define SEC_SCSI_CTL         (uchar)(0x80)
1632 #define SEC_ACTIVE_NEGATE    (uchar)(0x40)
1633 #define SEC_SLEW_RATE        (uchar)(0x20)
1634 #define SEC_ENABLE_FILTER    (uchar)(0x10)
1635 #define ASC_HALT_EXTMSG_IN     (ushort)0x8000
1636 #define ASC_HALT_CHK_CONDITION (ushort)0x8100
1637 #define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
1638 #define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX  (ushort)0x8300
1639 #define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX   (ushort)0x8400
1640 #define ASC_HALT_SDTR_REJECTED (ushort)0x4000
1641 #define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
1642 #define ASC_MAX_QNO        0xF8
1643 #define ASC_DATA_SEC_BEG   (ushort)0x0080
1644 #define ASC_DATA_SEC_END   (ushort)0x0080
1645 #define ASC_CODE_SEC_BEG   (ushort)0x0080
1646 #define ASC_CODE_SEC_END   (ushort)0x0080
1647 #define ASC_QADR_BEG       (0x4000)
1648 #define ASC_QADR_USED      (ushort)(ASC_MAX_QNO * 64)
1649 #define ASC_QADR_END       (ushort)0x7FFF
1650 #define ASC_QLAST_ADR      (ushort)0x7FC0
1651 #define ASC_QBLK_SIZE      0x40
1652 #define ASC_BIOS_DATA_QBEG 0xF8
1653 #define ASC_MIN_ACTIVE_QNO 0x01
1654 #define ASC_QLINK_END      0xFF
1655 #define ASC_EEPROM_WORDS   0x10
1656 #define ASC_MAX_MGS_LEN    0x10
1657 #define ASC_BIOS_ADDR_DEF  0xDC00
1658 #define ASC_BIOS_SIZE      0x3800
1659 #define ASC_BIOS_RAM_OFF   0x3800
1660 #define ASC_BIOS_RAM_SIZE  0x800
1661 #define ASC_BIOS_MIN_ADDR  0xC000
1662 #define ASC_BIOS_MAX_ADDR  0xEC00
1663 #define ASC_BIOS_BANK_SIZE 0x0400
1664 #define ASC_MCODE_START_ADDR  0x0080
1665 #define ASC_CFG0_HOST_INT_ON    0x0020
1666 #define ASC_CFG0_BIOS_ON        0x0040
1667 #define ASC_CFG0_VERA_BURST_ON  0x0080
1668 #define ASC_CFG0_SCSI_PARITY_ON 0x0800
1669 #define ASC_CFG1_SCSI_TARGET_ON 0x0080
1670 #define ASC_CFG1_LRAM_8BITS_ON  0x0800
1671 #define ASC_CFG_MSW_CLR_MASK    0x3080
1672 #define CSW_TEST1             (ASC_CS_TYPE)0x8000
1673 #define CSW_AUTO_CONFIG       (ASC_CS_TYPE)0x4000
1674 #define CSW_RESERVED1         (ASC_CS_TYPE)0x2000
1675 #define CSW_IRQ_WRITTEN       (ASC_CS_TYPE)0x1000
1676 #define CSW_33MHZ_SELECTED    (ASC_CS_TYPE)0x0800
1677 #define CSW_TEST2             (ASC_CS_TYPE)0x0400
1678 #define CSW_TEST3             (ASC_CS_TYPE)0x0200
1679 #define CSW_RESERVED2         (ASC_CS_TYPE)0x0100
1680 #define CSW_DMA_DONE          (ASC_CS_TYPE)0x0080
1681 #define CSW_FIFO_RDY          (ASC_CS_TYPE)0x0040
1682 #define CSW_EEP_READ_DONE     (ASC_CS_TYPE)0x0020
1683 #define CSW_HALTED            (ASC_CS_TYPE)0x0010
1684 #define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
1685 #define CSW_PARITY_ERR        (ASC_CS_TYPE)0x0004
1686 #define CSW_SCSI_RESET_LATCH  (ASC_CS_TYPE)0x0002
1687 #define CSW_INT_PENDING       (ASC_CS_TYPE)0x0001
1688 #define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
1689 #define CIW_INT_ACK      (ASC_CS_TYPE)0x0100
1690 #define CIW_TEST1        (ASC_CS_TYPE)0x0200
1691 #define CIW_TEST2        (ASC_CS_TYPE)0x0400
1692 #define CIW_SEL_33MHZ    (ASC_CS_TYPE)0x0800
1693 #define CIW_IRQ_ACT      (ASC_CS_TYPE)0x1000
1694 #define CC_CHIP_RESET   (uchar)0x80
1695 #define CC_SCSI_RESET   (uchar)0x40
1696 #define CC_HALT         (uchar)0x20
1697 #define CC_SINGLE_STEP  (uchar)0x10
1698 #define CC_DMA_ABLE     (uchar)0x08
1699 #define CC_TEST         (uchar)0x04
1700 #define CC_BANK_ONE     (uchar)0x02
1701 #define CC_DIAG         (uchar)0x01
1702 #define ASC_1000_ID0W      0x04C1
1703 #define ASC_1000_ID0W_FIX  0x00C1
1704 #define ASC_1000_ID1B      0x25
1705 #define ASC_EISA_REV_IOP_MASK  (0x0C83)
1706 #define ASC_EISA_PID_IOP_MASK  (0x0C80)
1707 #define ASC_EISA_CFG_IOP_MASK  (0x0C86)
1708 #define ASC_GET_EISA_SLOT(iop)  (PortAddr)((iop) & 0xF000)
1709 #define INS_HALTINT        (ushort)0x6281
1710 #define INS_HALT           (ushort)0x6280
1711 #define INS_SINT           (ushort)0x6200
1712 #define INS_RFLAG_WTM      (ushort)0x7380
1713 #define ASC_MC_SAVE_CODE_WSIZE  0x500
1714 #define ASC_MC_SAVE_DATA_WSIZE  0x40
1715
1716 typedef struct asc_mc_saved {
1717         ushort data[ASC_MC_SAVE_DATA_WSIZE];
1718         ushort code[ASC_MC_SAVE_CODE_WSIZE];
1719 } ASC_MC_SAVED;
1720
1721 #define AscGetQDoneInProgress(port)         AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
1722 #define AscPutQDoneInProgress(port, val)    AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
1723 #define AscGetVarFreeQHead(port)            AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
1724 #define AscGetVarDoneQTail(port)            AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
1725 #define AscPutVarFreeQHead(port, val)       AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
1726 #define AscPutVarDoneQTail(port, val)       AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
1727 #define AscGetRiscVarFreeQHead(port)        AscReadLramByte((port), ASCV_NEXTRDY_B)
1728 #define AscGetRiscVarDoneQTail(port)        AscReadLramByte((port), ASCV_DONENEXT_B)
1729 #define AscPutRiscVarFreeQHead(port, val)   AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
1730 #define AscPutRiscVarDoneQTail(port, val)   AscWriteLramByte((port), ASCV_DONENEXT_B, val)
1731 #define AscPutMCodeSDTRDoneAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
1732 #define AscGetMCodeSDTRDoneAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
1733 #define AscPutMCodeInitSDTRAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
1734 #define AscGetMCodeInitSDTRAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
1735 #define AscSynIndexToPeriod(index)        (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1736 #define AscGetChipSignatureByte(port)     (uchar)inp((port)+IOP_SIG_BYTE)
1737 #define AscGetChipSignatureWord(port)     (ushort)inpw((port)+IOP_SIG_WORD)
1738 #define AscGetChipVerNo(port)             (uchar)inp((port)+IOP_VERSION)
1739 #define AscGetChipCfgLsw(port)            (ushort)inpw((port)+IOP_CONFIG_LOW)
1740 #define AscGetChipCfgMsw(port)            (ushort)inpw((port)+IOP_CONFIG_HIGH)
1741 #define AscSetChipCfgLsw(port, data)      outpw((port)+IOP_CONFIG_LOW, data)
1742 #define AscSetChipCfgMsw(port, data)      outpw((port)+IOP_CONFIG_HIGH, data)
1743 #define AscGetChipEEPCmd(port)            (uchar)inp((port)+IOP_EEP_CMD)
1744 #define AscSetChipEEPCmd(port, data)      outp((port)+IOP_EEP_CMD, data)
1745 #define AscGetChipEEPData(port)           (ushort)inpw((port)+IOP_EEP_DATA)
1746 #define AscSetChipEEPData(port, data)     outpw((port)+IOP_EEP_DATA, data)
1747 #define AscGetChipLramAddr(port)          (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1748 #define AscSetChipLramAddr(port, addr)    outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1749 #define AscGetChipLramData(port)          (ushort)inpw((port)+IOP_RAM_DATA)
1750 #define AscSetChipLramData(port, data)    outpw((port)+IOP_RAM_DATA, data)
1751 #define AscGetChipIFC(port)               (uchar)inp((port)+IOP_REG_IFC)
1752 #define AscSetChipIFC(port, data)          outp((port)+IOP_REG_IFC, data)
1753 #define AscGetChipStatus(port)            (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1754 #define AscSetChipStatus(port, cs_val)    outpw((port)+IOP_STATUS, cs_val)
1755 #define AscGetChipControl(port)           (uchar)inp((port)+IOP_CTRL)
1756 #define AscSetChipControl(port, cc_val)   outp((port)+IOP_CTRL, cc_val)
1757 #define AscGetChipSyn(port)               (uchar)inp((port)+IOP_SYN_OFFSET)
1758 #define AscSetChipSyn(port, data)         outp((port)+IOP_SYN_OFFSET, data)
1759 #define AscSetPCAddr(port, data)          outpw((port)+IOP_REG_PC, data)
1760 #define AscGetPCAddr(port)                (ushort)inpw((port)+IOP_REG_PC)
1761 #define AscIsIntPending(port)             (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1762 #define AscGetChipScsiID(port)            ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1763 #define AscGetExtraControl(port)          (uchar)inp((port)+IOP_EXTRA_CONTROL)
1764 #define AscSetExtraControl(port, data)    outp((port)+IOP_EXTRA_CONTROL, data)
1765 #define AscReadChipAX(port)               (ushort)inpw((port)+IOP_REG_AX)
1766 #define AscWriteChipAX(port, data)        outpw((port)+IOP_REG_AX, data)
1767 #define AscReadChipIX(port)               (uchar)inp((port)+IOP_REG_IX)
1768 #define AscWriteChipIX(port, data)        outp((port)+IOP_REG_IX, data)
1769 #define AscReadChipIH(port)               (ushort)inpw((port)+IOP_REG_IH)
1770 #define AscWriteChipIH(port, data)        outpw((port)+IOP_REG_IH, data)
1771 #define AscReadChipQP(port)               (uchar)inp((port)+IOP_REG_QP)
1772 #define AscWriteChipQP(port, data)        outp((port)+IOP_REG_QP, data)
1773 #define AscReadChipFIFO_L(port)           (ushort)inpw((port)+IOP_REG_FIFO_L)
1774 #define AscWriteChipFIFO_L(port, data)    outpw((port)+IOP_REG_FIFO_L, data)
1775 #define AscReadChipFIFO_H(port)           (ushort)inpw((port)+IOP_REG_FIFO_H)
1776 #define AscWriteChipFIFO_H(port, data)    outpw((port)+IOP_REG_FIFO_H, data)
1777 #define AscReadChipDmaSpeed(port)         (uchar)inp((port)+IOP_DMA_SPEED)
1778 #define AscWriteChipDmaSpeed(port, data)  outp((port)+IOP_DMA_SPEED, data)
1779 #define AscReadChipDA0(port)              (ushort)inpw((port)+IOP_REG_DA0)
1780 #define AscWriteChipDA0(port)             outpw((port)+IOP_REG_DA0, data)
1781 #define AscReadChipDA1(port)              (ushort)inpw((port)+IOP_REG_DA1)
1782 #define AscWriteChipDA1(port)             outpw((port)+IOP_REG_DA1, data)
1783 #define AscReadChipDC0(port)              (ushort)inpw((port)+IOP_REG_DC0)
1784 #define AscWriteChipDC0(port)             outpw((port)+IOP_REG_DC0, data)
1785 #define AscReadChipDC1(port)              (ushort)inpw((port)+IOP_REG_DC1)
1786 #define AscWriteChipDC1(port)             outpw((port)+IOP_REG_DC1, data)
1787 #define AscReadChipDvcID(port)            (uchar)inp((port)+IOP_REG_ID)
1788 #define AscWriteChipDvcID(port, data)     outp((port)+IOP_REG_ID, data)
1789
1790 static int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
1791 static int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
1792 static void AscWaitEEPRead(void);
1793 static void AscWaitEEPWrite(void);
1794 static ushort AscReadEEPWord(PortAddr, uchar);
1795 static ushort AscWriteEEPWord(PortAddr, uchar, ushort);
1796 static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1797 static int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
1798 static int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1799 static int AscStartChip(PortAddr);
1800 static int AscStopChip(PortAddr);
1801 static void AscSetChipIH(PortAddr, ushort);
1802 static int AscIsChipHalted(PortAddr);
1803 static void AscAckInterrupt(PortAddr);
1804 static void AscDisableInterrupt(PortAddr);
1805 static void AscEnableInterrupt(PortAddr);
1806 static void AscSetBank(PortAddr, uchar);
1807 static int AscResetChipAndScsiBus(ASC_DVC_VAR *);
1808 #ifdef CONFIG_ISA
1809 static uchar AscGetIsaDmaSpeed(PortAddr);
1810 #endif /* CONFIG_ISA */
1811 static uchar AscReadLramByte(PortAddr, ushort);
1812 static ushort AscReadLramWord(PortAddr, ushort);
1813 #if CC_VERY_LONG_SG_LIST
1814 static ASC_DCNT AscReadLramDWord(PortAddr, ushort);
1815 #endif /* CC_VERY_LONG_SG_LIST */
1816 static void AscWriteLramWord(PortAddr, ushort, ushort);
1817 static void AscWriteLramByte(PortAddr, ushort, uchar);
1818 static ASC_DCNT AscMemSumLramWord(PortAddr, ushort, int);
1819 static void AscMemWordSetLram(PortAddr, ushort, ushort, int);
1820 static void AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1821 static void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1822 static void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
1823 static ushort AscInitAscDvcVar(ASC_DVC_VAR *);
1824 static ushort AscInitFromEEP(ASC_DVC_VAR *);
1825 static ushort AscInitMicroCodeVar(ASC_DVC_VAR *);
1826 static int AscTestExternalLram(ASC_DVC_VAR *);
1827 static uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
1828 static uchar AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
1829 static void AscSetChipSDTR(PortAddr, uchar, uchar);
1830 static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
1831 static uchar AscAllocFreeQueue(PortAddr, uchar);
1832 static uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
1833 static int AscHostReqRiscHalt(PortAddr);
1834 static int AscStopQueueExe(PortAddr);
1835 static int AscSendScsiQueue(ASC_DVC_VAR *,
1836                             ASC_SCSI_Q *scsiq, uchar n_q_required);
1837 static int AscPutReadyQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1838 static int AscPutReadySgListQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1839 static int AscSetChipSynRegAtID(PortAddr, uchar, uchar);
1840 static int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
1841 static ushort AscInitLram(ASC_DVC_VAR *);
1842 static ushort AscInitQLinkVar(ASC_DVC_VAR *);
1843 static int AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
1844 static int AscIsrChipHalted(ASC_DVC_VAR *);
1845 static uchar _AscCopyLramScsiDoneQ(PortAddr, ushort,
1846                                    ASC_QDONE_INFO *, ASC_DCNT);
1847 static int AscIsrQDone(ASC_DVC_VAR *);
1848 #ifdef CONFIG_ISA
1849 static ushort AscGetEisaChipCfg(PortAddr);
1850 #endif /* CONFIG_ISA */
1851 static uchar AscGetChipScsiCtrl(PortAddr);
1852 static uchar AscGetChipVersion(PortAddr, ushort);
1853 static ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
1854 static void AscToggleIRQAct(PortAddr);
1855 static inline ulong DvcEnterCritical(void);
1856 static inline void DvcLeaveCritical(ulong);
1857 static void DvcSleepMilliSecond(ASC_DCNT);
1858 static void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
1859 static void DvcPutScsiQ(PortAddr, ushort, uchar *, int);
1860 static void DvcGetQinfo(PortAddr, ushort, uchar *, int);
1861 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *);
1862 static void AscAsyncFix(ASC_DVC_VAR *, struct scsi_device *);
1863 static int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
1864 static int AscISR(ASC_DVC_VAR *);
1865 static uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar, uchar);
1866 static int AscSgListToQueue(int);
1867 #ifdef CONFIG_ISA
1868 static void AscEnableIsaDma(uchar);
1869 #endif /* CONFIG_ISA */
1870 static const char *advansys_info(struct Scsi_Host *shost);
1871
1872 /*
1873  * --- Adv Library Constants and Macros
1874  */
1875
1876 #define ADV_LIB_VERSION_MAJOR  5
1877 #define ADV_LIB_VERSION_MINOR  14
1878
1879 /*
1880  * Define Adv Library required special types.
1881  */
1882
1883 /*
1884  * Portable Data Types
1885  *
1886  * Any instance where a 32-bit long or pointer type is assumed
1887  * for precision or HW defined structures, the following define
1888  * types must be used. In Linux the char, short, and int types
1889  * are all consistent at 8, 16, and 32 bits respectively. Pointers
1890  * and long types are 64 bits on Alpha and UltraSPARC.
1891  */
1892 #define ADV_PADDR __u32         /* Physical address data type. */
1893 #define ADV_VADDR __u32         /* Virtual address data type. */
1894 #define ADV_DCNT  __u32         /* Unsigned Data count type. */
1895 #define ADV_SDCNT __s32         /* Signed Data count type. */
1896
1897 /*
1898  * These macros are used to convert a virtual address to a
1899  * 32-bit value. This currently can be used on Linux Alpha
1900  * which uses 64-bit virtual address but a 32-bit bus address.
1901  * This is likely to break in the future, but doing this now
1902  * will give us time to change the HW and FW to handle 64-bit
1903  * addresses.
1904  */
1905 #define ADV_VADDR_TO_U32   virt_to_bus
1906 #define ADV_U32_TO_VADDR   bus_to_virt
1907
1908 #define AdvPortAddr  void __iomem *     /* Virtual memory address size */
1909
1910 /*
1911  * Define Adv Library required memory access macros.
1912  */
1913 #define ADV_MEM_READB(addr) readb(addr)
1914 #define ADV_MEM_READW(addr) readw(addr)
1915 #define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
1916 #define ADV_MEM_WRITEW(addr, word) writew(word, addr)
1917 #define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
1918
1919 #define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
1920
1921 /*
1922  * For wide  boards a CDB length maximum of 16 bytes
1923  * is supported.
1924  */
1925 #define ADV_MAX_CDB_LEN     16
1926
1927 /*
1928  * Define total number of simultaneous maximum element scatter-gather
1929  * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
1930  * maximum number of outstanding commands per wide host adapter. Each
1931  * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
1932  * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
1933  * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
1934  * structures or 255 scatter-gather elements.
1935  *
1936  */
1937 #define ADV_TOT_SG_BLOCK        ASC_DEF_MAX_HOST_QNG
1938
1939 /*
1940  * Define Adv Library required maximum number of scatter-gather
1941  * elements per request.
1942  */
1943 #define ADV_MAX_SG_LIST         255
1944
1945 /* Number of SG blocks needed. */
1946 #define ADV_NUM_SG_BLOCK \
1947     ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
1948
1949 /* Total contiguous memory needed for SG blocks. */
1950 #define ADV_SG_TOTAL_MEM_SIZE \
1951     (sizeof(ADV_SG_BLOCK) *  ADV_NUM_SG_BLOCK)
1952
1953 #define ADV_PAGE_SIZE PAGE_SIZE
1954
1955 #define ADV_NUM_PAGE_CROSSING \
1956     ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
1957
1958 #define ADV_EEP_DVC_CFG_BEGIN           (0x00)
1959 #define ADV_EEP_DVC_CFG_END             (0x15)
1960 #define ADV_EEP_DVC_CTL_BEGIN           (0x16)  /* location of OEM name */
1961 #define ADV_EEP_MAX_WORD_ADDR           (0x1E)
1962
1963 #define ADV_EEP_DELAY_MS                100
1964
1965 #define ADV_EEPROM_BIG_ENDIAN          0x8000   /* EEPROM Bit 15 */
1966 #define ADV_EEPROM_BIOS_ENABLE         0x4000   /* EEPROM Bit 14 */
1967 /*
1968  * For the ASC3550 Bit 13 is Termination Polarity control bit.
1969  * For later ICs Bit 13 controls whether the CIS (Card Information
1970  * Service Section) is loaded from EEPROM.
1971  */
1972 #define ADV_EEPROM_TERM_POL            0x2000   /* EEPROM Bit 13 */
1973 #define ADV_EEPROM_CIS_LD              0x2000   /* EEPROM Bit 13 */
1974 /*
1975  * ASC38C1600 Bit 11
1976  *
1977  * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
1978  * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
1979  * Function 0 will specify INT B.
1980  *
1981  * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
1982  * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
1983  * Function 1 will specify INT A.
1984  */
1985 #define ADV_EEPROM_INTAB               0x0800   /* EEPROM Bit 11 */
1986
1987 typedef struct adveep_3550_config {
1988         /* Word Offset, Description */
1989
1990         ushort cfg_lsw;         /* 00 power up initialization */
1991         /*  bit 13 set - Term Polarity Control */
1992         /*  bit 14 set - BIOS Enable */
1993         /*  bit 15 set - Big Endian Mode */
1994         ushort cfg_msw;         /* 01 unused      */
1995         ushort disc_enable;     /* 02 disconnect enable */
1996         ushort wdtr_able;       /* 03 Wide DTR able */
1997         ushort sdtr_able;       /* 04 Synchronous DTR able */
1998         ushort start_motor;     /* 05 send start up motor */
1999         ushort tagqng_able;     /* 06 tag queuing able */
2000         ushort bios_scan;       /* 07 BIOS device control */
2001         ushort scam_tolerant;   /* 08 no scam */
2002
2003         uchar adapter_scsi_id;  /* 09 Host Adapter ID */
2004         uchar bios_boot_delay;  /*    power up wait */
2005
2006         uchar scsi_reset_delay; /* 10 reset delay */
2007         uchar bios_id_lun;      /*    first boot device scsi id & lun */
2008         /*    high nibble is lun */
2009         /*    low nibble is scsi id */
2010
2011         uchar termination;      /* 11 0 - automatic */
2012         /*    1 - low off / high off */
2013         /*    2 - low off / high on */
2014         /*    3 - low on  / high on */
2015         /*    There is no low on  / high off */
2016
2017         uchar reserved1;        /*    reserved byte (not used) */
2018
2019         ushort bios_ctrl;       /* 12 BIOS control bits */
2020         /*  bit 0  BIOS don't act as initiator. */
2021         /*  bit 1  BIOS > 1 GB support */
2022         /*  bit 2  BIOS > 2 Disk Support */
2023         /*  bit 3  BIOS don't support removables */
2024         /*  bit 4  BIOS support bootable CD */
2025         /*  bit 5  BIOS scan enabled */
2026         /*  bit 6  BIOS support multiple LUNs */
2027         /*  bit 7  BIOS display of message */
2028         /*  bit 8  SCAM disabled */
2029         /*  bit 9  Reset SCSI bus during init. */
2030         /*  bit 10 */
2031         /*  bit 11 No verbose initialization. */
2032         /*  bit 12 SCSI parity enabled */
2033         /*  bit 13 */
2034         /*  bit 14 */
2035         /*  bit 15 */
2036         ushort ultra_able;      /* 13 ULTRA speed able */
2037         ushort reserved2;       /* 14 reserved */
2038         uchar max_host_qng;     /* 15 maximum host queuing */
2039         uchar max_dvc_qng;      /*    maximum per device queuing */
2040         ushort dvc_cntl;        /* 16 control bit for driver */
2041         ushort bug_fix;         /* 17 control bit for bug fix */
2042         ushort serial_number_word1;     /* 18 Board serial number word 1 */
2043         ushort serial_number_word2;     /* 19 Board serial number word 2 */
2044         ushort serial_number_word3;     /* 20 Board serial number word 3 */
2045         ushort check_sum;       /* 21 EEP check sum */
2046         uchar oem_name[16];     /* 22 OEM name */
2047         ushort dvc_err_code;    /* 30 last device driver error code */
2048         ushort adv_err_code;    /* 31 last uc and Adv Lib error code */
2049         ushort adv_err_addr;    /* 32 last uc error address */
2050         ushort saved_dvc_err_code;      /* 33 saved last dev. driver error code   */
2051         ushort saved_adv_err_code;      /* 34 saved last uc and Adv Lib error code */
2052         ushort saved_adv_err_addr;      /* 35 saved last uc error address         */
2053         ushort num_of_err;      /* 36 number of error */
2054 } ADVEEP_3550_CONFIG;
2055
2056 typedef struct adveep_38C0800_config {
2057         /* Word Offset, Description */
2058
2059         ushort cfg_lsw;         /* 00 power up initialization */
2060         /*  bit 13 set - Load CIS */
2061         /*  bit 14 set - BIOS Enable */
2062         /*  bit 15 set - Big Endian Mode */
2063         ushort cfg_msw;         /* 01 unused      */
2064         ushort disc_enable;     /* 02 disconnect enable */
2065         ushort wdtr_able;       /* 03 Wide DTR able */
2066         ushort sdtr_speed1;     /* 04 SDTR Speed TID 0-3 */
2067         ushort start_motor;     /* 05 send start up motor */
2068         ushort tagqng_able;     /* 06 tag queuing able */
2069         ushort bios_scan;       /* 07 BIOS device control */
2070         ushort scam_tolerant;   /* 08 no scam */
2071
2072         uchar adapter_scsi_id;  /* 09 Host Adapter ID */
2073         uchar bios_boot_delay;  /*    power up wait */
2074
2075         uchar scsi_reset_delay; /* 10 reset delay */
2076         uchar bios_id_lun;      /*    first boot device scsi id & lun */
2077         /*    high nibble is lun */
2078         /*    low nibble is scsi id */
2079
2080         uchar termination_se;   /* 11 0 - automatic */
2081         /*    1 - low off / high off */
2082         /*    2 - low off / high on */
2083         /*    3 - low on  / high on */
2084         /*    There is no low on  / high off */
2085
2086         uchar termination_lvd;  /* 11 0 - automatic */
2087         /*    1 - low off / high off */
2088         /*    2 - low off / high on */
2089         /*    3 - low on  / high on */
2090         /*    There is no low on  / high off */
2091
2092         ushort bios_ctrl;       /* 12 BIOS control bits */
2093         /*  bit 0  BIOS don't act as initiator. */
2094         /*  bit 1  BIOS > 1 GB support */
2095         /*  bit 2  BIOS > 2 Disk Support */
2096         /*  bit 3  BIOS don't support removables */
2097         /*  bit 4  BIOS support bootable CD */
2098         /*  bit 5  BIOS scan enabled */
2099         /*  bit 6  BIOS support multiple LUNs */
2100         /*  bit 7  BIOS display of message */
2101         /*  bit 8  SCAM disabled */
2102         /*  bit 9  Reset SCSI bus during init. */
2103         /*  bit 10 */
2104         /*  bit 11 No verbose initialization. */
2105         /*  bit 12 SCSI parity enabled */
2106         /*  bit 13 */
2107         /*  bit 14 */
2108         /*  bit 15 */
2109         ushort sdtr_speed2;     /* 13 SDTR speed TID 4-7 */
2110         ushort sdtr_speed3;     /* 14 SDTR speed TID 8-11 */
2111         uchar max_host_qng;     /* 15 maximum host queueing */
2112         uchar max_dvc_qng;      /*    maximum per device queuing */
2113         ushort dvc_cntl;        /* 16 control bit for driver */
2114         ushort sdtr_speed4;     /* 17 SDTR speed 4 TID 12-15 */
2115         ushort serial_number_word1;     /* 18 Board serial number word 1 */
2116         ushort serial_number_word2;     /* 19 Board serial number word 2 */
2117         ushort serial_number_word3;     /* 20 Board serial number word 3 */
2118         ushort check_sum;       /* 21 EEP check sum */
2119         uchar oem_name[16];     /* 22 OEM name */
2120         ushort dvc_err_code;    /* 30 last device driver error code */
2121         ushort adv_err_code;    /* 31 last uc and Adv Lib error code */
2122         ushort adv_err_addr;    /* 32 last uc error address */
2123         ushort saved_dvc_err_code;      /* 33 saved last dev. driver error code   */
2124         ushort saved_adv_err_code;      /* 34 saved last uc and Adv Lib error code */
2125         ushort saved_adv_err_addr;      /* 35 saved last uc error address         */
2126         ushort reserved36;      /* 36 reserved */
2127         ushort reserved37;      /* 37 reserved */
2128         ushort reserved38;      /* 38 reserved */
2129         ushort reserved39;      /* 39 reserved */
2130         ushort reserved40;      /* 40 reserved */
2131         ushort reserved41;      /* 41 reserved */
2132         ushort reserved42;      /* 42 reserved */
2133         ushort reserved43;      /* 43 reserved */
2134         ushort reserved44;      /* 44 reserved */
2135         ushort reserved45;      /* 45 reserved */
2136         ushort reserved46;      /* 46 reserved */
2137         ushort reserved47;      /* 47 reserved */
2138         ushort reserved48;      /* 48 reserved */
2139         ushort reserved49;      /* 49 reserved */
2140         ushort reserved50;      /* 50 reserved */
2141         ushort reserved51;      /* 51 reserved */
2142         ushort reserved52;      /* 52 reserved */
2143         ushort reserved53;      /* 53 reserved */
2144         ushort reserved54;      /* 54 reserved */
2145         ushort reserved55;      /* 55 reserved */
2146         ushort cisptr_lsw;      /* 56 CIS PTR LSW */
2147         ushort cisprt_msw;      /* 57 CIS PTR MSW */
2148         ushort subsysvid;       /* 58 SubSystem Vendor ID */
2149         ushort subsysid;        /* 59 SubSystem ID */
2150         ushort reserved60;      /* 60 reserved */
2151         ushort reserved61;      /* 61 reserved */
2152         ushort reserved62;      /* 62 reserved */
2153         ushort reserved63;      /* 63 reserved */
2154 } ADVEEP_38C0800_CONFIG;
2155
2156 typedef struct adveep_38C1600_config {
2157         /* Word Offset, Description */
2158
2159         ushort cfg_lsw;         /* 00 power up initialization */
2160         /*  bit 11 set - Func. 0 INTB, Func. 1 INTA */
2161         /*       clear - Func. 0 INTA, Func. 1 INTB */
2162         /*  bit 13 set - Load CIS */
2163         /*  bit 14 set - BIOS Enable */
2164         /*  bit 15 set - Big Endian Mode */
2165         ushort cfg_msw;         /* 01 unused */
2166         ushort disc_enable;     /* 02 disconnect enable */
2167         ushort wdtr_able;       /* 03 Wide DTR able */
2168         ushort sdtr_speed1;     /* 04 SDTR Speed TID 0-3 */
2169         ushort start_motor;     /* 05 send start up motor */
2170         ushort tagqng_able;     /* 06 tag queuing able */
2171         ushort bios_scan;       /* 07 BIOS device control */
2172         ushort scam_tolerant;   /* 08 no scam */
2173
2174         uchar adapter_scsi_id;  /* 09 Host Adapter ID */
2175         uchar bios_boot_delay;  /*    power up wait */
2176
2177         uchar scsi_reset_delay; /* 10 reset delay */
2178         uchar bios_id_lun;      /*    first boot device scsi id & lun */
2179         /*    high nibble is lun */
2180         /*    low nibble is scsi id */
2181
2182         uchar termination_se;   /* 11 0 - automatic */
2183         /*    1 - low off / high off */
2184         /*    2 - low off / high on */
2185         /*    3 - low on  / high on */
2186         /*    There is no low on  / high off */
2187
2188         uchar termination_lvd;  /* 11 0 - automatic */
2189         /*    1 - low off / high off */
2190         /*    2 - low off / high on */
2191         /*    3 - low on  / high on */
2192         /*    There is no low on  / high off */
2193
2194         ushort bios_ctrl;       /* 12 BIOS control bits */
2195         /*  bit 0  BIOS don't act as initiator. */
2196         /*  bit 1  BIOS > 1 GB support */
2197         /*  bit 2  BIOS > 2 Disk Support */
2198         /*  bit 3  BIOS don't support removables */
2199         /*  bit 4  BIOS support bootable CD */
2200         /*  bit 5  BIOS scan enabled */
2201         /*  bit 6  BIOS support multiple LUNs */
2202         /*  bit 7  BIOS display of message */
2203         /*  bit 8  SCAM disabled */
2204         /*  bit 9  Reset SCSI bus during init. */
2205         /*  bit 10 Basic Integrity Checking disabled */
2206         /*  bit 11 No verbose initialization. */
2207         /*  bit 12 SCSI parity enabled */
2208         /*  bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
2209         /*  bit 14 */
2210         /*  bit 15 */
2211         ushort sdtr_speed2;     /* 13 SDTR speed TID 4-7 */
2212         ushort sdtr_speed3;     /* 14 SDTR speed TID 8-11 */
2213         uchar max_host_qng;     /* 15 maximum host queueing */
2214         uchar max_dvc_qng;      /*    maximum per device queuing */
2215         ushort dvc_cntl;        /* 16 control bit for driver */
2216         ushort sdtr_speed4;     /* 17 SDTR speed 4 TID 12-15 */
2217         ushort serial_number_word1;     /* 18 Board serial number word 1 */
2218         ushort serial_number_word2;     /* 19 Board serial number word 2 */
2219         ushort serial_number_word3;     /* 20 Board serial number word 3 */
2220         ushort check_sum;       /* 21 EEP check sum */
2221         uchar oem_name[16];     /* 22 OEM name */
2222         ushort dvc_err_code;    /* 30 last device driver error code */
2223         ushort adv_err_code;    /* 31 last uc and Adv Lib error code */
2224         ushort adv_err_addr;    /* 32 last uc error address */
2225         ushort saved_dvc_err_code;      /* 33 saved last dev. driver error code   */
2226         ushort saved_adv_err_code;      /* 34 saved last uc and Adv Lib error code */
2227         ushort saved_adv_err_addr;      /* 35 saved last uc error address         */
2228         ushort reserved36;      /* 36 reserved */
2229         ushort reserved37;      /* 37 reserved */
2230         ushort reserved38;      /* 38 reserved */
2231         ushort reserved39;      /* 39 reserved */
2232         ushort reserved40;      /* 40 reserved */
2233         ushort reserved41;      /* 41 reserved */
2234         ushort reserved42;      /* 42 reserved */
2235         ushort reserved43;      /* 43 reserved */
2236         ushort reserved44;      /* 44 reserved */
2237         ushort reserved45;      /* 45 reserved */
2238         ushort reserved46;      /* 46 reserved */
2239         ushort reserved47;      /* 47 reserved */
2240         ushort reserved48;      /* 48 reserved */
2241         ushort reserved49;      /* 49 reserved */
2242         ushort reserved50;      /* 50 reserved */
2243         ushort reserved51;      /* 51 reserved */
2244         ushort reserved52;      /* 52 reserved */
2245         ushort reserved53;      /* 53 reserved */
2246         ushort reserved54;      /* 54 reserved */
2247         ushort reserved55;      /* 55 reserved */
2248         ushort cisptr_lsw;      /* 56 CIS PTR LSW */
2249         ushort cisprt_msw;      /* 57 CIS PTR MSW */
2250         ushort subsysvid;       /* 58 SubSystem Vendor ID */
2251         ushort subsysid;        /* 59 SubSystem ID */
2252         ushort reserved60;      /* 60 reserved */
2253         ushort reserved61;      /* 61 reserved */
2254         ushort reserved62;      /* 62 reserved */
2255         ushort reserved63;      /* 63 reserved */
2256 } ADVEEP_38C1600_CONFIG;
2257
2258 /*
2259  * EEPROM Commands
2260  */
2261 #define ASC_EEP_CMD_DONE             0x0200
2262 #define ASC_EEP_CMD_DONE_ERR         0x0001
2263
2264 /* cfg_word */
2265 #define EEP_CFG_WORD_BIG_ENDIAN      0x8000
2266
2267 /* bios_ctrl */
2268 #define BIOS_CTRL_BIOS               0x0001
2269 #define BIOS_CTRL_EXTENDED_XLAT      0x0002
2270 #define BIOS_CTRL_GT_2_DISK          0x0004
2271 #define BIOS_CTRL_BIOS_REMOVABLE     0x0008
2272 #define BIOS_CTRL_BOOTABLE_CD        0x0010
2273 #define BIOS_CTRL_MULTIPLE_LUN       0x0040
2274 #define BIOS_CTRL_DISPLAY_MSG        0x0080
2275 #define BIOS_CTRL_NO_SCAM            0x0100
2276 #define BIOS_CTRL_RESET_SCSI_BUS     0x0200
2277 #define BIOS_CTRL_INIT_VERBOSE       0x0800
2278 #define BIOS_CTRL_SCSI_PARITY        0x1000
2279 #define BIOS_CTRL_AIPP_DIS           0x2000
2280
2281 #define ADV_3550_MEMSIZE   0x2000       /* 8 KB Internal Memory */
2282
2283 #define ADV_38C0800_MEMSIZE  0x4000     /* 16 KB Internal Memory */
2284
2285 /*
2286  * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
2287  * a special 16K Adv Library and Microcode version. After the issue is
2288  * resolved, should restore 32K support.
2289  *
2290  * #define ADV_38C1600_MEMSIZE  0x8000L   * 32 KB Internal Memory *
2291  */
2292 #define ADV_38C1600_MEMSIZE  0x4000     /* 16 KB Internal Memory */
2293
2294 /*
2295  * Byte I/O register address from base of 'iop_base'.
2296  */
2297 #define IOPB_INTR_STATUS_REG    0x00
2298 #define IOPB_CHIP_ID_1          0x01
2299 #define IOPB_INTR_ENABLES       0x02
2300 #define IOPB_CHIP_TYPE_REV      0x03
2301 #define IOPB_RES_ADDR_4         0x04
2302 #define IOPB_RES_ADDR_5         0x05
2303 #define IOPB_RAM_DATA           0x06
2304 #define IOPB_RES_ADDR_7         0x07
2305 #define IOPB_FLAG_REG           0x08
2306 #define IOPB_RES_ADDR_9         0x09
2307 #define IOPB_RISC_CSR           0x0A
2308 #define IOPB_RES_ADDR_B         0x0B
2309 #define IOPB_RES_ADDR_C         0x0C
2310 #define IOPB_RES_ADDR_D         0x0D
2311 #define IOPB_SOFT_OVER_WR       0x0E
2312 #define IOPB_RES_ADDR_F         0x0F
2313 #define IOPB_MEM_CFG            0x10
2314 #define IOPB_RES_ADDR_11        0x11
2315 #define IOPB_GPIO_DATA          0x12
2316 #define IOPB_RES_ADDR_13        0x13
2317 #define IOPB_FLASH_PAGE         0x14
2318 #define IOPB_RES_ADDR_15        0x15
2319 #define IOPB_GPIO_CNTL          0x16
2320 #define IOPB_RES_ADDR_17        0x17
2321 #define IOPB_FLASH_DATA         0x18
2322 #define IOPB_RES_ADDR_19        0x19
2323 #define IOPB_RES_ADDR_1A        0x1A
2324 #define IOPB_RES_ADDR_1B        0x1B
2325 #define IOPB_RES_ADDR_1C        0x1C
2326 #define IOPB_RES_ADDR_1D        0x1D
2327 #define IOPB_RES_ADDR_1E        0x1E
2328 #define IOPB_RES_ADDR_1F        0x1F
2329 #define IOPB_DMA_CFG0           0x20
2330 #define IOPB_DMA_CFG1           0x21
2331 #define IOPB_TICKLE             0x22
2332 #define IOPB_DMA_REG_WR         0x23
2333 #define IOPB_SDMA_STATUS        0x24
2334 #define IOPB_SCSI_BYTE_CNT      0x25
2335 #define IOPB_HOST_BYTE_CNT      0x26
2336 #define IOPB_BYTE_LEFT_TO_XFER  0x27
2337 #define IOPB_BYTE_TO_XFER_0     0x28
2338 #define IOPB_BYTE_TO_XFER_1     0x29
2339 #define IOPB_BYTE_TO_XFER_2     0x2A
2340 #define IOPB_BYTE_TO_XFER_3     0x2B
2341 #define IOPB_ACC_GRP            0x2C
2342 #define IOPB_RES_ADDR_2D        0x2D
2343 #define IOPB_DEV_ID             0x2E
2344 #define IOPB_RES_ADDR_2F        0x2F
2345 #define IOPB_SCSI_DATA          0x30
2346 #define IOPB_RES_ADDR_31        0x31
2347 #define IOPB_RES_ADDR_32        0x32
2348 #define IOPB_SCSI_DATA_HSHK     0x33
2349 #define IOPB_SCSI_CTRL          0x34
2350 #define IOPB_RES_ADDR_35        0x35
2351 #define IOPB_RES_ADDR_36        0x36
2352 #define IOPB_RES_ADDR_37        0x37
2353 #define IOPB_RAM_BIST           0x38
2354 #define IOPB_PLL_TEST           0x39
2355 #define IOPB_PCI_INT_CFG        0x3A
2356 #define IOPB_RES_ADDR_3B        0x3B
2357 #define IOPB_RFIFO_CNT          0x3C
2358 #define IOPB_RES_ADDR_3D        0x3D
2359 #define IOPB_RES_ADDR_3E        0x3E
2360 #define IOPB_RES_ADDR_3F        0x3F
2361
2362 /*
2363  * Word I/O register address from base of 'iop_base'.
2364  */
2365 #define IOPW_CHIP_ID_0          0x00    /* CID0  */
2366 #define IOPW_CTRL_REG           0x02    /* CC    */
2367 #define IOPW_RAM_ADDR           0x04    /* LA    */
2368 #define IOPW_RAM_DATA           0x06    /* LD    */
2369 #define IOPW_RES_ADDR_08        0x08
2370 #define IOPW_RISC_CSR           0x0A    /* CSR   */
2371 #define IOPW_SCSI_CFG0          0x0C    /* CFG0  */
2372 #define IOPW_SCSI_CFG1          0x0E    /* CFG1  */
2373 #define IOPW_RES_ADDR_10        0x10
2374 #define IOPW_SEL_MASK           0x12    /* SM    */
2375 #define IOPW_RES_ADDR_14        0x14
2376 #define IOPW_FLASH_ADDR         0x16    /* FA    */
2377 #define IOPW_RES_ADDR_18        0x18
2378 #define IOPW_EE_CMD             0x1A    /* EC    */
2379 #define IOPW_EE_DATA            0x1C    /* ED    */
2380 #define IOPW_SFIFO_CNT          0x1E    /* SFC   */
2381 #define IOPW_RES_ADDR_20        0x20
2382 #define IOPW_Q_BASE             0x22    /* QB    */
2383 #define IOPW_QP                 0x24    /* QP    */
2384 #define IOPW_IX                 0x26    /* IX    */
2385 #define IOPW_SP                 0x28    /* SP    */
2386 #define IOPW_PC                 0x2A    /* PC    */
2387 #define IOPW_RES_ADDR_2C        0x2C
2388 #define IOPW_RES_ADDR_2E        0x2E
2389 #define IOPW_SCSI_DATA          0x30    /* SD    */
2390 #define IOPW_SCSI_DATA_HSHK     0x32    /* SDH   */
2391 #define IOPW_SCSI_CTRL          0x34    /* SC    */
2392 #define IOPW_HSHK_CFG           0x36    /* HCFG  */
2393 #define IOPW_SXFR_STATUS        0x36    /* SXS   */
2394 #define IOPW_SXFR_CNTL          0x38    /* SXL   */
2395 #define IOPW_SXFR_CNTH          0x3A    /* SXH   */
2396 #define IOPW_RES_ADDR_3C        0x3C
2397 #define IOPW_RFIFO_DATA         0x3E    /* RFD   */
2398
2399 /*
2400  * Doubleword I/O register address from base of 'iop_base'.
2401  */
2402 #define IOPDW_RES_ADDR_0         0x00
2403 #define IOPDW_RAM_DATA           0x04
2404 #define IOPDW_RES_ADDR_8         0x08
2405 #define IOPDW_RES_ADDR_C         0x0C
2406 #define IOPDW_RES_ADDR_10        0x10
2407 #define IOPDW_COMMA              0x14
2408 #define IOPDW_COMMB              0x18
2409 #define IOPDW_RES_ADDR_1C        0x1C
2410 #define IOPDW_SDMA_ADDR0         0x20
2411 #define IOPDW_SDMA_ADDR1         0x24
2412 #define IOPDW_SDMA_COUNT         0x28
2413 #define IOPDW_SDMA_ERROR         0x2C
2414 #define IOPDW_RDMA_ADDR0         0x30
2415 #define IOPDW_RDMA_ADDR1         0x34
2416 #define IOPDW_RDMA_COUNT         0x38
2417 #define IOPDW_RDMA_ERROR         0x3C
2418
2419 #define ADV_CHIP_ID_BYTE         0x25
2420 #define ADV_CHIP_ID_WORD         0x04C1
2421
2422 #define ADV_SC_SCSI_BUS_RESET    0x2000
2423
2424 #define ADV_INTR_ENABLE_HOST_INTR                   0x01
2425 #define ADV_INTR_ENABLE_SEL_INTR                    0x02
2426 #define ADV_INTR_ENABLE_DPR_INTR                    0x04
2427 #define ADV_INTR_ENABLE_RTA_INTR                    0x08
2428 #define ADV_INTR_ENABLE_RMA_INTR                    0x10
2429 #define ADV_INTR_ENABLE_RST_INTR                    0x20
2430 #define ADV_INTR_ENABLE_DPE_INTR                    0x40
2431 #define ADV_INTR_ENABLE_GLOBAL_INTR                 0x80
2432
2433 #define ADV_INTR_STATUS_INTRA            0x01
2434 #define ADV_INTR_STATUS_INTRB            0x02
2435 #define ADV_INTR_STATUS_INTRC            0x04
2436
2437 #define ADV_RISC_CSR_STOP           (0x0000)
2438 #define ADV_RISC_TEST_COND          (0x2000)
2439 #define ADV_RISC_CSR_RUN            (0x4000)
2440 #define ADV_RISC_CSR_SINGLE_STEP    (0x8000)
2441
2442 #define ADV_CTRL_REG_HOST_INTR      0x0100
2443 #define ADV_CTRL_REG_SEL_INTR       0x0200
2444 #define ADV_CTRL_REG_DPR_INTR       0x0400
2445 #define ADV_CTRL_REG_RTA_INTR       0x0800
2446 #define ADV_CTRL_REG_RMA_INTR       0x1000
2447 #define ADV_CTRL_REG_RES_BIT14      0x2000
2448 #define ADV_CTRL_REG_DPE_INTR       0x4000
2449 #define ADV_CTRL_REG_POWER_DONE     0x8000
2450 #define ADV_CTRL_REG_ANY_INTR       0xFF00
2451
2452 #define ADV_CTRL_REG_CMD_RESET             0x00C6
2453 #define ADV_CTRL_REG_CMD_WR_IO_REG         0x00C5
2454 #define ADV_CTRL_REG_CMD_RD_IO_REG         0x00C4
2455 #define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE  0x00C3
2456 #define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE  0x00C2
2457
2458 #define ADV_TICKLE_NOP                      0x00
2459 #define ADV_TICKLE_A                        0x01
2460 #define ADV_TICKLE_B                        0x02
2461 #define ADV_TICKLE_C                        0x03
2462
2463 #define ADV_SCSI_CTRL_RSTOUT        0x2000
2464
2465 #define AdvIsIntPending(port) \
2466     (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
2467
2468 /*
2469  * SCSI_CFG0 Register bit definitions
2470  */
2471 #define TIMER_MODEAB    0xC000  /* Watchdog, Second, and Select. Timer Ctrl. */
2472 #define PARITY_EN       0x2000  /* Enable SCSI Parity Error detection */
2473 #define EVEN_PARITY     0x1000  /* Select Even Parity */
2474 #define WD_LONG         0x0800  /* Watchdog Interval, 1: 57 min, 0: 13 sec */
2475 #define QUEUE_128       0x0400  /* Queue Size, 1: 128 byte, 0: 64 byte */
2476 #define PRIM_MODE       0x0100  /* Primitive SCSI mode */
2477 #define SCAM_EN         0x0080  /* Enable SCAM selection */
2478 #define SEL_TMO_LONG    0x0040  /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
2479 #define CFRM_ID         0x0020  /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
2480 #define OUR_ID_EN       0x0010  /* Enable OUR_ID bits */
2481 #define OUR_ID          0x000F  /* SCSI ID */
2482
2483 /*
2484  * SCSI_CFG1 Register bit definitions
2485  */
2486 #define BIG_ENDIAN      0x8000  /* Enable Big Endian Mode MIO:15, EEP:15 */
2487 #define TERM_POL        0x2000  /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
2488 #define SLEW_RATE       0x1000  /* SCSI output buffer slew rate */
2489 #define FILTER_SEL      0x0C00  /* Filter Period Selection */
2490 #define  FLTR_DISABLE    0x0000 /* Input Filtering Disabled */
2491 #define  FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
2492 #define  FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
2493 #define ACTIVE_DBL      0x0200  /* Disable Active Negation */
2494 #define DIFF_MODE       0x0100  /* SCSI differential Mode (Read-Only) */
2495 #define DIFF_SENSE      0x0080  /* 1: No SE cables, 0: SE cable (Read-Only) */
2496 #define TERM_CTL_SEL    0x0040  /* Enable TERM_CTL_H and TERM_CTL_L */
2497 #define TERM_CTL        0x0030  /* External SCSI Termination Bits */
2498 #define  TERM_CTL_H      0x0020 /* Enable External SCSI Upper Termination */
2499 #define  TERM_CTL_L      0x0010 /* Enable External SCSI Lower Termination */
2500 #define CABLE_DETECT    0x000F  /* External SCSI Cable Connection Status */
2501
2502 /*
2503  * Addendum for ASC-38C0800 Chip
2504  *
2505  * The ASC-38C1600 Chip uses the same definitions except that the
2506  * bus mode override bits [12:10] have been moved to byte register
2507  * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
2508  * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
2509  * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
2510  * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
2511  * and [1:0]. Bits [14], [7:6], [3:2] are unused.
2512  */
2513 #define DIS_TERM_DRV    0x4000  /* 1: Read c_det[3:0], 0: cannot read */
2514 #define HVD_LVD_SE      0x1C00  /* Device Detect Bits */
2515 #define  HVD             0x1000 /* HVD Device Detect */
2516 #define  LVD             0x0800 /* LVD Device Detect */
2517 #define  SE              0x0400 /* SE Device Detect */
2518 #define TERM_LVD        0x00C0  /* LVD Termination Bits */
2519 #define  TERM_LVD_HI     0x0080 /* Enable LVD Upper Termination */
2520 #define  TERM_LVD_LO     0x0040 /* Enable LVD Lower Termination */
2521 #define TERM_SE         0x0030  /* SE Termination Bits */
2522 #define  TERM_SE_HI      0x0020 /* Enable SE Upper Termination */
2523 #define  TERM_SE_LO      0x0010 /* Enable SE Lower Termination */
2524 #define C_DET_LVD       0x000C  /* LVD Cable Detect Bits */
2525 #define  C_DET3          0x0008 /* Cable Detect for LVD External Wide */
2526 #define  C_DET2          0x0004 /* Cable Detect for LVD Internal Wide */
2527 #define C_DET_SE        0x0003  /* SE Cable Detect Bits */
2528 #define  C_DET1          0x0002 /* Cable Detect for SE Internal Wide */
2529 #define  C_DET0          0x0001 /* Cable Detect for SE Internal Narrow */
2530
2531 #define CABLE_ILLEGAL_A 0x7
2532     /* x 0 0 0  | on  on | Illegal (all 3 connectors are used) */
2533
2534 #define CABLE_ILLEGAL_B 0xB
2535     /* 0 x 0 0  | on  on | Illegal (all 3 connectors are used) */
2536
2537 /*
2538  * MEM_CFG Register bit definitions
2539  */
2540 #define BIOS_EN         0x40    /* BIOS Enable MIO:14,EEP:14 */
2541 #define FAST_EE_CLK     0x20    /* Diagnostic Bit */
2542 #define RAM_SZ          0x1C    /* Specify size of RAM to RISC */
2543 #define  RAM_SZ_2KB      0x00   /* 2 KB */
2544 #define  RAM_SZ_4KB      0x04   /* 4 KB */
2545 #define  RAM_SZ_8KB      0x08   /* 8 KB */
2546 #define  RAM_SZ_16KB     0x0C   /* 16 KB */
2547 #define  RAM_SZ_32KB     0x10   /* 32 KB */
2548 #define  RAM_SZ_64KB     0x14   /* 64 KB */
2549
2550 /*
2551  * DMA_CFG0 Register bit definitions
2552  *
2553  * This register is only accessible to the host.
2554  */
2555 #define BC_THRESH_ENB   0x80    /* PCI DMA Start Conditions */
2556 #define FIFO_THRESH     0x70    /* PCI DMA FIFO Threshold */
2557 #define  FIFO_THRESH_16B  0x00  /* 16 bytes */
2558 #define  FIFO_THRESH_32B  0x20  /* 32 bytes */
2559 #define  FIFO_THRESH_48B  0x30  /* 48 bytes */
2560 #define  FIFO_THRESH_64B  0x40  /* 64 bytes */
2561 #define  FIFO_THRESH_80B  0x50  /* 80 bytes (default) */
2562 #define  FIFO_THRESH_96B  0x60  /* 96 bytes */
2563 #define  FIFO_THRESH_112B 0x70  /* 112 bytes */
2564 #define START_CTL       0x0C    /* DMA start conditions */
2565 #define  START_CTL_TH    0x00   /* Wait threshold level (default) */
2566 #define  START_CTL_ID    0x04   /* Wait SDMA/SBUS idle */
2567 #define  START_CTL_THID  0x08   /* Wait threshold and SDMA/SBUS idle */
2568 #define  START_CTL_EMFU  0x0C   /* Wait SDMA FIFO empty/full */
2569 #define READ_CMD        0x03    /* Memory Read Method */
2570 #define  READ_CMD_MR     0x00   /* Memory Read */
2571 #define  READ_CMD_MRL    0x02   /* Memory Read Long */
2572 #define  READ_CMD_MRM    0x03   /* Memory Read Multiple (default) */
2573
2574 /*
2575  * ASC-38C0800 RAM BIST Register bit definitions
2576  */
2577 #define RAM_TEST_MODE         0x80
2578 #define PRE_TEST_MODE         0x40
2579 #define NORMAL_MODE           0x00
2580 #define RAM_TEST_DONE         0x10
2581 #define RAM_TEST_STATUS       0x0F
2582 #define  RAM_TEST_HOST_ERROR   0x08
2583 #define  RAM_TEST_INTRAM_ERROR 0x04
2584 #define  RAM_TEST_RISC_ERROR   0x02
2585 #define  RAM_TEST_SCSI_ERROR   0x01
2586 #define  RAM_TEST_SUCCESS      0x00
2587 #define PRE_TEST_VALUE        0x05
2588 #define NORMAL_VALUE          0x00
2589
2590 /*
2591  * ASC38C1600 Definitions
2592  *
2593  * IOPB_PCI_INT_CFG Bit Field Definitions
2594  */
2595
2596 #define INTAB_LD        0x80    /* Value loaded from EEPROM Bit 11. */
2597
2598 /*
2599  * Bit 1 can be set to change the interrupt for the Function to operate in
2600  * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
2601  * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
2602  * mode, otherwise the operating mode is undefined.
2603  */
2604 #define TOTEMPOLE       0x02
2605
2606 /*
2607  * Bit 0 can be used to change the Int Pin for the Function. The value is
2608  * 0 by default for both Functions with Function 0 using INT A and Function
2609  * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
2610  * INT A is used.
2611  *
2612  * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
2613  * value specified in the PCI Configuration Space.
2614  */
2615 #define INTAB           0x01
2616
2617 /* a_advlib.h */
2618
2619 /*
2620  * Adv Library Status Definitions
2621  */
2622 #define ADV_TRUE        1
2623 #define ADV_FALSE       0
2624 #define ADV_NOERROR     1
2625 #define ADV_SUCCESS     1
2626 #define ADV_BUSY        0
2627 #define ADV_ERROR       (-1)
2628
2629 /*
2630  * ADV_DVC_VAR 'warn_code' values
2631  */
2632 #define ASC_WARN_BUSRESET_ERROR         0x0001  /* SCSI Bus Reset error */
2633 #define ASC_WARN_EEPROM_CHKSUM          0x0002  /* EEP check sum error */
2634 #define ASC_WARN_EEPROM_TERMINATION     0x0004  /* EEP termination bad field */
2635 #define ASC_WARN_SET_PCI_CONFIG_SPACE   0x0080  /* PCI config space set error */
2636 #define ASC_WARN_ERROR                  0xFFFF  /* ADV_ERROR return */
2637
2638 #define ADV_MAX_TID                     15      /* max. target identifier */
2639 #define ADV_MAX_LUN                     7       /* max. logical unit number */
2640
2641 /*
2642  * Error code values are set in ADV_DVC_VAR 'err_code'.
2643  */
2644 #define ASC_IERR_WRITE_EEPROM       0x0001      /* write EEPROM error */
2645 #define ASC_IERR_MCODE_CHKSUM       0x0002      /* micro code check sum error */
2646 #define ASC_IERR_NO_CARRIER         0x0004      /* No more carrier memory. */
2647 #define ASC_IERR_START_STOP_CHIP    0x0008      /* start/stop chip failed */
2648 #define ASC_IERR_CHIP_VERSION       0x0040      /* wrong chip version */
2649 #define ASC_IERR_SET_SCSI_ID        0x0080      /* set SCSI ID failed */
2650 #define ASC_IERR_HVD_DEVICE         0x0100      /* HVD attached to LVD connector. */
2651 #define ASC_IERR_BAD_SIGNATURE      0x0200      /* signature not found */
2652 #define ASC_IERR_ILLEGAL_CONNECTION 0x0400      /* Illegal cable connection */
2653 #define ASC_IERR_SINGLE_END_DEVICE  0x0800      /* Single-end used w/differential */
2654 #define ASC_IERR_REVERSED_CABLE     0x1000      /* Narrow flat cable reversed */
2655 #define ASC_IERR_BIST_PRE_TEST      0x2000      /* BIST pre-test error */
2656 #define ASC_IERR_BIST_RAM_TEST      0x4000      /* BIST RAM test error */
2657 #define ASC_IERR_BAD_CHIPTYPE       0x8000      /* Invalid 'chip_type' setting. */
2658
2659 /*
2660  * Fixed locations of microcode operating variables.
2661  */
2662 #define ASC_MC_CODE_BEGIN_ADDR          0x0028  /* microcode start address */
2663 #define ASC_MC_CODE_END_ADDR            0x002A  /* microcode end address */
2664 #define ASC_MC_CODE_CHK_SUM             0x002C  /* microcode code checksum */
2665 #define ASC_MC_VERSION_DATE             0x0038  /* microcode version */
2666 #define ASC_MC_VERSION_NUM              0x003A  /* microcode number */
2667 #define ASC_MC_BIOSMEM                  0x0040  /* BIOS RISC Memory Start */
2668 #define ASC_MC_BIOSLEN                  0x0050  /* BIOS RISC Memory Length */
2669 #define ASC_MC_BIOS_SIGNATURE           0x0058  /* BIOS Signature 0x55AA */
2670 #define ASC_MC_BIOS_VERSION             0x005A  /* BIOS Version (2 bytes) */
2671 #define ASC_MC_SDTR_SPEED1              0x0090  /* SDTR Speed for TID 0-3 */
2672 #define ASC_MC_SDTR_SPEED2              0x0092  /* SDTR Speed for TID 4-7 */
2673 #define ASC_MC_SDTR_SPEED3              0x0094  /* SDTR Speed for TID 8-11 */
2674 #define ASC_MC_SDTR_SPEED4              0x0096  /* SDTR Speed for TID 12-15 */
2675 #define ASC_MC_CHIP_TYPE                0x009A
2676 #define ASC_MC_INTRB_CODE               0x009B
2677 #define ASC_MC_WDTR_ABLE                0x009C
2678 #define ASC_MC_SDTR_ABLE                0x009E
2679 #define ASC_MC_TAGQNG_ABLE              0x00A0
2680 #define ASC_MC_DISC_ENABLE              0x00A2
2681 #define ASC_MC_IDLE_CMD_STATUS          0x00A4
2682 #define ASC_MC_IDLE_CMD                 0x00A6
2683 #define ASC_MC_IDLE_CMD_PARAMETER       0x00A8
2684 #define ASC_MC_DEFAULT_SCSI_CFG0        0x00AC
2685 #define ASC_MC_DEFAULT_SCSI_CFG1        0x00AE
2686 #define ASC_MC_DEFAULT_MEM_CFG          0x00B0
2687 #define ASC_MC_DEFAULT_SEL_MASK         0x00B2
2688 #define ASC_MC_SDTR_DONE                0x00B6
2689 #define ASC_MC_NUMBER_OF_QUEUED_CMD     0x00C0
2690 #define ASC_MC_NUMBER_OF_MAX_CMD        0x00D0
2691 #define ASC_MC_DEVICE_HSHK_CFG_TABLE    0x0100
2692 #define ASC_MC_CONTROL_FLAG             0x0122  /* Microcode control flag. */
2693 #define ASC_MC_WDTR_DONE                0x0124
2694 #define ASC_MC_CAM_MODE_MASK            0x015E  /* CAM mode TID bitmask. */
2695 #define ASC_MC_ICQ                      0x0160
2696 #define ASC_MC_IRQ                      0x0164
2697 #define ASC_MC_PPR_ABLE                 0x017A
2698
2699 /*
2700  * BIOS LRAM variable absolute offsets.
2701  */
2702 #define BIOS_CODESEG    0x54
2703 #define BIOS_CODELEN    0x56
2704 #define BIOS_SIGNATURE  0x58
2705 #define BIOS_VERSION    0x5A
2706
2707 /*
2708  * Microcode Control Flags
2709  *
2710  * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
2711  * and handled by the microcode.
2712  */
2713 #define CONTROL_FLAG_IGNORE_PERR        0x0001  /* Ignore DMA Parity Errors */
2714 #define CONTROL_FLAG_ENABLE_AIPP        0x0002  /* Enabled AIPP checking. */
2715
2716 /*
2717  * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
2718  */
2719 #define HSHK_CFG_WIDE_XFR       0x8000
2720 #define HSHK_CFG_RATE           0x0F00
2721 #define HSHK_CFG_OFFSET         0x001F
2722
2723 #define ASC_DEF_MAX_HOST_QNG    0xFD    /* Max. number of host commands (253) */
2724 #define ASC_DEF_MIN_HOST_QNG    0x10    /* Min. number of host commands (16) */
2725 #define ASC_DEF_MAX_DVC_QNG     0x3F    /* Max. number commands per device (63) */
2726 #define ASC_DEF_MIN_DVC_QNG     0x04    /* Min. number commands per device (4) */
2727
2728 #define ASC_QC_DATA_CHECK  0x01 /* Require ASC_QC_DATA_OUT set or clear. */
2729 #define ASC_QC_DATA_OUT    0x02 /* Data out DMA transfer. */
2730 #define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
2731 #define ASC_QC_NO_OVERRUN  0x08 /* Don't report overrun. */
2732 #define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
2733
2734 #define ASC_QSC_NO_DISC     0x01        /* Don't allow disconnect for request. */
2735 #define ASC_QSC_NO_TAGMSG   0x02        /* Don't allow tag queuing for request. */
2736 #define ASC_QSC_NO_SYNC     0x04        /* Don't use Synch. transfer on request. */
2737 #define ASC_QSC_NO_WIDE     0x08        /* Don't use Wide transfer on request. */
2738 #define ASC_QSC_REDO_DTR    0x10        /* Renegotiate WDTR/SDTR before request. */
2739 /*
2740  * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
2741  * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
2742  */
2743 #define ASC_QSC_HEAD_TAG    0x40        /* Use Head Tag Message (0x21). */
2744 #define ASC_QSC_ORDERED_TAG 0x80        /* Use Ordered Tag Message (0x22). */
2745
2746 /*
2747  * All fields here are accessed by the board microcode and need to be
2748  * little-endian.
2749  */
2750 typedef struct adv_carr_t {
2751         ADV_VADDR carr_va;      /* Carrier Virtual Address */
2752         ADV_PADDR carr_pa;      /* Carrier Physical Address */
2753         ADV_VADDR areq_vpa;     /* ASC_SCSI_REQ_Q Virtual or Physical Address */
2754         /*
2755          * next_vpa [31:4]            Carrier Virtual or Physical Next Pointer
2756          *
2757          * next_vpa [3:1]             Reserved Bits
2758          * next_vpa [0]               Done Flag set in Response Queue.
2759          */
2760         ADV_VADDR next_vpa;
2761 } ADV_CARR_T;
2762
2763 /*
2764  * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
2765  */
2766 #define ASC_NEXT_VPA_MASK       0xFFFFFFF0
2767
2768 #define ASC_RQ_DONE             0x00000001
2769 #define ASC_RQ_GOOD             0x00000002
2770 #define ASC_CQ_STOPPER          0x00000000
2771
2772 #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
2773
2774 #define ADV_CARRIER_NUM_PAGE_CROSSING \
2775     (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
2776         (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2777
2778 #define ADV_CARRIER_BUFSIZE \
2779     ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
2780
2781 /*
2782  * ASC_SCSI_REQ_Q 'a_flag' definitions
2783  *
2784  * The Adv Library should limit use to the lower nibble (4 bits) of
2785  * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
2786  */
2787 #define ADV_POLL_REQUEST                0x01    /* poll for request completion */
2788 #define ADV_SCSIQ_DONE                  0x02    /* request done */
2789 #define ADV_DONT_RETRY                  0x08    /* don't do retry */
2790
2791 #define ADV_CHIP_ASC3550          0x01  /* Ultra-Wide IC */
2792 #define ADV_CHIP_ASC38C0800       0x02  /* Ultra2-Wide/LVD IC */
2793 #define ADV_CHIP_ASC38C1600       0x03  /* Ultra3-Wide/LVD2 IC */
2794
2795 /*
2796  * Adapter temporary configuration structure
2797  *
2798  * This structure can be discarded after initialization. Don't add
2799  * fields here needed after initialization.
2800  *
2801  * Field naming convention:
2802  *
2803  *  *_enable indicates the field enables or disables a feature. The
2804  *  value of the field is never reset.
2805  */
2806 typedef struct adv_dvc_cfg {
2807         ushort disc_enable;     /* enable disconnection */
2808         uchar chip_version;     /* chip version */
2809         uchar termination;      /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
2810         ushort lib_version;     /* Adv Library version number */
2811         ushort control_flag;    /* Microcode Control Flag */
2812         ushort mcode_date;      /* Microcode date */
2813         ushort mcode_version;   /* Microcode version */
2814         ushort serial1;         /* EEPROM serial number word 1 */
2815         ushort serial2;         /* EEPROM serial number word 2 */
2816         ushort serial3;         /* EEPROM serial number word 3 */
2817 } ADV_DVC_CFG;
2818
2819 struct adv_dvc_var;
2820 struct adv_scsi_req_q;
2821
2822 /*
2823  * Adapter operation variable structure.
2824  *
2825  * One structure is required per host adapter.
2826  *
2827  * Field naming convention:
2828  *
2829  *  *_able indicates both whether a feature should be enabled or disabled
2830  *  and whether a device isi capable of the feature. At initialization
2831  *  this field may be set, but later if a device is found to be incapable
2832  *  of the feature, the field is cleared.
2833  */
2834 typedef struct adv_dvc_var {
2835         AdvPortAddr iop_base;   /* I/O port address */
2836         ushort err_code;        /* fatal error code */
2837         ushort bios_ctrl;       /* BIOS control word, EEPROM word 12 */
2838         ushort wdtr_able;       /* try WDTR for a device */
2839         ushort sdtr_able;       /* try SDTR for a device */
2840         ushort ultra_able;      /* try SDTR Ultra speed for a device */
2841         ushort sdtr_speed1;     /* EEPROM SDTR Speed for TID 0-3   */
2842         ushort sdtr_speed2;     /* EEPROM SDTR Speed for TID 4-7   */
2843         ushort sdtr_speed3;     /* EEPROM SDTR Speed for TID 8-11  */
2844         ushort sdtr_speed4;     /* EEPROM SDTR Speed for TID 12-15 */
2845         ushort tagqng_able;     /* try tagged queuing with a device */
2846         ushort ppr_able;        /* PPR message capable per TID bitmask. */
2847         uchar max_dvc_qng;      /* maximum number of tagged commands per device */
2848         ushort start_motor;     /* start motor command allowed */
2849         uchar scsi_reset_wait;  /* delay in seconds after scsi bus reset */
2850         uchar chip_no;          /* should be assigned by caller */
2851         uchar max_host_qng;     /* maximum number of Q'ed command allowed */
2852         uchar irq_no;           /* IRQ number */
2853         ushort no_scam;         /* scam_tolerant of EEPROM */
2854         struct asc_board *drv_ptr;      /* driver pointer to private structure */
2855         uchar chip_scsi_id;     /* chip SCSI target ID */
2856         uchar chip_type;
2857         uchar bist_err_code;
2858         ADV_CARR_T *carrier_buf;
2859         ADV_CARR_T *carr_freelist;      /* Carrier free list. */
2860         ADV_CARR_T *icq_sp;     /* Initiator command queue stopper pointer. */
2861         ADV_CARR_T *irq_sp;     /* Initiator response queue stopper pointer. */
2862         ushort carr_pending_cnt;        /* Count of pending carriers. */
2863         /*
2864          * Note: The following fields will not be used after initialization. The
2865          * driver may discard the buffer after initialization is done.
2866          */
2867         ADV_DVC_CFG *cfg;       /* temporary configuration structure  */
2868 } ADV_DVC_VAR;
2869
2870 #define NO_OF_SG_PER_BLOCK              15
2871
2872 typedef struct asc_sg_block {
2873         uchar reserved1;
2874         uchar reserved2;
2875         uchar reserved3;
2876         uchar sg_cnt;           /* Valid entries in block. */
2877         ADV_PADDR sg_ptr;       /* Pointer to next sg block. */
2878         struct {
2879                 ADV_PADDR sg_addr;      /* SG element address. */
2880                 ADV_DCNT sg_count;      /* SG element count. */
2881         } sg_list[NO_OF_SG_PER_BLOCK];
2882 } ADV_SG_BLOCK;
2883
2884 /*
2885  * ADV_SCSI_REQ_Q - microcode request structure
2886  *
2887  * All fields in this structure up to byte 60 are used by the microcode.
2888  * The microcode makes assumptions about the size and ordering of fields
2889  * in this structure. Do not change the structure definition here without
2890  * coordinating the change with the microcode.
2891  *
2892  * All fields accessed by microcode must be maintained in little_endian
2893  * order.
2894  */
2895 typedef struct adv_scsi_req_q {
2896         uchar cntl;             /* Ucode flags and state (ASC_MC_QC_*). */
2897         uchar target_cmd;
2898         uchar target_id;        /* Device target identifier. */
2899         uchar target_lun;       /* Device target logical unit number. */
2900         ADV_PADDR data_addr;    /* Data buffer physical address. */
2901         ADV_DCNT data_cnt;      /* Data count. Ucode sets to residual. */
2902         ADV_PADDR sense_addr;
2903         ADV_PADDR carr_pa;
2904         uchar mflag;
2905         uchar sense_len;
2906         uchar cdb_len;          /* SCSI CDB length. Must <= 16 bytes. */
2907         uchar scsi_cntl;
2908         uchar done_status;      /* Completion status. */
2909         uchar scsi_status;      /* SCSI status byte. */
2910         uchar host_status;      /* Ucode host status. */
2911         uchar sg_working_ix;
2912         uchar cdb[12];          /* SCSI CDB bytes 0-11. */
2913         ADV_PADDR sg_real_addr; /* SG list physical address. */
2914         ADV_PADDR scsiq_rptr;
2915         uchar cdb16[4];         /* SCSI CDB bytes 12-15. */
2916         ADV_VADDR scsiq_ptr;
2917         ADV_VADDR carr_va;
2918         /*
2919          * End of microcode structure - 60 bytes. The rest of the structure
2920          * is used by the Adv Library and ignored by the microcode.
2921          */
2922         ADV_VADDR srb_ptr;
2923         ADV_SG_BLOCK *sg_list_ptr;      /* SG list virtual address. */
2924         char *vdata_addr;       /* Data buffer virtual address. */
2925         uchar a_flag;
2926         uchar pad[2];           /* Pad out to a word boundary. */
2927 } ADV_SCSI_REQ_Q;
2928
2929 /*
2930  * Microcode idle loop commands
2931  */
2932 #define IDLE_CMD_COMPLETED           0
2933 #define IDLE_CMD_STOP_CHIP           0x0001
2934 #define IDLE_CMD_STOP_CHIP_SEND_INT  0x0002
2935 #define IDLE_CMD_SEND_INT            0x0004
2936 #define IDLE_CMD_ABORT               0x0008
2937 #define IDLE_CMD_DEVICE_RESET        0x0010
2938 #define IDLE_CMD_SCSI_RESET_START    0x0020     /* Assert SCSI Bus Reset */
2939 #define IDLE_CMD_SCSI_RESET_END      0x0040     /* Deassert SCSI Bus Reset */
2940 #define IDLE_CMD_SCSIREQ             0x0080
2941
2942 #define IDLE_CMD_STATUS_SUCCESS      0x0001
2943 #define IDLE_CMD_STATUS_FAILURE      0x0002
2944
2945 /*
2946  * AdvSendIdleCmd() flag definitions.
2947  */
2948 #define ADV_NOWAIT     0x01
2949
2950 /*
2951  * Wait loop time out values.
2952  */
2953 #define SCSI_WAIT_10_SEC             10UL       /* 10 seconds */
2954 #define SCSI_WAIT_100_MSEC           100UL      /* 100 milliseconds */
2955 #define SCSI_US_PER_MSEC             1000       /* microseconds per millisecond */
2956 #define SCSI_MS_PER_SEC              1000UL     /* milliseconds per second */
2957 #define SCSI_MAX_RETRY               10 /* retry count */
2958
2959 #define ADV_ASYNC_RDMA_FAILURE          0x01    /* Fatal RDMA failure. */
2960 #define ADV_ASYNC_SCSI_BUS_RESET_DET    0x02    /* Detected SCSI Bus Reset. */
2961 #define ADV_ASYNC_CARRIER_READY_FAILURE 0x03    /* Carrier Ready failure. */
2962 #define ADV_RDMA_IN_CARR_AND_Q_INVALID  0x04    /* RDMAed-in data invalid. */
2963
2964 #define ADV_HOST_SCSI_BUS_RESET      0x80       /* Host Initiated SCSI Bus Reset. */
2965
2966 /*
2967  * Device drivers must define the following functions.
2968  */
2969 static inline ulong DvcEnterCritical(void);
2970 static inline void DvcLeaveCritical(ulong);
2971 static void DvcSleepMilliSecond(ADV_DCNT);
2972 static ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
2973                                uchar *, ASC_SDCNT *, int);
2974 static void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
2975
2976 /*
2977  * Adv Library functions available to drivers.
2978  */
2979 static int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
2980 static int AdvISR(ADV_DVC_VAR *);
2981 static int AdvInitAsc3550Driver(ADV_DVC_VAR *);
2982 static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
2983 static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
2984 static int AdvResetChipAndSB(ADV_DVC_VAR *);
2985 static int AdvResetSB(ADV_DVC_VAR *asc_dvc);
2986
2987 /*
2988  * Internal Adv Library functions.
2989  */
2990 static int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
2991 static int AdvInitFrom3550EEP(ADV_DVC_VAR *);
2992 static int AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
2993 static int AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
2994 static ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
2995 static void AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
2996 static ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
2997 static void AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
2998 static ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
2999 static void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3000 static void AdvWaitEEPCmd(AdvPortAddr);
3001 static ushort AdvReadEEPWord(AdvPortAddr, int);
3002
3003 /* Read byte from a register. */
3004 #define AdvReadByteRegister(iop_base, reg_off) \
3005      (ADV_MEM_READB((iop_base) + (reg_off)))
3006
3007 /* Write byte to a register. */
3008 #define AdvWriteByteRegister(iop_base, reg_off, byte) \
3009      (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
3010
3011 /* Read word (2 bytes) from a register. */
3012 #define AdvReadWordRegister(iop_base, reg_off) \
3013      (ADV_MEM_READW((iop_base) + (reg_off)))
3014
3015 /* Write word (2 bytes) to a register. */
3016 #define AdvWriteWordRegister(iop_base, reg_off, word) \
3017      (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
3018
3019 /* Write dword (4 bytes) to a register. */
3020 #define AdvWriteDWordRegister(iop_base, reg_off, dword) \
3021      (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
3022
3023 /* Read byte from LRAM. */
3024 #define AdvReadByteLram(iop_base, addr, byte) \
3025 do { \
3026     ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3027     (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
3028 } while (0)
3029
3030 /* Write byte to LRAM. */
3031 #define AdvWriteByteLram(iop_base, addr, byte) \
3032     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3033      ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
3034
3035 /* Read word (2 bytes) from LRAM. */
3036 #define AdvReadWordLram(iop_base, addr, word) \
3037 do { \
3038     ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3039     (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
3040 } while (0)
3041
3042 /* Write word (2 bytes) to LRAM. */
3043 #define AdvWriteWordLram(iop_base, addr, word) \
3044     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3045      ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3046
3047 /* Write little-endian double word (4 bytes) to LRAM */
3048 /* Because of unspecified C language ordering don't use auto-increment. */
3049 #define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
3050     ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3051       ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3052                      cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
3053      (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
3054       ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3055                      cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
3056
3057 /* Read word (2 bytes) from LRAM assuming that the address is already set. */
3058 #define AdvReadWordAutoIncLram(iop_base) \
3059      (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
3060
3061 /* Write word (2 bytes) to LRAM assuming that the address is already set. */
3062 #define AdvWriteWordAutoIncLram(iop_base, word) \
3063      (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3064
3065 /*
3066  * Define macro to check for Condor signature.
3067  *
3068  * Evaluate to ADV_TRUE if a Condor chip is found the specified port
3069  * address 'iop_base'. Otherwise evalue to ADV_FALSE.
3070  */
3071 #define AdvFindSignature(iop_base) \
3072     (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
3073     ADV_CHIP_ID_BYTE) && \
3074      (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
3075     ADV_CHIP_ID_WORD)) ?  ADV_TRUE : ADV_FALSE)
3076
3077 /*
3078  * Define macro to Return the version number of the chip at 'iop_base'.
3079  *
3080  * The second parameter 'bus_type' is currently unused.
3081  */
3082 #define AdvGetChipVersion(iop_base, bus_type) \
3083     AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
3084
3085 /*
3086  * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
3087  * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
3088  *
3089  * If the request has not yet been sent to the device it will simply be
3090  * aborted from RISC memory. If the request is disconnected it will be
3091  * aborted on reselection by sending an Abort Message to the target ID.
3092  *
3093  * Return value:
3094  *      ADV_TRUE(1) - Queue was successfully aborted.
3095  *      ADV_FALSE(0) - Queue was not found on the active queue list.
3096  */
3097 #define AdvAbortQueue(asc_dvc, scsiq) \
3098         AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
3099                        (ADV_DCNT) (scsiq))
3100
3101 /*
3102  * Send a Bus Device Reset Message to the specified target ID.
3103  *
3104  * All outstanding commands will be purged if sending the
3105  * Bus Device Reset Message is successful.
3106  *
3107  * Return Value:
3108  *      ADV_TRUE(1) - All requests on the target are purged.
3109  *      ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
3110  *                     are not purged.
3111  */
3112 #define AdvResetDevice(asc_dvc, target_id) \
3113         AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
3114                     (ADV_DCNT) (target_id))
3115
3116 /*
3117  * SCSI Wide Type definition.
3118  */
3119 #define ADV_SCSI_BIT_ID_TYPE   ushort
3120
3121 /*
3122  * AdvInitScsiTarget() 'cntl_flag' options.
3123  */
3124 #define ADV_SCAN_LUN           0x01
3125 #define ADV_CAPINFO_NOLUN      0x02
3126
3127 /*
3128  * Convert target id to target id bit mask.
3129  */
3130 #define ADV_TID_TO_TIDMASK(tid)   (0x01 << ((tid) & ADV_MAX_TID))
3131
3132 /*
3133  * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
3134  */
3135
3136 #define QD_NO_STATUS         0x00       /* Request not completed yet. */
3137 #define QD_NO_ERROR          0x01
3138 #define QD_ABORTED_BY_HOST   0x02
3139 #define QD_WITH_ERROR        0x04
3140
3141 #define QHSTA_NO_ERROR              0x00
3142 #define QHSTA_M_SEL_TIMEOUT         0x11
3143 #define QHSTA_M_DATA_OVER_RUN       0x12
3144 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
3145 #define QHSTA_M_QUEUE_ABORTED       0x15
3146 #define QHSTA_M_SXFR_SDMA_ERR       0x16        /* SXFR_STATUS SCSI DMA Error */
3147 #define QHSTA_M_SXFR_SXFR_PERR      0x17        /* SXFR_STATUS SCSI Bus Parity Error */
3148 #define QHSTA_M_RDMA_PERR           0x18        /* RISC PCI DMA parity error */
3149 #define QHSTA_M_SXFR_OFF_UFLW       0x19        /* SXFR_STATUS Offset Underflow */
3150 #define QHSTA_M_SXFR_OFF_OFLW       0x20        /* SXFR_STATUS Offset Overflow */
3151 #define QHSTA_M_SXFR_WD_TMO         0x21        /* SXFR_STATUS Watchdog Timeout */
3152 #define QHSTA_M_SXFR_DESELECTED     0x22        /* SXFR_STATUS Deselected */
3153 /* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
3154 #define QHSTA_M_SXFR_XFR_OFLW       0x12        /* SXFR_STATUS Transfer Overflow */
3155 #define QHSTA_M_SXFR_XFR_PH_ERR     0x24        /* SXFR_STATUS Transfer Phase Error */
3156 #define QHSTA_M_SXFR_UNKNOWN_ERROR  0x25        /* SXFR_STATUS Unknown Error */
3157 #define QHSTA_M_SCSI_BUS_RESET      0x30        /* Request aborted from SBR */
3158 #define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31       /* Request aborted from unsol. SBR */
3159 #define QHSTA_M_BUS_DEVICE_RESET    0x32        /* Request aborted from BDR */
3160 #define QHSTA_M_DIRECTION_ERR       0x35        /* Data Phase mismatch */
3161 #define QHSTA_M_DIRECTION_ERR_HUNG  0x36        /* Data Phase mismatch and bus hang */
3162 #define QHSTA_M_WTM_TIMEOUT         0x41
3163 #define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
3164 #define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
3165 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
3166 #define QHSTA_M_INVALID_DEVICE      0x45        /* Bad target ID */
3167 #define QHSTA_M_FROZEN_TIDQ         0x46        /* TID Queue frozen. */
3168 #define QHSTA_M_SGBACKUP_ERROR      0x47        /* Scatter-Gather backup error */
3169
3170 /*
3171  * DvcGetPhyAddr() flag arguments
3172  */
3173 #define ADV_IS_SCSIQ_FLAG       0x01    /* 'addr' is ASC_SCSI_REQ_Q pointer */
3174 #define ADV_ASCGETSGLIST_VADDR  0x02    /* 'addr' is AscGetSGList() virtual addr */
3175 #define ADV_IS_SENSE_FLAG       0x04    /* 'addr' is sense virtual pointer */
3176 #define ADV_IS_DATA_FLAG        0x08    /* 'addr' is data virtual pointer */
3177 #define ADV_IS_SGLIST_FLAG      0x10    /* 'addr' is sglist virtual pointer */
3178 #define ADV_IS_CARRIER_FLAG     0x20    /* 'addr' is ADV_CARR_T pointer */
3179
3180 /* Return the address that is aligned at the next doubleword >= to 'addr'. */
3181 #define ADV_8BALIGN(addr)      (((ulong) (addr) + 0x7) & ~0x7)
3182 #define ADV_16BALIGN(addr)     (((ulong) (addr) + 0xF) & ~0xF)
3183 #define ADV_32BALIGN(addr)     (((ulong) (addr) + 0x1F) & ~0x1F)
3184
3185 /*
3186  * Total contiguous memory needed for driver SG blocks.
3187  *
3188  * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
3189  * number of scatter-gather elements the driver supports in a
3190  * single request.
3191  */
3192
3193 #define ADV_SG_LIST_MAX_BYTE_SIZE \
3194          (sizeof(ADV_SG_BLOCK) * \
3195           ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
3196
3197 /*
3198  * --- Driver Constants and Macros
3199  */
3200
3201 /* Reference Scsi_Host hostdata */
3202 #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
3203
3204 /* asc_board_t flags */
3205 #define ASC_HOST_IN_RESET       0x01
3206 #define ASC_IS_WIDE_BOARD       0x04    /* AdvanSys Wide Board */
3207 #define ASC_SELECT_QUEUE_DEPTHS 0x08
3208
3209 #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
3210 #define ASC_WIDE_BOARD(boardp)   ((boardp)->flags & ASC_IS_WIDE_BOARD)
3211
3212 #define NO_ISA_DMA              0xff    /* No ISA DMA Channel Used */
3213
3214 #define ASC_INFO_SIZE           128     /* advansys_info() line size */
3215
3216 #ifdef CONFIG_PROC_FS
3217 /* /proc/scsi/advansys/[0...] related definitions */
3218 #define ASC_PRTBUF_SIZE         2048
3219 #define ASC_PRTLINE_SIZE        160
3220
3221 #define ASC_PRT_NEXT() \
3222     if (cp) { \
3223         totlen += len; \
3224         leftlen -= len; \
3225         if (leftlen == 0) { \
3226             return totlen; \
3227         } \
3228         cp += len; \
3229     }
3230 #endif /* CONFIG_PROC_FS */
3231
3232 /* Asc Library return codes */
3233 #define ASC_TRUE        1
3234 #define ASC_FALSE       0
3235 #define ASC_NOERROR     1
3236 #define ASC_BUSY        0
3237 #define ASC_ERROR       (-1)
3238
3239 /* struct scsi_cmnd function return codes */
3240 #define STATUS_BYTE(byte)   (byte)
3241 #define MSG_BYTE(byte)      ((byte) << 8)
3242 #define HOST_BYTE(byte)     ((byte) << 16)
3243 #define DRIVER_BYTE(byte)   ((byte) << 24)
3244
3245 /*
3246  * The following definitions and macros are OS independent interfaces to
3247  * the queue functions:
3248  *  REQ - SCSI request structure
3249  *  REQP - pointer to SCSI request structure
3250  *  REQPTID(reqp) - reqp's target id
3251  *  REQPNEXT(reqp) - reqp's next pointer
3252  *  REQPNEXTP(reqp) - pointer to reqp's next pointer
3253  *  REQPTIME(reqp) - reqp's time stamp value
3254  *  REQTIMESTAMP() - system time stamp value
3255  */
3256 typedef struct scsi_cmnd REQ, *REQP;
3257 #define REQPNEXT(reqp)       ((REQP) ((reqp)->host_scribble))
3258 #define REQPNEXTP(reqp)      ((REQP *) &((reqp)->host_scribble))
3259 #define REQPTID(reqp)        ((reqp)->device->id)
3260 #define REQPTIME(reqp)       ((reqp)->SCp.this_residual)
3261 #define REQTIMESTAMP()       (jiffies)
3262
3263 #define REQTIMESTAT(function, ascq, reqp, tid) \
3264 { \
3265     /*
3266      * If the request time stamp is less than the system time stamp, then \
3267      * maybe the system time stamp wrapped. Set the request time to zero.\
3268      */ \
3269     if (REQPTIME(reqp) <= REQTIMESTAMP()) { \
3270         REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \
3271     } else { \
3272         /* Indicate an error occurred with the assertion. */ \
3273         ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \
3274         REQPTIME(reqp) = 0; \
3275     } \
3276     /* Handle first minimum time case without external initialization. */ \
3277     if (((ascq)->q_tot_cnt[tid] == 1) ||  \
3278         (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \
3279             (ascq)->q_min_tim[tid] = REQPTIME(reqp); \
3280             ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
3281                 (function), (tid), (ascq)->q_min_tim[tid]); \
3282         } \
3283     if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \
3284         (ascq)->q_max_tim[tid] = REQPTIME(reqp); \
3285         ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
3286             (function), tid, (ascq)->q_max_tim[tid]); \
3287     } \
3288     (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \
3289     /* Reset the time stamp field. */ \
3290     REQPTIME(reqp) = 0; \
3291 }
3292
3293 /* asc_enqueue() flags */
3294 #define ASC_FRONT       1
3295 #define ASC_BACK        2
3296
3297 /* asc_dequeue_list() argument */
3298 #define ASC_TID_ALL        (-1)
3299
3300 /* Return non-zero, if the queue is empty. */
3301 #define ASC_QUEUE_EMPTY(ascq)    ((ascq)->q_tidmask == 0)
3302
3303 #ifndef ADVANSYS_STATS
3304 #define ASC_STATS(shost, counter)
3305 #define ASC_STATS_ADD(shost, counter, count)
3306 #else /* ADVANSYS_STATS */
3307 #define ASC_STATS(shost, counter) \
3308     (ASC_BOARDP(shost)->asc_stats.counter++)
3309
3310 #define ASC_STATS_ADD(shost, counter, count) \
3311     (ASC_BOARDP(shost)->asc_stats.counter += (count))
3312 #endif /* ADVANSYS_STATS */
3313
3314 #define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
3315
3316 /* If the result wraps when calculating tenths, return 0. */
3317 #define ASC_TENTHS(num, den) \
3318     (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
3319     0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
3320
3321 /*
3322  * Display a message to the console.
3323  */
3324 #define ASC_PRINT(s) \
3325     { \
3326         printk("advansys: "); \
3327         printk(s); \
3328     }
3329
3330 #define ASC_PRINT1(s, a1) \
3331     { \
3332         printk("advansys: "); \
3333         printk((s), (a1)); \
3334     }
3335
3336 #define ASC_PRINT2(s, a1, a2) \
3337     { \
3338         printk("advansys: "); \
3339         printk((s), (a1), (a2)); \
3340     }
3341
3342 #define ASC_PRINT3(s, a1, a2, a3) \
3343     { \
3344         printk("advansys: "); \
3345         printk((s), (a1), (a2), (a3)); \
3346     }
3347
3348 #define ASC_PRINT4(s, a1, a2, a3, a4) \
3349     { \
3350         printk("advansys: "); \
3351         printk((s), (a1), (a2), (a3), (a4)); \
3352     }
3353
3354 #ifndef ADVANSYS_DEBUG
3355
3356 #define ASC_DBG(lvl, s)
3357 #define ASC_DBG1(lvl, s, a1)
3358 #define ASC_DBG2(lvl, s, a1, a2)
3359 #define ASC_DBG3(lvl, s, a1, a2, a3)
3360 #define ASC_DBG4(lvl, s, a1, a2, a3, a4)
3361 #define ASC_DBG_PRT_SCSI_HOST(lvl, s)
3362 #define ASC_DBG_PRT_SCSI_CMND(lvl, s)
3363 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
3364 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3365 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
3366 #define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3367 #define ASC_DBG_PRT_HEX(lvl, name, start, length)
3368 #define ASC_DBG_PRT_CDB(lvl, cdb, len)
3369 #define ASC_DBG_PRT_SENSE(lvl, sense, len)
3370 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
3371
3372 #else /* ADVANSYS_DEBUG */
3373
3374 /*
3375  * Debugging Message Levels:
3376  * 0: Errors Only
3377  * 1: High-Level Tracing
3378  * 2-N: Verbose Tracing
3379  */
3380
3381 #define ASC_DBG(lvl, s) \
3382     { \
3383         if (asc_dbglvl >= (lvl)) { \
3384             printk(s); \
3385         } \
3386     }
3387
3388 #define ASC_DBG1(lvl, s, a1) \
3389     { \
3390         if (asc_dbglvl >= (lvl)) { \
3391             printk((s), (a1)); \
3392         } \
3393     }
3394
3395 #define ASC_DBG2(lvl, s, a1, a2) \
3396     { \
3397         if (asc_dbglvl >= (lvl)) { \
3398             printk((s), (a1), (a2)); \
3399         } \
3400     }
3401
3402 #define ASC_DBG3(lvl, s, a1, a2, a3) \
3403     { \
3404         if (asc_dbglvl >= (lvl)) { \
3405             printk((s), (a1), (a2), (a3)); \
3406         } \
3407     }
3408
3409 #define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
3410     { \
3411         if (asc_dbglvl >= (lvl)) { \
3412             printk((s), (a1), (a2), (a3), (a4)); \
3413         } \
3414     }
3415
3416 #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
3417     { \
3418         if (asc_dbglvl >= (lvl)) { \
3419             asc_prt_scsi_host(s); \
3420         } \
3421     }
3422
3423 #define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
3424     { \
3425         if (asc_dbglvl >= (lvl)) { \
3426             asc_prt_scsi_cmnd(s); \
3427         } \
3428     }
3429
3430 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
3431     { \
3432         if (asc_dbglvl >= (lvl)) { \
3433             asc_prt_asc_scsi_q(scsiqp); \
3434         } \
3435     }
3436
3437 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
3438     { \
3439         if (asc_dbglvl >= (lvl)) { \
3440             asc_prt_asc_qdone_info(qdone); \
3441         } \
3442     }
3443
3444 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
3445     { \
3446         if (asc_dbglvl >= (lvl)) { \
3447             asc_prt_adv_scsi_req_q(scsiqp); \
3448         } \
3449     }
3450
3451 #define ASC_DBG_PRT_HEX(lvl, name, start, length) \
3452     { \
3453         if (asc_dbglvl >= (lvl)) { \
3454             asc_prt_hex((name), (start), (length)); \
3455         } \
3456     }
3457
3458 #define ASC_DBG_PRT_CDB(lvl, cdb, len) \
3459         ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
3460
3461 #define ASC_DBG_PRT_SENSE(lvl, sense, len) \
3462         ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
3463
3464 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
3465         ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
3466 #endif /* ADVANSYS_DEBUG */
3467
3468 #ifndef ADVANSYS_ASSERT
3469 #define ASC_ASSERT(a)
3470 #else /* ADVANSYS_ASSERT */
3471
3472 #define ASC_ASSERT(a) \
3473     { \
3474         if (!(a)) { \
3475             printk("ASC_ASSERT() Failure: file %s, line %d\n", \
3476                 __FILE__, __LINE__); \
3477         } \
3478     }
3479
3480 #endif /* ADVANSYS_ASSERT */
3481
3482 /*
3483  * --- Driver Structures
3484  */
3485
3486 #ifdef ADVANSYS_STATS
3487
3488 /* Per board statistics structure */
3489 struct asc_stats {
3490         /* Driver Entrypoint Statistics */
3491         ADV_DCNT queuecommand;  /* # calls to advansys_queuecommand() */
3492         ADV_DCNT reset;         /* # calls to advansys_eh_bus_reset() */
3493         ADV_DCNT biosparam;     /* # calls to advansys_biosparam() */
3494         ADV_DCNT interrupt;     /* # advansys_interrupt() calls */
3495         ADV_DCNT callback;      /* # calls to asc/adv_isr_callback() */
3496         ADV_DCNT done;          /* # calls to request's scsi_done function */
3497         ADV_DCNT build_error;   /* # asc/adv_build_req() ASC_ERROR returns. */
3498         ADV_DCNT adv_build_noreq;       /* # adv_build_req() adv_req_t alloc. fail. */
3499         ADV_DCNT adv_build_nosg;        /* # adv_build_req() adv_sgblk_t alloc. fail. */
3500         /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
3501         ADV_DCNT exe_noerror;   /* # ASC_NOERROR returns. */
3502         ADV_DCNT exe_busy;      /* # ASC_BUSY returns. */
3503         ADV_DCNT exe_error;     /* # ASC_ERROR returns. */
3504         ADV_DCNT exe_unknown;   /* # unknown returns. */
3505         /* Data Transfer Statistics */
3506         ADV_DCNT cont_cnt;      /* # non-scatter-gather I/O requests received */
3507         ADV_DCNT cont_xfer;     /* # contiguous transfer 512-bytes */
3508         ADV_DCNT sg_cnt;        /* # scatter-gather I/O requests received */
3509         ADV_DCNT sg_elem;       /* # scatter-gather elements */
3510         ADV_DCNT sg_xfer;       /* # scatter-gather transfer 512-bytes */
3511 };
3512 #endif /* ADVANSYS_STATS */
3513
3514 /*
3515  * Request queuing structure
3516  */
3517 typedef struct asc_queue {
3518         ADV_SCSI_BIT_ID_TYPE q_tidmask; /* queue mask */
3519         REQP q_first[ADV_MAX_TID + 1];  /* first queued request */
3520         REQP q_last[ADV_MAX_TID + 1];   /* last queued request */
3521 #ifdef ADVANSYS_STATS
3522         short q_cur_cnt[ADV_MAX_TID + 1];       /* current queue count */
3523         short q_max_cnt[ADV_MAX_TID + 1];       /* maximum queue count */
3524         ADV_DCNT q_tot_cnt[ADV_MAX_TID + 1];    /* total enqueue count */
3525         ADV_DCNT q_tot_tim[ADV_MAX_TID + 1];    /* total time queued */
3526         ushort q_max_tim[ADV_MAX_TID + 1];      /* maximum time queued */
3527         ushort q_min_tim[ADV_MAX_TID + 1];      /* minimum time queued */
3528 #endif                          /* ADVANSYS_STATS */
3529 } asc_queue_t;
3530
3531 /*
3532  * Adv Library Request Structures
3533  *
3534  * The following two structures are used to process Wide Board requests.
3535  *
3536  * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
3537  * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
3538  * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
3539  * Mid-Level SCSI request structure.
3540  *
3541  * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
3542  * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
3543  * up to 255 scatter-gather elements may be used per request or
3544  * ADV_SCSI_REQ_Q.
3545  *
3546  * Both structures must be 32 byte aligned.
3547  */
3548 typedef struct adv_sgblk {
3549         ADV_SG_BLOCK sg_block;  /* Sgblock structure. */
3550         uchar align[32];        /* Sgblock structure padding. */
3551         struct adv_sgblk *next_sgblkp;  /* Next scatter-gather structure. */
3552 } adv_sgblk_t;
3553
3554 typedef struct adv_req {
3555         ADV_SCSI_REQ_Q scsi_req_q;      /* Adv Library request structure. */
3556         uchar align[32];        /* Request structure padding. */
3557         struct scsi_cmnd *cmndp;        /* Mid-Level SCSI command pointer. */
3558         adv_sgblk_t *sgblkp;    /* Adv Library scatter-gather pointer. */
3559         struct adv_req *next_reqp;      /* Next Request Structure. */
3560 } adv_req_t;
3561
3562 /*
3563  * Structure allocated for each board.
3564  *
3565  * This structure is allocated by scsi_host_alloc() at the end
3566  * of the 'Scsi_Host' structure starting at the 'hostdata'
3567  * field. It is guaranteed to be allocated from DMA-able memory.
3568  */
3569 typedef struct asc_board {
3570         struct device *dev;
3571         int id;                 /* Board Id */
3572         uint flags;             /* Board flags */
3573         union {
3574                 ASC_DVC_VAR asc_dvc_var;        /* Narrow board */
3575                 ADV_DVC_VAR adv_dvc_var;        /* Wide board */
3576         } dvc_var;
3577         union {
3578                 ASC_DVC_CFG asc_dvc_cfg;        /* Narrow board */
3579                 ADV_DVC_CFG adv_dvc_cfg;        /* Wide board */
3580         } dvc_cfg;
3581         ushort asc_n_io_port;   /* Number I/O ports. */
3582         asc_queue_t active;     /* Active command queue */
3583         asc_queue_t waiting;    /* Waiting command queue */
3584         asc_queue_t done;       /* Done command queue */
3585         ADV_SCSI_BIT_ID_TYPE init_tidmask;      /* Target init./valid mask */
3586         struct scsi_device *device[ADV_MAX_TID + 1];    /* Mid-Level Scsi Device */
3587         ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */
3588         ADV_SCSI_BIT_ID_TYPE queue_full;        /* Queue full mask */
3589         ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */
3590         union {
3591                 ASCEEP_CONFIG asc_eep;  /* Narrow EEPROM config. */
3592                 ADVEEP_3550_CONFIG adv_3550_eep;        /* 3550 EEPROM config. */
3593                 ADVEEP_38C0800_CONFIG adv_38C0800_eep;  /* 38C0800 EEPROM config. */
3594                 ADVEEP_38C1600_CONFIG adv_38C1600_eep;  /* 38C1600 EEPROM config. */
3595         } eep_config;
3596         ulong last_reset;       /* Saved last reset time */
3597         spinlock_t lock;        /* Board spinlock */
3598         /* /proc/scsi/advansys/[0...] */
3599         char *prtbuf;           /* /proc print buffer */
3600 #ifdef ADVANSYS_STATS
3601         struct asc_stats asc_stats;     /* Board statistics */
3602 #endif                          /* ADVANSYS_STATS */
3603         /*
3604          * The following fields are used only for Narrow Boards.
3605          */
3606         uchar sdtr_data[ASC_MAX_TID + 1];       /* SDTR information */
3607         /*
3608          * The following fields are used only for Wide Boards.
3609          */
3610         void __iomem *ioremap_addr;     /* I/O Memory remap address. */
3611         ushort ioport;          /* I/O Port address. */
3612         ADV_CARR_T *carrp;      /* ADV_CARR_T memory block. */
3613         adv_req_t *orig_reqp;   /* adv_req_t memory block. */
3614         adv_req_t *adv_reqp;    /* Request structures. */
3615         adv_sgblk_t *adv_sgblkp;        /* Scatter-gather structures. */
3616         ushort bios_signature;  /* BIOS Signature. */
3617         ushort bios_version;    /* BIOS Version. */
3618         ushort bios_codeseg;    /* BIOS Code Segment. */
3619         ushort bios_codelen;    /* BIOS Code Segment Length. */
3620 } asc_board_t;
3621
3622 #define adv_dvc_to_board(adv_dvc) container_of(adv_dvc, struct asc_board, \
3623                                                         dvc_var.adv_dvc_var)
3624 #define adv_dvc_to_pdev(adv_dvc) to_pci_dev(adv_dvc_to_board(adv_dvc)->dev)
3625
3626 /* Number of boards detected in system. */
3627 static int asc_board_count;
3628
3629 /* Overrun buffer used by all narrow boards. */
3630 static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
3631
3632 /*
3633  * Global structures required to issue a command.
3634  */
3635 static ASC_SCSI_Q asc_scsi_q = { {0} };
3636 static ASC_SG_HEAD asc_sg_head = { 0 };
3637
3638 #ifdef ADVANSYS_DEBUG
3639 static int asc_dbglvl = 3;
3640 #endif /* ADVANSYS_DEBUG */
3641
3642 /*
3643  * --- Driver Function Prototypes
3644  */
3645
3646 static int advansys_slave_configure(struct scsi_device *);
3647 static void asc_scsi_done_list(struct scsi_cmnd *);
3648 static int asc_execute_scsi_cmnd(struct scsi_cmnd *);
3649 static int asc_build_req(asc_board_t *, struct scsi_cmnd *);
3650 static int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **);
3651 static int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int);
3652 static void asc_enqueue(asc_queue_t *, REQP, int);
3653 static REQP asc_dequeue(asc_queue_t *, int);
3654 static REQP asc_dequeue_list(asc_queue_t *, REQP *, int);
3655 static int asc_rmqueue(asc_queue_t *, REQP);
3656 static void asc_execute_queue(asc_queue_t *);
3657 #ifdef CONFIG_PROC_FS
3658 static int asc_proc_copy(off_t, off_t, char *, int, char *, int);
3659 static int asc_prt_board_devices(struct Scsi_Host *, char *, int);
3660 static int asc_prt_adv_bios(struct Scsi_Host *, char *, int);
3661 static int asc_get_eeprom_string(ushort *serialnum, uchar *cp);
3662 static int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
3663 static int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
3664 static int asc_prt_driver_conf(struct Scsi_Host *, char *, int);
3665 static int asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
3666 static int asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
3667 static int asc_prt_line(char *, int, char *fmt, ...);
3668 #endif /* CONFIG_PROC_FS */
3669
3670 /* Statistics function prototypes. */
3671 #ifdef ADVANSYS_STATS
3672 #ifdef CONFIG_PROC_FS
3673 static int asc_prt_board_stats(struct Scsi_Host *, char *, int);
3674 static int asc_prt_target_stats(struct Scsi_Host *, int, char *, int);
3675 #endif /* CONFIG_PROC_FS */
3676 #endif /* ADVANSYS_STATS */
3677
3678 /* Debug function prototypes. */
3679 #ifdef ADVANSYS_DEBUG
3680 static void asc_prt_scsi_host(struct Scsi_Host *);
3681 static void asc_prt_scsi_cmnd(struct scsi_cmnd *);
3682 static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
3683 static void asc_prt_asc_dvc_var(ASC_DVC_VAR *);
3684 static void asc_prt_asc_scsi_q(ASC_SCSI_Q *);
3685 static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
3686 static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
3687 static void asc_prt_adv_dvc_var(ADV_DVC_VAR *);
3688 static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
3689 static void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
3690 static void asc_prt_hex(char *f, uchar *, int);
3691 #endif /* ADVANSYS_DEBUG */
3692
3693 #ifdef CONFIG_PROC_FS
3694 /*
3695  * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...}
3696  *
3697  * *buffer: I/O buffer
3698  * **start: if inout == FALSE pointer into buffer where user read should start
3699  * offset: current offset into a /proc/scsi/advansys/[0...] file
3700  * length: length of buffer
3701  * hostno: Scsi_Host host_no
3702  * inout: TRUE - user is writing; FALSE - user is reading
3703  *
3704  * Return the number of bytes read from or written to a
3705  * /proc/scsi/advansys/[0...] file.
3706  *
3707  * Note: This function uses the per board buffer 'prtbuf' which is
3708  * allocated when the board is initialized in advansys_detect(). The
3709  * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
3710  * used to write to the buffer. The way asc_proc_copy() is written
3711  * if 'prtbuf' is too small it will not be overwritten. Instead the
3712  * user just won't get all the available statistics.
3713  */
3714 static int
3715 advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
3716                    off_t offset, int length, int inout)
3717 {
3718         asc_board_t *boardp;
3719         char *cp;
3720         int cplen;
3721         int cnt;
3722         int totcnt;
3723         int leftlen;
3724         char *curbuf;
3725         off_t advoffset;
3726 #ifdef ADVANSYS_STATS
3727         int tgt_id;
3728 #endif /* ADVANSYS_STATS */
3729
3730         ASC_DBG(1, "advansys_proc_info: begin\n");
3731
3732         /*
3733          * User write not supported.
3734          */
3735         if (inout == TRUE) {
3736                 return (-ENOSYS);
3737         }
3738
3739         /*
3740          * User read of /proc/scsi/advansys/[0...] file.
3741          */
3742
3743         boardp = ASC_BOARDP(shost);
3744
3745         /* Copy read data starting at the beginning of the buffer. */
3746         *start = buffer;
3747         curbuf = buffer;
3748         advoffset = 0;
3749         totcnt = 0;
3750         leftlen = length;
3751
3752         /*
3753          * Get board configuration information.
3754          *
3755          * advansys_info() returns the board string from its own static buffer.
3756          */
3757         cp = (char *)advansys_info(shost);
3758         strcat(cp, "\n");
3759         cplen = strlen(cp);
3760         /* Copy board information. */
3761         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3762         totcnt += cnt;
3763         leftlen -= cnt;
3764         if (leftlen == 0) {
3765                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3766                 return totcnt;
3767         }
3768         advoffset += cplen;
3769         curbuf += cnt;
3770
3771         /*
3772          * Display Wide Board BIOS Information.
3773          */
3774         if (ASC_WIDE_BOARD(boardp)) {
3775                 cp = boardp->prtbuf;
3776                 cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
3777                 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3778                 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
3779                                   cplen);
3780                 totcnt += cnt;
3781                 leftlen -= cnt;
3782                 if (leftlen == 0) {
3783                         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3784                         return totcnt;
3785                 }
3786                 advoffset += cplen;
3787                 curbuf += cnt;
3788         }
3789
3790         /*
3791          * Display driver information for each device attached to the board.
3792          */
3793         cp = boardp->prtbuf;
3794         cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE);
3795         ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3796         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3797         totcnt += cnt;
3798         leftlen -= cnt;
3799         if (leftlen == 0) {
3800                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3801                 return totcnt;
3802         }
3803         advoffset += cplen;
3804         curbuf += cnt;
3805
3806         /*
3807          * Display EEPROM configuration for the board.
3808          */
3809         cp = boardp->prtbuf;
3810         if (ASC_NARROW_BOARD(boardp)) {
3811                 cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
3812         } else {
3813                 cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
3814         }
3815         ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3816         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3817         totcnt += cnt;
3818         leftlen -= cnt;
3819         if (leftlen == 0) {
3820                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3821                 return totcnt;
3822         }
3823         advoffset += cplen;
3824         curbuf += cnt;
3825
3826         /*
3827          * Display driver configuration and information for the board.
3828          */
3829         cp = boardp->prtbuf;
3830         cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE);
3831         ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3832         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3833         totcnt += cnt;
3834         leftlen -= cnt;
3835         if (leftlen == 0) {
3836                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3837                 return totcnt;
3838         }
3839         advoffset += cplen;
3840         curbuf += cnt;
3841
3842 #ifdef ADVANSYS_STATS
3843         /*
3844          * Display driver statistics for the board.
3845          */
3846         cp = boardp->prtbuf;
3847         cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE);
3848         ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
3849         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3850         totcnt += cnt;
3851         leftlen -= cnt;
3852         if (leftlen == 0) {
3853                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3854                 return totcnt;
3855         }
3856         advoffset += cplen;
3857         curbuf += cnt;
3858
3859         /*
3860          * Display driver statistics for each target.
3861          */
3862         for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) {
3863                 cp = boardp->prtbuf;
3864                 cplen = asc_prt_target_stats(shost, tgt_id, cp,
3865                                              ASC_PRTBUF_SIZE);
3866                 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
3867                 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
3868                                     cplen);
3869                 totcnt += cnt;
3870                 leftlen -= cnt;
3871                 if (leftlen == 0) {
3872                         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3873                         return totcnt;
3874                 }
3875                 advoffset += cplen;
3876                 curbuf += cnt;
3877         }
3878 #endif /* ADVANSYS_STATS */
3879
3880         /*
3881          * Display Asc Library dynamic configuration information
3882          * for the board.
3883          */
3884         cp = boardp->prtbuf;
3885         if (ASC_NARROW_BOARD(boardp)) {
3886                 cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
3887         } else {
3888                 cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
3889         }
3890         ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3891         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3892         totcnt += cnt;
3893         leftlen -= cnt;
3894         if (leftlen == 0) {
3895                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3896                 return totcnt;
3897         }
3898         advoffset += cplen;
3899         curbuf += cnt;
3900
3901         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3902
3903         return totcnt;
3904 }
3905 #endif /* CONFIG_PROC_FS */
3906
3907 /*
3908  * advansys_info()
3909  *
3910  * Return suitable for printing on the console with the argument
3911  * adapter's configuration information.
3912  *
3913  * Note: The information line should not exceed ASC_INFO_SIZE bytes,
3914  * otherwise the static 'info' array will be overrun.
3915  */
3916 static const char *advansys_info(struct Scsi_Host *shost)
3917 {
3918         static char info[ASC_INFO_SIZE];
3919         asc_board_t *boardp;
3920         ASC_DVC_VAR *asc_dvc_varp;
3921         ADV_DVC_VAR *adv_dvc_varp;
3922         char *busname;
3923         char *widename = NULL;
3924
3925         boardp = ASC_BOARDP(shost);
3926         if (ASC_NARROW_BOARD(boardp)) {
3927                 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
3928                 ASC_DBG(1, "advansys_info: begin\n");
3929                 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
3930                         if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) ==
3931                             ASC_IS_ISAPNP) {
3932                                 busname = "ISA PnP";
3933                         } else {
3934                                 busname = "ISA";
3935                         }
3936                         sprintf(info,
3937                                 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
3938                                 ASC_VERSION, busname,
3939                                 (ulong)shost->io_port,
3940                                 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
3941                                 shost->irq, shost->dma_channel);
3942                 } else {
3943                         if (asc_dvc_varp->bus_type & ASC_IS_VL) {
3944                                 busname = "VL";
3945                         } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
3946                                 busname = "EISA";
3947                         } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
3948                                 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
3949                                     == ASC_IS_PCI_ULTRA) {
3950                                         busname = "PCI Ultra";
3951                                 } else {
3952                                         busname = "PCI";
3953                                 }
3954                         } else {
3955                                 busname = "?";
3956                                 ASC_PRINT2("advansys_info: board %d: unknown "
3957                                            "bus type %d\n", boardp->id,
3958                                            asc_dvc_varp->bus_type);
3959                         }
3960                         sprintf(info,
3961                                 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
3962                                 ASC_VERSION, busname, (ulong)shost->io_port,
3963                                 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
3964                                 shost->irq);
3965                 }
3966         } else {
3967                 /*
3968                  * Wide Adapter Information
3969                  *
3970                  * Memory-mapped I/O is used instead of I/O space to access
3971                  * the adapter, but display the I/O Port range. The Memory
3972                  * I/O address is displayed through the driver /proc file.
3973                  */
3974                 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
3975                 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3976                         widename = "Ultra-Wide";
3977                 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3978                         widename = "Ultra2-Wide";
3979                 } else {
3980                         widename = "Ultra3-Wide";
3981                 }
3982                 sprintf(info,
3983                         "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
3984                         ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
3985                         (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, shost->irq);
3986         }
3987         ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
3988         ASC_DBG(1, "advansys_info: end\n");
3989         return info;
3990 }
3991
3992 /*
3993  * advansys_queuecommand() - interrupt-driven I/O entrypoint.
3994  *
3995  * This function always returns 0. Command return status is saved
3996  * in the 'scp' result field.
3997  */
3998 static int
3999 advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *))
4000 {
4001         struct Scsi_Host *shost;
4002         asc_board_t *boardp;
4003         ulong flags;
4004         struct scsi_cmnd *done_scp;
4005
4006         shost = scp->device->host;
4007         boardp = ASC_BOARDP(shost);
4008         ASC_STATS(shost, queuecommand);
4009
4010         /* host_lock taken by mid-level prior to call but need to protect */
4011         /* against own ISR */
4012         spin_lock_irqsave(&boardp->lock, flags);
4013
4014         /*
4015          * Block new commands while handling a reset or abort request.
4016          */
4017         if (boardp->flags & ASC_HOST_IN_RESET) {
4018                 ASC_DBG1(1,
4019                          "advansys_queuecommand: scp 0x%lx blocked for reset request\n",
4020                          (ulong)scp);
4021                 scp->result = HOST_BYTE(DID_RESET);
4022
4023                 /*
4024                  * Add blocked requests to the board's 'done' queue. The queued
4025                  * requests will be completed at the end of the abort or reset
4026                  * handling.
4027                  */
4028                 asc_enqueue(&boardp->done, scp, ASC_BACK);
4029                 spin_unlock_irqrestore(&boardp->lock, flags);
4030                 return 0;
4031         }
4032
4033         /*
4034          * Attempt to execute any waiting commands for the board.
4035          */
4036         if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
4037                 ASC_DBG(1,
4038                         "advansys_queuecommand: before asc_execute_queue() waiting\n");
4039                 asc_execute_queue(&boardp->waiting);
4040         }
4041
4042         /*
4043          * Save the function pointer to Linux mid-level 'done' function
4044          * and attempt to execute the command.
4045          *
4046          * If ASC_NOERROR is returned the request has been added to the
4047          * board's 'active' queue and will be completed by the interrupt
4048          * handler.
4049          *
4050          * If ASC_BUSY is returned add the request to the board's per
4051          * target waiting list. This is the first time the request has
4052          * been tried. Add it to the back of the waiting list. It will be
4053          * retried later.
4054          *
4055          * If an error occurred, the request will have been placed on the
4056          * board's 'done' queue and must be completed before returning.
4057          */
4058         scp->scsi_done = done;
4059         switch (asc_execute_scsi_cmnd(scp)) {
4060         case ASC_NOERROR:
4061                 break;
4062         case ASC_BUSY:
4063                 asc_enqueue(&boardp->waiting, scp, ASC_BACK);
4064                 break;
4065         case ASC_ERROR:
4066         default:
4067                 done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
4068                 /* Interrupts could be enabled here. */
4069                 asc_scsi_done_list(done_scp);
4070                 break;
4071         }
4072         spin_unlock_irqrestore(&boardp->lock, flags);
4073
4074         return 0;
4075 }
4076
4077 /*
4078  * advansys_reset()
4079  *
4080  * Reset the bus associated with the command 'scp'.
4081  *
4082  * This function runs its own thread. Interrupts must be blocked but
4083  * sleeping is allowed and no locking other than for host structures is
4084  * required. Returns SUCCESS or FAILED.
4085  */
4086 static int advansys_reset(struct scsi_cmnd *scp)
4087 {
4088         struct Scsi_Host *shost;
4089         asc_board_t *boardp;
4090         ASC_DVC_VAR *asc_dvc_varp;
4091         ADV_DVC_VAR *adv_dvc_varp;
4092         ulong flags;
4093         struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
4094         struct scsi_cmnd *tscp, *new_last_scp;
4095         int status;
4096         int ret = SUCCESS;
4097
4098         ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong)scp);
4099
4100 #ifdef ADVANSYS_STATS
4101         if (scp->device->host != NULL) {
4102                 ASC_STATS(scp->device->host, reset);
4103         }
4104 #endif /* ADVANSYS_STATS */
4105
4106         if ((shost = scp->device->host) == NULL) {
4107                 scp->result = HOST_BYTE(DID_ERROR);
4108                 return FAILED;
4109         }
4110
4111         boardp = ASC_BOARDP(shost);
4112
4113         ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
4114                    boardp->id);
4115         /*
4116          * Check for re-entrancy.
4117          */
4118         spin_lock_irqsave(&boardp->lock, flags);
4119         if (boardp->flags & ASC_HOST_IN_RESET) {
4120                 spin_unlock_irqrestore(&boardp->lock, flags);
4121                 return FAILED;
4122         }
4123         boardp->flags |= ASC_HOST_IN_RESET;
4124         spin_unlock_irqrestore(&boardp->lock, flags);
4125
4126         if (ASC_NARROW_BOARD(boardp)) {
4127                 /*
4128                  * Narrow Board
4129                  */
4130                 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4131
4132                 /*
4133                  * Reset the chip and SCSI bus.
4134                  */
4135                 ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
4136                 status = AscInitAsc1000Driver(asc_dvc_varp);
4137
4138                 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
4139                 if (asc_dvc_varp->err_code) {
4140                         ASC_PRINT2("advansys_reset: board %d: SCSI bus reset "
4141                                    "error: 0x%x\n", boardp->id,
4142                                    asc_dvc_varp->err_code);
4143                         ret = FAILED;
4144                 } else if (status) {
4145                         ASC_PRINT2("advansys_reset: board %d: SCSI bus reset "
4146                                    "warning: 0x%x\n", boardp->id, status);
4147                 } else {
4148                         ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
4149                                    "successful.\n", boardp->id);
4150                 }
4151
4152                 ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
4153                 spin_lock_irqsave(&boardp->lock, flags);
4154
4155         } else {
4156                 /*
4157                  * Wide Board
4158                  *
4159                  * If the suggest reset bus flags are set, then reset the bus.
4160                  * Otherwise only reset the device.
4161                  */
4162                 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4163
4164                 /*
4165                  * Reset the target's SCSI bus.
4166                  */
4167                 ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
4168                 switch (AdvResetChipAndSB(adv_dvc_varp)) {
4169                 case ASC_TRUE:
4170                         ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
4171                                    "successful.\n", boardp->id);
4172                         break;
4173                 case ASC_FALSE:
4174                 default:
4175                         ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
4176                                    "error.\n", boardp->id);
4177                         ret = FAILED;
4178                         break;
4179                 }
4180                 spin_lock_irqsave(&boardp->lock, flags);
4181                 (void)AdvISR(adv_dvc_varp);
4182         }
4183         /* Board lock is held. */
4184
4185         /*
4186          * Dequeue all board 'done' requests. A pointer to the last request
4187          * is returned in 'last_scp'.
4188          */
4189         done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL);
4190
4191         /*
4192          * Dequeue all board 'active' requests for all devices and set
4193          * the request status to DID_RESET. A pointer to the last request
4194          * is returned in 'last_scp'.
4195          */
4196         if (done_scp == NULL) {
4197                 done_scp = asc_dequeue_list(&boardp->active, &last_scp,
4198                                             ASC_TID_ALL);
4199                 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
4200                         tscp->result = HOST_BYTE(DID_RESET);
4201                 }
4202         } else {
4203                 /* Append to 'done_scp' at the end with 'last_scp'. */
4204                 ASC_ASSERT(last_scp != NULL);
4205                 last_scp->host_scribble =
4206                     (unsigned char *)asc_dequeue_list(&boardp->active,
4207                                                       &new_last_scp,
4208                                                       ASC_TID_ALL);
4209                 if (new_last_scp != NULL) {
4210                         ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4211                         for (tscp = REQPNEXT(last_scp); tscp;
4212                              tscp = REQPNEXT(tscp)) {
4213                                 tscp->result = HOST_BYTE(DID_RESET);
4214                         }
4215                         last_scp = new_last_scp;
4216                 }
4217         }
4218
4219         /*
4220          * Dequeue all 'waiting' requests and set the request status
4221          * to DID_RESET.
4222          */
4223         if (done_scp == NULL) {
4224                 done_scp = asc_dequeue_list(&boardp->waiting, &last_scp,
4225                                             ASC_TID_ALL);
4226                 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
4227                         tscp->result = HOST_BYTE(DID_RESET);
4228                 }
4229         } else {
4230                 /* Append to 'done_scp' at the end with 'last_scp'. */
4231                 ASC_ASSERT(last_scp != NULL);
4232                 last_scp->host_scribble =
4233                     (unsigned char *)asc_dequeue_list(&boardp->waiting,
4234                                                       &new_last_scp,
4235                                                       ASC_TID_ALL);
4236                 if (new_last_scp != NULL) {
4237                         ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4238                         for (tscp = REQPNEXT(last_scp); tscp;
4239                              tscp = REQPNEXT(tscp)) {
4240                                 tscp->result = HOST_BYTE(DID_RESET);
4241                         }
4242                         last_scp = new_last_scp;
4243                 }
4244         }
4245
4246         /* Save the time of the most recently completed reset. */
4247         boardp->last_reset = jiffies;
4248
4249         /* Clear reset flag. */
4250         boardp->flags &= ~ASC_HOST_IN_RESET;
4251         spin_unlock_irqrestore(&boardp->lock, flags);
4252
4253         /*
4254          * Complete all the 'done_scp' requests.
4255          */
4256         if (done_scp)
4257                 asc_scsi_done_list(done_scp);
4258
4259         ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
4260
4261         return ret;
4262 }
4263
4264 /*
4265  * advansys_biosparam()
4266  *
4267  * Translate disk drive geometry if the "BIOS greater than 1 GB"
4268  * support is enabled for a drive.
4269  *
4270  * ip (information pointer) is an int array with the following definition:
4271  * ip[0]: heads
4272  * ip[1]: sectors
4273  * ip[2]: cylinders
4274  */
4275 static int
4276 advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
4277                    sector_t capacity, int ip[])
4278 {
4279         asc_board_t *boardp;
4280
4281         ASC_DBG(1, "advansys_biosparam: begin\n");
4282         ASC_STATS(sdev->host, biosparam);
4283         boardp = ASC_BOARDP(sdev->host);
4284         if (ASC_NARROW_BOARD(boardp)) {
4285                 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
4286                      ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
4287                         ip[0] = 255;
4288                         ip[1] = 63;
4289                 } else {
4290                         ip[0] = 64;
4291                         ip[1] = 32;
4292                 }
4293         } else {
4294                 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
4295                      BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
4296                         ip[0] = 255;
4297                         ip[1] = 63;
4298                 } else {
4299                         ip[0] = 64;
4300                         ip[1] = 32;
4301                 }
4302         }
4303         ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
4304         ASC_DBG(1, "advansys_biosparam: end\n");
4305         return 0;
4306 }
4307
4308 static struct scsi_host_template advansys_template = {
4309         .proc_name = "advansys",
4310 #ifdef CONFIG_PROC_FS
4311         .proc_info = advansys_proc_info,
4312 #endif
4313         .name = "advansys",
4314         .info = advansys_info,
4315         .queuecommand = advansys_queuecommand,
4316         .eh_bus_reset_handler = advansys_reset,
4317         .bios_param = advansys_biosparam,
4318         .slave_configure = advansys_slave_configure,
4319         /*
4320          * Because the driver may control an ISA adapter 'unchecked_isa_dma'
4321          * must be set. The flag will be cleared in advansys_board_found
4322          * for non-ISA adapters.
4323          */
4324         .unchecked_isa_dma = 1,
4325         /*
4326          * All adapters controlled by this driver are capable of large
4327          * scatter-gather lists. According to the mid-level SCSI documentation
4328          * this obviates any performance gain provided by setting
4329          * 'use_clustering'. But empirically while CPU utilization is increased
4330          * by enabling clustering, I/O throughput increases as well.
4331          */
4332         .use_clustering = ENABLE_CLUSTERING,
4333 };
4334
4335 /*
4336  * --- Miscellaneous Driver Functions
4337  */
4338
4339 /*
4340  * First-level interrupt handler.
4341  *
4342  * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
4343  * all boards are currently checked for interrupts on each interrupt, 'dev_id'
4344  * is not referenced. 'dev_id' could be used to identify an interrupt passed
4345  * to the AdvanSys driver which is for a device sharing an interrupt with
4346  * an AdvanSys adapter.
4347  */
4348 static irqreturn_t advansys_interrupt(int irq, void *dev_id)
4349 {
4350         unsigned long flags;
4351         struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
4352         struct scsi_cmnd *new_last_scp;
4353         struct Scsi_Host *shost = dev_id;
4354         asc_board_t *boardp = ASC_BOARDP(shost);
4355         irqreturn_t result = IRQ_NONE;
4356
4357         ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp);
4358         spin_lock_irqsave(&boardp->lock, flags);
4359         if (ASC_NARROW_BOARD(boardp)) {
4360                 /*
4361                  * Narrow Board
4362                  */
4363                 if (AscIsIntPending(shost->io_port)) {
4364                         result = IRQ_HANDLED;
4365                         ASC_STATS(shost, interrupt);
4366                         ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
4367                         AscISR(&boardp->dvc_var.asc_dvc_var);
4368                 }
4369         } else {
4370                 /*
4371                  * Wide Board
4372                  */
4373                 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
4374                 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
4375                         result = IRQ_HANDLED;
4376                         ASC_STATS(shost, interrupt);
4377                 }
4378         }
4379
4380         /*
4381          * Start waiting requests and create a list of completed requests.
4382          *
4383          * If a reset request is being performed for the board, the reset
4384          * handler will complete pending requests after it has completed.
4385          */
4386         if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
4387                 ASC_DBG2(1, "advansys_interrupt: done_scp 0x%p, "
4388                          "last_scp 0x%p\n", done_scp, last_scp);
4389
4390                 /* Start any waiting commands for the board. */
4391                 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
4392                         ASC_DBG(1, "advansys_interrupt: before "
4393                                 "asc_execute_queue()\n");
4394                         asc_execute_queue(&boardp->waiting);
4395                 }
4396
4397                 /*
4398                  * Add to the list of requests that must be completed.
4399                  *
4400                  * 'done_scp' will always be NULL on the first iteration of
4401                  * this loop. 'last_scp' is set at the same time as 'done_scp'.
4402                  */
4403                 if (done_scp == NULL) {
4404                         done_scp = asc_dequeue_list(&boardp->done,
4405                                                 &last_scp, ASC_TID_ALL);
4406                 } else {
4407                         ASC_ASSERT(last_scp != NULL);
4408                         last_scp->host_scribble =
4409                             (unsigned char *)asc_dequeue_list(&boardp->
4410                                                               done,
4411                                                               &new_last_scp,
4412                                                               ASC_TID_ALL);
4413                         if (new_last_scp != NULL) {
4414                                 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4415                                 last_scp = new_last_scp;
4416                         }
4417                 }
4418         }
4419         spin_unlock_irqrestore(&boardp->lock, flags);
4420
4421         /*
4422          * If interrupts were enabled on entry, then they
4423          * are now enabled here.
4424          *
4425          * Complete all requests on the done list.
4426          */
4427
4428         asc_scsi_done_list(done_scp);
4429
4430         ASC_DBG(1, "advansys_interrupt: end\n");
4431         return result;
4432 }
4433
4434 static void
4435 advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc)
4436 {
4437         ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id;
4438         ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng;
4439
4440         if (sdev->lun == 0) {
4441                 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr;
4442                 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) {
4443                         asc_dvc->init_sdtr |= tid_bit;
4444                 } else {
4445                         asc_dvc->init_sdtr &= ~tid_bit;
4446                 }
4447
4448                 if (orig_init_sdtr != asc_dvc->init_sdtr)
4449                         AscAsyncFix(asc_dvc, sdev);
4450         }
4451
4452         if (sdev->tagged_supported) {
4453                 if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) {
4454                         if (sdev->lun == 0) {
4455                                 asc_dvc->cfg->can_tagged_qng |= tid_bit;
4456                                 asc_dvc->use_tagged_qng |= tid_bit;
4457                         }
4458                         scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
4459                                                 asc_dvc->max_dvc_qng[sdev->id]);
4460                 }
4461         } else {
4462                 if (sdev->lun == 0) {
4463                         asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
4464                         asc_dvc->use_tagged_qng &= ~tid_bit;
4465                 }
4466                 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
4467         }
4468
4469         if ((sdev->lun == 0) &&
4470             (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) {
4471                 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
4472                                  asc_dvc->cfg->disc_enable);
4473                 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
4474                                  asc_dvc->use_tagged_qng);
4475                 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
4476                                  asc_dvc->cfg->can_tagged_qng);
4477
4478                 asc_dvc->max_dvc_qng[sdev->id] =
4479                                         asc_dvc->cfg->max_tag_qng[sdev->id];
4480                 AscWriteLramByte(asc_dvc->iop_base,
4481                                  (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id),
4482                                  asc_dvc->max_dvc_qng[sdev->id]);
4483         }
4484 }
4485
4486 /*
4487  * Wide Transfers
4488  *
4489  * If the EEPROM enabled WDTR for the device and the device supports wide
4490  * bus (16 bit) transfers, then turn on the device's 'wdtr_able' bit and
4491  * write the new value to the microcode.
4492  */
4493 static void
4494 advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask)
4495 {
4496         unsigned short cfg_word;
4497         AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
4498         if ((cfg_word & tidmask) != 0)
4499                 return;
4500
4501         cfg_word |= tidmask;
4502         AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
4503
4504         /*
4505          * Clear the microcode SDTR and WDTR negotiation done indicators for
4506          * the target to cause it to negotiate with the new setting set above.
4507          * WDTR when accepted causes the target to enter asynchronous mode, so
4508          * SDTR must be negotiated.
4509          */
4510         AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
4511         cfg_word &= ~tidmask;
4512         AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
4513         AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
4514         cfg_word &= ~tidmask;
4515         AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
4516 }
4517
4518 /*
4519  * Synchronous Transfers
4520  *
4521  * If the EEPROM enabled SDTR for the device and the device
4522  * supports synchronous transfers, then turn on the device's
4523  * 'sdtr_able' bit. Write the new value to the microcode.
4524  */
4525 static void
4526 advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask)
4527 {
4528         unsigned short cfg_word;
4529         AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
4530         if ((cfg_word & tidmask) != 0)
4531                 return;
4532
4533         cfg_word |= tidmask;
4534         AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
4535
4536         /*
4537          * Clear the microcode "SDTR negotiation" done indicator for the
4538          * target to cause it to negotiate with the new setting set above.
4539          */
4540         AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
4541         cfg_word &= ~tidmask;
4542         AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
4543 }
4544
4545 /*
4546  * PPR (Parallel Protocol Request) Capable
4547  *
4548  * If the device supports DT mode, then it must be PPR capable.
4549  * The PPR message will be used in place of the SDTR and WDTR
4550  * messages to negotiate synchronous speed and offset, transfer
4551  * width, and protocol options.
4552  */
4553 static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc,
4554                                 AdvPortAddr iop_base, unsigned short tidmask)
4555 {
4556         AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
4557         adv_dvc->ppr_able |= tidmask;
4558         AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
4559 }
4560
4561 static void
4562 advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc)
4563 {
4564         AdvPortAddr iop_base = adv_dvc->iop_base;
4565         unsigned short tidmask = 1 << sdev->id;
4566
4567         if (sdev->lun == 0) {
4568                 /*
4569                  * Handle WDTR, SDTR, and Tag Queuing. If the feature
4570                  * is enabled in the EEPROM and the device supports the
4571                  * feature, then enable it in the microcode.
4572                  */
4573
4574                 if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr)
4575                         advansys_wide_enable_wdtr(iop_base, tidmask);
4576                 if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr)
4577                         advansys_wide_enable_sdtr(iop_base, tidmask);
4578                 if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr)
4579                         advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask);
4580
4581                 /*
4582                  * Tag Queuing is disabled for the BIOS which runs in polled
4583                  * mode and would see no benefit from Tag Queuing. Also by
4584                  * disabling Tag Queuing in the BIOS devices with Tag Queuing
4585                  * bugs will at least work with the BIOS.
4586                  */
4587                 if ((adv_dvc->tagqng_able & tidmask) &&
4588                     sdev->tagged_supported) {
4589                         unsigned short cfg_word;
4590                         AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
4591                         cfg_word |= tidmask;
4592                         AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
4593                                          cfg_word);
4594                         AdvWriteByteLram(iop_base,
4595                                          ASC_MC_NUMBER_OF_MAX_CMD + sdev->id,
4596                                          adv_dvc->max_dvc_qng);
4597                 }
4598         }
4599
4600         if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) {
4601                 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
4602                                         adv_dvc->max_dvc_qng);
4603         } else {
4604                 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
4605         }
4606 }
4607
4608 /*
4609  * Set the number of commands to queue per device for the
4610  * specified host adapter.
4611  */
4612 static int advansys_slave_configure(struct scsi_device *sdev)
4613 {
4614         asc_board_t *boardp = ASC_BOARDP(sdev->host);
4615         boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
4616
4617         /*
4618          * Save a pointer to the sdev and set its initial/maximum
4619          * queue depth.  Only save the pointer for a lun0 dev though.
4620          */
4621         if (sdev->lun == 0)
4622                 boardp->device[sdev->id] = sdev;
4623
4624         if (ASC_NARROW_BOARD(boardp))
4625                 advansys_narrow_slave_configure(sdev,
4626                                                 &boardp->dvc_var.asc_dvc_var);
4627         else
4628                 advansys_wide_slave_configure(sdev,
4629                                                 &boardp->dvc_var.adv_dvc_var);
4630
4631         return 0;
4632 }
4633
4634 /*
4635  * Complete all requests on the singly linked list pointed
4636  * to by 'scp'.
4637  *
4638  * Interrupts can be enabled on entry.
4639  */
4640 static void asc_scsi_done_list(struct scsi_cmnd *scp)
4641 {
4642         struct scsi_cmnd *tscp;
4643
4644         ASC_DBG(2, "asc_scsi_done_list: begin\n");
4645         while (scp != NULL) {
4646                 asc_board_t *boardp;
4647
4648                 ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong)scp);
4649                 tscp = REQPNEXT(scp);
4650                 scp->host_scribble = NULL;
4651
4652                 boardp = ASC_BOARDP(scp->device->host);
4653
4654                 if (scp->use_sg)
4655                         dma_unmap_sg(boardp->dev,
4656                                      (struct scatterlist *)scp->request_buffer,
4657                                      scp->use_sg, scp->sc_data_direction);
4658                 else if (scp->request_bufflen)
4659                         dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
4660                                          scp->request_bufflen,
4661                                          scp->sc_data_direction);
4662
4663                 ASC_STATS(scp->device->host, done);
4664                 ASC_ASSERT(scp->scsi_done != NULL);
4665
4666                 scp->scsi_done(scp);
4667
4668                 scp = tscp;
4669         }
4670         ASC_DBG(2, "asc_scsi_done_list: done\n");
4671         return;
4672 }
4673
4674 /*
4675  * Execute a single 'Scsi_Cmnd'.
4676  *
4677  * The function 'done' is called when the request has been completed.
4678  *
4679  * Scsi_Cmnd:
4680  *
4681  *  host - board controlling device
4682  *  device - device to send command
4683  *  target - target of device
4684  *  lun - lun of device
4685  *  cmd_len - length of SCSI CDB
4686  *  cmnd - buffer for SCSI 8, 10, or 12 byte CDB
4687  *  use_sg - if non-zero indicates scatter-gather request with use_sg elements
4688  *
4689  *  if (use_sg == 0) {
4690  *    request_buffer - buffer address for request
4691  *    request_bufflen - length of request buffer
4692  *  } else {
4693  *    request_buffer - pointer to scatterlist structure
4694  *  }
4695  *
4696  *  sense_buffer - sense command buffer
4697  *
4698  *  result (4 bytes of an int):
4699  *    Byte Meaning
4700  *    0 SCSI Status Byte Code
4701  *    1 SCSI One Byte Message Code
4702  *    2 Host Error Code
4703  *    3 Mid-Level Error Code
4704  *
4705  *  host driver fields:
4706  *    SCp - Scsi_Pointer used for command processing status
4707  *    scsi_done - used to save caller's done function
4708  *    host_scribble - used for pointer to another struct scsi_cmnd
4709  *
4710  * If this function returns ASC_NOERROR the request has been enqueued
4711  * on the board's 'active' queue and will be completed from the
4712  * interrupt handler.
4713  *
4714  * If this function returns ASC_NOERROR the request has been enqueued
4715  * on the board's 'done' queue and must be completed by the caller.
4716  *
4717  * If ASC_BUSY is returned the request will be enqueued by the
4718  * caller on the target's waiting queue and re-tried later.
4719  */
4720 static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
4721 {
4722         asc_board_t *boardp;
4723         ASC_DVC_VAR *asc_dvc_varp;
4724         ADV_DVC_VAR *adv_dvc_varp;
4725         ADV_SCSI_REQ_Q *adv_scsiqp;
4726         struct scsi_device *device;
4727         int ret;
4728
4729         ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
4730                  (ulong)scp, (ulong)scp->scsi_done);
4731
4732         boardp = ASC_BOARDP(scp->device->host);
4733         device = boardp->device[scp->device->id];
4734
4735         if (ASC_NARROW_BOARD(boardp)) {
4736                 /*
4737                  * Build and execute Narrow Board request.
4738                  */
4739
4740                 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4741
4742                 /*
4743                  * Build Asc Library request structure using the
4744                  * global structures 'asc_scsi_req' and 'asc_sg_head'.
4745                  *
4746                  * If an error is returned, then the request has been
4747                  * queued on the board done queue. It will be completed
4748                  * by the caller.
4749                  *
4750                  * asc_build_req() can not return ASC_BUSY.
4751                  */
4752                 if (asc_build_req(boardp, scp) == ASC_ERROR) {
4753                         ASC_STATS(scp->device->host, build_error);
4754                         return ASC_ERROR;
4755                 }
4756
4757                 /*
4758                  * Execute the command. If there is no error, add the command
4759                  * to the active queue.
4760                  */
4761                 switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
4762                 case ASC_NOERROR:
4763                         ASC_STATS(scp->device->host, exe_noerror);
4764                         /*
4765                          * Increment monotonically increasing per device
4766                          * successful request counter. Wrapping doesn't matter.
4767                          */
4768                         boardp->reqcnt[scp->device->id]++;
4769                         asc_enqueue(&boardp->active, scp, ASC_BACK);
4770                         ASC_DBG(1, "asc_execute_scsi_cmnd: AscExeScsiQueue(), "
4771                                 "ASC_NOERROR\n");
4772                         break;
4773                 case ASC_BUSY:
4774                         /*
4775                          * Caller will enqueue request on the target's waiting
4776                          * queue and retry later.
4777                          */
4778                         ASC_STATS(scp->device->host, exe_busy);
4779                         break;
4780                 case ASC_ERROR:
4781                         ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
4782                                 "AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
4783                                 boardp->id, asc_dvc_varp->err_code);
4784                         ASC_STATS(scp->device->host, exe_error);
4785                         scp->result = HOST_BYTE(DID_ERROR);
4786                         asc_enqueue(&boardp->done, scp, ASC_BACK);
4787                         break;
4788                 default:
4789                         ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
4790                                 "AscExeScsiQueue() unknown, err_code 0x%x\n",
4791                                 boardp->id, asc_dvc_varp->err_code);
4792                         ASC_STATS(scp->device->host, exe_unknown);
4793                         scp->result = HOST_BYTE(DID_ERROR);
4794                         asc_enqueue(&boardp->done, scp, ASC_BACK);
4795                         break;
4796                 }
4797         } else {
4798                 /*
4799                  * Build and execute Wide Board request.
4800                  */
4801                 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4802
4803                 /*
4804                  * Build and get a pointer to an Adv Library request structure.
4805                  *
4806                  * If the request is successfully built then send it below,
4807                  * otherwise return with an error.
4808                  */
4809                 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
4810                 case ASC_NOERROR:
4811                         ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req "
4812                                 "ASC_NOERROR\n");
4813                         break;
4814                 case ASC_BUSY:
4815                         ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
4816                                 "ASC_BUSY\n");
4817                         /*
4818                          * If busy is returned the request has not been
4819                          * enqueued.  It will be enqueued by the caller on the
4820                          * target's waiting queue and retried later.
4821                          *
4822                          * The asc_stats fields 'adv_build_noreq' and
4823                          * 'adv_build_nosg' count wide board busy conditions.
4824                          * They are updated in adv_build_req and
4825                          * adv_get_sglist, respectively.
4826                          */
4827                         return ASC_BUSY;
4828                 case ASC_ERROR:
4829                         /* 
4830                          * If an error is returned, then the request has been
4831                          * queued on the board done queue. It will be completed
4832                          * by the caller.
4833                          */
4834                 default:
4835                         ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
4836                                 "ASC_ERROR\n");
4837                         ASC_STATS(scp->device->host, build_error);
4838                         return ASC_ERROR;
4839                 }
4840
4841                 /*
4842                  * Execute the command. If there is no error, add the command
4843                  * to the active queue.
4844                  */
4845                 switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
4846                 case ASC_NOERROR:
4847                         ASC_STATS(scp->device->host, exe_noerror);
4848                         /*
4849                          * Increment monotonically increasing per device
4850                          * successful request counter. Wrapping doesn't matter.
4851                          */
4852                         boardp->reqcnt[scp->device->id]++;
4853                         asc_enqueue(&boardp->active, scp, ASC_BACK);
4854                         ASC_DBG(1, "asc_execute_scsi_cmnd: AdvExeScsiQueue(), "
4855                                 "ASC_NOERROR\n");
4856                         break;
4857                 case ASC_BUSY:
4858                         /*
4859                          * Caller will enqueue request on the target's waiting
4860                          * queue and retry later.
4861                          */
4862                         ASC_STATS(scp->device->host, exe_busy);
4863                         break;
4864                 case ASC_ERROR:
4865                         ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
4866                                 "AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
4867                                 boardp->id, adv_dvc_varp->err_code);
4868                         ASC_STATS(scp->device->host, exe_error);
4869                         scp->result = HOST_BYTE(DID_ERROR);
4870                         asc_enqueue(&boardp->done, scp, ASC_BACK);
4871                         break;
4872                 default:
4873                         ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
4874                                 "AdvExeScsiQueue() unknown, err_code 0x%x\n",
4875                                 boardp->id, adv_dvc_varp->err_code);
4876                         ASC_STATS(scp->device->host, exe_unknown);
4877                         scp->result = HOST_BYTE(DID_ERROR);
4878                         asc_enqueue(&boardp->done, scp, ASC_BACK);
4879                         break;
4880                 }
4881         }
4882
4883         ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
4884         return ret;
4885 }
4886
4887 /*
4888  * Build a request structure for the Asc Library (Narrow Board).
4889  *
4890  * The global structures 'asc_scsi_q' and 'asc_sg_head' are
4891  * used to build the request.
4892  *
4893  * If an error occurs, then queue the request on the board done
4894  * queue and return ASC_ERROR.
4895  */
4896 static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
4897 {
4898         /*
4899          * Mutually exclusive access is required to 'asc_scsi_q' and
4900          * 'asc_sg_head' until after the request is started.
4901          */
4902         memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
4903
4904         /*
4905          * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
4906          */
4907         asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
4908
4909         /*
4910          * Build the ASC_SCSI_Q request.
4911          *
4912          * For narrow boards a CDB length maximum of 12 bytes
4913          * is supported.
4914          */
4915         if (scp->cmd_len > ASC_MAX_CDB_LEN) {
4916                 ASC_PRINT3("asc_build_req: board %d: cmd_len %d > "
4917                         "ASC_MAX_CDB_LEN %d\n", boardp->id, scp->cmd_len,
4918                         ASC_MAX_CDB_LEN);
4919                 scp->result = HOST_BYTE(DID_ERROR);
4920                 asc_enqueue(&boardp->done, scp, ASC_BACK);
4921                 return ASC_ERROR;
4922         }
4923         asc_scsi_q.cdbptr = &scp->cmnd[0];
4924         asc_scsi_q.q2.cdb_len = scp->cmd_len;
4925         asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
4926         asc_scsi_q.q1.target_lun = scp->device->lun;
4927         asc_scsi_q.q2.target_ix =
4928             ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
4929         asc_scsi_q.q1.sense_addr =
4930             cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
4931         asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
4932
4933         /*
4934          * If there are any outstanding requests for the current target,
4935          * then every 255th request send an ORDERED request. This heuristic
4936          * tries to retain the benefit of request sorting while preventing
4937          * request starvation. 255 is the max number of tags or pending commands
4938          * a device may have outstanding.
4939          *
4940          * The request count is incremented below for every successfully
4941          * started request.
4942          *
4943          */
4944         if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
4945             (boardp->reqcnt[scp->device->id] % 255) == 0) {
4946                 asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG;
4947         } else {
4948                 asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG;
4949         }
4950
4951         /*
4952          * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
4953          * buffer command.
4954          */
4955         if (scp->use_sg == 0) {
4956                 /*
4957                  * CDB request of single contiguous buffer.
4958                  */
4959                 ASC_STATS(scp->device->host, cont_cnt);
4960                 scp->SCp.dma_handle = scp->request_bufflen ?
4961                     dma_map_single(boardp->dev, scp->request_buffer,
4962                                    scp->request_bufflen,
4963                                    scp->sc_data_direction) : 0;
4964                 asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
4965                 asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
4966                 ASC_STATS_ADD(scp->device->host, cont_xfer,
4967                               ASC_CEILING(scp->request_bufflen, 512));
4968                 asc_scsi_q.q1.sg_queue_cnt = 0;
4969                 asc_scsi_q.sg_head = NULL;
4970         } else {
4971                 /*
4972                  * CDB scatter-gather request list.
4973                  */
4974                 int sgcnt;
4975                 int use_sg;
4976                 struct scatterlist *slp;
4977
4978                 slp = (struct scatterlist *)scp->request_buffer;
4979                 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
4980                                     scp->sc_data_direction);
4981
4982                 if (use_sg > scp->device->host->sg_tablesize) {
4983                         ASC_PRINT3("asc_build_req: board %d: use_sg %d > "
4984                                    "sg_tablesize %d\n", boardp->id, use_sg,
4985                                    scp->device->host->sg_tablesize);
4986                         dma_unmap_sg(boardp->dev, slp, scp->use_sg,
4987                                      scp->sc_data_direction);
4988                         scp->result = HOST_BYTE(DID_ERROR);
4989                         asc_enqueue(&boardp->done, scp, ASC_BACK);
4990                         return ASC_ERROR;
4991                 }
4992
4993                 ASC_STATS(scp->device->host, sg_cnt);
4994
4995                 /*
4996                  * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
4997                  * structure to point to it.
4998                  */
4999                 memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
5000
5001                 asc_scsi_q.q1.cntl |= QC_SG_HEAD;
5002                 asc_scsi_q.sg_head = &asc_sg_head;
5003                 asc_scsi_q.q1.data_cnt = 0;
5004                 asc_scsi_q.q1.data_addr = 0;
5005                 /* This is a byte value, otherwise it would need to be swapped. */
5006                 asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg;
5007                 ASC_STATS_ADD(scp->device->host, sg_elem,
5008                               asc_sg_head.entry_cnt);
5009
5010                 /*
5011                  * Convert scatter-gather list into ASC_SG_HEAD list.
5012                  */
5013                 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
5014                         asc_sg_head.sg_list[sgcnt].addr =
5015                             cpu_to_le32(sg_dma_address(slp));
5016                         asc_sg_head.sg_list[sgcnt].bytes =
5017                             cpu_to_le32(sg_dma_len(slp));
5018                         ASC_STATS_ADD(scp->device->host, sg_xfer,
5019                                       ASC_CEILING(sg_dma_len(slp), 512));
5020                 }
5021         }
5022
5023         ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
5024         ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
5025
5026         return ASC_NOERROR;
5027 }
5028
5029 /*
5030  * Build a request structure for the Adv Library (Wide Board).
5031  *
5032  * If an adv_req_t can not be allocated to issue the request,
5033  * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
5034  *
5035  * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
5036  * microcode for DMA addresses or math operations are byte swapped
5037  * to little-endian order.
5038  */
5039 static int
5040 adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
5041               ADV_SCSI_REQ_Q **adv_scsiqpp)
5042 {
5043         adv_req_t *reqp;
5044         ADV_SCSI_REQ_Q *scsiqp;
5045         int i;
5046         int ret;
5047
5048         /*
5049          * Allocate an adv_req_t structure from the board to execute
5050          * the command.
5051          */
5052         if (boardp->adv_reqp == NULL) {
5053                 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
5054                 ASC_STATS(scp->device->host, adv_build_noreq);
5055                 return ASC_BUSY;
5056         } else {
5057                 reqp = boardp->adv_reqp;
5058                 boardp->adv_reqp = reqp->next_reqp;
5059                 reqp->next_reqp = NULL;
5060         }
5061
5062         /*
5063          * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
5064          */
5065         scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
5066
5067         /*
5068          * Initialize the structure.
5069          */
5070         scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
5071
5072         /*
5073          * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
5074          */
5075         scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
5076
5077         /*
5078          * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
5079          */
5080         reqp->cmndp = scp;
5081
5082         /*
5083          * Build the ADV_SCSI_REQ_Q request.
5084          */
5085
5086         /*
5087          * Set CDB length and copy it to the request structure.
5088          * For wide  boards a CDB length maximum of 16 bytes
5089          * is supported.
5090          */
5091         if (scp->cmd_len > ADV_MAX_CDB_LEN) {
5092                 ASC_PRINT3
5093                     ("adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN  %d\n",
5094                      boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN);
5095                 scp->result = HOST_BYTE(DID_ERROR);
5096                 asc_enqueue(&boardp->done, scp, ASC_BACK);
5097                 return ASC_ERROR;
5098         }
5099         scsiqp->cdb_len = scp->cmd_len;
5100         /* Copy first 12 CDB bytes to cdb[]. */
5101         for (i = 0; i < scp->cmd_len && i < 12; i++) {
5102                 scsiqp->cdb[i] = scp->cmnd[i];
5103         }
5104         /* Copy last 4 CDB bytes, if present, to cdb16[]. */
5105         for (; i < scp->cmd_len; i++) {
5106                 scsiqp->cdb16[i - 12] = scp->cmnd[i];
5107         }
5108
5109         scsiqp->target_id = scp->device->id;
5110         scsiqp->target_lun = scp->device->lun;
5111
5112         scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
5113         scsiqp->sense_len = sizeof(scp->sense_buffer);
5114
5115         /*
5116          * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
5117          * buffer command.
5118          */
5119
5120         scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
5121         scsiqp->vdata_addr = scp->request_buffer;
5122         scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
5123
5124         if (scp->use_sg == 0) {
5125                 /*
5126                  * CDB request of single contiguous buffer.
5127                  */
5128                 reqp->sgblkp = NULL;
5129                 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
5130                 if (scp->request_bufflen) {
5131                         scsiqp->vdata_addr = scp->request_buffer;
5132                         scp->SCp.dma_handle =
5133                             dma_map_single(boardp->dev, scp->request_buffer,
5134                                            scp->request_bufflen,
5135                                            scp->sc_data_direction);
5136                 } else {
5137                         scsiqp->vdata_addr = NULL;
5138                         scp->SCp.dma_handle = 0;
5139                 }
5140                 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
5141                 scsiqp->sg_list_ptr = NULL;
5142                 scsiqp->sg_real_addr = 0;
5143                 ASC_STATS(scp->device->host, cont_cnt);
5144                 ASC_STATS_ADD(scp->device->host, cont_xfer,
5145                               ASC_CEILING(scp->request_bufflen, 512));
5146         } else {
5147                 /*
5148                  * CDB scatter-gather request list.
5149                  */
5150                 struct scatterlist *slp;
5151                 int use_sg;
5152
5153                 slp = (struct scatterlist *)scp->request_buffer;
5154                 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
5155                                     scp->sc_data_direction);
5156
5157                 if (use_sg > ADV_MAX_SG_LIST) {
5158                         ASC_PRINT3("adv_build_req: board %d: use_sg %d > "
5159                                    "ADV_MAX_SG_LIST %d\n", boardp->id, use_sg,
5160                                    scp->device->host->sg_tablesize);
5161                         dma_unmap_sg(boardp->dev, slp, scp->use_sg,
5162                                      scp->sc_data_direction);
5163                         scp->result = HOST_BYTE(DID_ERROR);
5164                         asc_enqueue(&boardp->done, scp, ASC_BACK);
5165
5166                         /*
5167                          * Free the 'adv_req_t' structure by adding it back
5168                          * to the board free list.
5169                          */
5170                         reqp->next_reqp = boardp->adv_reqp;
5171                         boardp->adv_reqp = reqp;
5172
5173                         return ASC_ERROR;
5174                 }
5175
5176                 ret = adv_get_sglist(boardp, reqp, scp, use_sg);
5177                 if (ret != ADV_SUCCESS) {
5178                         /*
5179                          * Free the adv_req_t structure by adding it back to
5180                          * the board free list.
5181                          */
5182                         reqp->next_reqp = boardp->adv_reqp;
5183                         boardp->adv_reqp = reqp;
5184
5185                         return ret;
5186                 }
5187
5188                 ASC_STATS(scp->device->host, sg_cnt);
5189                 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
5190         }
5191
5192         ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5193         ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
5194
5195         *adv_scsiqpp = scsiqp;
5196
5197         return ASC_NOERROR;
5198 }
5199
5200 /*
5201  * Build scatter-gather list for Adv Library (Wide Board).
5202  *
5203  * Additional ADV_SG_BLOCK structures will need to be allocated
5204  * if the total number of scatter-gather elements exceeds
5205  * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
5206  * assumed to be physically contiguous.
5207  *
5208  * Return:
5209  *      ADV_SUCCESS(1) - SG List successfully created
5210  *      ADV_ERROR(-1) - SG List creation failed
5211  */
5212 static int
5213 adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
5214                int use_sg)
5215 {
5216         adv_sgblk_t *sgblkp;
5217         ADV_SCSI_REQ_Q *scsiqp;
5218         struct scatterlist *slp;
5219         int sg_elem_cnt;
5220         ADV_SG_BLOCK *sg_block, *prev_sg_block;
5221         ADV_PADDR sg_block_paddr;
5222         int i;
5223
5224         scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
5225         slp = (struct scatterlist *)scp->request_buffer;
5226         sg_elem_cnt = use_sg;
5227         prev_sg_block = NULL;
5228         reqp->sgblkp = NULL;
5229
5230         do {
5231                 /*
5232                  * Allocate a 'adv_sgblk_t' structure from the board free
5233                  * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
5234                  * (15) scatter-gather elements.
5235                  */
5236                 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
5237                         ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
5238                         ASC_STATS(scp->device->host, adv_build_nosg);
5239
5240                         /*
5241                          * Allocation failed. Free 'adv_sgblk_t' structures already
5242                          * allocated for the request.
5243                          */
5244                         while ((sgblkp = reqp->sgblkp) != NULL) {
5245                                 /* Remove 'sgblkp' from the request list. */
5246                                 reqp->sgblkp = sgblkp->next_sgblkp;
5247
5248                                 /* Add 'sgblkp' to the board free list. */
5249                                 sgblkp->next_sgblkp = boardp->adv_sgblkp;
5250                                 boardp->adv_sgblkp = sgblkp;
5251                         }
5252                         return ASC_BUSY;
5253                 } else {
5254                         /* Complete 'adv_sgblk_t' board allocation. */
5255                         boardp->adv_sgblkp = sgblkp->next_sgblkp;
5256                         sgblkp->next_sgblkp = NULL;
5257
5258                         /*
5259                          * Get 8 byte aligned virtual and physical addresses for
5260                          * the allocated ADV_SG_BLOCK structure.
5261                          */
5262                         sg_block =
5263                             (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
5264                         sg_block_paddr = virt_to_bus(sg_block);
5265
5266                         /*
5267                          * Check if this is the first 'adv_sgblk_t' for the request.
5268                          */
5269                         if (reqp->sgblkp == NULL) {
5270                                 /* Request's first scatter-gather block. */
5271                                 reqp->sgblkp = sgblkp;
5272
5273                                 /*
5274                                  * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
5275                                  * address pointers.
5276                                  */
5277                                 scsiqp->sg_list_ptr = sg_block;
5278                                 scsiqp->sg_real_addr =
5279                                     cpu_to_le32(sg_block_paddr);
5280                         } else {
5281                                 /* Request's second or later scatter-gather block. */
5282                                 sgblkp->next_sgblkp = reqp->sgblkp;
5283                                 reqp->sgblkp = sgblkp;
5284
5285                                 /*
5286                                  * Point the previous ADV_SG_BLOCK structure to
5287                                  * the newly allocated ADV_SG_BLOCK structure.
5288                                  */
5289                                 ASC_ASSERT(prev_sg_block != NULL);
5290                                 prev_sg_block->sg_ptr =
5291                                     cpu_to_le32(sg_block_paddr);
5292                         }
5293                 }
5294
5295                 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
5296                         sg_block->sg_list[i].sg_addr =
5297                             cpu_to_le32(sg_dma_address(slp));
5298                         sg_block->sg_list[i].sg_count =
5299                             cpu_to_le32(sg_dma_len(slp));
5300                         ASC_STATS_ADD(scp->device->host, sg_xfer,
5301                                       ASC_CEILING(sg_dma_len(slp), 512));
5302
5303                         if (--sg_elem_cnt == 0) {       /* Last ADV_SG_BLOCK and scatter-gather entry. */
5304                                 sg_block->sg_cnt = i + 1;
5305                                 sg_block->sg_ptr = 0L;  /* Last ADV_SG_BLOCK in list. */
5306                                 return ADV_SUCCESS;
5307                         }
5308                         slp++;
5309                 }
5310                 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
5311                 prev_sg_block = sg_block;
5312         }
5313         while (1);
5314         /* NOTREACHED */
5315 }
5316
5317 /*
5318  * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
5319  *
5320  * Interrupt callback function for the Narrow SCSI Asc Library.
5321  */
5322 static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
5323 {
5324         asc_board_t *boardp;
5325         struct scsi_cmnd *scp;
5326         struct Scsi_Host *shost;
5327
5328         ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
5329                  (ulong)asc_dvc_varp, (ulong)qdonep);
5330         ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
5331
5332         /*
5333          * Get the struct scsi_cmnd structure and Scsi_Host structure for the
5334          * command that has been completed.
5335          */
5336         scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
5337         ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong)scp);
5338
5339         if (scp == NULL) {
5340                 ASC_PRINT("asc_isr_callback: scp is NULL\n");
5341                 return;
5342         }
5343         ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5344
5345         shost = scp->device->host;
5346         ASC_STATS(shost, callback);
5347         ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost);
5348
5349         /*
5350          * If the request isn't found on the active queue, it may
5351          * have been removed to handle a reset request.
5352          * Display a message and return.
5353          */
5354         boardp = ASC_BOARDP(shost);
5355         ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
5356         if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
5357                 ASC_PRINT2
5358                     ("asc_isr_callback: board %d: scp 0x%lx not on active queue\n",
5359                      boardp->id, (ulong)scp);
5360                 return;
5361         }
5362
5363         /*
5364          * 'qdonep' contains the command's ending status.
5365          */
5366         switch (qdonep->d3.done_stat) {
5367         case QD_NO_ERROR:
5368                 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
5369                 scp->result = 0;
5370
5371                 /*
5372                  * Check for an underrun condition.
5373                  *
5374                  * If there was no error and an underrun condition, then
5375                  * return the number of underrun bytes.
5376                  */
5377                 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
5378                     qdonep->remain_bytes <= scp->request_bufflen) {
5379                         ASC_DBG1(1,
5380                                  "asc_isr_callback: underrun condition %u bytes\n",
5381                                  (unsigned)qdonep->remain_bytes);
5382                         scp->resid = qdonep->remain_bytes;
5383                 }
5384                 break;
5385
5386         case QD_WITH_ERROR:
5387                 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
5388                 switch (qdonep->d3.host_stat) {
5389                 case QHSTA_NO_ERROR:
5390                         if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
5391                                 ASC_DBG(2,
5392                                         "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
5393                                 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
5394                                                   sizeof(scp->sense_buffer));
5395                                 /*
5396                                  * Note: The 'status_byte()' macro used by target drivers
5397                                  * defined in scsi.h shifts the status byte returned by
5398                                  * host drivers right by 1 bit. This is why target drivers
5399                                  * also use right shifted status byte definitions. For
5400                                  * instance target drivers use CHECK_CONDITION, defined to
5401                                  * 0x1, instead of the SCSI defined check condition value
5402                                  * of 0x2. Host drivers are supposed to return the status
5403                                  * byte as it is defined by SCSI.
5404                                  */
5405                                 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
5406                                     STATUS_BYTE(qdonep->d3.scsi_stat);
5407                         } else {
5408                                 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
5409                         }
5410                         break;
5411
5412                 default:
5413                         /* QHSTA error occurred */
5414                         ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
5415                                  qdonep->d3.host_stat);
5416                         scp->result = HOST_BYTE(DID_BAD_TARGET);
5417                         break;
5418                 }
5419                 break;
5420
5421         case QD_ABORTED_BY_HOST:
5422                 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
5423                 scp->result =
5424                     HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
5425                                                     scsi_msg) |
5426                     STATUS_BYTE(qdonep->d3.scsi_stat);
5427                 break;
5428
5429         default:
5430                 ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n",
5431                          qdonep->d3.done_stat);
5432                 scp->result =
5433                     HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
5434                                                     scsi_msg) |
5435                     STATUS_BYTE(qdonep->d3.scsi_stat);
5436                 break;
5437         }
5438
5439         /*
5440          * If the 'init_tidmask' bit isn't already set for the target and the
5441          * current request finished normally, then set the bit for the target
5442          * to indicate that a device is present.
5443          */
5444         if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
5445             qdonep->d3.done_stat == QD_NO_ERROR &&
5446             qdonep->d3.host_stat == QHSTA_NO_ERROR) {
5447                 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
5448         }
5449
5450         /*
5451          * Because interrupts may be enabled by the 'struct scsi_cmnd' done
5452          * function, add the command to the end of the board's done queue.
5453          * The done function for the command will be called from
5454          * advansys_interrupt().
5455          */
5456         asc_enqueue(&boardp->done, scp, ASC_BACK);
5457
5458         return;
5459 }
5460
5461 /*
5462  * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
5463  *
5464  * Callback function for the Wide SCSI Adv Library.
5465  */
5466 static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
5467 {
5468         asc_board_t *boardp;
5469         adv_req_t *reqp;
5470         adv_sgblk_t *sgblkp;
5471         struct scsi_cmnd *scp;
5472         struct Scsi_Host *shost;
5473         ADV_DCNT resid_cnt;
5474
5475         ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
5476                  (ulong)adv_dvc_varp, (ulong)scsiqp);
5477         ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5478
5479         /*
5480          * Get the adv_req_t structure for the command that has been
5481          * completed. The adv_req_t structure actually contains the
5482          * completed ADV_SCSI_REQ_Q structure.
5483          */
5484         reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr);
5485         ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong)reqp);
5486         if (reqp == NULL) {
5487                 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
5488                 return;
5489         }
5490
5491         /*
5492          * Get the struct scsi_cmnd structure and Scsi_Host structure for the
5493          * command that has been completed.
5494          *
5495          * Note: The adv_req_t request structure and adv_sgblk_t structure,
5496          * if any, are dropped, because a board structure pointer can not be
5497          * determined.
5498          */
5499         scp = reqp->cmndp;
5500         ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong)scp);
5501         if (scp == NULL) {
5502                 ASC_PRINT
5503                     ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
5504                 return;
5505         }
5506         ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5507
5508         shost = scp->device->host;
5509         ASC_STATS(shost, callback);
5510         ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost);
5511
5512         /*
5513          * If the request isn't found on the active queue, it may have been
5514          * removed to handle a reset request. Display a message and return.
5515          *
5516          * Note: Because the structure may still be in use don't attempt
5517          * to free the adv_req_t and adv_sgblk_t, if any, structures.
5518          */
5519         boardp = ASC_BOARDP(shost);
5520         ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
5521         if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
5522                 ASC_PRINT2
5523                     ("adv_isr_callback: board %d: scp 0x%lx not on active queue\n",
5524                      boardp->id, (ulong)scp);
5525                 return;
5526         }
5527
5528         /*
5529          * 'done_status' contains the command's ending status.
5530          */
5531         switch (scsiqp->done_status) {
5532         case QD_NO_ERROR:
5533                 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
5534                 scp->result = 0;
5535
5536                 /*
5537                  * Check for an underrun condition.
5538                  *
5539                  * If there was no error and an underrun condition, then
5540                  * then return the number of underrun bytes.
5541                  */
5542                 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
5543                 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
5544                     resid_cnt <= scp->request_bufflen) {
5545                         ASC_DBG1(1,
5546                                  "adv_isr_callback: underrun condition %lu bytes\n",
5547                                  (ulong)resid_cnt);
5548                         scp->resid = resid_cnt;
5549                 }
5550                 break;
5551
5552         case QD_WITH_ERROR:
5553                 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
5554                 switch (scsiqp->host_status) {
5555                 case QHSTA_NO_ERROR:
5556                         if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
5557                                 ASC_DBG(2,
5558                                         "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
5559                                 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
5560                                                   sizeof(scp->sense_buffer));
5561                                 /*
5562                                  * Note: The 'status_byte()' macro used by target drivers
5563                                  * defined in scsi.h shifts the status byte returned by
5564                                  * host drivers right by 1 bit. This is why target drivers
5565                                  * also use right shifted status byte definitions. For
5566                                  * instance target drivers use CHECK_CONDITION, defined to
5567                                  * 0x1, instead of the SCSI defined check condition value
5568                                  * of 0x2. Host drivers are supposed to return the status
5569                                  * byte as it is defined by SCSI.
5570                                  */
5571                                 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
5572                                     STATUS_BYTE(scsiqp->scsi_status);
5573                         } else {
5574                                 scp->result = STATUS_BYTE(scsiqp->scsi_status);
5575                         }
5576                         break;
5577
5578                 default:
5579                         /* Some other QHSTA error occurred. */
5580                         ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
5581                                  scsiqp->host_status);
5582                         scp->result = HOST_BYTE(DID_BAD_TARGET);
5583                         break;
5584                 }
5585                 break;
5586
5587         case QD_ABORTED_BY_HOST:
5588                 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
5589                 scp->result =
5590                     HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
5591                 break;
5592
5593         default:
5594                 ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n",
5595                          scsiqp->done_status);
5596                 scp->result =
5597                     HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
5598                 break;
5599         }
5600
5601         /*
5602          * If the 'init_tidmask' bit isn't already set for the target and the
5603          * current request finished normally, then set the bit for the target
5604          * to indicate that a device is present.
5605          */
5606         if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
5607             scsiqp->done_status == QD_NO_ERROR &&
5608             scsiqp->host_status == QHSTA_NO_ERROR) {
5609                 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
5610         }
5611
5612         /*
5613          * Because interrupts may be enabled by the 'struct scsi_cmnd' done
5614          * function, add the command to the end of the board's done queue.
5615          * The done function for the command will be called from
5616          * advansys_interrupt().
5617          */
5618         asc_enqueue(&boardp->done, scp, ASC_BACK);
5619
5620         /*
5621          * Free all 'adv_sgblk_t' structures allocated for the request.
5622          */
5623         while ((sgblkp = reqp->sgblkp) != NULL) {
5624                 /* Remove 'sgblkp' from the request list. */
5625                 reqp->sgblkp = sgblkp->next_sgblkp;
5626
5627                 /* Add 'sgblkp' to the board free list. */
5628                 sgblkp->next_sgblkp = boardp->adv_sgblkp;
5629                 boardp->adv_sgblkp = sgblkp;
5630         }
5631
5632         /*
5633          * Free the adv_req_t structure used with the command by adding
5634          * it back to the board free list.
5635          */
5636         reqp->next_reqp = boardp->adv_reqp;
5637         boardp->adv_reqp = reqp;
5638
5639         ASC_DBG(1, "adv_isr_callback: done\n");
5640
5641         return;
5642 }
5643
5644 /*
5645  * adv_async_callback() - Adv Library asynchronous event callback function.
5646  */
5647 static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
5648 {
5649         switch (code) {
5650         case ADV_ASYNC_SCSI_BUS_RESET_DET:
5651                 /*
5652                  * The firmware detected a SCSI Bus reset.
5653                  */
5654                 ASC_DBG(0,
5655                         "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
5656                 break;
5657
5658         case ADV_ASYNC_RDMA_FAILURE:
5659                 /*
5660                  * Handle RDMA failure by resetting the SCSI Bus and
5661                  * possibly the chip if it is unresponsive. Log the error
5662                  * with a unique code.
5663                  */
5664                 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
5665                 AdvResetChipAndSB(adv_dvc_varp);
5666                 break;
5667
5668         case ADV_HOST_SCSI_BUS_RESET:
5669                 /*
5670                  * Host generated SCSI bus reset occurred.
5671                  */
5672                 ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
5673                 break;
5674
5675         default:
5676                 ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
5677                 break;
5678         }
5679 }
5680
5681 /*
5682  * Add a 'REQP' to the end of specified queue. Set 'tidmask'
5683  * to indicate a command is queued for the device.
5684  *
5685  * 'flag' may be either ASC_FRONT or ASC_BACK.
5686  *
5687  * 'REQPNEXT(reqp)' returns reqp's next pointer.
5688  */
5689 static void asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
5690 {
5691         int tid;
5692
5693         ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n",
5694                  (ulong)ascq, (ulong)reqp, flag);
5695         ASC_ASSERT(reqp != NULL);
5696         ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
5697         tid = REQPTID(reqp);
5698         ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5699         if (flag == ASC_FRONT) {
5700                 reqp->host_scribble = (unsigned char *)ascq->q_first[tid];
5701                 ascq->q_first[tid] = reqp;
5702                 /* If the queue was empty, set the last pointer. */
5703                 if (ascq->q_last[tid] == NULL) {
5704                         ascq->q_last[tid] = reqp;
5705                 }
5706         } else {                /* ASC_BACK */
5707                 if (ascq->q_last[tid] != NULL) {
5708                         ascq->q_last[tid]->host_scribble =
5709                             (unsigned char *)reqp;
5710                 }
5711                 ascq->q_last[tid] = reqp;
5712                 reqp->host_scribble = NULL;
5713                 /* If the queue was empty, set the first pointer. */
5714                 if (ascq->q_first[tid] == NULL) {
5715                         ascq->q_first[tid] = reqp;
5716                 }
5717         }
5718         /* The queue has at least one entry, set its bit. */
5719         ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
5720 #ifdef ADVANSYS_STATS
5721         /* Maintain request queue statistics. */
5722         ascq->q_tot_cnt[tid]++;
5723         ascq->q_cur_cnt[tid]++;
5724         if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
5725                 ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
5726                 ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
5727                          tid, ascq->q_max_cnt[tid]);
5728         }
5729         REQPTIME(reqp) = REQTIMESTAMP();
5730 #endif /* ADVANSYS_STATS */
5731         ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong)reqp);
5732         return;
5733 }
5734
5735 /*
5736  * Return first queued 'REQP' on the specified queue for
5737  * the specified target device. Clear the 'tidmask' bit for
5738  * the device if no more commands are left queued for it.
5739  *
5740  * 'REQPNEXT(reqp)' returns reqp's next pointer.
5741  */
5742 static REQP asc_dequeue(asc_queue_t *ascq, int tid)
5743 {
5744         REQP reqp;
5745
5746         ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
5747         ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5748         if ((reqp = ascq->q_first[tid]) != NULL) {
5749                 ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
5750                 ascq->q_first[tid] = REQPNEXT(reqp);
5751                 /* If the queue is empty, clear its bit and the last pointer. */
5752                 if (ascq->q_first[tid] == NULL) {
5753                         ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5754                         ASC_ASSERT(ascq->q_last[tid] == reqp);
5755                         ascq->q_last[tid] = NULL;
5756                 }
5757 #ifdef ADVANSYS_STATS
5758                 /* Maintain request queue statistics. */
5759                 ascq->q_cur_cnt[tid]--;
5760                 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
5761                 REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
5762 #endif /* ADVANSYS_STATS */
5763         }
5764         ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong)reqp);
5765         return reqp;
5766 }
5767
5768 /*
5769  * Return a pointer to a singly linked list of all the requests queued
5770  * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
5771  *
5772  * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
5773  * the last request returned in the singly linked list.
5774  *
5775  * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
5776  * then all queued requests are concatenated into one list and
5777  * returned.
5778  *
5779  * Note: If 'lastpp' is used to append a new list to the end of
5780  * an old list, only change the old list last pointer if '*lastpp'
5781  * (or the function return value) is not NULL, i.e. use a temporary
5782  * variable for 'lastpp' and check its value after the function return
5783  * before assigning it to the list last pointer.
5784  *
5785  * Unfortunately collecting queuing time statistics adds overhead to
5786  * the function that isn't inherent to the function's algorithm.
5787  */
5788 static REQP asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
5789 {
5790         REQP firstp, lastp;
5791         int i;
5792
5793         ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
5794         ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
5795
5796         /*
5797          * If 'tid' is not ASC_TID_ALL, return requests only for
5798          * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
5799          * requests for all tids.
5800          */
5801         if (tid != ASC_TID_ALL) {
5802                 /* Return all requests for the specified 'tid'. */
5803                 if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
5804                         /* List is empty; Set first and last return pointers to NULL. */
5805                         firstp = lastp = NULL;
5806                 } else {
5807                         firstp = ascq->q_first[tid];
5808                         lastp = ascq->q_last[tid];
5809                         ascq->q_first[tid] = ascq->q_last[tid] = NULL;
5810                         ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5811 #ifdef ADVANSYS_STATS
5812                         {
5813                                 REQP reqp;
5814                                 ascq->q_cur_cnt[tid] = 0;
5815                                 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
5816                                         REQTIMESTAT("asc_dequeue_list", ascq,
5817                                                     reqp, tid);
5818                                 }
5819                         }
5820 #endif /* ADVANSYS_STATS */
5821                 }
5822         } else {
5823                 /* Return all requests for all tids. */
5824                 firstp = lastp = NULL;
5825                 for (i = 0; i <= ADV_MAX_TID; i++) {
5826                         if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
5827                                 if (firstp == NULL) {
5828                                         firstp = ascq->q_first[i];
5829                                         lastp = ascq->q_last[i];
5830                                 } else {
5831                                         ASC_ASSERT(lastp != NULL);
5832                                         lastp->host_scribble =
5833                                             (unsigned char *)ascq->q_first[i];
5834                                         lastp = ascq->q_last[i];
5835                                 }
5836                                 ascq->q_first[i] = ascq->q_last[i] = NULL;
5837                                 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
5838 #ifdef ADVANSYS_STATS
5839                                 ascq->q_cur_cnt[i] = 0;
5840 #endif /* ADVANSYS_STATS */
5841                         }
5842                 }
5843 #ifdef ADVANSYS_STATS
5844                 {
5845                         REQP reqp;
5846                         for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
5847                                 REQTIMESTAT("asc_dequeue_list", ascq, reqp,
5848                                             reqp->device->id);
5849                         }
5850                 }
5851 #endif /* ADVANSYS_STATS */
5852         }
5853         if (lastpp) {
5854                 *lastpp = lastp;
5855         }
5856         ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong)firstp);
5857         return firstp;
5858 }
5859
5860 /*
5861  * Remove the specified 'REQP' from the specified queue for
5862  * the specified target device. Clear the 'tidmask' bit for the
5863  * device if no more commands are left queued for it.
5864  *
5865  * 'REQPNEXT(reqp)' returns reqp's the next pointer.
5866  *
5867  * Return ASC_TRUE if the command was found and removed,
5868  * otherwise return ASC_FALSE.
5869  */
5870 static int asc_rmqueue(asc_queue_t *ascq, REQP reqp)
5871 {
5872         REQP currp, prevp;
5873         int tid;
5874         int ret = ASC_FALSE;
5875
5876         ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n",
5877                  (ulong)ascq, (ulong)reqp);
5878         ASC_ASSERT(reqp != NULL);
5879
5880         tid = REQPTID(reqp);
5881         ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5882
5883         /*
5884          * Handle the common case of 'reqp' being the first
5885          * entry on the queue.
5886          */
5887         if (reqp == ascq->q_first[tid]) {
5888                 ret = ASC_TRUE;
5889                 ascq->q_first[tid] = REQPNEXT(reqp);
5890                 /* If the queue is now empty, clear its bit and the last pointer. */
5891                 if (ascq->q_first[tid] == NULL) {
5892                         ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5893                         ASC_ASSERT(ascq->q_last[tid] == reqp);
5894                         ascq->q_last[tid] = NULL;
5895                 }
5896         } else if (ascq->q_first[tid] != NULL) {
5897                 ASC_ASSERT(ascq->q_last[tid] != NULL);
5898                 /*
5899                  * Because the case of 'reqp' being the first entry has been
5900                  * handled above and it is known the queue is not empty, if
5901                  * 'reqp' is found on the queue it is guaranteed the queue will
5902                  * not become empty and that 'q_first[tid]' will not be changed.
5903                  *
5904                  * Set 'prevp' to the first entry, 'currp' to the second entry,
5905                  * and search for 'reqp'.
5906                  */
5907                 for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
5908                      currp; prevp = currp, currp = REQPNEXT(currp)) {
5909                         if (currp == reqp) {
5910                                 ret = ASC_TRUE;
5911                                 prevp->host_scribble =
5912                                     (unsigned char *)REQPNEXT(currp);
5913                                 reqp->host_scribble = NULL;
5914                                 if (ascq->q_last[tid] == reqp) {
5915                                         ascq->q_last[tid] = prevp;
5916                                 }
5917                                 break;
5918                         }
5919                 }
5920         }
5921 #ifdef ADVANSYS_STATS
5922         /* Maintain request queue statistics. */
5923         if (ret == ASC_TRUE) {
5924                 ascq->q_cur_cnt[tid]--;
5925                 REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
5926         }
5927         ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
5928 #endif /* ADVANSYS_STATS */
5929         ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong)reqp, ret);
5930         return ret;
5931 }
5932
5933 /*
5934  * Execute as many queued requests as possible for the specified queue.
5935  *
5936  * Calls asc_execute_scsi_cmnd() to execute a REQP/struct scsi_cmnd.
5937  */
5938 static void asc_execute_queue(asc_queue_t *ascq)
5939 {
5940         ADV_SCSI_BIT_ID_TYPE scan_tidmask;
5941         REQP reqp;
5942         int i;
5943
5944         ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong)ascq);
5945         /*
5946          * Execute queued commands for devices attached to
5947          * the current board in round-robin fashion.
5948          */
5949         scan_tidmask = ascq->q_tidmask;
5950         do {
5951                 for (i = 0; i <= ADV_MAX_TID; i++) {
5952                         if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
5953                                 if ((reqp = asc_dequeue(ascq, i)) == NULL) {
5954                                         scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
5955                                 } else
5956                                     if (asc_execute_scsi_cmnd
5957                                         ((struct scsi_cmnd *)reqp)
5958                                         == ASC_BUSY) {
5959                                         scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
5960                                         /*
5961                                          * The request returned ASC_BUSY. Enqueue at the front of
5962                                          * target's waiting list to maintain correct ordering.
5963                                          */
5964                                         asc_enqueue(ascq, reqp, ASC_FRONT);
5965                                 }
5966                         }
5967                 }
5968         } while (scan_tidmask);
5969         return;
5970 }
5971
5972 #ifdef CONFIG_PROC_FS
5973 /*
5974  * asc_prt_board_devices()
5975  *
5976  * Print driver information for devices attached to the board.
5977  *
5978  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
5979  * cf. asc_prt_line().
5980  *
5981  * Return the number of characters copied into 'cp'. No more than
5982  * 'cplen' characters will be copied to 'cp'.
5983  */
5984 static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
5985 {
5986         asc_board_t *boardp;
5987         int leftlen;
5988         int totlen;
5989         int len;
5990         int chip_scsi_id;
5991         int i;
5992
5993         boardp = ASC_BOARDP(shost);
5994         leftlen = cplen;
5995         totlen = len = 0;
5996
5997         len = asc_prt_line(cp, leftlen,
5998                            "\nDevice Information for AdvanSys SCSI Host %d:\n",
5999                            shost->host_no);
6000         ASC_PRT_NEXT();
6001
6002         if (ASC_NARROW_BOARD(boardp)) {
6003                 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6004         } else {
6005                 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6006         }
6007
6008         len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
6009         ASC_PRT_NEXT();
6010         for (i = 0; i <= ADV_MAX_TID; i++) {
6011                 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
6012                         len = asc_prt_line(cp, leftlen, " %X,", i);
6013                         ASC_PRT_NEXT();
6014                 }
6015         }
6016         len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
6017         ASC_PRT_NEXT();
6018
6019         return totlen;
6020 }
6021
6022 /*
6023  * Display Wide Board BIOS Information.
6024  */
6025 static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
6026 {
6027         asc_board_t *boardp;
6028         int leftlen;
6029         int totlen;
6030         int len;
6031         ushort major, minor, letter;
6032
6033         boardp = ASC_BOARDP(shost);
6034         leftlen = cplen;
6035         totlen = len = 0;
6036
6037         len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
6038         ASC_PRT_NEXT();
6039
6040         /*
6041          * If the BIOS saved a valid signature, then fill in
6042          * the BIOS code segment base address.
6043          */
6044         if (boardp->bios_signature != 0x55AA) {
6045                 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
6046                 ASC_PRT_NEXT();
6047                 len = asc_prt_line(cp, leftlen,
6048                                    "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
6049                 ASC_PRT_NEXT();
6050                 len = asc_prt_line(cp, leftlen,
6051                                    "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
6052                 ASC_PRT_NEXT();
6053         } else {
6054                 major = (boardp->bios_version >> 12) & 0xF;
6055                 minor = (boardp->bios_version >> 8) & 0xF;
6056                 letter = (boardp->bios_version & 0xFF);
6057
6058                 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
6059                                    major, minor,
6060                                    letter >= 26 ? '?' : letter + 'A');
6061                 ASC_PRT_NEXT();
6062
6063                 /*
6064                  * Current available ROM BIOS release is 3.1I for UW
6065                  * and 3.2I for U2W. This code doesn't differentiate
6066                  * UW and U2W boards.
6067                  */
6068                 if (major < 3 || (major <= 3 && minor < 1) ||
6069                     (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
6070                         len = asc_prt_line(cp, leftlen,
6071                                            "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
6072                         ASC_PRT_NEXT();
6073                         len = asc_prt_line(cp, leftlen,
6074                                            "ftp://ftp.connectcom.net/pub\n");
6075                         ASC_PRT_NEXT();
6076                 }
6077         }
6078
6079         return totlen;
6080 }
6081
6082 /*
6083  * Add serial number to information bar if signature AAh
6084  * is found in at bit 15-9 (7 bits) of word 1.
6085  *
6086  * Serial Number consists fo 12 alpha-numeric digits.
6087  *
6088  *       1 - Product type (A,B,C,D..)  Word0: 15-13 (3 bits)
6089  *       2 - MFG Location (A,B,C,D..)  Word0: 12-10 (3 bits)
6090  *     3-4 - Product ID (0-99)         Word0: 9-0 (10 bits)
6091  *       5 - Product revision (A-J)    Word0:  "         "
6092  *
6093  *           Signature                 Word1: 15-9 (7 bits)
6094  *       6 - Year (0-9)                Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
6095  *     7-8 - Week of the year (1-52)   Word1: 5-0 (6 bits)
6096  *
6097  *    9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
6098  *
6099  * Note 1: Only production cards will have a serial number.
6100  *
6101  * Note 2: Signature is most significant 7 bits (0xFE).
6102  *
6103  * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
6104  */
6105 static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
6106 {
6107         ushort w, num;
6108
6109         if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
6110                 return ASC_FALSE;
6111         } else {
6112                 /*
6113                  * First word - 6 digits.
6114                  */
6115                 w = serialnum[0];
6116
6117                 /* Product type - 1st digit. */
6118                 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
6119                         /* Product type is P=Prototype */
6120                         *cp += 0x8;
6121                 }
6122                 cp++;
6123
6124                 /* Manufacturing location - 2nd digit. */
6125                 *cp++ = 'A' + ((w & 0x1C00) >> 10);
6126
6127                 /* Product ID - 3rd, 4th digits. */
6128                 num = w & 0x3FF;
6129                 *cp++ = '0' + (num / 100);
6130                 num %= 100;
6131                 *cp++ = '0' + (num / 10);
6132
6133                 /* Product revision - 5th digit. */
6134                 *cp++ = 'A' + (num % 10);
6135
6136                 /*
6137                  * Second word
6138                  */
6139                 w = serialnum[1];
6140
6141                 /*
6142                  * Year - 6th digit.
6143                  *
6144                  * If bit 15 of third word is set, then the
6145                  * last digit of the year is greater than 7.
6146                  */
6147                 if (serialnum[2] & 0x8000) {
6148                         *cp++ = '8' + ((w & 0x1C0) >> 6);
6149                 } else {
6150                         *cp++ = '0' + ((w & 0x1C0) >> 6);
6151                 }
6152
6153                 /* Week of year - 7th, 8th digits. */
6154                 num = w & 0x003F;
6155                 *cp++ = '0' + num / 10;
6156                 num %= 10;
6157                 *cp++ = '0' + num;
6158
6159                 /*
6160                  * Third word
6161                  */
6162                 w = serialnum[2] & 0x7FFF;
6163
6164                 /* Serial number - 9th digit. */
6165                 *cp++ = 'A' + (w / 1000);
6166
6167                 /* 10th, 11th, 12th digits. */
6168                 num = w % 1000;
6169                 *cp++ = '0' + num / 100;
6170                 num %= 100;
6171                 *cp++ = '0' + num / 10;
6172                 num %= 10;
6173                 *cp++ = '0' + num;
6174
6175                 *cp = '\0';     /* Null Terminate the string. */
6176                 return ASC_TRUE;
6177         }
6178 }
6179
6180 /*
6181  * asc_prt_asc_board_eeprom()
6182  *
6183  * Print board EEPROM configuration.
6184  *
6185  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6186  * cf. asc_prt_line().
6187  *
6188  * Return the number of characters copied into 'cp'. No more than
6189  * 'cplen' characters will be copied to 'cp'.
6190  */
6191 static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
6192 {
6193         asc_board_t *boardp;
6194         ASC_DVC_VAR *asc_dvc_varp;
6195         int leftlen;
6196         int totlen;
6197         int len;
6198         ASCEEP_CONFIG *ep;
6199         int i;
6200 #ifdef CONFIG_ISA
6201         int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
6202 #endif /* CONFIG_ISA */
6203         uchar serialstr[13];
6204
6205         boardp = ASC_BOARDP(shost);
6206         asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6207         ep = &boardp->eep_config.asc_eep;
6208
6209         leftlen = cplen;
6210         totlen = len = 0;
6211
6212         len = asc_prt_line(cp, leftlen,
6213                            "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
6214                            shost->host_no);
6215         ASC_PRT_NEXT();
6216
6217         if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
6218             == ASC_TRUE) {
6219                 len =
6220                     asc_prt_line(cp, leftlen, " Serial Number: %s\n",
6221                                  serialstr);
6222                 ASC_PRT_NEXT();
6223         } else {
6224                 if (ep->adapter_info[5] == 0xBB) {
6225                         len = asc_prt_line(cp, leftlen,
6226                                            " Default Settings Used for EEPROM-less Adapter.\n");
6227                         ASC_PRT_NEXT();
6228                 } else {
6229                         len = asc_prt_line(cp, leftlen,
6230                                            " Serial Number Signature Not Present.\n");
6231                         ASC_PRT_NEXT();
6232                 }
6233         }
6234
6235         len = asc_prt_line(cp, leftlen,
6236                            " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6237                            ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
6238                            ep->max_tag_qng);
6239         ASC_PRT_NEXT();
6240
6241         len = asc_prt_line(cp, leftlen,
6242                            " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
6243         ASC_PRT_NEXT();
6244
6245         len = asc_prt_line(cp, leftlen, " Target ID:           ");
6246         ASC_PRT_NEXT();
6247         for (i = 0; i <= ASC_MAX_TID; i++) {
6248                 len = asc_prt_line(cp, leftlen, " %d", i);
6249                 ASC_PRT_NEXT();
6250         }
6251         len = asc_prt_line(cp, leftlen, "\n");
6252         ASC_PRT_NEXT();
6253
6254         len = asc_prt_line(cp, leftlen, " Disconnects:         ");
6255         ASC_PRT_NEXT();
6256         for (i = 0; i <= ASC_MAX_TID; i++) {
6257                 len = asc_prt_line(cp, leftlen, " %c",
6258                                    (ep->
6259                                     disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6260                                    'N');
6261                 ASC_PRT_NEXT();
6262         }
6263         len = asc_prt_line(cp, leftlen, "\n");
6264         ASC_PRT_NEXT();
6265
6266         len = asc_prt_line(cp, leftlen, " Command Queuing:     ");
6267         ASC_PRT_NEXT();
6268         for (i = 0; i <= ASC_MAX_TID; i++) {
6269                 len = asc_prt_line(cp, leftlen, " %c",
6270                                    (ep->
6271                                     use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6272                                    'N');
6273                 ASC_PRT_NEXT();
6274         }
6275         len = asc_prt_line(cp, leftlen, "\n");
6276         ASC_PRT_NEXT();
6277
6278         len = asc_prt_line(cp, leftlen, " Start Motor:         ");
6279         ASC_PRT_NEXT();
6280         for (i = 0; i <= ASC_MAX_TID; i++) {
6281                 len = asc_prt_line(cp, leftlen, " %c",
6282                                    (ep->
6283                                     start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6284                                    'N');
6285                 ASC_PRT_NEXT();
6286         }
6287         len = asc_prt_line(cp, leftlen, "\n");
6288         ASC_PRT_NEXT();
6289
6290         len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6291         ASC_PRT_NEXT();
6292         for (i = 0; i <= ASC_MAX_TID; i++) {
6293                 len = asc_prt_line(cp, leftlen, " %c",
6294                                    (ep->
6295                                     init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6296                                    'N');
6297                 ASC_PRT_NEXT();
6298         }
6299         len = asc_prt_line(cp, leftlen, "\n");
6300         ASC_PRT_NEXT();
6301
6302 #ifdef CONFIG_ISA
6303         if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
6304                 len = asc_prt_line(cp, leftlen,
6305                                    " Host ISA DMA speed:   %d MB/S\n",
6306                                    isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
6307                 ASC_PRT_NEXT();
6308         }
6309 #endif /* CONFIG_ISA */
6310
6311         return totlen;
6312 }
6313
6314 /*
6315  * asc_prt_adv_board_eeprom()
6316  *
6317  * Print board EEPROM configuration.
6318  *
6319  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6320  * cf. asc_prt_line().
6321  *
6322  * Return the number of characters copied into 'cp'. No more than
6323  * 'cplen' characters will be copied to 'cp'.
6324  */
6325 static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
6326 {
6327         asc_board_t *boardp;
6328         ADV_DVC_VAR *adv_dvc_varp;
6329         int leftlen;
6330         int totlen;
6331         int len;
6332         int i;
6333         char *termstr;
6334         uchar serialstr[13];
6335         ADVEEP_3550_CONFIG *ep_3550 = NULL;
6336         ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
6337         ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
6338         ushort word;
6339         ushort *wordp;
6340         ushort sdtr_speed = 0;
6341
6342         boardp = ASC_BOARDP(shost);
6343         adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6344         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6345                 ep_3550 = &boardp->eep_config.adv_3550_eep;
6346         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6347                 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
6348         } else {
6349                 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
6350         }
6351
6352         leftlen = cplen;
6353         totlen = len = 0;
6354
6355         len = asc_prt_line(cp, leftlen,
6356                            "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
6357                            shost->host_no);
6358         ASC_PRT_NEXT();
6359
6360         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6361                 wordp = &ep_3550->serial_number_word1;
6362         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6363                 wordp = &ep_38C0800->serial_number_word1;
6364         } else {
6365                 wordp = &ep_38C1600->serial_number_word1;
6366         }
6367
6368         if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
6369                 len =
6370                     asc_prt_line(cp, leftlen, " Serial Number: %s\n",
6371                                  serialstr);
6372                 ASC_PRT_NEXT();
6373         } else {
6374                 len = asc_prt_line(cp, leftlen,
6375                                    " Serial Number Signature Not Present.\n");
6376                 ASC_PRT_NEXT();
6377         }
6378
6379         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6380                 len = asc_prt_line(cp, leftlen,
6381                                    " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6382                                    ep_3550->adapter_scsi_id,
6383                                    ep_3550->max_host_qng, ep_3550->max_dvc_qng);
6384                 ASC_PRT_NEXT();
6385         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6386                 len = asc_prt_line(cp, leftlen,
6387                                    " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6388                                    ep_38C0800->adapter_scsi_id,
6389                                    ep_38C0800->max_host_qng,
6390                                    ep_38C0800->max_dvc_qng);
6391                 ASC_PRT_NEXT();
6392         } else {
6393                 len = asc_prt_line(cp, leftlen,
6394                                    " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6395                                    ep_38C1600->adapter_scsi_id,
6396                                    ep_38C1600->max_host_qng,
6397                                    ep_38C1600->max_dvc_qng);
6398                 ASC_PRT_NEXT();
6399         }
6400         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6401                 word = ep_3550->termination;
6402         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6403                 word = ep_38C0800->termination_lvd;
6404         } else {
6405                 word = ep_38C1600->termination_lvd;
6406         }
6407         switch (word) {
6408         case 1:
6409                 termstr = "Low Off/High Off";
6410                 break;
6411         case 2:
6412                 termstr = "Low Off/High On";
6413                 break;
6414         case 3:
6415                 termstr = "Low On/High On";
6416                 break;
6417         default:
6418         case 0:
6419                 termstr = "Automatic";
6420                 break;
6421         }
6422
6423         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6424                 len = asc_prt_line(cp, leftlen,
6425                                    " termination: %u (%s), bios_ctrl: 0x%x\n",
6426                                    ep_3550->termination, termstr,
6427                                    ep_3550->bios_ctrl);
6428                 ASC_PRT_NEXT();
6429         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6430                 len = asc_prt_line(cp, leftlen,
6431                                    " termination: %u (%s), bios_ctrl: 0x%x\n",
6432                                    ep_38C0800->termination_lvd, termstr,
6433                                    ep_38C0800->bios_ctrl);
6434                 ASC_PRT_NEXT();
6435         } else {
6436                 len = asc_prt_line(cp, leftlen,
6437                                    " termination: %u (%s), bios_ctrl: 0x%x\n",
6438                                    ep_38C1600->termination_lvd, termstr,
6439                                    ep_38C1600->bios_ctrl);
6440                 ASC_PRT_NEXT();
6441         }
6442
6443         len = asc_prt_line(cp, leftlen, " Target ID:           ");
6444         ASC_PRT_NEXT();
6445         for (i = 0; i <= ADV_MAX_TID; i++) {
6446                 len = asc_prt_line(cp, leftlen, " %X", i);
6447                 ASC_PRT_NEXT();
6448         }
6449         len = asc_prt_line(cp, leftlen, "\n");
6450         ASC_PRT_NEXT();
6451
6452         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6453                 word = ep_3550->disc_enable;
6454         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6455                 word = ep_38C0800->disc_enable;
6456         } else {
6457                 word = ep_38C1600->disc_enable;
6458         }
6459         len = asc_prt_line(cp, leftlen, " Disconnects:         ");
6460         ASC_PRT_NEXT();
6461         for (i = 0; i <= ADV_MAX_TID; i++) {
6462                 len = asc_prt_line(cp, leftlen, " %c",
6463                                    (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6464                 ASC_PRT_NEXT();
6465         }
6466         len = asc_prt_line(cp, leftlen, "\n");
6467         ASC_PRT_NEXT();
6468
6469         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6470                 word = ep_3550->tagqng_able;
6471         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6472                 word = ep_38C0800->tagqng_able;
6473         } else {
6474                 word = ep_38C1600->tagqng_able;
6475         }
6476         len = asc_prt_line(cp, leftlen, " Command Queuing:     ");
6477         ASC_PRT_NEXT();
6478         for (i = 0; i <= ADV_MAX_TID; i++) {
6479                 len = asc_prt_line(cp, leftlen, " %c",
6480                                    (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6481                 ASC_PRT_NEXT();
6482         }
6483         len = asc_prt_line(cp, leftlen, "\n");
6484         ASC_PRT_NEXT();
6485
6486         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6487                 word = ep_3550->start_motor;
6488         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6489                 word = ep_38C0800->start_motor;
6490         } else {
6491                 word = ep_38C1600->start_motor;
6492         }
6493         len = asc_prt_line(cp, leftlen, " Start Motor:         ");
6494         ASC_PRT_NEXT();
6495         for (i = 0; i <= ADV_MAX_TID; i++) {
6496                 len = asc_prt_line(cp, leftlen, " %c",
6497                                    (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6498                 ASC_PRT_NEXT();
6499         }
6500         len = asc_prt_line(cp, leftlen, "\n");
6501         ASC_PRT_NEXT();
6502
6503         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6504                 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6505                 ASC_PRT_NEXT();
6506                 for (i = 0; i <= ADV_MAX_TID; i++) {
6507                         len = asc_prt_line(cp, leftlen, " %c",
6508                                            (ep_3550->
6509                                             sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
6510                                            'Y' : 'N');
6511                         ASC_PRT_NEXT();
6512                 }
6513                 len = asc_prt_line(cp, leftlen, "\n");
6514                 ASC_PRT_NEXT();
6515         }
6516
6517         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6518                 len = asc_prt_line(cp, leftlen, " Ultra Transfer:      ");
6519                 ASC_PRT_NEXT();
6520                 for (i = 0; i <= ADV_MAX_TID; i++) {
6521                         len = asc_prt_line(cp, leftlen, " %c",
6522                                            (ep_3550->
6523                                             ultra_able & ADV_TID_TO_TIDMASK(i))
6524                                            ? 'Y' : 'N');
6525                         ASC_PRT_NEXT();
6526                 }
6527                 len = asc_prt_line(cp, leftlen, "\n");
6528                 ASC_PRT_NEXT();
6529         }
6530
6531         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6532                 word = ep_3550->wdtr_able;
6533         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6534                 word = ep_38C0800->wdtr_able;
6535         } else {
6536                 word = ep_38C1600->wdtr_able;
6537         }
6538         len = asc_prt_line(cp, leftlen, " Wide Transfer:       ");
6539         ASC_PRT_NEXT();
6540         for (i = 0; i <= ADV_MAX_TID; i++) {
6541                 len = asc_prt_line(cp, leftlen, " %c",
6542                                    (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6543                 ASC_PRT_NEXT();
6544         }
6545         len = asc_prt_line(cp, leftlen, "\n");
6546         ASC_PRT_NEXT();
6547
6548         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
6549             adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
6550                 len = asc_prt_line(cp, leftlen,
6551                                    " Synchronous Transfer Speed (Mhz):\n  ");
6552                 ASC_PRT_NEXT();
6553                 for (i = 0; i <= ADV_MAX_TID; i++) {
6554                         char *speed_str;
6555
6556                         if (i == 0) {
6557                                 sdtr_speed = adv_dvc_varp->sdtr_speed1;
6558                         } else if (i == 4) {
6559                                 sdtr_speed = adv_dvc_varp->sdtr_speed2;
6560                         } else if (i == 8) {
6561                                 sdtr_speed = adv_dvc_varp->sdtr_speed3;
6562                         } else if (i == 12) {
6563                                 sdtr_speed = adv_dvc_varp->sdtr_speed4;
6564                         }
6565                         switch (sdtr_speed & ADV_MAX_TID) {
6566                         case 0:
6567                                 speed_str = "Off";
6568                                 break;
6569                         case 1:
6570                                 speed_str = "  5";
6571                                 break;
6572                         case 2:
6573                                 speed_str = " 10";
6574                                 break;
6575                         case 3:
6576                                 speed_str = " 20";
6577                                 break;
6578                         case 4:
6579                                 speed_str = " 40";
6580                                 break;
6581                         case 5:
6582                                 speed_str = " 80";
6583                                 break;
6584                         default:
6585                                 speed_str = "Unk";
6586                                 break;
6587                         }
6588                         len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
6589                         ASC_PRT_NEXT();
6590                         if (i == 7) {
6591                                 len = asc_prt_line(cp, leftlen, "\n  ");
6592                                 ASC_PRT_NEXT();
6593                         }
6594                         sdtr_speed >>= 4;
6595                 }
6596                 len = asc_prt_line(cp, leftlen, "\n");
6597                 ASC_PRT_NEXT();
6598         }
6599
6600         return totlen;
6601 }
6602
6603 /*
6604  * asc_prt_driver_conf()
6605  *
6606  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6607  * cf. asc_prt_line().
6608  *
6609  * Return the number of characters copied into 'cp'. No more than
6610  * 'cplen' characters will be copied to 'cp'.
6611  */
6612 static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
6613 {
6614         asc_board_t *boardp;
6615         int leftlen;
6616         int totlen;
6617         int len;
6618         int chip_scsi_id;
6619
6620         boardp = ASC_BOARDP(shost);
6621
6622         leftlen = cplen;
6623         totlen = len = 0;
6624
6625         len = asc_prt_line(cp, leftlen,
6626                            "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
6627                            shost->host_no);
6628         ASC_PRT_NEXT();
6629
6630         len = asc_prt_line(cp, leftlen,
6631                            " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
6632                            shost->host_busy, shost->last_reset, shost->max_id,
6633                            shost->max_lun, shost->max_channel);
6634         ASC_PRT_NEXT();
6635
6636         len = asc_prt_line(cp, leftlen,
6637                            " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
6638                            shost->unique_id, shost->can_queue, shost->this_id,
6639                            shost->sg_tablesize, shost->cmd_per_lun);
6640         ASC_PRT_NEXT();
6641
6642         len = asc_prt_line(cp, leftlen,
6643                            " unchecked_isa_dma %d, use_clustering %d\n",
6644                            shost->unchecked_isa_dma, shost->use_clustering);
6645         ASC_PRT_NEXT();
6646
6647         len = asc_prt_line(cp, leftlen,
6648                            " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
6649                            boardp->flags, boardp->last_reset, jiffies,
6650                            boardp->asc_n_io_port);
6651         ASC_PRT_NEXT();
6652
6653         len = asc_prt_line(cp, leftlen, " io_port 0x%x\n", shost->io_port);
6654         ASC_PRT_NEXT();
6655
6656         if (ASC_NARROW_BOARD(boardp)) {
6657                 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6658         } else {
6659                 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6660         }
6661
6662         return totlen;
6663 }
6664
6665 /*
6666  * asc_prt_asc_board_info()
6667  *
6668  * Print dynamic board configuration information.
6669  *
6670  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6671  * cf. asc_prt_line().
6672  *
6673  * Return the number of characters copied into 'cp'. No more than
6674  * 'cplen' characters will be copied to 'cp'.
6675  */
6676 static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
6677 {
6678         asc_board_t *boardp;
6679         int chip_scsi_id;
6680         int leftlen;
6681         int totlen;
6682         int len;
6683         ASC_DVC_VAR *v;
6684         ASC_DVC_CFG *c;
6685         int i;
6686         int renegotiate = 0;
6687
6688         boardp = ASC_BOARDP(shost);
6689         v = &boardp->dvc_var.asc_dvc_var;
6690         c = &boardp->dvc_cfg.asc_dvc_cfg;
6691         chip_scsi_id = c->chip_scsi_id;
6692
6693         leftlen = cplen;
6694         totlen = len = 0;
6695
6696         len = asc_prt_line(cp, leftlen,
6697                            "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
6698                            shost->host_no);
6699         ASC_PRT_NEXT();
6700
6701         len = asc_prt_line(cp, leftlen,
6702                            " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
6703                            c->chip_version, c->lib_version, c->lib_serial_no,
6704                            c->mcode_date);
6705         ASC_PRT_NEXT();
6706
6707         len = asc_prt_line(cp, leftlen,
6708                            " mcode_version 0x%x, err_code %u\n",
6709                            c->mcode_version, v->err_code);
6710         ASC_PRT_NEXT();
6711
6712         /* Current number of commands waiting for the host. */
6713         len = asc_prt_line(cp, leftlen,
6714                            " Total Command Pending: %d\n", v->cur_total_qng);
6715         ASC_PRT_NEXT();
6716
6717         len = asc_prt_line(cp, leftlen, " Command Queuing:");
6718         ASC_PRT_NEXT();
6719         for (i = 0; i <= ASC_MAX_TID; i++) {
6720                 if ((chip_scsi_id == i) ||
6721                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6722                         continue;
6723                 }
6724                 len = asc_prt_line(cp, leftlen, " %X:%c",
6725                                    i,
6726                                    (v->
6727                                     use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
6728                                    'Y' : 'N');
6729                 ASC_PRT_NEXT();
6730         }
6731         len = asc_prt_line(cp, leftlen, "\n");
6732         ASC_PRT_NEXT();
6733
6734         /* Current number of commands waiting for a device. */
6735         len = asc_prt_line(cp, leftlen, " Command Queue Pending:");
6736         ASC_PRT_NEXT();
6737         for (i = 0; i <= ASC_MAX_TID; i++) {
6738                 if ((chip_scsi_id == i) ||
6739                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6740                         continue;
6741                 }
6742                 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
6743                 ASC_PRT_NEXT();
6744         }
6745         len = asc_prt_line(cp, leftlen, "\n");
6746         ASC_PRT_NEXT();
6747
6748         /* Current limit on number of commands that can be sent to a device. */
6749         len = asc_prt_line(cp, leftlen, " Command Queue Limit:");
6750         ASC_PRT_NEXT();
6751         for (i = 0; i <= ASC_MAX_TID; i++) {
6752                 if ((chip_scsi_id == i) ||
6753                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6754                         continue;
6755                 }
6756                 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
6757                 ASC_PRT_NEXT();
6758         }
6759         len = asc_prt_line(cp, leftlen, "\n");
6760         ASC_PRT_NEXT();
6761
6762         /* Indicate whether the device has returned queue full status. */
6763         len = asc_prt_line(cp, leftlen, " Command Queue Full:");
6764         ASC_PRT_NEXT();
6765         for (i = 0; i <= ASC_MAX_TID; i++) {
6766                 if ((chip_scsi_id == i) ||
6767                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6768                         continue;
6769                 }
6770                 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
6771                         len = asc_prt_line(cp, leftlen, " %X:Y-%d",
6772                                            i, boardp->queue_full_cnt[i]);
6773                 } else {
6774                         len = asc_prt_line(cp, leftlen, " %X:N", i);
6775                 }
6776                 ASC_PRT_NEXT();
6777         }
6778         len = asc_prt_line(cp, leftlen, "\n");
6779         ASC_PRT_NEXT();
6780
6781         len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6782         ASC_PRT_NEXT();
6783         for (i = 0; i <= ASC_MAX_TID; i++) {
6784                 if ((chip_scsi_id == i) ||
6785                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6786                         continue;
6787                 }
6788                 len = asc_prt_line(cp, leftlen, " %X:%c",
6789                                    i,
6790                                    (v->
6791                                     sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6792                                    'N');
6793                 ASC_PRT_NEXT();
6794         }
6795         len = asc_prt_line(cp, leftlen, "\n");
6796         ASC_PRT_NEXT();
6797
6798         for (i = 0; i <= ASC_MAX_TID; i++) {
6799                 uchar syn_period_ix;
6800
6801                 if ((chip_scsi_id == i) ||
6802                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
6803                     ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
6804                         continue;
6805                 }
6806
6807                 len = asc_prt_line(cp, leftlen, "  %X:", i);
6808                 ASC_PRT_NEXT();
6809
6810                 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
6811                         len = asc_prt_line(cp, leftlen, " Asynchronous");
6812                         ASC_PRT_NEXT();
6813                 } else {
6814                         syn_period_ix =
6815                             (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
6816                                                            1);
6817
6818                         len = asc_prt_line(cp, leftlen,
6819                                            " Transfer Period Factor: %d (%d.%d Mhz),",
6820                                            v->sdtr_period_tbl[syn_period_ix],
6821                                            250 /
6822                                            v->sdtr_period_tbl[syn_period_ix],
6823                                            ASC_TENTHS(250,
6824                                                       v->
6825                                                       sdtr_period_tbl
6826                                                       [syn_period_ix]));
6827                         ASC_PRT_NEXT();
6828
6829                         len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
6830                                            boardp->
6831                                            sdtr_data[i] & ASC_SYN_MAX_OFFSET);
6832                         ASC_PRT_NEXT();
6833                 }
6834
6835                 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
6836                         len = asc_prt_line(cp, leftlen, "*\n");
6837                         renegotiate = 1;
6838                 } else {
6839                         len = asc_prt_line(cp, leftlen, "\n");
6840                 }
6841                 ASC_PRT_NEXT();
6842         }
6843
6844         if (renegotiate) {
6845                 len = asc_prt_line(cp, leftlen,
6846                                    " * = Re-negotiation pending before next command.\n");
6847                 ASC_PRT_NEXT();
6848         }
6849
6850         return totlen;
6851 }
6852
6853 /*
6854  * asc_prt_adv_board_info()
6855  *
6856  * Print dynamic board configuration information.
6857  *
6858  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6859  * cf. asc_prt_line().
6860  *
6861  * Return the number of characters copied into 'cp'. No more than
6862  * 'cplen' characters will be copied to 'cp'.
6863  */
6864 static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
6865 {
6866         asc_board_t *boardp;
6867         int leftlen;
6868         int totlen;
6869         int len;
6870         int i;
6871         ADV_DVC_VAR *v;
6872         ADV_DVC_CFG *c;
6873         AdvPortAddr iop_base;
6874         ushort chip_scsi_id;
6875         ushort lramword;
6876         uchar lrambyte;
6877         ushort tagqng_able;
6878         ushort sdtr_able, wdtr_able;
6879         ushort wdtr_done, sdtr_done;
6880         ushort period = 0;
6881         int renegotiate = 0;
6882
6883         boardp = ASC_BOARDP(shost);
6884         v = &boardp->dvc_var.adv_dvc_var;
6885         c = &boardp->dvc_cfg.adv_dvc_cfg;
6886         iop_base = v->iop_base;
6887         chip_scsi_id = v->chip_scsi_id;
6888
6889         leftlen = cplen;
6890         totlen = len = 0;
6891
6892         len = asc_prt_line(cp, leftlen,
6893                            "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
6894                            shost->host_no);
6895         ASC_PRT_NEXT();
6896
6897         len = asc_prt_line(cp, leftlen,
6898                            " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
6899                            v->iop_base,
6900                            AdvReadWordRegister(iop_base,
6901                                                IOPW_SCSI_CFG1) & CABLE_DETECT,
6902                            v->err_code);
6903         ASC_PRT_NEXT();
6904
6905         len = asc_prt_line(cp, leftlen,
6906                            " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
6907                            c->chip_version, c->lib_version, c->mcode_date,
6908                            c->mcode_version);
6909         ASC_PRT_NEXT();
6910
6911         AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
6912         len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
6913         ASC_PRT_NEXT();
6914         for (i = 0; i <= ADV_MAX_TID; i++) {
6915                 if ((chip_scsi_id == i) ||
6916                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6917                         continue;
6918                 }
6919
6920                 len = asc_prt_line(cp, leftlen, " %X:%c",
6921                                    i,
6922                                    (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6923                                    'N');
6924                 ASC_PRT_NEXT();
6925         }
6926         len = asc_prt_line(cp, leftlen, "\n");
6927         ASC_PRT_NEXT();
6928
6929         len = asc_prt_line(cp, leftlen, " Queue Limit:");
6930         ASC_PRT_NEXT();
6931         for (i = 0; i <= ADV_MAX_TID; i++) {
6932                 if ((chip_scsi_id == i) ||
6933                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6934                         continue;
6935                 }
6936
6937                 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
6938                                 lrambyte);
6939
6940                 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
6941                 ASC_PRT_NEXT();
6942         }
6943         len = asc_prt_line(cp, leftlen, "\n");
6944         ASC_PRT_NEXT();
6945
6946         len = asc_prt_line(cp, leftlen, " Command Pending:");
6947         ASC_PRT_NEXT();
6948         for (i = 0; i <= ADV_MAX_TID; i++) {
6949                 if ((chip_scsi_id == i) ||
6950                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6951                         continue;
6952                 }
6953
6954                 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
6955                                 lrambyte);
6956
6957                 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
6958                 ASC_PRT_NEXT();
6959         }
6960         len = asc_prt_line(cp, leftlen, "\n");
6961         ASC_PRT_NEXT();
6962
6963         AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
6964         len = asc_prt_line(cp, leftlen, " Wide Enabled:");
6965         ASC_PRT_NEXT();
6966         for (i = 0; i <= ADV_MAX_TID; i++) {
6967                 if ((chip_scsi_id == i) ||
6968                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6969                         continue;
6970                 }
6971
6972                 len = asc_prt_line(cp, leftlen, " %X:%c",
6973                                    i,
6974                                    (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6975                                    'N');
6976                 ASC_PRT_NEXT();
6977         }
6978         len = asc_prt_line(cp, leftlen, "\n");
6979         ASC_PRT_NEXT();
6980
6981         AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
6982         len = asc_prt_line(cp, leftlen, " Transfer Bit Width:");
6983         ASC_PRT_NEXT();
6984         for (i = 0; i <= ADV_MAX_TID; i++) {
6985                 if ((chip_scsi_id == i) ||
6986                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6987                         continue;
6988                 }
6989
6990                 AdvReadWordLram(iop_base,
6991                                 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
6992                                 lramword);
6993
6994                 len = asc_prt_line(cp, leftlen, " %X:%d",
6995                                    i, (lramword & 0x8000) ? 16 : 8);
6996                 ASC_PRT_NEXT();
6997
6998                 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
6999                     (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7000                         len = asc_prt_line(cp, leftlen, "*");
7001                         ASC_PRT_NEXT();
7002                         renegotiate = 1;
7003                 }
7004         }
7005         len = asc_prt_line(cp, leftlen, "\n");
7006         ASC_PRT_NEXT();
7007
7008         AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7009         len = asc_prt_line(cp, leftlen, " Synchronous Enabled:");
7010         ASC_PRT_NEXT();
7011         for (i = 0; i <= ADV_MAX_TID; i++) {
7012                 if ((chip_scsi_id == i) ||
7013                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7014                         continue;
7015                 }
7016
7017                 len = asc_prt_line(cp, leftlen, " %X:%c",
7018                                    i,
7019                                    (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7020                                    'N');
7021                 ASC_PRT_NEXT();
7022         }
7023         len = asc_prt_line(cp, leftlen, "\n");
7024         ASC_PRT_NEXT();
7025
7026         AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
7027         for (i = 0; i <= ADV_MAX_TID; i++) {
7028
7029                 AdvReadWordLram(iop_base,
7030                                 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
7031                                 lramword);
7032                 lramword &= ~0x8000;
7033
7034                 if ((chip_scsi_id == i) ||
7035                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
7036                     ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
7037                         continue;
7038                 }
7039
7040                 len = asc_prt_line(cp, leftlen, "  %X:", i);
7041                 ASC_PRT_NEXT();
7042
7043                 if ((lramword & 0x1F) == 0) {   /* Check for REQ/ACK Offset 0. */
7044                         len = asc_prt_line(cp, leftlen, " Asynchronous");
7045                         ASC_PRT_NEXT();
7046                 } else {
7047                         len =
7048                             asc_prt_line(cp, leftlen,
7049                                          " Transfer Period Factor: ");
7050                         ASC_PRT_NEXT();
7051
7052                         if ((lramword & 0x1F00) == 0x1100) {    /* 80 Mhz */
7053                                 len =
7054                                     asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
7055                                 ASC_PRT_NEXT();
7056                         } else if ((lramword & 0x1F00) == 0x1000) {     /* 40 Mhz */
7057                                 len =
7058                                     asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
7059                                 ASC_PRT_NEXT();
7060                         } else {        /* 20 Mhz or below. */
7061
7062                                 period = (((lramword >> 8) * 25) + 50) / 4;
7063
7064                                 if (period == 0) {      /* Should never happen. */
7065                                         len =
7066                                             asc_prt_line(cp, leftlen,
7067                                                          "%d (? Mhz), ");
7068                                         ASC_PRT_NEXT();
7069                                 } else {
7070                                         len = asc_prt_line(cp, leftlen,
7071                                                            "%d (%d.%d Mhz),",
7072                                                            period, 250 / period,
7073                                                            ASC_TENTHS(250,
7074                                                                       period));
7075                                         ASC_PRT_NEXT();
7076                                 }
7077                         }
7078
7079                         len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
7080                                            lramword & 0x1F);
7081                         ASC_PRT_NEXT();
7082                 }
7083
7084                 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7085                         len = asc_prt_line(cp, leftlen, "*\n");
7086                         renegotiate = 1;
7087                 } else {
7088                         len = asc_prt_line(cp, leftlen, "\n");
7089                 }
7090                 ASC_PRT_NEXT();
7091         }
7092
7093         if (renegotiate) {
7094                 len = asc_prt_line(cp, leftlen,
7095                                    " * = Re-negotiation pending before next command.\n");
7096                 ASC_PRT_NEXT();
7097         }
7098
7099         return totlen;
7100 }
7101
7102 /*
7103  * asc_proc_copy()
7104  *
7105  * Copy proc information to a read buffer taking into account the current
7106  * read offset in the file and the remaining space in the read buffer.
7107  */
7108 static int
7109 asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
7110               char *cp, int cplen)
7111 {
7112         int cnt = 0;
7113
7114         ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
7115                  (unsigned)offset, (unsigned)advoffset, cplen);
7116         if (offset <= advoffset) {
7117                 /* Read offset below current offset, copy everything. */
7118                 cnt = min(cplen, leftlen);
7119                 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
7120                          (ulong)curbuf, (ulong)cp, cnt);
7121                 memcpy(curbuf, cp, cnt);
7122         } else if (offset < advoffset + cplen) {
7123                 /* Read offset within current range, partial copy. */
7124                 cnt = (advoffset + cplen) - offset;
7125                 cp = (cp + cplen) - cnt;
7126                 cnt = min(cnt, leftlen);
7127                 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
7128                          (ulong)curbuf, (ulong)cp, cnt);
7129                 memcpy(curbuf, cp, cnt);
7130         }
7131         return cnt;
7132 }
7133
7134 /*
7135  * asc_prt_line()
7136  *
7137  * If 'cp' is NULL print to the console, otherwise print to a buffer.
7138  *
7139  * Return 0 if printing to the console, otherwise return the number of
7140  * bytes written to the buffer.
7141  *
7142  * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
7143  * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
7144  */
7145 static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
7146 {
7147         va_list args;
7148         int ret;
7149         char s[ASC_PRTLINE_SIZE];
7150
7151         va_start(args, fmt);
7152         ret = vsprintf(s, fmt, args);
7153         ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
7154         if (buf == NULL) {
7155                 (void)printk(s);
7156                 ret = 0;
7157         } else {
7158                 ret = min(buflen, ret);
7159                 memcpy(buf, s, ret);
7160         }
7161         va_end(args);
7162         return ret;
7163 }
7164 #endif /* CONFIG_PROC_FS */
7165
7166 /*
7167  * --- Functions Required by the Asc Library
7168  */
7169
7170 /*
7171  * Delay for 'n' milliseconds. Don't use the 'jiffies'
7172  * global variable which is incremented once every 5 ms
7173  * from a timer interrupt, because this function may be
7174  * called when interrupts are disabled.
7175  */
7176 static void DvcSleepMilliSecond(ADV_DCNT n)
7177 {
7178         ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong)n);
7179         mdelay(n);
7180 }
7181
7182 /*
7183  * Currently and inline noop but leave as a placeholder.
7184  * Leave DvcEnterCritical() as a noop placeholder.
7185  */
7186 static inline ulong DvcEnterCritical(void)
7187 {
7188         return 0;
7189 }
7190
7191 /*
7192  * Critical sections are all protected by the board spinlock.
7193  * Leave DvcLeaveCritical() as a noop placeholder.
7194  */
7195 static inline void DvcLeaveCritical(ulong flags)
7196 {
7197         return;
7198 }
7199
7200 /*
7201  * void
7202  * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7203  *
7204  * Calling/Exit State:
7205  *    none
7206  *
7207  * Description:
7208  *     Output an ASC_SCSI_Q structure to the chip
7209  */
7210 static void
7211 DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7212 {
7213         int i;
7214
7215         ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
7216         AscSetChipLramAddr(iop_base, s_addr);
7217         for (i = 0; i < 2 * words; i += 2) {
7218                 if (i == 4 || i == 20) {
7219                         continue;
7220                 }
7221                 outpw(iop_base + IOP_RAM_DATA,
7222                       ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
7223         }
7224 }
7225
7226 /*
7227  * void
7228  * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
7229  *
7230  * Calling/Exit State:
7231  *    none
7232  *
7233  * Description:
7234  *     Input an ASC_QDONE_INFO structure from the chip
7235  */
7236 static void
7237 DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
7238 {
7239         int i;
7240         ushort word;
7241
7242         AscSetChipLramAddr(iop_base, s_addr);
7243         for (i = 0; i < 2 * words; i += 2) {
7244                 if (i == 10) {
7245                         continue;
7246                 }
7247                 word = inpw(iop_base + IOP_RAM_DATA);
7248                 inbuf[i] = word & 0xff;
7249                 inbuf[i + 1] = (word >> 8) & 0xff;
7250         }
7251         ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
7252 }
7253
7254 /*
7255  * Return the BIOS address of the adapter at the specified
7256  * I/O port and with the specified bus type.
7257  */
7258 static unsigned short __devinit
7259 AscGetChipBiosAddress(PortAddr iop_base, unsigned short bus_type)
7260 {
7261         unsigned short cfg_lsw;
7262         unsigned short bios_addr;
7263
7264         /*
7265          * The PCI BIOS is re-located by the motherboard BIOS. Because
7266          * of this the driver can not determine where a PCI BIOS is
7267          * loaded and executes.
7268          */
7269         if (bus_type & ASC_IS_PCI)
7270                 return 0;
7271
7272 #ifdef CONFIG_ISA
7273         if ((bus_type & ASC_IS_EISA) != 0) {
7274                 cfg_lsw = AscGetEisaChipCfg(iop_base);
7275                 cfg_lsw &= 0x000F;
7276                 bios_addr = ASC_BIOS_MIN_ADDR + cfg_lsw * ASC_BIOS_BANK_SIZE;
7277                 return bios_addr;
7278         }
7279 #endif /* CONFIG_ISA */
7280
7281         cfg_lsw = AscGetChipCfgLsw(iop_base);
7282
7283         /*
7284          *  ISA PnP uses the top bit as the 32K BIOS flag
7285          */
7286         if (bus_type == ASC_IS_ISAPNP)
7287                 cfg_lsw &= 0x7FFF;
7288         bios_addr = ASC_BIOS_MIN_ADDR + (cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE;
7289         return bios_addr;
7290 }
7291
7292 /*
7293  * --- Functions Required by the Adv Library
7294  */
7295
7296 /*
7297  * DvcGetPhyAddr()
7298  *
7299  * Return the physical address of 'vaddr' and set '*lenp' to the
7300  * number of physically contiguous bytes that follow 'vaddr'.
7301  * 'flag' indicates the type of structure whose physical address
7302  * is being translated.
7303  *
7304  * Note: Because Linux currently doesn't page the kernel and all
7305  * kernel buffers are physically contiguous, leave '*lenp' unchanged.
7306  */
7307 ADV_PADDR
7308 DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
7309               uchar *vaddr, ADV_SDCNT *lenp, int flag)
7310 {
7311         ADV_PADDR paddr;
7312
7313         paddr = virt_to_bus(vaddr);
7314
7315         ASC_DBG4(4,
7316                  "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
7317                  (ulong)vaddr, (ulong)lenp, (ulong)*((ulong *)lenp),
7318                  (ulong)paddr);
7319
7320         return paddr;
7321 }
7322
7323 /*
7324  * --- Tracing and Debugging Functions
7325  */
7326
7327 #ifdef ADVANSYS_STATS
7328 #ifdef CONFIG_PROC_FS
7329 /*
7330  * asc_prt_board_stats()
7331  *
7332  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7333  * cf. asc_prt_line().
7334  *
7335  * Return the number of characters copied into 'cp'. No more than
7336  * 'cplen' characters will be copied to 'cp'.
7337  */
7338 static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
7339 {
7340         int leftlen;
7341         int totlen;
7342         int len;
7343         struct asc_stats *s;
7344         asc_board_t *boardp;
7345
7346         leftlen = cplen;
7347         totlen = len = 0;
7348
7349         boardp = ASC_BOARDP(shost);
7350         s = &boardp->asc_stats;
7351
7352         len = asc_prt_line(cp, leftlen,
7353                            "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
7354                            shost->host_no);
7355         ASC_PRT_NEXT();
7356
7357         len = asc_prt_line(cp, leftlen,
7358                            " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
7359                            s->queuecommand, s->reset, s->biosparam,
7360                            s->interrupt);
7361         ASC_PRT_NEXT();
7362
7363         len = asc_prt_line(cp, leftlen,
7364                            " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
7365                            s->callback, s->done, s->build_error,
7366                            s->adv_build_noreq, s->adv_build_nosg);
7367         ASC_PRT_NEXT();
7368
7369         len = asc_prt_line(cp, leftlen,
7370                            " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
7371                            s->exe_noerror, s->exe_busy, s->exe_error,
7372                            s->exe_unknown);
7373         ASC_PRT_NEXT();
7374
7375         /*
7376          * Display data transfer statistics.
7377          */
7378         if (s->cont_cnt > 0) {
7379                 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
7380                 ASC_PRT_NEXT();
7381
7382                 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
7383                                    s->cont_xfer / 2,
7384                                    ASC_TENTHS(s->cont_xfer, 2));
7385                 ASC_PRT_NEXT();
7386
7387                 /* Contiguous transfer average size */
7388                 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
7389                                    (s->cont_xfer / 2) / s->cont_cnt,
7390                                    ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt));
7391                 ASC_PRT_NEXT();
7392         }
7393
7394         if (s->sg_cnt > 0) {
7395
7396                 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
7397                                    s->sg_cnt, s->sg_elem);
7398                 ASC_PRT_NEXT();
7399
7400                 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
7401                                    s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2));
7402                 ASC_PRT_NEXT();
7403
7404                 /* Scatter gather transfer statistics */
7405                 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
7406                                    s->sg_elem / s->sg_cnt,
7407                                    ASC_TENTHS(s->sg_elem, s->sg_cnt));
7408                 ASC_PRT_NEXT();
7409
7410                 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
7411                                    (s->sg_xfer / 2) / s->sg_elem,
7412                                    ASC_TENTHS((s->sg_xfer / 2), s->sg_elem));
7413                 ASC_PRT_NEXT();
7414
7415                 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
7416                                    (s->sg_xfer / 2) / s->sg_cnt,
7417                                    ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt));
7418                 ASC_PRT_NEXT();
7419         }
7420
7421         /*
7422          * Display request queuing statistics.
7423          */
7424         len = asc_prt_line(cp, leftlen,
7425                            " Active and Waiting Request Queues (Time Unit: %d HZ):\n",
7426                            HZ);
7427         ASC_PRT_NEXT();
7428
7429         return totlen;
7430 }
7431
7432 /*
7433  * asc_prt_target_stats()
7434  *
7435  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7436  * cf. asc_prt_line().
7437  *
7438  * This is separated from asc_prt_board_stats because a full set
7439  * of targets will overflow ASC_PRTBUF_SIZE.
7440  *
7441  * Return the number of characters copied into 'cp'. No more than
7442  * 'cplen' characters will be copied to 'cp'.
7443  */
7444 static int
7445 asc_prt_target_stats(struct Scsi_Host *shost, int tgt_id, char *cp, int cplen)
7446 {
7447         int leftlen;
7448         int totlen;
7449         int len;
7450         struct asc_stats *s;
7451         ushort chip_scsi_id;
7452         asc_board_t *boardp;
7453         asc_queue_t *active;
7454         asc_queue_t *waiting;
7455
7456         leftlen = cplen;
7457         totlen = len = 0;
7458
7459         boardp = ASC_BOARDP(shost);
7460         s = &boardp->asc_stats;
7461
7462         active = &ASC_BOARDP(shost)->active;
7463         waiting = &ASC_BOARDP(shost)->waiting;
7464
7465         if (ASC_NARROW_BOARD(boardp)) {
7466                 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
7467         } else {
7468                 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
7469         }
7470
7471         if ((chip_scsi_id == tgt_id) ||
7472             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) {
7473                 return 0;
7474         }
7475
7476         do {
7477                 if (active->q_tot_cnt[tgt_id] > 0
7478                     || waiting->q_tot_cnt[tgt_id] > 0) {
7479                         len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id);
7480                         ASC_PRT_NEXT();
7481
7482                         len = asc_prt_line(cp, leftlen,
7483                                            "   active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
7484                                            active->q_cur_cnt[tgt_id],
7485                                            active->q_max_cnt[tgt_id],
7486                                            active->q_tot_cnt[tgt_id],
7487                                            active->q_min_tim[tgt_id],
7488                                            active->q_max_tim[tgt_id],
7489                                            (active->q_tot_cnt[tgt_id] ==
7490                                             0) ? 0 : (active->
7491                                                       q_tot_tim[tgt_id] /
7492                                                       active->
7493                                                       q_tot_cnt[tgt_id]),
7494                                            (active->q_tot_cnt[tgt_id] ==
7495                                             0) ? 0 : ASC_TENTHS(active->
7496                                                                 q_tot_tim
7497                                                                 [tgt_id],
7498                                                                 active->
7499                                                                 q_tot_cnt
7500                                                                 [tgt_id]));
7501                         ASC_PRT_NEXT();
7502
7503                         len = asc_prt_line(cp, leftlen,
7504                                            "   waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
7505                                            waiting->q_cur_cnt[tgt_id],
7506                                            waiting->q_max_cnt[tgt_id],
7507                                            waiting->q_tot_cnt[tgt_id],
7508                                            waiting->q_min_tim[tgt_id],
7509                                            waiting->q_max_tim[tgt_id],
7510                                            (waiting->q_tot_cnt[tgt_id] ==
7511                                             0) ? 0 : (waiting->
7512                                                       q_tot_tim[tgt_id] /
7513                                                       waiting->
7514                                                       q_tot_cnt[tgt_id]),
7515                                            (waiting->q_tot_cnt[tgt_id] ==
7516                                             0) ? 0 : ASC_TENTHS(waiting->
7517                                                                 q_tot_tim
7518                                                                 [tgt_id],
7519                                                                 waiting->
7520                                                                 q_tot_cnt
7521                                                                 [tgt_id]));
7522                         ASC_PRT_NEXT();
7523                 }
7524         } while (0);
7525
7526         return totlen;
7527 }
7528 #endif /* CONFIG_PROC_FS */
7529 #endif /* ADVANSYS_STATS */
7530
7531 #ifdef ADVANSYS_DEBUG
7532 /*
7533  * asc_prt_scsi_host()
7534  */
7535 static void asc_prt_scsi_host(struct Scsi_Host *s)
7536 {
7537         asc_board_t *boardp;
7538
7539         boardp = ASC_BOARDP(s);
7540
7541         printk("Scsi_Host at addr 0x%lx\n", (ulong)s);
7542         printk(" host_busy %u, host_no %d, last_reset %d,\n",
7543                s->host_busy, s->host_no, (unsigned)s->last_reset);
7544
7545         printk(" base 0x%lx, io_port 0x%lx, irq 0x%x,\n",
7546                (ulong)s->base, (ulong)s->io_port, s->irq);
7547
7548         printk(" dma_channel %d, this_id %d, can_queue %d,\n",
7549                s->dma_channel, s->this_id, s->can_queue);
7550
7551         printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
7552                s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
7553
7554         if (ASC_NARROW_BOARD(boardp)) {
7555                 asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
7556                 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
7557         } else {
7558                 asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
7559                 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
7560         }
7561 }
7562
7563 /*
7564  * asc_prt_scsi_cmnd()
7565  */
7566 static void asc_prt_scsi_cmnd(struct scsi_cmnd *s)
7567 {
7568         printk("struct scsi_cmnd at addr 0x%lx\n", (ulong)s);
7569
7570         printk(" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
7571                (ulong)s->device->host, (ulong)s->device, s->device->id,
7572                s->device->lun, s->device->channel);
7573
7574         asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
7575
7576         printk("sc_data_direction %u, resid %d\n",
7577                s->sc_data_direction, s->resid);
7578
7579         printk(" use_sg %u, sglist_len %u\n", s->use_sg, s->sglist_len);
7580
7581         printk(" serial_number 0x%x, retries %d, allowed %d\n",
7582                (unsigned)s->serial_number, s->retries, s->allowed);
7583
7584         printk(" timeout_per_command %d\n", s->timeout_per_command);
7585
7586         printk(" scsi_done 0x%p, done 0x%p, host_scribble 0x%p, result 0x%x\n",
7587                 s->scsi_done, s->done, s->host_scribble, s->result);
7588
7589         printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid);
7590 }
7591
7592 /*
7593  * asc_prt_asc_dvc_var()
7594  */
7595 static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
7596 {
7597         printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
7598
7599         printk(" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl "
7600                "%d,\n", h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
7601
7602         printk(" bus_type %d, init_sdtr 0x%x,\n", h->bus_type,
7603                 (unsigned)h->init_sdtr);
7604
7605         printk(" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, "
7606                "chip_no 0x%x,\n", (unsigned)h->sdtr_done,
7607                (unsigned)h->use_tagged_qng, (unsigned)h->unit_not_ready,
7608                (unsigned)h->chip_no);
7609
7610         printk(" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait "
7611                "%u,\n", (unsigned)h->queue_full_or_busy,
7612                (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
7613
7614         printk(" is_in_int %u, max_total_qng %u, cur_total_qng %u, "
7615                "in_critical_cnt %u,\n", (unsigned)h->is_in_int,
7616                (unsigned)h->max_total_qng, (unsigned)h->cur_total_qng,
7617                (unsigned)h->in_critical_cnt);
7618
7619         printk(" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, "
7620                "pci_fix_asyn_xfer 0x%x,\n", (unsigned)h->last_q_shortage,
7621                (unsigned)h->init_state, (unsigned)h->no_scam,
7622                (unsigned)h->pci_fix_asyn_xfer);
7623
7624         printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no);
7625 }
7626
7627 /*
7628  * asc_prt_asc_dvc_cfg()
7629  */
7630 static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
7631 {
7632         printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
7633
7634         printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
7635                h->can_tagged_qng, h->cmd_qng_enabled);
7636         printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n",
7637                h->disc_enable, h->sdtr_enable);
7638
7639         printk
7640             (" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
7641              h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
7642              h->chip_version);
7643
7644         printk
7645             (" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
7646              to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
7647              h->mcode_date);
7648
7649         printk(" mcode_version %d, overrun_buf 0x%lx\n",
7650                h->mcode_version, (ulong)h->overrun_buf);
7651 }
7652
7653 /*
7654  * asc_prt_asc_scsi_q()
7655  */
7656 static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
7657 {
7658         ASC_SG_HEAD *sgp;
7659         int i;
7660
7661         printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
7662
7663         printk
7664             (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
7665              q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr,
7666              q->q2.tag_code);
7667
7668         printk
7669             (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
7670              (ulong)le32_to_cpu(q->q1.data_addr),
7671              (ulong)le32_to_cpu(q->q1.data_cnt),
7672              (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
7673
7674         printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
7675                (ulong)q->cdbptr, q->q2.cdb_len,
7676                (ulong)q->sg_head, q->q1.sg_queue_cnt);
7677
7678         if (q->sg_head) {
7679                 sgp = q->sg_head;
7680                 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp);
7681                 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt,
7682                        sgp->queue_cnt);
7683                 for (i = 0; i < sgp->entry_cnt; i++) {
7684                         printk(" [%u]: addr 0x%lx, bytes %lu\n",
7685                                i, (ulong)le32_to_cpu(sgp->sg_list[i].addr),
7686                                (ulong)le32_to_cpu(sgp->sg_list[i].bytes));
7687                 }
7688
7689         }
7690 }
7691
7692 /*
7693  * asc_prt_asc_qdone_info()
7694  */
7695 static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
7696 {
7697         printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q);
7698         printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
7699                (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
7700                q->d2.tag_code);
7701         printk
7702             (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
7703              q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
7704 }
7705
7706 /*
7707  * asc_prt_adv_dvc_var()
7708  *
7709  * Display an ADV_DVC_VAR structure.
7710  */
7711 static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
7712 {
7713         printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
7714
7715         printk("  iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
7716                (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able);
7717
7718         printk("  isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
7719                (ulong)h->isr_callback, (unsigned)h->sdtr_able,
7720                (unsigned)h->wdtr_able);
7721
7722         printk("  start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
7723                (unsigned)h->start_motor,
7724                (unsigned)h->scsi_reset_wait, (unsigned)h->irq_no);
7725
7726         printk("  max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
7727                (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
7728                (ulong)h->carr_freelist);
7729
7730         printk("  icq_sp 0x%lx, irq_sp 0x%lx\n",
7731                (ulong)h->icq_sp, (ulong)h->irq_sp);
7732
7733         printk("  no_scam 0x%x, tagqng_able 0x%x\n",
7734                (unsigned)h->no_scam, (unsigned)h->tagqng_able);
7735
7736         printk("  chip_scsi_id 0x%x, cfg 0x%lx\n",
7737                (unsigned)h->chip_scsi_id, (ulong)h->cfg);
7738 }
7739
7740 /*
7741  * asc_prt_adv_dvc_cfg()
7742  *
7743  * Display an ADV_DVC_CFG structure.
7744  */
7745 static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
7746 {
7747         printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
7748
7749         printk("  disc_enable 0x%x, termination 0x%x\n",
7750                h->disc_enable, h->termination);
7751
7752         printk("  chip_version 0x%x, mcode_date 0x%x\n",
7753                h->chip_version, h->mcode_date);
7754
7755         printk("  mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
7756                h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
7757
7758         printk("  control_flag 0x%x\n", h->control_flag);
7759 }
7760
7761 /*
7762  * asc_prt_adv_scsi_req_q()
7763  *
7764  * Display an ADV_SCSI_REQ_Q structure.
7765  */
7766 static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
7767 {
7768         int sg_blk_cnt;
7769         struct asc_sg_block *sg_ptr;
7770
7771         printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
7772
7773         printk("  target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
7774                q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag);
7775
7776         printk("  cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
7777                q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr);
7778
7779         printk("  data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
7780                (ulong)le32_to_cpu(q->data_cnt),
7781                (ulong)le32_to_cpu(q->sense_addr), q->sense_len);
7782
7783         printk
7784             ("  cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
7785              q->cdb_len, q->done_status, q->host_status, q->scsi_status);
7786
7787         printk("  sg_working_ix 0x%x, target_cmd %u\n",
7788                q->sg_working_ix, q->target_cmd);
7789
7790         printk("  scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
7791                (ulong)le32_to_cpu(q->scsiq_rptr),
7792                (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr);
7793
7794         /* Display the request's ADV_SG_BLOCK structures. */
7795         if (q->sg_list_ptr != NULL) {
7796                 sg_blk_cnt = 0;
7797                 while (1) {
7798                         /*
7799                          * 'sg_ptr' is a physical address. Convert it to a virtual
7800                          * address by indexing 'sg_blk_cnt' into the virtual address
7801                          * array 'sg_list_ptr'.
7802                          *
7803                          * XXX - Assumes all SG physical blocks are virtually contiguous.
7804                          */
7805                         sg_ptr =
7806                             &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]);
7807                         asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
7808                         if (sg_ptr->sg_ptr == 0) {
7809                                 break;
7810                         }
7811                         sg_blk_cnt++;
7812                 }
7813         }
7814 }
7815
7816 /*
7817  * asc_prt_adv_sgblock()
7818  *
7819  * Display an ADV_SG_BLOCK structure.
7820  */
7821 static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
7822 {
7823         int i;
7824
7825         printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
7826                (ulong)b, sgblockno);
7827         printk("  sg_cnt %u, sg_ptr 0x%lx\n",
7828                b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr));
7829         ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
7830         if (b->sg_ptr != 0) {
7831                 ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
7832         }
7833         for (i = 0; i < b->sg_cnt; i++) {
7834                 printk("  [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
7835                        i, (ulong)b->sg_list[i].sg_addr,
7836                        (ulong)b->sg_list[i].sg_count);
7837         }
7838 }
7839
7840 /*
7841  * asc_prt_hex()
7842  *
7843  * Print hexadecimal output in 4 byte groupings 32 bytes
7844  * or 8 double-words per line.
7845  */
7846 static void asc_prt_hex(char *f, uchar *s, int l)
7847 {
7848         int i;
7849         int j;
7850         int k;
7851         int m;
7852
7853         printk("%s: (%d bytes)\n", f, l);
7854
7855         for (i = 0; i < l; i += 32) {
7856
7857                 /* Display a maximum of 8 double-words per line. */
7858                 if ((k = (l - i) / 4) >= 8) {
7859                         k = 8;
7860                         m = 0;
7861                 } else {
7862                         m = (l - i) % 4;
7863                 }
7864
7865                 for (j = 0; j < k; j++) {
7866                         printk(" %2.2X%2.2X%2.2X%2.2X",
7867                                (unsigned)s[i + (j * 4)],
7868                                (unsigned)s[i + (j * 4) + 1],
7869                                (unsigned)s[i + (j * 4) + 2],
7870                                (unsigned)s[i + (j * 4) + 3]);
7871                 }
7872
7873                 switch (m) {
7874                 case 0:
7875                 default:
7876                         break;
7877                 case 1:
7878                         printk(" %2.2X", (unsigned)s[i + (j * 4)]);
7879                         break;
7880                 case 2:
7881                         printk(" %2.2X%2.2X",
7882                                (unsigned)s[i + (j * 4)],
7883                                (unsigned)s[i + (j * 4) + 1]);
7884                         break;
7885                 case 3:
7886                         printk(" %2.2X%2.2X%2.2X",
7887                                (unsigned)s[i + (j * 4) + 1],
7888                                (unsigned)s[i + (j * 4) + 2],
7889                                (unsigned)s[i + (j * 4) + 3]);
7890                         break;
7891                 }
7892
7893                 printk("\n");
7894         }
7895 }
7896 #endif /* ADVANSYS_DEBUG */
7897
7898 /*
7899  * --- Asc Library Functions
7900  */
7901
7902 static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
7903 {
7904         PortAddr eisa_cfg_iop;
7905
7906         eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
7907             (PortAddr) (ASC_EISA_CFG_IOP_MASK);
7908         return (inpw(eisa_cfg_iop));
7909 }
7910
7911 static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
7912 {
7913         ushort cfg_lsw;
7914
7915         if (AscGetChipScsiID(iop_base) == new_host_id) {
7916                 return (new_host_id);
7917         }
7918         cfg_lsw = AscGetChipCfgLsw(iop_base);
7919         cfg_lsw &= 0xF8FF;
7920         cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
7921         AscSetChipCfgLsw(iop_base, cfg_lsw);
7922         return (AscGetChipScsiID(iop_base));
7923 }
7924
7925 static unsigned char __devinit AscGetChipScsiCtrl(PortAddr iop_base)
7926 {
7927         unsigned char sc;
7928
7929         AscSetBank(iop_base, 1);
7930         sc = inp(iop_base + IOP_REG_SC);
7931         AscSetBank(iop_base, 0);
7932         return sc;
7933 }
7934
7935 static unsigned char __devinit
7936 AscGetChipVersion(PortAddr iop_base, unsigned short bus_type)
7937 {
7938         if (bus_type & ASC_IS_EISA) {
7939                 PortAddr eisa_iop;
7940                 unsigned char revision;
7941                 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
7942                     (PortAddr) ASC_EISA_REV_IOP_MASK;
7943                 revision = inp(eisa_iop);
7944                 return ASC_CHIP_MIN_VER_EISA - 1 + revision;
7945         }
7946         return AscGetChipVerNo(iop_base);
7947 }
7948
7949 static ASC_DCNT
7950 AscLoadMicroCode(PortAddr iop_base,
7951                  ushort s_addr, uchar *mcode_buf, ushort mcode_size)
7952 {
7953         ASC_DCNT chksum;
7954         ushort mcode_word_size;
7955         ushort mcode_chksum;
7956
7957         /* Write the microcode buffer starting at LRAM address 0. */
7958         mcode_word_size = (ushort)(mcode_size >> 1);
7959         AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
7960         AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
7961
7962         chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
7963         ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong)chksum);
7964         mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
7965                                                  (ushort)ASC_CODE_SEC_BEG,
7966                                                  (ushort)((mcode_size -
7967                                                            s_addr - (ushort)
7968                                                            ASC_CODE_SEC_BEG) /
7969                                                           2));
7970         ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
7971                  (ulong)mcode_chksum);
7972         AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
7973         AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
7974         return (chksum);
7975 }
7976
7977 static int AscFindSignature(PortAddr iop_base)
7978 {
7979         ushort sig_word;
7980
7981         ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
7982                  iop_base, AscGetChipSignatureByte(iop_base));
7983         if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
7984                 ASC_DBG2(1,
7985                          "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
7986                          iop_base, AscGetChipSignatureWord(iop_base));
7987                 sig_word = AscGetChipSignatureWord(iop_base);
7988                 if ((sig_word == (ushort)ASC_1000_ID0W) ||
7989                     (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
7990                         return (1);
7991                 }
7992         }
7993         return (0);
7994 }
7995
7996 static void __devinit AscToggleIRQAct(PortAddr iop_base)
7997 {
7998         AscSetChipStatus(iop_base, CIW_IRQ_ACT);
7999         AscSetChipStatus(iop_base, 0);
8000         return;
8001 }
8002
8003 static uchar __devinit AscGetChipIRQ(PortAddr iop_base, ushort bus_type)
8004 {
8005         ushort cfg_lsw;
8006         uchar chip_irq;
8007
8008         if ((bus_type & ASC_IS_EISA) != 0) {
8009                 cfg_lsw = AscGetEisaChipCfg(iop_base);
8010                 chip_irq = (uchar)(((cfg_lsw >> 8) & 0x07) + 10);
8011                 if ((chip_irq == 13) || (chip_irq > 15)) {
8012                         return (0);
8013                 }
8014                 return (chip_irq);
8015         }
8016         if ((bus_type & ASC_IS_VL) != 0) {
8017                 cfg_lsw = AscGetChipCfgLsw(iop_base);
8018                 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x07));
8019                 if ((chip_irq == 0) || (chip_irq == 4) || (chip_irq == 7)) {
8020                         return (0);
8021                 }
8022                 return ((uchar)(chip_irq + (ASC_MIN_IRQ_NO - 1)));
8023         }
8024         cfg_lsw = AscGetChipCfgLsw(iop_base);
8025         chip_irq = (uchar)(((cfg_lsw >> 2) & 0x03));
8026         if (chip_irq == 3)
8027                 chip_irq += (uchar)2;
8028         return ((uchar)(chip_irq + ASC_MIN_IRQ_NO));
8029 }
8030
8031 static uchar __devinit
8032 AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type)
8033 {
8034         ushort cfg_lsw;
8035
8036         if ((bus_type & ASC_IS_VL) != 0) {
8037                 if (irq_no != 0) {
8038                         if ((irq_no < ASC_MIN_IRQ_NO)
8039                             || (irq_no > ASC_MAX_IRQ_NO)) {
8040                                 irq_no = 0;
8041                         } else {
8042                                 irq_no -= (uchar)((ASC_MIN_IRQ_NO - 1));
8043                         }
8044                 }
8045                 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE3);
8046                 cfg_lsw |= (ushort)0x0010;
8047                 AscSetChipCfgLsw(iop_base, cfg_lsw);
8048                 AscToggleIRQAct(iop_base);
8049                 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE0);
8050                 cfg_lsw |= (ushort)((irq_no & 0x07) << 2);
8051                 AscSetChipCfgLsw(iop_base, cfg_lsw);
8052                 AscToggleIRQAct(iop_base);
8053                 return (AscGetChipIRQ(iop_base, bus_type));
8054         }
8055         if ((bus_type & (ASC_IS_ISA)) != 0) {
8056                 if (irq_no == 15)
8057                         irq_no -= (uchar)2;
8058                 irq_no -= (uchar)ASC_MIN_IRQ_NO;
8059                 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFF3);
8060                 cfg_lsw |= (ushort)((irq_no & 0x03) << 2);
8061                 AscSetChipCfgLsw(iop_base, cfg_lsw);
8062                 return (AscGetChipIRQ(iop_base, bus_type));
8063         }
8064         return (0);
8065 }
8066
8067 #ifdef CONFIG_ISA
8068 static void __devinit AscEnableIsaDma(uchar dma_channel)
8069 {
8070         if (dma_channel < 4) {
8071                 outp(0x000B, (ushort)(0xC0 | dma_channel));
8072                 outp(0x000A, dma_channel);
8073         } else if (dma_channel < 8) {
8074                 outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
8075                 outp(0x00D4, (ushort)(dma_channel - 4));
8076         }
8077         return;
8078 }
8079 #endif /* CONFIG_ISA */
8080
8081 static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
8082 {
8083         EXT_MSG ext_msg;
8084         EXT_MSG out_msg;
8085         ushort halt_q_addr;
8086         int sdtr_accept;
8087         ushort int_halt_code;
8088         ASC_SCSI_BIT_ID_TYPE scsi_busy;
8089         ASC_SCSI_BIT_ID_TYPE target_id;
8090         PortAddr iop_base;
8091         uchar tag_code;
8092         uchar q_status;
8093         uchar halt_qp;
8094         uchar sdtr_data;
8095         uchar target_ix;
8096         uchar q_cntl, tid_no;
8097         uchar cur_dvc_qng;
8098         uchar asyn_sdtr;
8099         uchar scsi_status;
8100         asc_board_t *boardp;
8101
8102         ASC_ASSERT(asc_dvc->drv_ptr != NULL);
8103         boardp = asc_dvc->drv_ptr;
8104
8105         iop_base = asc_dvc->iop_base;
8106         int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
8107
8108         halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
8109         halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
8110         target_ix = AscReadLramByte(iop_base,
8111                                     (ushort)(halt_q_addr +
8112                                              (ushort)ASC_SCSIQ_B_TARGET_IX));
8113         q_cntl =
8114             AscReadLramByte(iop_base,
8115                             (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8116         tid_no = ASC_TIX_TO_TID(target_ix);
8117         target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
8118         if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8119                 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
8120         } else {
8121                 asyn_sdtr = 0;
8122         }
8123         if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
8124                 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8125                         AscSetChipSDTR(iop_base, 0, tid_no);
8126                         boardp->sdtr_data[tid_no] = 0;
8127                 }
8128                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8129                 return (0);
8130         } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
8131                 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8132                         AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8133                         boardp->sdtr_data[tid_no] = asyn_sdtr;
8134                 }
8135                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8136                 return (0);
8137         } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
8138
8139                 AscMemWordCopyPtrFromLram(iop_base,
8140                                           ASCV_MSGIN_BEG,
8141                                           (uchar *)&ext_msg,
8142                                           sizeof(EXT_MSG) >> 1);
8143
8144                 if (ext_msg.msg_type == EXTENDED_MESSAGE &&
8145                     ext_msg.msg_req == EXTENDED_SDTR &&
8146                     ext_msg.msg_len == MS_SDTR_LEN) {
8147                         sdtr_accept = TRUE;
8148                         if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
8149
8150                                 sdtr_accept = FALSE;
8151                                 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
8152                         }
8153                         if ((ext_msg.xfer_period <
8154                              asc_dvc->sdtr_period_tbl[asc_dvc->
8155                                                       host_init_sdtr_index])
8156                             || (ext_msg.xfer_period >
8157                                 asc_dvc->sdtr_period_tbl[asc_dvc->
8158                                                          max_sdtr_index])) {
8159                                 sdtr_accept = FALSE;
8160                                 ext_msg.xfer_period =
8161                                     asc_dvc->sdtr_period_tbl[asc_dvc->
8162                                                              host_init_sdtr_index];
8163                         }
8164                         if (sdtr_accept) {
8165                                 sdtr_data =
8166                                     AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
8167                                                    ext_msg.req_ack_offset);
8168                                 if ((sdtr_data == 0xFF)) {
8169
8170                                         q_cntl |= QC_MSG_OUT;
8171                                         asc_dvc->init_sdtr &= ~target_id;
8172                                         asc_dvc->sdtr_done &= ~target_id;
8173                                         AscSetChipSDTR(iop_base, asyn_sdtr,
8174                                                        tid_no);
8175                                         boardp->sdtr_data[tid_no] = asyn_sdtr;
8176                                 }
8177                         }
8178                         if (ext_msg.req_ack_offset == 0) {
8179
8180                                 q_cntl &= ~QC_MSG_OUT;
8181                                 asc_dvc->init_sdtr &= ~target_id;
8182                                 asc_dvc->sdtr_done &= ~target_id;
8183                                 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8184                         } else {
8185                                 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
8186
8187                                         q_cntl &= ~QC_MSG_OUT;
8188                                         asc_dvc->sdtr_done |= target_id;
8189                                         asc_dvc->init_sdtr |= target_id;
8190                                         asc_dvc->pci_fix_asyn_xfer &=
8191                                             ~target_id;
8192                                         sdtr_data =
8193                                             AscCalSDTRData(asc_dvc,
8194                                                            ext_msg.xfer_period,
8195                                                            ext_msg.
8196                                                            req_ack_offset);
8197                                         AscSetChipSDTR(iop_base, sdtr_data,
8198                                                        tid_no);
8199                                         boardp->sdtr_data[tid_no] = sdtr_data;
8200                                 } else {
8201
8202                                         q_cntl |= QC_MSG_OUT;
8203                                         AscMsgOutSDTR(asc_dvc,
8204                                                       ext_msg.xfer_period,
8205                                                       ext_msg.req_ack_offset);
8206                                         asc_dvc->pci_fix_asyn_xfer &=
8207                                             ~target_id;
8208                                         sdtr_data =
8209                                             AscCalSDTRData(asc_dvc,
8210                                                            ext_msg.xfer_period,
8211                                                            ext_msg.
8212                                                            req_ack_offset);
8213                                         AscSetChipSDTR(iop_base, sdtr_data,
8214                                                        tid_no);
8215                                         boardp->sdtr_data[tid_no] = sdtr_data;
8216                                         asc_dvc->sdtr_done |= target_id;
8217                                         asc_dvc->init_sdtr |= target_id;
8218                                 }
8219                         }
8220
8221                         AscWriteLramByte(iop_base,
8222                                          (ushort)(halt_q_addr +
8223                                                   (ushort)ASC_SCSIQ_B_CNTL),
8224                                          q_cntl);
8225                         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8226                         return (0);
8227                 } else if (ext_msg.msg_type == EXTENDED_MESSAGE &&
8228                            ext_msg.msg_req == EXTENDED_WDTR &&
8229                            ext_msg.msg_len == MS_WDTR_LEN) {
8230
8231                         ext_msg.wdtr_width = 0;
8232                         AscMemWordCopyPtrToLram(iop_base,
8233                                                 ASCV_MSGOUT_BEG,
8234                                                 (uchar *)&ext_msg,
8235                                                 sizeof(EXT_MSG) >> 1);
8236                         q_cntl |= QC_MSG_OUT;
8237                         AscWriteLramByte(iop_base,
8238                                          (ushort)(halt_q_addr +
8239                                                   (ushort)ASC_SCSIQ_B_CNTL),
8240                                          q_cntl);
8241                         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8242                         return (0);
8243                 } else {
8244
8245                         ext_msg.msg_type = MESSAGE_REJECT;
8246                         AscMemWordCopyPtrToLram(iop_base,
8247                                                 ASCV_MSGOUT_BEG,
8248                                                 (uchar *)&ext_msg,
8249                                                 sizeof(EXT_MSG) >> 1);
8250                         q_cntl |= QC_MSG_OUT;
8251                         AscWriteLramByte(iop_base,
8252                                          (ushort)(halt_q_addr +
8253                                                   (ushort)ASC_SCSIQ_B_CNTL),
8254                                          q_cntl);
8255                         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8256                         return (0);
8257                 }
8258         } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
8259
8260                 q_cntl |= QC_REQ_SENSE;
8261
8262                 if ((asc_dvc->init_sdtr & target_id) != 0) {
8263
8264                         asc_dvc->sdtr_done &= ~target_id;
8265
8266                         sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
8267                         q_cntl |= QC_MSG_OUT;
8268                         AscMsgOutSDTR(asc_dvc,
8269                                       asc_dvc->
8270                                       sdtr_period_tbl[(sdtr_data >> 4) &
8271                                                       (uchar)(asc_dvc->
8272                                                               max_sdtr_index -
8273                                                               1)],
8274                                       (uchar)(sdtr_data & (uchar)
8275                                               ASC_SYN_MAX_OFFSET));
8276                 }
8277
8278                 AscWriteLramByte(iop_base,
8279                                  (ushort)(halt_q_addr +
8280                                           (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8281
8282                 tag_code = AscReadLramByte(iop_base,
8283                                            (ushort)(halt_q_addr + (ushort)
8284                                                     ASC_SCSIQ_B_TAG_CODE));
8285                 tag_code &= 0xDC;
8286                 if ((asc_dvc->pci_fix_asyn_xfer & target_id)
8287                     && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
8288                     ) {
8289
8290                         tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
8291                                      | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
8292
8293                 }
8294                 AscWriteLramByte(iop_base,
8295                                  (ushort)(halt_q_addr +
8296                                           (ushort)ASC_SCSIQ_B_TAG_CODE),
8297                                  tag_code);
8298
8299                 q_status = AscReadLramByte(iop_base,
8300                                            (ushort)(halt_q_addr + (ushort)
8301                                                     ASC_SCSIQ_B_STATUS));
8302                 q_status |= (QS_READY | QS_BUSY);
8303                 AscWriteLramByte(iop_base,
8304                                  (ushort)(halt_q_addr +
8305                                           (ushort)ASC_SCSIQ_B_STATUS),
8306                                  q_status);
8307
8308                 scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
8309                 scsi_busy &= ~target_id;
8310                 AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8311
8312                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8313                 return (0);
8314         } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
8315
8316                 AscMemWordCopyPtrFromLram(iop_base,
8317                                           ASCV_MSGOUT_BEG,
8318                                           (uchar *)&out_msg,
8319                                           sizeof(EXT_MSG) >> 1);
8320
8321                 if ((out_msg.msg_type == EXTENDED_MESSAGE) &&
8322                     (out_msg.msg_len == MS_SDTR_LEN) &&
8323                     (out_msg.msg_req == EXTENDED_SDTR)) {
8324
8325                         asc_dvc->init_sdtr &= ~target_id;
8326                         asc_dvc->sdtr_done &= ~target_id;
8327                         AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8328                         boardp->sdtr_data[tid_no] = asyn_sdtr;
8329                 }
8330                 q_cntl &= ~QC_MSG_OUT;
8331                 AscWriteLramByte(iop_base,
8332                                  (ushort)(halt_q_addr +
8333                                           (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8334                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8335                 return (0);
8336         } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
8337
8338                 scsi_status = AscReadLramByte(iop_base,
8339                                               (ushort)((ushort)halt_q_addr +
8340                                                        (ushort)
8341                                                        ASC_SCSIQ_SCSI_STATUS));
8342                 cur_dvc_qng =
8343                     AscReadLramByte(iop_base,
8344                                     (ushort)((ushort)ASC_QADR_BEG +
8345                                              (ushort)target_ix));
8346                 if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
8347
8348                         scsi_busy = AscReadLramByte(iop_base,
8349                                                     (ushort)ASCV_SCSIBUSY_B);
8350                         scsi_busy |= target_id;
8351                         AscWriteLramByte(iop_base,
8352                                          (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8353                         asc_dvc->queue_full_or_busy |= target_id;
8354
8355                         if (scsi_status == SAM_STAT_TASK_SET_FULL) {
8356                                 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
8357                                         cur_dvc_qng -= 1;
8358                                         asc_dvc->max_dvc_qng[tid_no] =
8359                                             cur_dvc_qng;
8360
8361                                         AscWriteLramByte(iop_base,
8362                                                          (ushort)((ushort)
8363                                                                   ASCV_MAX_DVC_QNG_BEG
8364                                                                   + (ushort)
8365                                                                   tid_no),
8366                                                          cur_dvc_qng);
8367
8368                                         /*
8369                                          * Set the device queue depth to the number of
8370                                          * active requests when the QUEUE FULL condition
8371                                          * was encountered.
8372                                          */
8373                                         boardp->queue_full |= target_id;
8374                                         boardp->queue_full_cnt[tid_no] =
8375                                             cur_dvc_qng;
8376                                 }
8377                         }
8378                 }
8379                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8380                 return (0);
8381         }
8382 #if CC_VERY_LONG_SG_LIST
8383         else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) {
8384                 uchar q_no;
8385                 ushort q_addr;
8386                 uchar sg_wk_q_no;
8387                 uchar first_sg_wk_q_no;
8388                 ASC_SCSI_Q *scsiq;      /* Ptr to driver request. */
8389                 ASC_SG_HEAD *sg_head;   /* Ptr to driver SG request. */
8390                 ASC_SG_LIST_Q scsi_sg_q;        /* Structure written to queue. */
8391                 ushort sg_list_dwords;
8392                 ushort sg_entry_cnt;
8393                 uchar next_qp;
8394                 int i;
8395
8396                 q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP);
8397                 if (q_no == ASC_QLINK_END) {
8398                         return (0);
8399                 }
8400
8401                 q_addr = ASC_QNO_TO_QADDR(q_no);
8402
8403                 /*
8404                  * Convert the request's SRB pointer to a host ASC_SCSI_REQ
8405                  * structure pointer using a macro provided by the driver.
8406                  * The ASC_SCSI_REQ pointer provides a pointer to the
8407                  * host ASC_SG_HEAD structure.
8408                  */
8409                 /* Read request's SRB pointer. */
8410                 scsiq = (ASC_SCSI_Q *)
8411                     ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
8412                                                                     (ushort)
8413                                                                     (q_addr +
8414                                                                      ASC_SCSIQ_D_SRBPTR))));
8415
8416                 /*
8417                  * Get request's first and working SG queue.
8418                  */
8419                 sg_wk_q_no = AscReadLramByte(iop_base,
8420                                              (ushort)(q_addr +
8421                                                       ASC_SCSIQ_B_SG_WK_QP));
8422
8423                 first_sg_wk_q_no = AscReadLramByte(iop_base,
8424                                                    (ushort)(q_addr +
8425                                                             ASC_SCSIQ_B_FIRST_SG_WK_QP));
8426
8427                 /*
8428                  * Reset request's working SG queue back to the
8429                  * first SG queue.
8430                  */
8431                 AscWriteLramByte(iop_base,
8432                                  (ushort)(q_addr +
8433                                           (ushort)ASC_SCSIQ_B_SG_WK_QP),
8434                                  first_sg_wk_q_no);
8435
8436                 sg_head = scsiq->sg_head;
8437
8438                 /*
8439                  * Set sg_entry_cnt to the number of SG elements
8440                  * that will be completed on this interrupt.
8441                  *
8442                  * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
8443                  * SG elements. The data_cnt and data_addr fields which
8444                  * add 1 to the SG element capacity are not used when
8445                  * restarting SG handling after a halt.
8446                  */
8447                 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) {
8448                         sg_entry_cnt = ASC_MAX_SG_LIST - 1;
8449
8450                         /*
8451                          * Keep track of remaining number of SG elements that will
8452                          * need to be handled on the next interrupt.
8453                          */
8454                         scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
8455                 } else {
8456                         sg_entry_cnt = scsiq->remain_sg_entry_cnt;
8457                         scsiq->remain_sg_entry_cnt = 0;
8458                 }
8459
8460                 /*
8461                  * Copy SG elements into the list of allocated SG queues.
8462                  *
8463                  * Last index completed is saved in scsiq->next_sg_index.
8464                  */
8465                 next_qp = first_sg_wk_q_no;
8466                 q_addr = ASC_QNO_TO_QADDR(next_qp);
8467                 scsi_sg_q.sg_head_qp = q_no;
8468                 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
8469                 for (i = 0; i < sg_head->queue_cnt; i++) {
8470                         scsi_sg_q.seq_no = i + 1;
8471                         if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
8472                                 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
8473                                 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
8474                                 /*
8475                                  * After very first SG queue RISC FW uses next
8476                                  * SG queue first element then checks sg_list_cnt
8477                                  * against zero and then decrements, so set
8478                                  * sg_list_cnt 1 less than number of SG elements
8479                                  * in each SG queue.
8480                                  */
8481                                 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
8482                                 scsi_sg_q.sg_cur_list_cnt =
8483                                     ASC_SG_LIST_PER_Q - 1;
8484                         } else {
8485                                 /*
8486                                  * This is the last SG queue in the list of
8487                                  * allocated SG queues. If there are more
8488                                  * SG elements than will fit in the allocated
8489                                  * queues, then set the QCSG_SG_XFER_MORE flag.
8490                                  */
8491                                 if (scsiq->remain_sg_entry_cnt != 0) {
8492                                         scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
8493                                 } else {
8494                                         scsi_sg_q.cntl |= QCSG_SG_XFER_END;
8495                                 }
8496                                 /* equals sg_entry_cnt * 2 */
8497                                 sg_list_dwords = sg_entry_cnt << 1;
8498                                 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
8499                                 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
8500                                 sg_entry_cnt = 0;
8501                         }
8502
8503                         scsi_sg_q.q_no = next_qp;
8504                         AscMemWordCopyPtrToLram(iop_base,
8505                                                 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
8506                                                 (uchar *)&scsi_sg_q,
8507                                                 sizeof(ASC_SG_LIST_Q) >> 1);
8508
8509                         AscMemDWordCopyPtrToLram(iop_base,
8510                                                  q_addr + ASC_SGQ_LIST_BEG,
8511                                                  (uchar *)&sg_head->
8512                                                  sg_list[scsiq->next_sg_index],
8513                                                  sg_list_dwords);
8514
8515                         scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
8516
8517                         /*
8518                          * If the just completed SG queue contained the
8519                          * last SG element, then no more SG queues need
8520                          * to be written.
8521                          */
8522                         if (scsi_sg_q.cntl & QCSG_SG_XFER_END) {
8523                                 break;
8524                         }
8525
8526                         next_qp = AscReadLramByte(iop_base,
8527                                                   (ushort)(q_addr +
8528                                                            ASC_SCSIQ_B_FWD));
8529                         q_addr = ASC_QNO_TO_QADDR(next_qp);
8530                 }
8531
8532                 /*
8533                  * Clear the halt condition so the RISC will be restarted
8534                  * after the return.
8535                  */
8536                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8537                 return (0);
8538         }
8539 #endif /* CC_VERY_LONG_SG_LIST */
8540         return (0);
8541 }
8542
8543 static uchar
8544 _AscCopyLramScsiDoneQ(PortAddr iop_base,
8545                       ushort q_addr,
8546                       ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count)
8547 {
8548         ushort _val;
8549         uchar sg_queue_cnt;
8550
8551         DvcGetQinfo(iop_base,
8552                     q_addr + ASC_SCSIQ_DONE_INFO_BEG,
8553                     (uchar *)scsiq,
8554                     (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
8555
8556         _val = AscReadLramWord(iop_base,
8557                                (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
8558         scsiq->q_status = (uchar)_val;
8559         scsiq->q_no = (uchar)(_val >> 8);
8560         _val = AscReadLramWord(iop_base,
8561                                (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8562         scsiq->cntl = (uchar)_val;
8563         sg_queue_cnt = (uchar)(_val >> 8);
8564         _val = AscReadLramWord(iop_base,
8565                                (ushort)(q_addr +
8566                                         (ushort)ASC_SCSIQ_B_SENSE_LEN));
8567         scsiq->sense_len = (uchar)_val;
8568         scsiq->extra_bytes = (uchar)(_val >> 8);
8569
8570         /*
8571          * Read high word of remain bytes from alternate location.
8572          */
8573         scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base,
8574                                                           (ushort)(q_addr +
8575                                                                    (ushort)
8576                                                                    ASC_SCSIQ_W_ALT_DC1)))
8577                                << 16);
8578         /*
8579          * Read low word of remain bytes from original location.
8580          */
8581         scsiq->remain_bytes += AscReadLramWord(iop_base,
8582                                                (ushort)(q_addr + (ushort)
8583                                                         ASC_SCSIQ_DW_REMAIN_XFER_CNT));
8584
8585         scsiq->remain_bytes &= max_dma_count;
8586         return (sg_queue_cnt);
8587 }
8588
8589 static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
8590 {
8591         uchar next_qp;
8592         uchar n_q_used;
8593         uchar sg_list_qp;
8594         uchar sg_queue_cnt;
8595         uchar q_cnt;
8596         uchar done_q_tail;
8597         uchar tid_no;
8598         ASC_SCSI_BIT_ID_TYPE scsi_busy;
8599         ASC_SCSI_BIT_ID_TYPE target_id;
8600         PortAddr iop_base;
8601         ushort q_addr;
8602         ushort sg_q_addr;
8603         uchar cur_target_qng;
8604         ASC_QDONE_INFO scsiq_buf;
8605         ASC_QDONE_INFO *scsiq;
8606         int false_overrun;
8607
8608         iop_base = asc_dvc->iop_base;
8609         n_q_used = 1;
8610         scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
8611         done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
8612         q_addr = ASC_QNO_TO_QADDR(done_q_tail);
8613         next_qp = AscReadLramByte(iop_base,
8614                                   (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
8615         if (next_qp != ASC_QLINK_END) {
8616                 AscPutVarDoneQTail(iop_base, next_qp);
8617                 q_addr = ASC_QNO_TO_QADDR(next_qp);
8618                 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
8619                                                      asc_dvc->max_dma_count);
8620                 AscWriteLramByte(iop_base,
8621                                  (ushort)(q_addr +
8622                                           (ushort)ASC_SCSIQ_B_STATUS),
8623                                  (uchar)(scsiq->
8624                                          q_status & (uchar)~(QS_READY |
8625                                                              QS_ABORTED)));
8626                 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
8627                 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
8628                 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
8629                         sg_q_addr = q_addr;
8630                         sg_list_qp = next_qp;
8631                         for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
8632                                 sg_list_qp = AscReadLramByte(iop_base,
8633                                                              (ushort)(sg_q_addr
8634                                                                       + (ushort)
8635                                                                       ASC_SCSIQ_B_FWD));
8636                                 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
8637                                 if (sg_list_qp == ASC_QLINK_END) {
8638                                         AscSetLibErrorCode(asc_dvc,
8639                                                            ASCQ_ERR_SG_Q_LINKS);
8640                                         scsiq->d3.done_stat = QD_WITH_ERROR;
8641                                         scsiq->d3.host_stat =
8642                                             QHSTA_D_QDONE_SG_LIST_CORRUPTED;
8643                                         goto FATAL_ERR_QDONE;
8644                                 }
8645                                 AscWriteLramByte(iop_base,
8646                                                  (ushort)(sg_q_addr + (ushort)
8647                                                           ASC_SCSIQ_B_STATUS),
8648                                                  QS_FREE);
8649                         }
8650                         n_q_used = sg_queue_cnt + 1;
8651                         AscPutVarDoneQTail(iop_base, sg_list_qp);
8652                 }
8653                 if (asc_dvc->queue_full_or_busy & target_id) {
8654                         cur_target_qng = AscReadLramByte(iop_base,
8655                                                          (ushort)((ushort)
8656                                                                   ASC_QADR_BEG
8657                                                                   + (ushort)
8658                                                                   scsiq->d2.
8659                                                                   target_ix));
8660                         if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
8661                                 scsi_busy = AscReadLramByte(iop_base, (ushort)
8662                                                             ASCV_SCSIBUSY_B);
8663                                 scsi_busy &= ~target_id;
8664                                 AscWriteLramByte(iop_base,
8665                                                  (ushort)ASCV_SCSIBUSY_B,
8666                                                  scsi_busy);
8667                                 asc_dvc->queue_full_or_busy &= ~target_id;
8668                         }
8669                 }
8670                 if (asc_dvc->cur_total_qng >= n_q_used) {
8671                         asc_dvc->cur_total_qng -= n_q_used;
8672                         if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
8673                                 asc_dvc->cur_dvc_qng[tid_no]--;
8674                         }
8675                 } else {
8676                         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
8677                         scsiq->d3.done_stat = QD_WITH_ERROR;
8678                         goto FATAL_ERR_QDONE;
8679                 }
8680                 if ((scsiq->d2.srb_ptr == 0UL) ||
8681                     ((scsiq->q_status & QS_ABORTED) != 0)) {
8682                         return (0x11);
8683                 } else if (scsiq->q_status == QS_DONE) {
8684                         false_overrun = FALSE;
8685                         if (scsiq->extra_bytes != 0) {
8686                                 scsiq->remain_bytes +=
8687                                     (ADV_DCNT)scsiq->extra_bytes;
8688                         }
8689                         if (scsiq->d3.done_stat == QD_WITH_ERROR) {
8690                                 if (scsiq->d3.host_stat ==
8691                                     QHSTA_M_DATA_OVER_RUN) {
8692                                         if ((scsiq->
8693                                              cntl & (QC_DATA_IN | QC_DATA_OUT))
8694                                             == 0) {
8695                                                 scsiq->d3.done_stat =
8696                                                     QD_NO_ERROR;
8697                                                 scsiq->d3.host_stat =
8698                                                     QHSTA_NO_ERROR;
8699                                         } else if (false_overrun) {
8700                                                 scsiq->d3.done_stat =
8701                                                     QD_NO_ERROR;
8702                                                 scsiq->d3.host_stat =
8703                                                     QHSTA_NO_ERROR;
8704                                         }
8705                                 } else if (scsiq->d3.host_stat ==
8706                                            QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
8707                                         AscStopChip(iop_base);
8708                                         AscSetChipControl(iop_base,
8709                                                           (uchar)(CC_SCSI_RESET
8710                                                                   | CC_HALT));
8711                                         DvcDelayNanoSecond(asc_dvc, 60000);
8712                                         AscSetChipControl(iop_base, CC_HALT);
8713                                         AscSetChipStatus(iop_base,
8714                                                          CIW_CLR_SCSI_RESET_INT);
8715                                         AscSetChipStatus(iop_base, 0);
8716                                         AscSetChipControl(iop_base, 0);
8717                                 }
8718                         }
8719                         if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
8720                                 asc_isr_callback(asc_dvc, scsiq);
8721                         } else {
8722                                 if ((AscReadLramByte(iop_base,
8723                                                      (ushort)(q_addr + (ushort)
8724                                                               ASC_SCSIQ_CDB_BEG))
8725                                      == START_STOP)) {
8726                                         asc_dvc->unit_not_ready &= ~target_id;
8727                                         if (scsiq->d3.done_stat != QD_NO_ERROR) {
8728                                                 asc_dvc->start_motor &=
8729                                                     ~target_id;
8730                                         }
8731                                 }
8732                         }
8733                         return (1);
8734                 } else {
8735                         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
8736  FATAL_ERR_QDONE:
8737                         if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
8738                                 asc_isr_callback(asc_dvc, scsiq);
8739                         }
8740                         return (0x80);
8741                 }
8742         }
8743         return (0);
8744 }
8745
8746 static int AscISR(ASC_DVC_VAR *asc_dvc)
8747 {
8748         ASC_CS_TYPE chipstat;
8749         PortAddr iop_base;
8750         ushort saved_ram_addr;
8751         uchar ctrl_reg;
8752         uchar saved_ctrl_reg;
8753         int int_pending;
8754         int status;
8755         uchar host_flag;
8756
8757         iop_base = asc_dvc->iop_base;
8758         int_pending = FALSE;
8759
8760         if (AscIsIntPending(iop_base) == 0) {
8761                 return int_pending;
8762         }
8763
8764         if ((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) {
8765                 return (ERR);
8766         }
8767         if (asc_dvc->in_critical_cnt != 0) {
8768                 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
8769                 return (ERR);
8770         }
8771         if (asc_dvc->is_in_int) {
8772                 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
8773                 return (ERR);
8774         }
8775         asc_dvc->is_in_int = TRUE;
8776         ctrl_reg = AscGetChipControl(iop_base);
8777         saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
8778                                        CC_SINGLE_STEP | CC_DIAG | CC_TEST));
8779         chipstat = AscGetChipStatus(iop_base);
8780         if (chipstat & CSW_SCSI_RESET_LATCH) {
8781                 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
8782                         int i = 10;
8783                         int_pending = TRUE;
8784                         asc_dvc->sdtr_done = 0;
8785                         saved_ctrl_reg &= (uchar)(~CC_HALT);
8786                         while ((AscGetChipStatus(iop_base) &
8787                                 CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
8788                                 DvcSleepMilliSecond(100);
8789                         }
8790                         AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
8791                         AscSetChipControl(iop_base, CC_HALT);
8792                         AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
8793                         AscSetChipStatus(iop_base, 0);
8794                         chipstat = AscGetChipStatus(iop_base);
8795                 }
8796         }
8797         saved_ram_addr = AscGetChipLramAddr(iop_base);
8798         host_flag = AscReadLramByte(iop_base,
8799                                     ASCV_HOST_FLAG_B) &
8800             (uchar)(~ASC_HOST_FLAG_IN_ISR);
8801         AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
8802                          (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
8803         if ((chipstat & CSW_INT_PENDING)
8804             || (int_pending)
8805             ) {
8806                 AscAckInterrupt(iop_base);
8807                 int_pending = TRUE;
8808                 if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
8809                         if (AscIsrChipHalted(asc_dvc) == ERR) {
8810                                 goto ISR_REPORT_QDONE_FATAL_ERROR;
8811                         } else {
8812                                 saved_ctrl_reg &= (uchar)(~CC_HALT);
8813                         }
8814                 } else {
8815  ISR_REPORT_QDONE_FATAL_ERROR:
8816                         if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
8817                                 while (((status =
8818                                          AscIsrQDone(asc_dvc)) & 0x01) != 0) {
8819                                 }
8820                         } else {
8821                                 do {
8822                                         if ((status =
8823                                              AscIsrQDone(asc_dvc)) == 1) {
8824                                                 break;
8825                                         }
8826                                 } while (status == 0x11);
8827                         }
8828                         if ((status & 0x80) != 0)
8829                                 int_pending = ERR;
8830                 }
8831         }
8832         AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
8833         AscSetChipLramAddr(iop_base, saved_ram_addr);
8834         AscSetChipControl(iop_base, saved_ctrl_reg);
8835         asc_dvc->is_in_int = FALSE;
8836         return (int_pending);
8837 }
8838
8839 /* Microcode buffer is kept after initialization for error recovery. */
8840 static uchar _asc_mcode_buf[] = {
8841         0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8842         0x00, 0x00, 0x00, 0x00,
8843         0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00,
8844         0x00, 0x00, 0x00, 0x00,
8845         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8846         0x00, 0x00, 0x00, 0x00,
8847         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8848         0x00, 0x00, 0x00, 0x00,
8849         0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, 0x01, 0x00, 0x00, 0x00,
8850         0x00, 0xFF, 0x00, 0x00,
8851         0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00,
8852         0x00, 0x00, 0x00, 0x00,
8853         0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
8854         0x00, 0x00, 0x00, 0x00,
8855         0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x88,
8856         0x00, 0x00, 0x00, 0x00,
8857         0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73,
8858         0x03, 0x23, 0x36, 0x40,
8859         0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
8860         0xC2, 0x00, 0x92, 0x80,
8861         0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xDF, 0x23, 0x36, 0x60,
8862         0xB6, 0x00, 0x92, 0x80,
8863         0x4F, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00,
8864         0x92, 0x80, 0x80, 0x62,
8865         0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
8866         0xCD, 0x04, 0x4D, 0x00,
8867         0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, 0x04, 0x61, 0x84, 0x01,
8868         0xE6, 0x84, 0xD2, 0xC1,
8869         0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97,
8870         0xC6, 0x81, 0xC2, 0x88,
8871         0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
8872         0x84, 0x97, 0x07, 0xA6,
8873         0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x01, 0xDE,
8874         0xC2, 0x88, 0xCE, 0x00,
8875         0x69, 0x60, 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01,
8876         0x80, 0x63, 0x07, 0xA6,
8877         0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
8878         0x34, 0x01, 0x00, 0x33,
8879         0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23,
8880         0x68, 0x98, 0x4D, 0x04,
8881         0x04, 0x85, 0x05, 0xD8, 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23,
8882         0xF8, 0x88, 0xFB, 0x23,
8883         0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
8884         0x00, 0x33, 0x0A, 0x00,
8885         0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, 0x00, 0x33, 0x0B, 0x00,
8886         0xC2, 0x88, 0xCD, 0x04,
8887         0x36, 0x2D, 0x00, 0x33, 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81,
8888         0x06, 0xAB, 0x82, 0x01,
8889         0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
8890         0x3C, 0x01, 0x00, 0x05,
8891         0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01,
8892         0x15, 0x23, 0xA1, 0x01,
8893         0xBE, 0x81, 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00,
8894         0x06, 0x61, 0x00, 0xA0,
8895         0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
8896         0xC2, 0x88, 0x06, 0x23,
8897         0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xD4, 0x01,
8898         0x57, 0x60, 0x00, 0xA0,
8899         0xDA, 0x01, 0xE6, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73,
8900         0x4B, 0x00, 0x06, 0x61,
8901         0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
8902         0x4F, 0x00, 0x84, 0x97,
8903         0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x62, 0x97,
8904         0x48, 0x04, 0x84, 0x80,
8905         0xF0, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00,
8906         0x81, 0x73, 0x06, 0x29,
8907         0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
8908         0x04, 0x98, 0xF0, 0x80,
8909         0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, 0x7C, 0x95, 0x06, 0xA6,
8910         0x34, 0x02, 0x03, 0xA6,
8911         0x4C, 0x04, 0x46, 0x82, 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96,
8912         0x46, 0x82, 0xFE, 0x95,
8913         0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
8914         0x07, 0xA6, 0x5A, 0x02,
8915         0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, 0xC2, 0x88, 0x7C, 0x95,
8916         0x48, 0x82, 0x60, 0x96,
8917         0x48, 0x82, 0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84,
8918         0x04, 0x01, 0x0C, 0xDC,
8919         0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
8920         0x6F, 0x00, 0xA5, 0x01,
8921         0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01,
8922         0x02, 0xA6, 0xAA, 0x02,
8923         0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04,
8924         0x01, 0xA6, 0xB4, 0x02,
8925         0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
8926         0x80, 0x63, 0x00, 0x43,
8927         0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23,
8928         0x04, 0x61, 0x84, 0x01,
8929         0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F,
8930         0x00, 0x00, 0xEA, 0x82,
8931         0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
8932         0x00, 0x33, 0x1F, 0x00,
8933         0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x7E, 0x98,
8934         0xB6, 0x2D, 0x01, 0xA6,
8935         0x14, 0x03, 0x00, 0xA6, 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6,
8936         0x10, 0x03, 0x03, 0xA6,
8937         0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
8938         0x7C, 0x95, 0xEE, 0x82,
8939         0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, 0x7E, 0x98, 0x64, 0xE4,
8940         0x04, 0x01, 0x2D, 0xC8,
8941         0x31, 0x05, 0x07, 0x01, 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01,
8942         0x05, 0x05, 0x86, 0x98,
8943         0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
8944         0x3C, 0x04, 0x06, 0xA6,
8945         0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, 0x25, 0x00, 0xC2, 0x88,
8946         0x7C, 0x95, 0x32, 0x83,
8947         0x60, 0x96, 0x32, 0x83, 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05,
8948         0xEB, 0x04, 0x00, 0x33,
8949         0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
8950         0xFF, 0xA2, 0x7A, 0x03,
8951         0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, 0x05, 0x05, 0x15, 0x01,
8952         0x00, 0xA2, 0x9A, 0x03,
8953         0xEC, 0x00, 0x6E, 0x00, 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00,
8954         0x01, 0xA6, 0x96, 0x03,
8955         0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
8956         0xA4, 0x03, 0x00, 0xA6,
8957         0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, 0x01, 0xA6, 0xA4, 0x03,
8958         0x07, 0xA6, 0xB2, 0x03,
8959         0xD4, 0x83, 0x7C, 0x95, 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88,
8960         0xA8, 0x98, 0x80, 0x42,
8961         0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
8962         0xC0, 0x83, 0x00, 0x33,
8963         0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36, 0x04, 0x23,
8964         0xA0, 0x01, 0x12, 0x23,
8965         0xA1, 0x01, 0x10, 0x84, 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B,
8966         0x80, 0x67, 0x05, 0x23,
8967         0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
8968         0x06, 0xA6, 0x0A, 0x04,
8969         0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xF4, 0x83, 0x60, 0x96,
8970         0xF4, 0x83, 0x20, 0x84,
8971         0x07, 0xF0, 0x06, 0xA4, 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
8972         0x83, 0x03, 0x80, 0x63,
8973         0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
8974         0x38, 0x04, 0x00, 0x33,
8975         0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, 0x60, 0x96, 0x20, 0x84,
8976         0x1D, 0x01, 0x06, 0xCC,
8977         0x00, 0x33, 0x00, 0x84, 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62,
8978         0xA2, 0x0D, 0x80, 0x63,
8979         0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
8980         0x80, 0x63, 0xA3, 0x01,
8981         0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, 0x86, 0x04, 0x0A, 0xA0,
8982         0x76, 0x04, 0xE0, 0x00,
8983         0x00, 0x33, 0x1D, 0x00, 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00,
8984         0x00, 0x33, 0x1E, 0x00,
8985         0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
8986         0x08, 0x23, 0x22, 0xA3,
8987         0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, 0x02, 0x23, 0x22, 0xA3,
8988         0xC4, 0x04, 0x42, 0x23,
8989         0xF8, 0x88, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23,
8990         0xF8, 0x88, 0x04, 0x98,
8991         0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
8992         0x81, 0x62, 0xE8, 0x81,
8993         0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, 0x04, 0x98, 0xB4, 0x98,
8994         0x00, 0x33, 0x00, 0x81,
8995         0xC0, 0x20, 0x81, 0x62, 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23,
8996         0xF8, 0x88, 0x04, 0x23,
8997         0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
8998         0xF4, 0x04, 0x00, 0x33,
8999         0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01,
9000         0x04, 0x23, 0xA0, 0x01,
9001         0x04, 0x98, 0x26, 0x95, 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00,
9002         0x00, 0xA3, 0x22, 0x05,
9003         0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
9004         0x46, 0x97, 0xCD, 0x04,
9005         0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23,
9006         0x82, 0x01, 0x34, 0x85,
9007         0x02, 0x23, 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05,
9008         0x1D, 0x01, 0x04, 0xD6,
9009         0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
9010         0x49, 0x00, 0x81, 0x01,
9011         0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01,
9012         0x49, 0x04, 0x80, 0x01,
9013         0xC9, 0x00, 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04,
9014         0x01, 0x23, 0xEA, 0x00,
9015         0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
9016         0x07, 0xA4, 0xF8, 0x05,
9017         0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, 0x00, 0x33, 0x2D, 0x00,
9018         0xC2, 0x88, 0x04, 0xA0,
9019         0xB8, 0x05, 0x80, 0x63, 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61,
9020         0x00, 0xA2, 0xA4, 0x05,
9021         0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
9022         0x62, 0x97, 0x04, 0x85,
9023         0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, 0x08, 0xA0, 0xBE, 0x05,
9024         0xF4, 0x85, 0x03, 0xA0,
9025         0xC4, 0x05, 0xF4, 0x85, 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63,
9026         0xCC, 0x86, 0x07, 0xA0,
9027         0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
9028         0x80, 0x67, 0x80, 0x63,
9029         0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, 0x68, 0x98, 0x48, 0x23,
9030         0xF8, 0x88, 0x07, 0x23,
9031         0x80, 0x00, 0x06, 0x87, 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00,
9032         0x00, 0x63, 0x4A, 0x00,
9033         0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
9034         0x07, 0x41, 0x83, 0x03,
9035         0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, 0x37, 0x00, 0xC2, 0x88,
9036         0x1D, 0x01, 0x01, 0xD6,
9037         0x20, 0x23, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00,
9038         0x07, 0xA6, 0x7C, 0x05,
9039         0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
9040         0x52, 0x00, 0x06, 0x61,
9041         0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, 0xC0, 0x23, 0x07, 0x41,
9042         0x00, 0x63, 0x1D, 0x01,
9043         0x04, 0xCC, 0x00, 0x33, 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23,
9044         0x07, 0x41, 0x00, 0x63,
9045         0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
9046         0xDF, 0x00, 0x06, 0xA6,
9047         0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x80, 0x63, 0x00, 0x33,
9048         0x00, 0x40, 0xC0, 0x20,
9049         0x81, 0x62, 0x00, 0x63, 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63,
9050         0x06, 0xA6, 0x94, 0x06,
9051         0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
9052         0x40, 0x0E, 0x80, 0x63,
9053         0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x40, 0x0E,
9054         0x80, 0x63, 0x00, 0x43,
9055         0x00, 0xA0, 0xA2, 0x06, 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05,
9056         0x80, 0x67, 0x40, 0x0E,
9057         0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
9058         0x07, 0xA6, 0xD6, 0x06,
9059         0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0x89, 0x00,
9060         0x0A, 0x2B, 0x07, 0xA6,
9061         0xE8, 0x06, 0x00, 0x33, 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2,
9062         0xF4, 0x06, 0xC0, 0x0E,
9063         0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
9064         0x81, 0x62, 0x04, 0x01,
9065         0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6,
9066         0x8C, 0x06, 0x00, 0x33,
9067         0x2C, 0x00, 0xC2, 0x88, 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03,
9068         0x80, 0x63, 0x06, 0xA6,
9069         0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
9070         0x00, 0x00, 0x80, 0x67,
9071         0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, 0x07, 0xA6, 0x7C, 0x05,
9072         0xBF, 0x23, 0x04, 0x61,
9073         0x84, 0x01, 0xE6, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00,
9074         0x00, 0x01, 0xF2, 0x00,
9075         0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
9076         0x80, 0x05, 0x81, 0x05,
9077         0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00,
9078         0x70, 0x00, 0x81, 0x01,
9079         0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04,
9080         0x70, 0x00, 0x80, 0x01,
9081         0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
9082         0xF1, 0x00, 0x70, 0x00,
9083         0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01,
9084         0x71, 0x04, 0x70, 0x00,
9085         0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05,
9086         0xA3, 0x01, 0xA2, 0x01,
9087         0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
9088         0xC4, 0x07, 0x00, 0x33,
9089         0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8,
9090         0x48, 0x00, 0xB0, 0x01,
9091         0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43,
9092         0x00, 0xA2, 0xE4, 0x07,
9093         0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
9094         0x05, 0x05, 0x00, 0x63,
9095         0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43,
9096         0x76, 0x08, 0x80, 0x02,
9097         0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
9098         0x00, 0x02, 0x00, 0xA0,
9099         0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
9100         0x00, 0x63, 0xF3, 0x04,
9101         0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40,
9102         0x00, 0xA2, 0x44, 0x08,
9103         0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1,
9104         0x24, 0x08, 0x04, 0x98,
9105         0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
9106         0x5A, 0x88, 0x02, 0x01,
9107         0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, 0x4A, 0x88, 0x75, 0x00,
9108         0x00, 0xA3, 0x64, 0x08,
9109         0x00, 0x05, 0x4E, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63,
9110         0x06, 0xA6, 0x76, 0x08,
9111         0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
9112         0x00, 0x63, 0x38, 0x2B,
9113         0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, 0x31, 0x05, 0x92, 0x98,
9114         0x05, 0x05, 0xB2, 0x09,
9115         0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63,
9116         0x80, 0x32, 0x80, 0x36,
9117         0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
9118         0x40, 0x36, 0x40, 0x3A,
9119         0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0xB4, 0x08,
9120         0x5D, 0x00, 0xFE, 0xC3,
9121         0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73,
9122         0xFF, 0xFD, 0x80, 0x73,
9123         0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
9124         0xA1, 0x23, 0xA1, 0x01,
9125         0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2,
9126         0x80, 0x00, 0x03, 0xC2,
9127         0xF1, 0xC7, 0x41, 0x23, 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23,
9128         0xA0, 0x01, 0xE6, 0x84,
9129 };
9130
9131 static ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
9132 static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
9133
9134 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST  16
9135 static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
9136         INQUIRY,
9137         REQUEST_SENSE,
9138         READ_CAPACITY,
9139         READ_TOC,
9140         MODE_SELECT,
9141         MODE_SENSE,
9142         MODE_SELECT_10,
9143         MODE_SENSE_10,
9144         0xFF,
9145         0xFF,
9146         0xFF,
9147         0xFF,
9148         0xFF,
9149         0xFF,
9150         0xFF,
9151         0xFF
9152 };
9153
9154 static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
9155 {
9156         PortAddr iop_base;
9157         ulong last_int_level;
9158         int sta;
9159         int n_q_required;
9160         int disable_syn_offset_one_fix;
9161         int i;
9162         ASC_PADDR addr;
9163         ushort sg_entry_cnt = 0;
9164         ushort sg_entry_cnt_minus_one = 0;
9165         uchar target_ix;
9166         uchar tid_no;
9167         uchar sdtr_data;
9168         uchar extra_bytes;
9169         uchar scsi_cmd;
9170         uchar disable_cmd;
9171         ASC_SG_HEAD *sg_head;
9172         ASC_DCNT data_cnt;
9173
9174         iop_base = asc_dvc->iop_base;
9175         sg_head = scsiq->sg_head;
9176         if (asc_dvc->err_code != 0)
9177                 return (ERR);
9178         if (scsiq == (ASC_SCSI_Q *)0L) {
9179                 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
9180                 return (ERR);
9181         }
9182         scsiq->q1.q_no = 0;
9183         if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
9184                 scsiq->q1.extra_bytes = 0;
9185         }
9186         sta = 0;
9187         target_ix = scsiq->q2.target_ix;
9188         tid_no = ASC_TIX_TO_TID(target_ix);
9189         n_q_required = 1;
9190         if (scsiq->cdbptr[0] == REQUEST_SENSE) {
9191                 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
9192                         asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
9193                         sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9194                         AscMsgOutSDTR(asc_dvc,
9195                                       asc_dvc->
9196                                       sdtr_period_tbl[(sdtr_data >> 4) &
9197                                                       (uchar)(asc_dvc->
9198                                                               max_sdtr_index -
9199                                                               1)],
9200                                       (uchar)(sdtr_data & (uchar)
9201                                               ASC_SYN_MAX_OFFSET));
9202                         scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
9203                 }
9204         }
9205         last_int_level = DvcEnterCritical();
9206         if (asc_dvc->in_critical_cnt != 0) {
9207                 DvcLeaveCritical(last_int_level);
9208                 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
9209                 return (ERR);
9210         }
9211         asc_dvc->in_critical_cnt++;
9212         if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
9213                 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
9214                         asc_dvc->in_critical_cnt--;
9215                         DvcLeaveCritical(last_int_level);
9216                         return (ERR);
9217                 }
9218 #if !CC_VERY_LONG_SG_LIST
9219                 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
9220                         asc_dvc->in_critical_cnt--;
9221                         DvcLeaveCritical(last_int_level);
9222                         return (ERR);
9223                 }
9224 #endif /* !CC_VERY_LONG_SG_LIST */
9225                 if (sg_entry_cnt == 1) {
9226                         scsiq->q1.data_addr =
9227                             (ADV_PADDR)sg_head->sg_list[0].addr;
9228                         scsiq->q1.data_cnt =
9229                             (ADV_DCNT)sg_head->sg_list[0].bytes;
9230                         scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
9231                 }
9232                 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
9233         }
9234         scsi_cmd = scsiq->cdbptr[0];
9235         disable_syn_offset_one_fix = FALSE;
9236         if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
9237             !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
9238                 if (scsiq->q1.cntl & QC_SG_HEAD) {
9239                         data_cnt = 0;
9240                         for (i = 0; i < sg_entry_cnt; i++) {
9241                                 data_cnt +=
9242                                     (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i].
9243                                                           bytes);
9244                         }
9245                 } else {
9246                         data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
9247                 }
9248                 if (data_cnt != 0UL) {
9249                         if (data_cnt < 512UL) {
9250                                 disable_syn_offset_one_fix = TRUE;
9251                         } else {
9252                                 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
9253                                      i++) {
9254                                         disable_cmd =
9255                                             _syn_offset_one_disable_cmd[i];
9256                                         if (disable_cmd == 0xFF) {
9257                                                 break;
9258                                         }
9259                                         if (scsi_cmd == disable_cmd) {
9260                                                 disable_syn_offset_one_fix =
9261                                                     TRUE;
9262                                                 break;
9263                                         }
9264                                 }
9265                         }
9266                 }
9267         }
9268         if (disable_syn_offset_one_fix) {
9269                 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
9270                 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
9271                                        ASC_TAG_FLAG_DISABLE_DISCONNECT);
9272         } else {
9273                 scsiq->q2.tag_code &= 0x27;
9274         }
9275         if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
9276                 if (asc_dvc->bug_fix_cntl) {
9277                         if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
9278                                 if ((scsi_cmd == READ_6) ||
9279                                     (scsi_cmd == READ_10)) {
9280                                         addr =
9281                                             (ADV_PADDR)le32_to_cpu(sg_head->
9282                                                                    sg_list
9283                                                                    [sg_entry_cnt_minus_one].
9284                                                                    addr) +
9285                                             (ADV_DCNT)le32_to_cpu(sg_head->
9286                                                                   sg_list
9287                                                                   [sg_entry_cnt_minus_one].
9288                                                                   bytes);
9289                                         extra_bytes =
9290                                             (uchar)((ushort)addr & 0x0003);
9291                                         if ((extra_bytes != 0)
9292                                             &&
9293                                             ((scsiq->q2.
9294                                               tag_code &
9295                                               ASC_TAG_FLAG_EXTRA_BYTES)
9296                                              == 0)) {
9297                                                 scsiq->q2.tag_code |=
9298                                                     ASC_TAG_FLAG_EXTRA_BYTES;
9299                                                 scsiq->q1.extra_bytes =
9300                                                     extra_bytes;
9301                                                 data_cnt =
9302                                                     le32_to_cpu(sg_head->
9303                                                                 sg_list
9304                                                                 [sg_entry_cnt_minus_one].
9305                                                                 bytes);
9306                                                 data_cnt -=
9307                                                     (ASC_DCNT) extra_bytes;
9308                                                 sg_head->
9309                                                     sg_list
9310                                                     [sg_entry_cnt_minus_one].
9311                                                     bytes =
9312                                                     cpu_to_le32(data_cnt);
9313                                         }
9314                                 }
9315                         }
9316                 }
9317                 sg_head->entry_to_copy = sg_head->entry_cnt;
9318 #if CC_VERY_LONG_SG_LIST
9319                 /*
9320                  * Set the sg_entry_cnt to the maximum possible. The rest of
9321                  * the SG elements will be copied when the RISC completes the
9322                  * SG elements that fit and halts.
9323                  */
9324                 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
9325                         sg_entry_cnt = ASC_MAX_SG_LIST;
9326                 }
9327 #endif /* CC_VERY_LONG_SG_LIST */
9328                 n_q_required = AscSgListToQueue(sg_entry_cnt);
9329                 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
9330                      (uint) n_q_required)
9331                     || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
9332                         if ((sta =
9333                              AscSendScsiQueue(asc_dvc, scsiq,
9334                                               n_q_required)) == 1) {
9335                                 asc_dvc->in_critical_cnt--;
9336                                 DvcLeaveCritical(last_int_level);
9337                                 return (sta);
9338                         }
9339                 }
9340         } else {
9341                 if (asc_dvc->bug_fix_cntl) {
9342                         if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
9343                                 if ((scsi_cmd == READ_6) ||
9344                                     (scsi_cmd == READ_10)) {
9345                                         addr =
9346                                             le32_to_cpu(scsiq->q1.data_addr) +
9347                                             le32_to_cpu(scsiq->q1.data_cnt);
9348                                         extra_bytes =
9349                                             (uchar)((ushort)addr & 0x0003);
9350                                         if ((extra_bytes != 0)
9351                                             &&
9352                                             ((scsiq->q2.
9353                                               tag_code &
9354                                               ASC_TAG_FLAG_EXTRA_BYTES)
9355                                              == 0)) {
9356                                                 data_cnt =
9357                                                     le32_to_cpu(scsiq->q1.
9358                                                                 data_cnt);
9359                                                 if (((ushort)data_cnt & 0x01FF)
9360                                                     == 0) {
9361                                                         scsiq->q2.tag_code |=
9362                                                             ASC_TAG_FLAG_EXTRA_BYTES;
9363                                                         data_cnt -= (ASC_DCNT)
9364                                                             extra_bytes;
9365                                                         scsiq->q1.data_cnt =
9366                                                             cpu_to_le32
9367                                                             (data_cnt);
9368                                                         scsiq->q1.extra_bytes =
9369                                                             extra_bytes;
9370                                                 }
9371                                         }
9372                                 }
9373                         }
9374                 }
9375                 n_q_required = 1;
9376                 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
9377                     ((scsiq->q1.cntl & QC_URGENT) != 0)) {
9378                         if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
9379                                                     n_q_required)) == 1) {
9380                                 asc_dvc->in_critical_cnt--;
9381                                 DvcLeaveCritical(last_int_level);
9382                                 return (sta);
9383                         }
9384                 }
9385         }
9386         asc_dvc->in_critical_cnt--;
9387         DvcLeaveCritical(last_int_level);
9388         return (sta);
9389 }
9390
9391 static int
9392 AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
9393 {
9394         PortAddr iop_base;
9395         uchar free_q_head;
9396         uchar next_qp;
9397         uchar tid_no;
9398         uchar target_ix;
9399         int sta;
9400
9401         iop_base = asc_dvc->iop_base;
9402         target_ix = scsiq->q2.target_ix;
9403         tid_no = ASC_TIX_TO_TID(target_ix);
9404         sta = 0;
9405         free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
9406         if (n_q_required > 1) {
9407                 if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
9408                                                          free_q_head, (uchar)
9409                                                          (n_q_required)))
9410                     != (uchar)ASC_QLINK_END) {
9411                         asc_dvc->last_q_shortage = 0;
9412                         scsiq->sg_head->queue_cnt = n_q_required - 1;
9413                         scsiq->q1.q_no = free_q_head;
9414                         if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
9415                                                           free_q_head)) == 1) {
9416                                 AscPutVarFreeQHead(iop_base, next_qp);
9417                                 asc_dvc->cur_total_qng += (uchar)(n_q_required);
9418                                 asc_dvc->cur_dvc_qng[tid_no]++;
9419                         }
9420                         return (sta);
9421                 }
9422         } else if (n_q_required == 1) {
9423                 if ((next_qp = AscAllocFreeQueue(iop_base,
9424                                                  free_q_head)) !=
9425                     ASC_QLINK_END) {
9426                         scsiq->q1.q_no = free_q_head;
9427                         if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
9428                                                     free_q_head)) == 1) {
9429                                 AscPutVarFreeQHead(iop_base, next_qp);
9430                                 asc_dvc->cur_total_qng++;
9431                                 asc_dvc->cur_dvc_qng[tid_no]++;
9432                         }
9433                         return (sta);
9434                 }
9435         }
9436         return (sta);
9437 }
9438
9439 static int AscSgListToQueue(int sg_list)
9440 {
9441         int n_sg_list_qs;
9442
9443         n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
9444         if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
9445                 n_sg_list_qs++;
9446         return (n_sg_list_qs + 1);
9447 }
9448
9449 static uint
9450 AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
9451 {
9452         uint cur_used_qs;
9453         uint cur_free_qs;
9454         ASC_SCSI_BIT_ID_TYPE target_id;
9455         uchar tid_no;
9456
9457         target_id = ASC_TIX_TO_TARGET_ID(target_ix);
9458         tid_no = ASC_TIX_TO_TID(target_ix);
9459         if ((asc_dvc->unit_not_ready & target_id) ||
9460             (asc_dvc->queue_full_or_busy & target_id)) {
9461                 return (0);
9462         }
9463         if (n_qs == 1) {
9464                 cur_used_qs = (uint) asc_dvc->cur_total_qng +
9465                     (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
9466         } else {
9467                 cur_used_qs = (uint) asc_dvc->cur_total_qng +
9468                     (uint) ASC_MIN_FREE_Q;
9469         }
9470         if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
9471                 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
9472                 if (asc_dvc->cur_dvc_qng[tid_no] >=
9473                     asc_dvc->max_dvc_qng[tid_no]) {
9474                         return (0);
9475                 }
9476                 return (cur_free_qs);
9477         }
9478         if (n_qs > 1) {
9479                 if ((n_qs > asc_dvc->last_q_shortage)
9480                     && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
9481                         asc_dvc->last_q_shortage = n_qs;
9482                 }
9483         }
9484         return (0);
9485 }
9486
9487 static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
9488 {
9489         ushort q_addr;
9490         uchar tid_no;
9491         uchar sdtr_data;
9492         uchar syn_period_ix;
9493         uchar syn_offset;
9494         PortAddr iop_base;
9495
9496         iop_base = asc_dvc->iop_base;
9497         if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
9498             ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
9499                 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
9500                 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9501                 syn_period_ix =
9502                     (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
9503                 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
9504                 AscMsgOutSDTR(asc_dvc,
9505                               asc_dvc->sdtr_period_tbl[syn_period_ix],
9506                               syn_offset);
9507                 scsiq->q1.cntl |= QC_MSG_OUT;
9508         }
9509         q_addr = ASC_QNO_TO_QADDR(q_no);
9510         if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
9511                 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
9512         }
9513         scsiq->q1.status = QS_FREE;
9514         AscMemWordCopyPtrToLram(iop_base,
9515                                 q_addr + ASC_SCSIQ_CDB_BEG,
9516                                 (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
9517
9518         DvcPutScsiQ(iop_base,
9519                     q_addr + ASC_SCSIQ_CPY_BEG,
9520                     (uchar *)&scsiq->q1.cntl,
9521                     ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
9522         AscWriteLramWord(iop_base,
9523                          (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
9524                          (ushort)(((ushort)scsiq->q1.
9525                                    q_no << 8) | (ushort)QS_READY));
9526         return (1);
9527 }
9528
9529 static int
9530 AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
9531 {
9532         int sta;
9533         int i;
9534         ASC_SG_HEAD *sg_head;
9535         ASC_SG_LIST_Q scsi_sg_q;
9536         ASC_DCNT saved_data_addr;
9537         ASC_DCNT saved_data_cnt;
9538         PortAddr iop_base;
9539         ushort sg_list_dwords;
9540         ushort sg_index;
9541         ushort sg_entry_cnt;
9542         ushort q_addr;
9543         uchar next_qp;
9544
9545         iop_base = asc_dvc->iop_base;
9546         sg_head = scsiq->sg_head;
9547         saved_data_addr = scsiq->q1.data_addr;
9548         saved_data_cnt = scsiq->q1.data_cnt;
9549         scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
9550         scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
9551 #if CC_VERY_LONG_SG_LIST
9552         /*
9553          * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
9554          * then not all SG elements will fit in the allocated queues.
9555          * The rest of the SG elements will be copied when the RISC
9556          * completes the SG elements that fit and halts.
9557          */
9558         if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
9559                 /*
9560                  * Set sg_entry_cnt to be the number of SG elements that
9561                  * will fit in the allocated SG queues. It is minus 1, because
9562                  * the first SG element is handled above. ASC_MAX_SG_LIST is
9563                  * already inflated by 1 to account for this. For example it
9564                  * may be 50 which is 1 + 7 queues * 7 SG elements.
9565                  */
9566                 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
9567
9568                 /*
9569                  * Keep track of remaining number of SG elements that will
9570                  * need to be handled from a_isr.c.
9571                  */
9572                 scsiq->remain_sg_entry_cnt =
9573                     sg_head->entry_cnt - ASC_MAX_SG_LIST;
9574         } else {
9575 #endif /* CC_VERY_LONG_SG_LIST */
9576                 /*
9577                  * Set sg_entry_cnt to be the number of SG elements that
9578                  * will fit in the allocated SG queues. It is minus 1, because
9579                  * the first SG element is handled above.
9580                  */
9581                 sg_entry_cnt = sg_head->entry_cnt - 1;
9582 #if CC_VERY_LONG_SG_LIST
9583         }
9584 #endif /* CC_VERY_LONG_SG_LIST */
9585         if (sg_entry_cnt != 0) {
9586                 scsiq->q1.cntl |= QC_SG_HEAD;
9587                 q_addr = ASC_QNO_TO_QADDR(q_no);
9588                 sg_index = 1;
9589                 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
9590                 scsi_sg_q.sg_head_qp = q_no;
9591                 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
9592                 for (i = 0; i < sg_head->queue_cnt; i++) {
9593                         scsi_sg_q.seq_no = i + 1;
9594                         if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
9595                                 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
9596                                 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
9597                                 if (i == 0) {
9598                                         scsi_sg_q.sg_list_cnt =
9599                                             ASC_SG_LIST_PER_Q;
9600                                         scsi_sg_q.sg_cur_list_cnt =
9601                                             ASC_SG_LIST_PER_Q;
9602                                 } else {
9603                                         scsi_sg_q.sg_list_cnt =
9604                                             ASC_SG_LIST_PER_Q - 1;
9605                                         scsi_sg_q.sg_cur_list_cnt =
9606                                             ASC_SG_LIST_PER_Q - 1;
9607                                 }
9608                         } else {
9609 #if CC_VERY_LONG_SG_LIST
9610                                 /*
9611                                  * This is the last SG queue in the list of
9612                                  * allocated SG queues. If there are more
9613                                  * SG elements than will fit in the allocated
9614                                  * queues, then set the QCSG_SG_XFER_MORE flag.
9615                                  */
9616                                 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
9617                                         scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
9618                                 } else {
9619 #endif /* CC_VERY_LONG_SG_LIST */
9620                                         scsi_sg_q.cntl |= QCSG_SG_XFER_END;
9621 #if CC_VERY_LONG_SG_LIST
9622                                 }
9623 #endif /* CC_VERY_LONG_SG_LIST */
9624                                 sg_list_dwords = sg_entry_cnt << 1;
9625                                 if (i == 0) {
9626                                         scsi_sg_q.sg_list_cnt = sg_entry_cnt;
9627                                         scsi_sg_q.sg_cur_list_cnt =
9628                                             sg_entry_cnt;
9629                                 } else {
9630                                         scsi_sg_q.sg_list_cnt =
9631                                             sg_entry_cnt - 1;
9632                                         scsi_sg_q.sg_cur_list_cnt =
9633                                             sg_entry_cnt - 1;
9634                                 }
9635                                 sg_entry_cnt = 0;
9636                         }
9637                         next_qp = AscReadLramByte(iop_base,
9638                                                   (ushort)(q_addr +
9639                                                            ASC_SCSIQ_B_FWD));
9640                         scsi_sg_q.q_no = next_qp;
9641                         q_addr = ASC_QNO_TO_QADDR(next_qp);
9642                         AscMemWordCopyPtrToLram(iop_base,
9643                                                 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
9644                                                 (uchar *)&scsi_sg_q,
9645                                                 sizeof(ASC_SG_LIST_Q) >> 1);
9646                         AscMemDWordCopyPtrToLram(iop_base,
9647                                                  q_addr + ASC_SGQ_LIST_BEG,
9648                                                  (uchar *)&sg_head->
9649                                                  sg_list[sg_index],
9650                                                  sg_list_dwords);
9651                         sg_index += ASC_SG_LIST_PER_Q;
9652                         scsiq->next_sg_index = sg_index;
9653                 }
9654         } else {
9655                 scsiq->q1.cntl &= ~QC_SG_HEAD;
9656         }
9657         sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
9658         scsiq->q1.data_addr = saved_data_addr;
9659         scsiq->q1.data_cnt = saved_data_cnt;
9660         return (sta);
9661 }
9662
9663 static int
9664 AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
9665 {
9666         int sta = FALSE;
9667
9668         if (AscHostReqRiscHalt(iop_base)) {
9669                 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
9670                 AscStartChip(iop_base);
9671                 return (sta);
9672         }
9673         return (sta);
9674 }
9675
9676 static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
9677 {
9678         ASC_SCSI_BIT_ID_TYPE org_id;
9679         int i;
9680         int sta = TRUE;
9681
9682         AscSetBank(iop_base, 1);
9683         org_id = AscReadChipDvcID(iop_base);
9684         for (i = 0; i <= ASC_MAX_TID; i++) {
9685                 if (org_id == (0x01 << i))
9686                         break;
9687         }
9688         org_id = (ASC_SCSI_BIT_ID_TYPE) i;
9689         AscWriteChipDvcID(iop_base, id);
9690         if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
9691                 AscSetBank(iop_base, 0);
9692                 AscSetChipSyn(iop_base, sdtr_data);
9693                 if (AscGetChipSyn(iop_base) != sdtr_data) {
9694                         sta = FALSE;
9695                 }
9696         } else {
9697                 sta = FALSE;
9698         }
9699         AscSetBank(iop_base, 1);
9700         AscWriteChipDvcID(iop_base, org_id);
9701         AscSetBank(iop_base, 0);
9702         return (sta);
9703 }
9704
9705 static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
9706 {
9707         uchar i;
9708         ushort s_addr;
9709         PortAddr iop_base;
9710         ushort warn_code;
9711
9712         iop_base = asc_dvc->iop_base;
9713         warn_code = 0;
9714         AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
9715                           (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
9716                                     64) >> 1)
9717             );
9718         i = ASC_MIN_ACTIVE_QNO;
9719         s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
9720         AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9721                          (uchar)(i + 1));
9722         AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9723                          (uchar)(asc_dvc->max_total_qng));
9724         AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9725                          (uchar)i);
9726         i++;
9727         s_addr += ASC_QBLK_SIZE;
9728         for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
9729                 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9730                                  (uchar)(i + 1));
9731                 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9732                                  (uchar)(i - 1));
9733                 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9734                                  (uchar)i);
9735         }
9736         AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9737                          (uchar)ASC_QLINK_END);
9738         AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9739                          (uchar)(asc_dvc->max_total_qng - 1));
9740         AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9741                          (uchar)asc_dvc->max_total_qng);
9742         i++;
9743         s_addr += ASC_QBLK_SIZE;
9744         for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
9745              i++, s_addr += ASC_QBLK_SIZE) {
9746                 AscWriteLramByte(iop_base,
9747                                  (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
9748                 AscWriteLramByte(iop_base,
9749                                  (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
9750                 AscWriteLramByte(iop_base,
9751                                  (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
9752         }
9753         return (warn_code);
9754 }
9755
9756 static ushort AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
9757 {
9758         PortAddr iop_base;
9759         int i;
9760         ushort lram_addr;
9761
9762         iop_base = asc_dvc->iop_base;
9763         AscPutRiscVarFreeQHead(iop_base, 1);
9764         AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
9765         AscPutVarFreeQHead(iop_base, 1);
9766         AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
9767         AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
9768                          (uchar)((int)asc_dvc->max_total_qng + 1));
9769         AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
9770                          (uchar)((int)asc_dvc->max_total_qng + 2));
9771         AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
9772                          asc_dvc->max_total_qng);
9773         AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
9774         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9775         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
9776         AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
9777         AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
9778         AscPutQDoneInProgress(iop_base, 0);
9779         lram_addr = ASC_QADR_BEG;
9780         for (i = 0; i < 32; i++, lram_addr += 2) {
9781                 AscWriteLramWord(iop_base, lram_addr, 0);
9782         }
9783         return (0);
9784 }
9785
9786 static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
9787 {
9788         if (asc_dvc->err_code == 0) {
9789                 asc_dvc->err_code = err_code;
9790                 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
9791                                  err_code);
9792         }
9793         return (err_code);
9794 }
9795
9796 static uchar
9797 AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
9798 {
9799         EXT_MSG sdtr_buf;
9800         uchar sdtr_period_index;
9801         PortAddr iop_base;
9802
9803         iop_base = asc_dvc->iop_base;
9804         sdtr_buf.msg_type = EXTENDED_MESSAGE;
9805         sdtr_buf.msg_len = MS_SDTR_LEN;
9806         sdtr_buf.msg_req = EXTENDED_SDTR;
9807         sdtr_buf.xfer_period = sdtr_period;
9808         sdtr_offset &= ASC_SYN_MAX_OFFSET;
9809         sdtr_buf.req_ack_offset = sdtr_offset;
9810         if ((sdtr_period_index =
9811              AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
9812             asc_dvc->max_sdtr_index) {
9813                 AscMemWordCopyPtrToLram(iop_base,
9814                                         ASCV_MSGOUT_BEG,
9815                                         (uchar *)&sdtr_buf,
9816                                         sizeof(EXT_MSG) >> 1);
9817                 return ((sdtr_period_index << 4) | sdtr_offset);
9818         } else {
9819
9820                 sdtr_buf.req_ack_offset = 0;
9821                 AscMemWordCopyPtrToLram(iop_base,
9822                                         ASCV_MSGOUT_BEG,
9823                                         (uchar *)&sdtr_buf,
9824                                         sizeof(EXT_MSG) >> 1);
9825                 return (0);
9826         }
9827 }
9828
9829 static uchar
9830 AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
9831 {
9832         uchar byte;
9833         uchar sdtr_period_ix;
9834
9835         sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
9836         if ((sdtr_period_ix > asc_dvc->max_sdtr_index)
9837             ) {
9838                 return (0xFF);
9839         }
9840         byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
9841         return (byte);
9842 }
9843
9844 static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
9845 {
9846         AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
9847         AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
9848         return;
9849 }
9850
9851 static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
9852 {
9853         uchar *period_table;
9854         int max_index;
9855         int min_index;
9856         int i;
9857
9858         period_table = asc_dvc->sdtr_period_tbl;
9859         max_index = (int)asc_dvc->max_sdtr_index;
9860         min_index = (int)asc_dvc->host_init_sdtr_index;
9861         if ((syn_time <= period_table[max_index])) {
9862                 for (i = min_index; i < (max_index - 1); i++) {
9863                         if (syn_time <= period_table[i]) {
9864                                 return ((uchar)i);
9865                         }
9866                 }
9867                 return ((uchar)max_index);
9868         } else {
9869                 return ((uchar)(max_index + 1));
9870         }
9871 }
9872
9873 static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
9874 {
9875         ushort q_addr;
9876         uchar next_qp;
9877         uchar q_status;
9878
9879         q_addr = ASC_QNO_TO_QADDR(free_q_head);
9880         q_status = (uchar)AscReadLramByte(iop_base,
9881                                           (ushort)(q_addr +
9882                                                    ASC_SCSIQ_B_STATUS));
9883         next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
9884         if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
9885                 return (next_qp);
9886         }
9887         return (ASC_QLINK_END);
9888 }
9889
9890 static uchar
9891 AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
9892 {
9893         uchar i;
9894
9895         for (i = 0; i < n_free_q; i++) {
9896                 if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
9897                     == ASC_QLINK_END) {
9898                         return (ASC_QLINK_END);
9899                 }
9900         }
9901         return (free_q_head);
9902 }
9903
9904 static int AscHostReqRiscHalt(PortAddr iop_base)
9905 {
9906         int count = 0;
9907         int sta = 0;
9908         uchar saved_stop_code;
9909
9910         if (AscIsChipHalted(iop_base))
9911                 return (1);
9912         saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
9913         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
9914                          ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
9915         do {
9916                 if (AscIsChipHalted(iop_base)) {
9917                         sta = 1;
9918                         break;
9919                 }
9920                 DvcSleepMilliSecond(100);
9921         } while (count++ < 20);
9922         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
9923         return (sta);
9924 }
9925
9926 static int AscStopQueueExe(PortAddr iop_base)
9927 {
9928         int count = 0;
9929
9930         if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
9931                 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
9932                                  ASC_STOP_REQ_RISC_STOP);
9933                 do {
9934                         if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
9935                             ASC_STOP_ACK_RISC_STOP) {
9936                                 return (1);
9937                         }
9938                         DvcSleepMilliSecond(100);
9939                 } while (count++ < 20);
9940         }
9941         return (0);
9942 }
9943
9944 static void DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
9945 {
9946         udelay(micro_sec);
9947 }
9948
9949 static void DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
9950 {
9951         udelay((nano_sec + 999) / 1000);
9952 }
9953
9954 static int AscStartChip(PortAddr iop_base)
9955 {
9956         AscSetChipControl(iop_base, 0);
9957         if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
9958                 return (0);
9959         }
9960         return (1);
9961 }
9962
9963 static int AscStopChip(PortAddr iop_base)
9964 {
9965         uchar cc_val;
9966
9967         cc_val =
9968             AscGetChipControl(iop_base) &
9969             (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
9970         AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
9971         AscSetChipIH(iop_base, INS_HALT);
9972         AscSetChipIH(iop_base, INS_RFLAG_WTM);
9973         if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
9974                 return (0);
9975         }
9976         return (1);
9977 }
9978
9979 static int AscIsChipHalted(PortAddr iop_base)
9980 {
9981         if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
9982                 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
9983                         return (1);
9984                 }
9985         }
9986         return (0);
9987 }
9988
9989 static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
9990 {
9991         AscSetBank(iop_base, 1);
9992         AscWriteChipIH(iop_base, ins_code);
9993         AscSetBank(iop_base, 0);
9994         return;
9995 }
9996
9997 static void AscAckInterrupt(PortAddr iop_base)
9998 {
9999         uchar host_flag;
10000         uchar risc_flag;
10001         ushort loop;
10002
10003         loop = 0;
10004         do {
10005                 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
10006                 if (loop++ > 0x7FFF) {
10007                         break;
10008                 }
10009         } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
10010         host_flag =
10011             AscReadLramByte(iop_base,
10012                             ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
10013         AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
10014                          (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
10015         AscSetChipStatus(iop_base, CIW_INT_ACK);
10016         loop = 0;
10017         while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
10018                 AscSetChipStatus(iop_base, CIW_INT_ACK);
10019                 if (loop++ > 3) {
10020                         break;
10021                 }
10022         }
10023         AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
10024         return;
10025 }
10026
10027 static void AscDisableInterrupt(PortAddr iop_base)
10028 {
10029         ushort cfg;
10030
10031         cfg = AscGetChipCfgLsw(iop_base);
10032         AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
10033         return;
10034 }
10035
10036 static void AscEnableInterrupt(PortAddr iop_base)
10037 {
10038         ushort cfg;
10039
10040         cfg = AscGetChipCfgLsw(iop_base);
10041         AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
10042         return;
10043 }
10044
10045 static void AscSetBank(PortAddr iop_base, uchar bank)
10046 {
10047         uchar val;
10048
10049         val = AscGetChipControl(iop_base) &
10050             (~
10051              (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
10052               CC_CHIP_RESET));
10053         if (bank == 1) {
10054                 val |= CC_BANK_ONE;
10055         } else if (bank == 2) {
10056                 val |= CC_DIAG | CC_BANK_ONE;
10057         } else {
10058                 val &= ~CC_BANK_ONE;
10059         }
10060         AscSetChipControl(iop_base, val);
10061         return;
10062 }
10063
10064 static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
10065 {
10066         PortAddr iop_base;
10067         int i = 10;
10068
10069         iop_base = asc_dvc->iop_base;
10070         while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
10071                && (i-- > 0)) {
10072                 DvcSleepMilliSecond(100);
10073         }
10074         AscStopChip(iop_base);
10075         AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
10076         DvcDelayNanoSecond(asc_dvc, 60000);
10077         AscSetChipIH(iop_base, INS_RFLAG_WTM);
10078         AscSetChipIH(iop_base, INS_HALT);
10079         AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
10080         AscSetChipControl(iop_base, CC_HALT);
10081         DvcSleepMilliSecond(200);
10082         AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10083         AscSetChipStatus(iop_base, 0);
10084         return (AscIsChipHalted(iop_base));
10085 }
10086
10087 static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type)
10088 {
10089         if (bus_type & ASC_IS_ISA)
10090                 return (ASC_MAX_ISA_DMA_COUNT);
10091         else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
10092                 return (ASC_MAX_VL_DMA_COUNT);
10093         return (ASC_MAX_PCI_DMA_COUNT);
10094 }
10095
10096 #ifdef CONFIG_ISA
10097 static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base)
10098 {
10099         ushort channel;
10100
10101         channel = AscGetChipCfgLsw(iop_base) & 0x0003;
10102         if (channel == 0x03)
10103                 return (0);
10104         else if (channel == 0x00)
10105                 return (7);
10106         return (channel + 4);
10107 }
10108
10109 static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
10110 {
10111         ushort cfg_lsw;
10112         uchar value;
10113
10114         if ((dma_channel >= 5) && (dma_channel <= 7)) {
10115                 if (dma_channel == 7)
10116                         value = 0x00;
10117                 else
10118                         value = dma_channel - 4;
10119                 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
10120                 cfg_lsw |= value;
10121                 AscSetChipCfgLsw(iop_base, cfg_lsw);
10122                 return (AscGetIsaDmaChannel(iop_base));
10123         }
10124         return (0);
10125 }
10126
10127 static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
10128 {
10129         speed_value &= 0x07;
10130         AscSetBank(iop_base, 1);
10131         AscWriteChipDmaSpeed(iop_base, speed_value);
10132         AscSetBank(iop_base, 0);
10133         return (AscGetIsaDmaSpeed(iop_base));
10134 }
10135
10136 static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base)
10137 {
10138         uchar speed_value;
10139
10140         AscSetBank(iop_base, 1);
10141         speed_value = AscReadChipDmaSpeed(iop_base);
10142         speed_value &= 0x07;
10143         AscSetBank(iop_base, 0);
10144         return (speed_value);
10145 }
10146 #endif /* CONFIG_ISA */
10147
10148 static ushort __devinit AscInitGetConfig(ASC_DVC_VAR *asc_dvc)
10149 {
10150         unsigned short warn_code = 0;
10151
10152         asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
10153         if (asc_dvc->err_code != 0)
10154                 return (UW_ERR);
10155
10156         if (AscFindSignature(asc_dvc->iop_base)) {
10157                 warn_code |= AscInitAscDvcVar(asc_dvc);
10158                 warn_code |= AscInitFromEEP(asc_dvc);
10159                 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
10160                 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT)
10161                         asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
10162         } else {
10163                 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10164         }
10165         return warn_code;
10166 }
10167
10168 static unsigned short __devinit
10169 AscInitSetConfig(struct pci_dev *pdev, ASC_DVC_VAR *asc_dvc)
10170 {
10171         PortAddr iop_base = asc_dvc->iop_base;
10172         unsigned short cfg_msw;
10173         unsigned short warn_code = 0;
10174
10175         asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
10176         if (asc_dvc->err_code != 0)
10177                 return UW_ERR;
10178         if (!AscFindSignature(asc_dvc->iop_base)) {
10179                 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10180                 return 0;
10181         }
10182
10183         cfg_msw = AscGetChipCfgMsw(iop_base);
10184         if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
10185                 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
10186                 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
10187                 AscSetChipCfgMsw(iop_base, cfg_msw);
10188         }
10189         if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
10190             asc_dvc->cfg->cmd_qng_enabled) {
10191                 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
10192                 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
10193         }
10194         if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
10195                 warn_code |= ASC_WARN_AUTO_CONFIG;
10196         }
10197         if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
10198                 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
10199                     != asc_dvc->irq_no) {
10200                         asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
10201                 }
10202         }
10203 #ifdef CONFIG_PCI
10204         if (asc_dvc->bus_type & ASC_IS_PCI) {
10205                 cfg_msw &= 0xFFC0;
10206                 AscSetChipCfgMsw(iop_base, cfg_msw);
10207                 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
10208                 } else {
10209                         if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
10210                             (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
10211                                 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
10212                                 asc_dvc->bug_fix_cntl |=
10213                                     ASC_BUG_FIX_ASYN_USE_SYN;
10214                         }
10215                 }
10216         } else
10217 #endif /* CONFIG_PCI */
10218         if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
10219                 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
10220                     == ASC_CHIP_VER_ASYN_BUG) {
10221                         asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
10222                 }
10223         }
10224         if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
10225             asc_dvc->cfg->chip_scsi_id) {
10226                 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
10227         }
10228 #ifdef CONFIG_ISA
10229         if (asc_dvc->bus_type & ASC_IS_ISA) {
10230                 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
10231                 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
10232         }
10233 #endif /* CONFIG_ISA */
10234
10235         asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
10236         return warn_code;
10237 }
10238
10239 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
10240 {
10241         ushort warn_code;
10242         PortAddr iop_base;
10243
10244         iop_base = asc_dvc->iop_base;
10245         warn_code = 0;
10246         if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
10247             !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
10248                 AscResetChipAndScsiBus(asc_dvc);
10249                 DvcSleepMilliSecond((ASC_DCNT)
10250                                     ((ushort)asc_dvc->scsi_reset_wait * 1000));
10251         }
10252         asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
10253         if (asc_dvc->err_code != 0)
10254                 return (UW_ERR);
10255         if (!AscFindSignature(asc_dvc->iop_base)) {
10256                 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10257                 return (warn_code);
10258         }
10259         AscDisableInterrupt(iop_base);
10260         warn_code |= AscInitLram(asc_dvc);
10261         if (asc_dvc->err_code != 0)
10262                 return (UW_ERR);
10263         ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
10264                  (ulong)_asc_mcode_chksum);
10265         if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
10266                              _asc_mcode_size) != _asc_mcode_chksum) {
10267                 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
10268                 return (warn_code);
10269         }
10270         warn_code |= AscInitMicroCodeVar(asc_dvc);
10271         asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
10272         AscEnableInterrupt(iop_base);
10273         return (warn_code);
10274 }
10275
10276 static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
10277 {
10278         int i;
10279         PortAddr iop_base;
10280         ushort warn_code;
10281         uchar chip_version;
10282
10283         iop_base = asc_dvc->iop_base;
10284         warn_code = 0;
10285         asc_dvc->err_code = 0;
10286         if ((asc_dvc->bus_type &
10287              (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
10288                 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
10289         }
10290         AscSetChipControl(iop_base, CC_HALT);
10291         AscSetChipStatus(iop_base, 0);
10292         asc_dvc->bug_fix_cntl = 0;
10293         asc_dvc->pci_fix_asyn_xfer = 0;
10294         asc_dvc->pci_fix_asyn_xfer_always = 0;
10295         /* asc_dvc->init_state initalized in AscInitGetConfig(). */
10296         asc_dvc->sdtr_done = 0;
10297         asc_dvc->cur_total_qng = 0;
10298         asc_dvc->is_in_int = 0;
10299         asc_dvc->in_critical_cnt = 0;
10300         asc_dvc->last_q_shortage = 0;
10301         asc_dvc->use_tagged_qng = 0;
10302         asc_dvc->no_scam = 0;
10303         asc_dvc->unit_not_ready = 0;
10304         asc_dvc->queue_full_or_busy = 0;
10305         asc_dvc->redo_scam = 0;
10306         asc_dvc->res2 = 0;
10307         asc_dvc->host_init_sdtr_index = 0;
10308         asc_dvc->cfg->can_tagged_qng = 0;
10309         asc_dvc->cfg->cmd_qng_enabled = 0;
10310         asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
10311         asc_dvc->init_sdtr = 0;
10312         asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
10313         asc_dvc->scsi_reset_wait = 3;
10314         asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
10315         asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
10316         asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
10317         asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
10318         asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
10319         asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
10320         asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
10321             ASC_LIB_VERSION_MINOR;
10322         chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
10323         asc_dvc->cfg->chip_version = chip_version;
10324         asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
10325         asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
10326         asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
10327         asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
10328         asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
10329         asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
10330         asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
10331         asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
10332         asc_dvc->max_sdtr_index = 7;
10333         if ((asc_dvc->bus_type & ASC_IS_PCI) &&
10334             (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
10335                 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
10336                 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
10337                 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
10338                 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
10339                 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
10340                 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
10341                 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
10342                 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
10343                 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
10344                 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
10345                 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
10346                 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
10347                 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
10348                 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
10349                 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
10350                 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
10351                 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
10352                 asc_dvc->max_sdtr_index = 15;
10353                 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
10354                         AscSetExtraControl(iop_base,
10355                                            (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
10356                 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
10357                         AscSetExtraControl(iop_base,
10358                                            (SEC_ACTIVE_NEGATE |
10359                                             SEC_ENABLE_FILTER));
10360                 }
10361         }
10362         if (asc_dvc->bus_type == ASC_IS_PCI) {
10363                 AscSetExtraControl(iop_base,
10364                                    (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
10365         }
10366
10367         asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
10368 #ifdef CONFIG_ISA
10369         if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
10370                 if (chip_version >= ASC_CHIP_MIN_VER_ISA_PNP) {
10371                         AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
10372                         asc_dvc->bus_type = ASC_IS_ISAPNP;
10373                 }
10374                 asc_dvc->cfg->isa_dma_channel =
10375                     (uchar)AscGetIsaDmaChannel(iop_base);
10376         }
10377 #endif /* CONFIG_ISA */
10378         for (i = 0; i <= ASC_MAX_TID; i++) {
10379                 asc_dvc->cur_dvc_qng[i] = 0;
10380                 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
10381                 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
10382                 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
10383                 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
10384         }
10385         return (warn_code);
10386 }
10387
10388 static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
10389 {
10390         ASCEEP_CONFIG eep_config_buf;
10391         ASCEEP_CONFIG *eep_config;
10392         PortAddr iop_base;
10393         ushort chksum;
10394         ushort warn_code;
10395         ushort cfg_msw, cfg_lsw;
10396         int i;
10397         int write_eep = 0;
10398
10399         iop_base = asc_dvc->iop_base;
10400         warn_code = 0;
10401         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
10402         AscStopQueueExe(iop_base);
10403         if ((AscStopChip(iop_base) == FALSE) ||
10404             (AscGetChipScsiCtrl(iop_base) != 0)) {
10405                 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
10406                 AscResetChipAndScsiBus(asc_dvc);
10407                 DvcSleepMilliSecond((ASC_DCNT)
10408                                     ((ushort)asc_dvc->scsi_reset_wait * 1000));
10409         }
10410         if (AscIsChipHalted(iop_base) == FALSE) {
10411                 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
10412                 return (warn_code);
10413         }
10414         AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
10415         if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
10416                 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
10417                 return (warn_code);
10418         }
10419         eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
10420         cfg_msw = AscGetChipCfgMsw(iop_base);
10421         cfg_lsw = AscGetChipCfgLsw(iop_base);
10422         if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
10423                 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
10424                 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
10425                 AscSetChipCfgMsw(iop_base, cfg_msw);
10426         }
10427         chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
10428         ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
10429         if (chksum == 0) {
10430                 chksum = 0xaa55;
10431         }
10432         if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
10433                 warn_code |= ASC_WARN_AUTO_CONFIG;
10434                 if (asc_dvc->cfg->chip_version == 3) {
10435                         if (eep_config->cfg_lsw != cfg_lsw) {
10436                                 warn_code |= ASC_WARN_EEPROM_RECOVER;
10437                                 eep_config->cfg_lsw =
10438                                     AscGetChipCfgLsw(iop_base);
10439                         }
10440                         if (eep_config->cfg_msw != cfg_msw) {
10441                                 warn_code |= ASC_WARN_EEPROM_RECOVER;
10442                                 eep_config->cfg_msw =
10443                                     AscGetChipCfgMsw(iop_base);
10444                         }
10445                 }
10446         }
10447         eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
10448         eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
10449         ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
10450                  eep_config->chksum);
10451         if (chksum != eep_config->chksum) {
10452                 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
10453                     ASC_CHIP_VER_PCI_ULTRA_3050) {
10454                         ASC_DBG(1,
10455                                 "AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
10456                         eep_config->init_sdtr = 0xFF;
10457                         eep_config->disc_enable = 0xFF;
10458                         eep_config->start_motor = 0xFF;
10459                         eep_config->use_cmd_qng = 0;
10460                         eep_config->max_total_qng = 0xF0;
10461                         eep_config->max_tag_qng = 0x20;
10462                         eep_config->cntl = 0xBFFF;
10463                         ASC_EEP_SET_CHIP_ID(eep_config, 7);
10464                         eep_config->no_scam = 0;
10465                         eep_config->adapter_info[0] = 0;
10466                         eep_config->adapter_info[1] = 0;
10467                         eep_config->adapter_info[2] = 0;
10468                         eep_config->adapter_info[3] = 0;
10469                         eep_config->adapter_info[4] = 0;
10470                         /* Indicate EEPROM-less board. */
10471                         eep_config->adapter_info[5] = 0xBB;
10472                 } else {
10473                         ASC_PRINT
10474                             ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
10475                         write_eep = 1;
10476                         warn_code |= ASC_WARN_EEPROM_CHKSUM;
10477                 }
10478         }
10479         asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
10480         asc_dvc->cfg->disc_enable = eep_config->disc_enable;
10481         asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
10482         asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
10483         asc_dvc->start_motor = eep_config->start_motor;
10484         asc_dvc->dvc_cntl = eep_config->cntl;
10485         asc_dvc->no_scam = eep_config->no_scam;
10486         asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
10487         asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
10488         asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
10489         asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
10490         asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
10491         asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
10492         if (!AscTestExternalLram(asc_dvc)) {
10493                 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
10494                      ASC_IS_PCI_ULTRA)) {
10495                         eep_config->max_total_qng =
10496                             ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
10497                         eep_config->max_tag_qng =
10498                             ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
10499                 } else {
10500                         eep_config->cfg_msw |= 0x0800;
10501                         cfg_msw |= 0x0800;
10502                         AscSetChipCfgMsw(iop_base, cfg_msw);
10503                         eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
10504                         eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
10505                 }
10506         } else {
10507         }
10508         if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
10509                 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
10510         }
10511         if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
10512                 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
10513         }
10514         if (eep_config->max_tag_qng > eep_config->max_total_qng) {
10515                 eep_config->max_tag_qng = eep_config->max_total_qng;
10516         }
10517         if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
10518                 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
10519         }
10520         asc_dvc->max_total_qng = eep_config->max_total_qng;
10521         if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
10522             eep_config->use_cmd_qng) {
10523                 eep_config->disc_enable = eep_config->use_cmd_qng;
10524                 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
10525         }
10526         if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
10527                 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
10528         }
10529         ASC_EEP_SET_CHIP_ID(eep_config,
10530                             ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
10531         asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
10532         if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
10533             !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
10534                 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
10535         }
10536
10537         for (i = 0; i <= ASC_MAX_TID; i++) {
10538                 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
10539                 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
10540                 asc_dvc->cfg->sdtr_period_offset[i] =
10541                     (uchar)(ASC_DEF_SDTR_OFFSET |
10542                             (asc_dvc->host_init_sdtr_index << 4));
10543         }
10544         eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
10545         if (write_eep) {
10546                 if ((i =
10547                      AscSetEEPConfig(iop_base, eep_config,
10548                                      asc_dvc->bus_type)) != 0) {
10549                         ASC_PRINT1
10550                             ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
10551                              i);
10552                 } else {
10553                         ASC_PRINT
10554                             ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
10555                 }
10556         }
10557         return (warn_code);
10558 }
10559
10560 static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
10561 {
10562         int i;
10563         ushort warn_code;
10564         PortAddr iop_base;
10565         ASC_PADDR phy_addr;
10566         ASC_DCNT phy_size;
10567
10568         iop_base = asc_dvc->iop_base;
10569         warn_code = 0;
10570         for (i = 0; i <= ASC_MAX_TID; i++) {
10571                 AscPutMCodeInitSDTRAtID(iop_base, i,
10572                                         asc_dvc->cfg->sdtr_period_offset[i]
10573                     );
10574         }
10575
10576         AscInitQLinkVar(asc_dvc);
10577         AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
10578                          asc_dvc->cfg->disc_enable);
10579         AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
10580                          ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
10581
10582         /* Align overrun buffer on an 8 byte boundary. */
10583         phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
10584         phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
10585         AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
10586                                  (uchar *)&phy_addr, 1);
10587         phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
10588         AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
10589                                  (uchar *)&phy_size, 1);
10590
10591         asc_dvc->cfg->mcode_date =
10592             AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
10593         asc_dvc->cfg->mcode_version =
10594             AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
10595
10596         AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
10597         if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
10598                 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
10599                 return (warn_code);
10600         }
10601         if (AscStartChip(iop_base) != 1) {
10602                 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
10603                 return (warn_code);
10604         }
10605
10606         return (warn_code);
10607 }
10608
10609 static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
10610 {
10611         PortAddr iop_base;
10612         ushort q_addr;
10613         ushort saved_word;
10614         int sta;
10615
10616         iop_base = asc_dvc->iop_base;
10617         sta = 0;
10618         q_addr = ASC_QNO_TO_QADDR(241);
10619         saved_word = AscReadLramWord(iop_base, q_addr);
10620         AscSetChipLramAddr(iop_base, q_addr);
10621         AscSetChipLramData(iop_base, 0x55AA);
10622         DvcSleepMilliSecond(10);
10623         AscSetChipLramAddr(iop_base, q_addr);
10624         if (AscGetChipLramData(iop_base) == 0x55AA) {
10625                 sta = 1;
10626                 AscWriteLramWord(iop_base, q_addr, saved_word);
10627         }
10628         return (sta);
10629 }
10630
10631 static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
10632 {
10633         uchar read_back;
10634         int retry;
10635
10636         retry = 0;
10637         while (TRUE) {
10638                 AscSetChipEEPCmd(iop_base, cmd_reg);
10639                 DvcSleepMilliSecond(1);
10640                 read_back = AscGetChipEEPCmd(iop_base);
10641                 if (read_back == cmd_reg) {
10642                         return (1);
10643                 }
10644                 if (retry++ > ASC_EEP_MAX_RETRY) {
10645                         return (0);
10646                 }
10647         }
10648 }
10649
10650 static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
10651 {
10652         ushort read_back;
10653         int retry;
10654
10655         retry = 0;
10656         while (TRUE) {
10657                 AscSetChipEEPData(iop_base, data_reg);
10658                 DvcSleepMilliSecond(1);
10659                 read_back = AscGetChipEEPData(iop_base);
10660                 if (read_back == data_reg) {
10661                         return (1);
10662                 }
10663                 if (retry++ > ASC_EEP_MAX_RETRY) {
10664                         return (0);
10665                 }
10666         }
10667 }
10668
10669 static void __devinit AscWaitEEPRead(void)
10670 {
10671         DvcSleepMilliSecond(1);
10672         return;
10673 }
10674
10675 static void __devinit AscWaitEEPWrite(void)
10676 {
10677         DvcSleepMilliSecond(20);
10678         return;
10679 }
10680
10681 static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr)
10682 {
10683         ushort read_wval;
10684         uchar cmd_reg;
10685
10686         AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
10687         AscWaitEEPRead();
10688         cmd_reg = addr | ASC_EEP_CMD_READ;
10689         AscWriteEEPCmdReg(iop_base, cmd_reg);
10690         AscWaitEEPRead();
10691         read_wval = AscGetChipEEPData(iop_base);
10692         AscWaitEEPRead();
10693         return (read_wval);
10694 }
10695
10696 static ushort __devinit
10697 AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
10698 {
10699         ushort read_wval;
10700
10701         read_wval = AscReadEEPWord(iop_base, addr);
10702         if (read_wval != word_val) {
10703                 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
10704                 AscWaitEEPRead();
10705                 AscWriteEEPDataReg(iop_base, word_val);
10706                 AscWaitEEPRead();
10707                 AscWriteEEPCmdReg(iop_base,
10708                                   (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
10709                 AscWaitEEPWrite();
10710                 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
10711                 AscWaitEEPRead();
10712                 return (AscReadEEPWord(iop_base, addr));
10713         }
10714         return (read_wval);
10715 }
10716
10717 static ushort __devinit
10718 AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
10719 {
10720         ushort wval;
10721         ushort sum;
10722         ushort *wbuf;
10723         int cfg_beg;
10724         int cfg_end;
10725         int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
10726         int s_addr;
10727
10728         wbuf = (ushort *)cfg_buf;
10729         sum = 0;
10730         /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
10731         for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
10732                 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
10733                 sum += *wbuf;
10734         }
10735         if (bus_type & ASC_IS_VL) {
10736                 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
10737                 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
10738         } else {
10739                 cfg_beg = ASC_EEP_DVC_CFG_BEG;
10740                 cfg_end = ASC_EEP_MAX_DVC_ADDR;
10741         }
10742         for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
10743                 wval = AscReadEEPWord(iop_base, (uchar)s_addr);
10744                 if (s_addr <= uchar_end_in_config) {
10745                         /*
10746                          * Swap all char fields - must unswap bytes already swapped
10747                          * by AscReadEEPWord().
10748                          */
10749                         *wbuf = le16_to_cpu(wval);
10750                 } else {
10751                         /* Don't swap word field at the end - cntl field. */
10752                         *wbuf = wval;
10753                 }
10754                 sum += wval;    /* Checksum treats all EEPROM data as words. */
10755         }
10756         /*
10757          * Read the checksum word which will be compared against 'sum'
10758          * by the caller. Word field already swapped.
10759          */
10760         *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
10761         return (sum);
10762 }
10763
10764 static int __devinit
10765 AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
10766 {
10767         int n_error;
10768         ushort *wbuf;
10769         ushort word;
10770         ushort sum;
10771         int s_addr;
10772         int cfg_beg;
10773         int cfg_end;
10774         int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
10775
10776         wbuf = (ushort *)cfg_buf;
10777         n_error = 0;
10778         sum = 0;
10779         /* Write two config words; AscWriteEEPWord() will swap bytes. */
10780         for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
10781                 sum += *wbuf;
10782                 if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
10783                         n_error++;
10784                 }
10785         }
10786         if (bus_type & ASC_IS_VL) {
10787                 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
10788                 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
10789         } else {
10790                 cfg_beg = ASC_EEP_DVC_CFG_BEG;
10791                 cfg_end = ASC_EEP_MAX_DVC_ADDR;
10792         }
10793         for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
10794                 if (s_addr <= uchar_end_in_config) {
10795                         /*
10796                          * This is a char field. Swap char fields before they are
10797                          * swapped again by AscWriteEEPWord().
10798                          */
10799                         word = cpu_to_le16(*wbuf);
10800                         if (word !=
10801                             AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
10802                                 n_error++;
10803                         }
10804                 } else {
10805                         /* Don't swap word field at the end - cntl field. */
10806                         if (*wbuf !=
10807                             AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
10808                                 n_error++;
10809                         }
10810                 }
10811                 sum += *wbuf;   /* Checksum calculated from word values. */
10812         }
10813         /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
10814         *wbuf = sum;
10815         if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
10816                 n_error++;
10817         }
10818
10819         /* Read EEPROM back again. */
10820         wbuf = (ushort *)cfg_buf;
10821         /*
10822          * Read two config words; Byte-swapping done by AscReadEEPWord().
10823          */
10824         for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
10825                 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
10826                         n_error++;
10827                 }
10828         }
10829         if (bus_type & ASC_IS_VL) {
10830                 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
10831                 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
10832         } else {
10833                 cfg_beg = ASC_EEP_DVC_CFG_BEG;
10834                 cfg_end = ASC_EEP_MAX_DVC_ADDR;
10835         }
10836         for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
10837                 if (s_addr <= uchar_end_in_config) {
10838                         /*
10839                          * Swap all char fields. Must unswap bytes already swapped
10840                          * by AscReadEEPWord().
10841                          */
10842                         word =
10843                             le16_to_cpu(AscReadEEPWord
10844                                         (iop_base, (uchar)s_addr));
10845                 } else {
10846                         /* Don't swap word field at the end - cntl field. */
10847                         word = AscReadEEPWord(iop_base, (uchar)s_addr);
10848                 }
10849                 if (*wbuf != word) {
10850                         n_error++;
10851                 }
10852         }
10853         /* Read checksum; Byte swapping not needed. */
10854         if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
10855                 n_error++;
10856         }
10857         return (n_error);
10858 }
10859
10860 static int __devinit
10861 AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
10862 {
10863         int retry;
10864         int n_error;
10865
10866         retry = 0;
10867         while (TRUE) {
10868                 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
10869                                                    bus_type)) == 0) {
10870                         break;
10871                 }
10872                 if (++retry > ASC_EEP_MAX_RETRY) {
10873                         break;
10874                 }
10875         }
10876         return (n_error);
10877 }
10878
10879 static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev)
10880 {
10881         char type = sdev->type;
10882         ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id;
10883
10884         if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) {
10885                 if (!(asc_dvc->init_sdtr & tid_bits)) {
10886                         if ((type == TYPE_ROM) &&
10887                             (strncmp(sdev->vendor, "HP ", 3) == 0)) {
10888                                 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
10889                         }
10890                         asc_dvc->pci_fix_asyn_xfer |= tid_bits;
10891                         if ((type == TYPE_PROCESSOR) ||
10892                             (type == TYPE_SCANNER) || (type == TYPE_ROM) ||
10893                             (type == TYPE_TAPE)) {
10894                                 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
10895                         }
10896
10897                         if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
10898                                 AscSetRunChipSynRegAtID(asc_dvc->iop_base,
10899                                         sdev->id,
10900                                         ASYN_SDTR_DATA_FIX_PCI_REV_AB);
10901                         }
10902                 }
10903         }
10904 }
10905
10906 static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
10907 {
10908         uchar byte_data;
10909         ushort word_data;
10910
10911         if (isodd_word(addr)) {
10912                 AscSetChipLramAddr(iop_base, addr - 1);
10913                 word_data = AscGetChipLramData(iop_base);
10914                 byte_data = (uchar)((word_data >> 8) & 0xFF);
10915         } else {
10916                 AscSetChipLramAddr(iop_base, addr);
10917                 word_data = AscGetChipLramData(iop_base);
10918                 byte_data = (uchar)(word_data & 0xFF);
10919         }
10920         return (byte_data);
10921 }
10922
10923 static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
10924 {
10925         ushort word_data;
10926
10927         AscSetChipLramAddr(iop_base, addr);
10928         word_data = AscGetChipLramData(iop_base);
10929         return (word_data);
10930 }
10931
10932 #if CC_VERY_LONG_SG_LIST
10933 static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr)
10934 {
10935         ushort val_low, val_high;
10936         ASC_DCNT dword_data;
10937
10938         AscSetChipLramAddr(iop_base, addr);
10939         val_low = AscGetChipLramData(iop_base);
10940         val_high = AscGetChipLramData(iop_base);
10941         dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
10942         return (dword_data);
10943 }
10944 #endif /* CC_VERY_LONG_SG_LIST */
10945
10946 static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
10947 {
10948         AscSetChipLramAddr(iop_base, addr);
10949         AscSetChipLramData(iop_base, word_val);
10950         return;
10951 }
10952
10953 static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
10954 {
10955         ushort word_data;
10956
10957         if (isodd_word(addr)) {
10958                 addr--;
10959                 word_data = AscReadLramWord(iop_base, addr);
10960                 word_data &= 0x00FF;
10961                 word_data |= (((ushort)byte_val << 8) & 0xFF00);
10962         } else {
10963                 word_data = AscReadLramWord(iop_base, addr);
10964                 word_data &= 0xFF00;
10965                 word_data |= ((ushort)byte_val & 0x00FF);
10966         }
10967         AscWriteLramWord(iop_base, addr, word_data);
10968         return;
10969 }
10970
10971 /*
10972  * Copy 2 bytes to LRAM.
10973  *
10974  * The source data is assumed to be in little-endian order in memory
10975  * and is maintained in little-endian order when written to LRAM.
10976  */
10977 static void
10978 AscMemWordCopyPtrToLram(PortAddr iop_base,
10979                         ushort s_addr, uchar *s_buffer, int words)
10980 {
10981         int i;
10982
10983         AscSetChipLramAddr(iop_base, s_addr);
10984         for (i = 0; i < 2 * words; i += 2) {
10985                 /*
10986                  * On a little-endian system the second argument below
10987                  * produces a little-endian ushort which is written to
10988                  * LRAM in little-endian order. On a big-endian system
10989                  * the second argument produces a big-endian ushort which
10990                  * is "transparently" byte-swapped by outpw() and written
10991                  * in little-endian order to LRAM.
10992                  */
10993                 outpw(iop_base + IOP_RAM_DATA,
10994                       ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
10995         }
10996         return;
10997 }
10998
10999 /*
11000  * Copy 4 bytes to LRAM.
11001  *
11002  * The source data is assumed to be in little-endian order in memory
11003  * and is maintained in little-endian order when writen to LRAM.
11004  */
11005 static void
11006 AscMemDWordCopyPtrToLram(PortAddr iop_base,
11007                          ushort s_addr, uchar *s_buffer, int dwords)
11008 {
11009         int i;
11010
11011         AscSetChipLramAddr(iop_base, s_addr);
11012         for (i = 0; i < 4 * dwords; i += 4) {
11013                 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);   /* LSW */
11014                 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]);       /* MSW */
11015         }
11016         return;
11017 }
11018
11019 /*
11020  * Copy 2 bytes from LRAM.
11021  *
11022  * The source data is assumed to be in little-endian order in LRAM
11023  * and is maintained in little-endian order when written to memory.
11024  */
11025 static void
11026 AscMemWordCopyPtrFromLram(PortAddr iop_base,
11027                           ushort s_addr, uchar *d_buffer, int words)
11028 {
11029         int i;
11030         ushort word;
11031
11032         AscSetChipLramAddr(iop_base, s_addr);
11033         for (i = 0; i < 2 * words; i += 2) {
11034                 word = inpw(iop_base + IOP_RAM_DATA);
11035                 d_buffer[i] = word & 0xff;
11036                 d_buffer[i + 1] = (word >> 8) & 0xff;
11037         }
11038         return;
11039 }
11040
11041 static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
11042 {
11043         ASC_DCNT sum;
11044         int i;
11045
11046         sum = 0L;
11047         for (i = 0; i < words; i++, s_addr += 2) {
11048                 sum += AscReadLramWord(iop_base, s_addr);
11049         }
11050         return (sum);
11051 }
11052
11053 static void
11054 AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
11055 {
11056         int i;
11057
11058         AscSetChipLramAddr(iop_base, s_addr);
11059         for (i = 0; i < words; i++) {
11060                 AscSetChipLramData(iop_base, set_wval);
11061         }
11062         return;
11063 }
11064
11065 /*
11066  * --- Adv Library Functions
11067  */
11068
11069 /* a_mcode.h */
11070
11071 /* Microcode buffer is kept after initialization for error recovery. */
11072 static unsigned char _adv_asc3550_buf[] = {
11073         0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
11074         0x01, 0x00, 0x48, 0xe4,
11075         0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0x00, 0xfa, 0xff, 0xff,
11076         0x28, 0x0e, 0x9e, 0xe7,
11077         0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7,
11078         0x55, 0xf0, 0x01, 0xf6,
11079         0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
11080         0x00, 0xec, 0x85, 0xf0,
11081         0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54, 0x00, 0xe6, 0x1e, 0xf0,
11082         0x86, 0xf0, 0xb4, 0x00,
11083         0x98, 0x57, 0xd0, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00,
11084         0xaa, 0x18, 0x02, 0x80,
11085         0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
11086         0x00, 0x57, 0x01, 0xea,
11087         0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x3e, 0x57, 0x00, 0x80,
11088         0x03, 0xe6, 0xb6, 0x00,
11089         0xc0, 0x00, 0x01, 0x01, 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12,
11090         0x02, 0x4a, 0xb9, 0x54,
11091         0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
11092         0x3e, 0x00, 0x80, 0x00,
11093         0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
11094         0x74, 0x01, 0x76, 0x01,
11095         0x78, 0x01, 0x62, 0x0a, 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13,
11096         0x4c, 0x1c, 0xbb, 0x55,
11097         0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
11098         0x03, 0xf7, 0x06, 0xf7,
11099         0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00, 0x00, 0x01, 0xb0, 0x08,
11100         0x30, 0x13, 0x64, 0x15,
11101         0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c,
11102         0x04, 0xea, 0x5d, 0xf0,
11103         0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
11104         0xcc, 0x00, 0x20, 0x01,
11105         0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10, 0x0a, 0x12, 0x04, 0x13,
11106         0x40, 0x13, 0x30, 0x1c,
11107         0x00, 0x4e, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
11108         0x59, 0xf0, 0xa7, 0xf0,
11109         0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
11110         0xa4, 0x00, 0xb5, 0x00,
11111         0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xde, 0x03, 0x56, 0x0a,
11112         0x14, 0x0e, 0x02, 0x10,
11113         0x04, 0x10, 0x0a, 0x10, 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13,
11114         0x10, 0x15, 0x14, 0x15,
11115         0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
11116         0x91, 0x44, 0x0a, 0x45,
11117         0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55, 0xb0, 0x57, 0x01, 0x58,
11118         0x83, 0x59, 0x05, 0xe6,
11119         0x0b, 0xf0, 0x0c, 0xf0, 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8,
11120         0x02, 0xfa, 0x03, 0xfa,
11121         0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
11122         0x9e, 0x00, 0xa8, 0x00,
11123         0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01,
11124         0x7a, 0x01, 0xc0, 0x01,
11125         0xc2, 0x01, 0x7c, 0x02, 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08,
11126         0x69, 0x08, 0xba, 0x08,
11127         0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
11128         0xf1, 0x10, 0x06, 0x12,
11129         0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13, 0x42, 0x14, 0xd6, 0x14,
11130         0x8a, 0x15, 0xc6, 0x17,
11131         0xd2, 0x17, 0x6b, 0x18, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
11132         0x0e, 0x47, 0x48, 0x47,
11133         0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
11134         0x14, 0x56, 0x77, 0x57,
11135         0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90, 0x03, 0xa1, 0xfe, 0x9c,
11136         0xf0, 0x29, 0x02, 0xfe,
11137         0xb8, 0x0c, 0xff, 0x10, 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf,
11138         0xfe, 0x80, 0x01, 0xff,
11139         0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
11140         0x00, 0xfe, 0x57, 0x24,
11141         0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00, 0x00, 0x10, 0xff, 0x09,
11142         0x00, 0x00, 0xff, 0x08,
11143         0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
11144         0xff, 0xff, 0xff, 0x0f,
11145         0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
11146         0xfe, 0x04, 0xf7, 0xcf,
11147         0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe, 0x04, 0xf7, 0xcf, 0x67,
11148         0x0b, 0x3c, 0x2a, 0xfe,
11149         0x3d, 0xf0, 0xfe, 0x02, 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0,
11150         0xfe, 0xf0, 0x01, 0xfe,
11151         0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
11152         0x02, 0xfe, 0xd4, 0x0c,
11153         0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
11154         0x1c, 0x05, 0xfe, 0xa6,
11155         0x00, 0xfe, 0xd3, 0x12, 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48,
11156         0xf0, 0xfe, 0x86, 0x02,
11157         0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
11158         0xfe, 0x46, 0xf0, 0xfe,
11159         0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
11160         0x44, 0x02, 0xfe, 0x44,
11161         0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b,
11162         0xa0, 0x17, 0x06, 0x18,
11163         0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
11164         0x1e, 0x1c, 0xfe, 0xe9,
11165         0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xc7,
11166         0x0a, 0x6b, 0x01, 0x9e,
11167         0x02, 0x29, 0x14, 0x4d, 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b,
11168         0x01, 0x82, 0xfe, 0xbd,
11169         0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
11170         0x58, 0x1c, 0x17, 0x06,
11171         0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0x21,
11172         0xfe, 0x94, 0x02, 0xfe,
11173         0x5a, 0x1c, 0xea, 0xfe, 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97,
11174         0x01, 0xfe, 0x54, 0x0f,
11175         0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
11176         0x69, 0x10, 0x17, 0x06,
11177         0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d, 0x12, 0x20, 0xfe, 0x05,
11178         0xf6, 0xc7, 0x01, 0xfe,
11179         0x52, 0x16, 0x09, 0x4a, 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6,
11180         0x02, 0x29, 0x0a, 0x40,
11181         0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
11182         0x58, 0x0a, 0x99, 0x01,
11183         0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03, 0x01, 0xe6, 0x02, 0x29,
11184         0x2a, 0x46, 0xfe, 0x02,
11185         0xe8, 0x27, 0xf8, 0xfe, 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc,
11186         0x01, 0xfe, 0x07, 0x4b,
11187         0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
11188         0xfe, 0x56, 0x03, 0xfe,
11189         0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0, 0x9c, 0xfe, 0xef, 0x10,
11190         0xfe, 0x9f, 0xf0, 0xfe,
11191         0x64, 0x03, 0xeb, 0x0f, 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48,
11192         0x1c, 0xeb, 0x09, 0x04,
11193         0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
11194         0x01, 0x0e, 0xac, 0x75,
11195         0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2, 0xfe, 0x01, 0xf0, 0xd2,
11196         0xfe, 0x82, 0xf0, 0xfe,
11197         0x92, 0x03, 0xec, 0x11, 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25,
11198         0x32, 0x1f, 0xfe, 0xb4,
11199         0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
11200         0x0a, 0xf0, 0xfe, 0x7a,
11201         0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe, 0xf6, 0x04, 0x14, 0x2c,
11202         0x01, 0x33, 0x8f, 0xfe,
11203         0x66, 0x02, 0x02, 0xd1, 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8,
11204         0xf7, 0xfe, 0x48, 0x1c,
11205         0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
11206         0x0a, 0xca, 0x01, 0x0e,
11207         0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28, 0xfe, 0x10, 0x12, 0x14,
11208         0x2c, 0x01, 0x33, 0x8f,
11209         0xfe, 0x66, 0x02, 0x02, 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65,
11210         0xfe, 0x3c, 0x04, 0x1f,
11211         0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
11212         0x12, 0x2b, 0xff, 0x02,
11213         0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04, 0x2b, 0x01, 0x08, 0x1f,
11214         0x22, 0x30, 0x2e, 0xd5,
11215         0xfe, 0x4c, 0x44, 0xfe, 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c,
11216         0xfe, 0x4c, 0x54, 0x64,
11217         0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
11218         0xfe, 0x2a, 0x13, 0x2f,
11219         0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
11220         0xd3, 0xfa, 0xef, 0x86,
11221         0x09, 0x04, 0x1d, 0xfe, 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04,
11222         0x1d, 0xfe, 0x1c, 0x12,
11223         0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
11224         0x70, 0x0c, 0x02, 0x22,
11225         0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90, 0xf9, 0x03, 0x14, 0x92,
11226         0x01, 0x33, 0x02, 0x29,
11227         0xfe, 0x42, 0x5b, 0x67, 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87,
11228         0x80, 0xfe, 0x31, 0xe4,
11229         0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
11230         0xfe, 0x70, 0x12, 0x49,
11231         0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2, 0x00, 0x28, 0x16, 0xfe,
11232         0x80, 0x05, 0xfe, 0x31,
11233         0xe4, 0x6a, 0x49, 0x04, 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00,
11234         0x28, 0xfe, 0x42, 0x12,
11235         0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
11236         0x11, 0xfe, 0xe3, 0x00,
11237         0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
11238         0x64, 0x05, 0x83, 0x24,
11239         0xfe, 0x21, 0x00, 0xa1, 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe,
11240         0x09, 0x48, 0x01, 0x08,
11241         0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
11242         0x86, 0x24, 0x06, 0x12,
11243         0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d, 0xfe, 0x22, 0x12, 0x47,
11244         0x01, 0xa7, 0x14, 0x92,
11245         0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c,
11246         0x02, 0x22, 0x05, 0xfe,
11247         0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
11248         0x47, 0x01, 0xa7, 0x26,
11249         0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19, 0xfe, 0x02, 0x12, 0x5f,
11250         0x01, 0xfe, 0xaa, 0x14,
11251         0x1f, 0xfe, 0xfe, 0x05, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00,
11252         0x05, 0x50, 0xb4, 0x0c,
11253         0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
11254         0x13, 0x01, 0xfe, 0x14,
11255         0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48, 0xb7, 0x19, 0x13, 0x6c,
11256         0xff, 0x02, 0x00, 0x57,
11257         0x48, 0x8b, 0x1c, 0x3d, 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe,
11258         0x72, 0x06, 0x49, 0x04,
11259         0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
11260         0x06, 0x11, 0x9a, 0x01,
11261         0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4, 0x0c, 0x3f, 0x17, 0x06,
11262         0x01, 0xa7, 0xec, 0x72,
11263         0x70, 0x01, 0x6e, 0x87, 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32,
11264         0xfe, 0x0a, 0xf0, 0xfe,
11265         0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
11266         0x8d, 0x81, 0x02, 0x22,
11267         0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a, 0x01, 0x08, 0x15, 0x00,
11268         0x01, 0x08, 0x15, 0x00,
11269         0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15,
11270         0x00, 0x02, 0xfe, 0x32,
11271         0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
11272         0xfe, 0x1b, 0x00, 0x01,
11273         0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
11274         0x08, 0x15, 0x06, 0x01,
11275         0x08, 0x15, 0x00, 0x02, 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe,
11276         0x9a, 0x81, 0x4b, 0x1d,
11277         0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
11278         0x45, 0xfe, 0x32, 0x12,
11279         0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0,
11280         0xfe, 0x32, 0x07, 0x8d,
11281         0x81, 0x8c, 0xfe, 0x5c, 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a,
11282         0x06, 0x15, 0x19, 0x02,
11283         0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
11284         0x90, 0x77, 0xfe, 0xca,
11285         0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a, 0x35, 0x1e, 0x20, 0x07,
11286         0x10, 0xfe, 0x0e, 0x12,
11287         0x74, 0xfe, 0x80, 0x80, 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe,
11288         0x83, 0xe7, 0xc4, 0xa1,
11289         0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
11290         0x40, 0x12, 0x58, 0x01,
11291         0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6,
11292         0x51, 0x83, 0xfb, 0xfe,
11293         0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90,
11294         0xfe, 0x40, 0x50, 0xfe,
11295         0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
11296         0xfe, 0x2a, 0x12, 0xfe,
11297         0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x04, 0x4f,
11298         0x85, 0x01, 0xa8, 0xfe,
11299         0x1f, 0x80, 0x12, 0x58, 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56,
11300         0x18, 0x57, 0xfb, 0xfe,
11301         0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
11302         0x0c, 0x39, 0x18, 0x3a,
11303         0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35, 0x2a, 0x13, 0xfe, 0x4e,
11304         0x11, 0x65, 0xfe, 0x48,
11305         0x08, 0xfe, 0x9e, 0xf0, 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73,
11306         0xdd, 0xb8, 0xfe, 0x80,
11307         0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
11308         0xfe, 0x7a, 0x08, 0x8d,
11309         0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10, 0x15, 0x19, 0xfe, 0xc9,
11310         0x10, 0x61, 0x04, 0x06,
11311         0xfe, 0x10, 0x12, 0x61, 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68,
11312         0x12, 0xfe, 0x2e, 0x1c,
11313         0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
11314         0x52, 0x12, 0xfe, 0x2c,
11315         0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0xbe,
11316         0x08, 0xfe, 0x8a, 0x10,
11317         0xaa, 0xfe, 0xf3, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe,
11318         0x24, 0x0a, 0xab, 0xfe,
11319         0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
11320         0x1c, 0x12, 0xb5, 0xfe,
11321         0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x16, 0x9d, 0x05, 0xcb,
11322         0x1c, 0x06, 0x16, 0x9d,
11323         0xb8, 0x6d, 0xb9, 0x6d, 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b,
11324         0x14, 0x92, 0x01, 0x33,
11325         0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
11326         0xfe, 0x74, 0x18, 0x1c,
11327         0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01, 0xfe, 0x44, 0x0d, 0x3b,
11328         0x01, 0xe6, 0x1e, 0x27,
11329         0x74, 0x67, 0x1a, 0x02, 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a,
11330         0x09, 0x04, 0x6a, 0xfe,
11331         0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
11332         0xfe, 0x83, 0x80, 0xfe,
11333         0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x63,
11334         0x27, 0xfe, 0x40, 0x59,
11335         0xfe, 0xc1, 0x59, 0x77, 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18,
11336         0x7c, 0xbe, 0x54, 0xbf,
11337         0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
11338         0x79, 0x56, 0x68, 0x57,
11339         0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0x01, 0xa5,
11340         0xa2, 0x23, 0x0c, 0x7b,
11341         0x0c, 0x7c, 0x79, 0x56, 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19,
11342         0x16, 0xd7, 0x79, 0x39,
11343         0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
11344         0xfe, 0x10, 0x58, 0xfe,
11345         0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x02, 0x6d, 0x09, 0x04,
11346         0x19, 0x16, 0xd7, 0x09,
11347         0x04, 0xfe, 0xf7, 0x00, 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f,
11348         0xfe, 0x10, 0x90, 0xfe,
11349         0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
11350         0x11, 0x9b, 0x09, 0x04,
11351         0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a, 0x77, 0xfe, 0xc6, 0x08,
11352         0xfe, 0x0c, 0x58, 0xfe,
11353         0x8d, 0x58, 0x02, 0x6d, 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04,
11354         0x0b, 0xfe, 0x1a, 0x12,
11355         0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
11356         0x14, 0x7a, 0x01, 0x33,
11357         0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0xbe, 0x39,
11358         0xfe, 0xed, 0x19, 0xbf,
11359         0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff,
11360         0x34, 0xfe, 0x74, 0x10,
11361         0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
11362         0x84, 0x05, 0xcb, 0x1c,
11363         0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00, 0x02, 0x5a, 0xfe, 0xd1,
11364         0xf0, 0xfe, 0xc4, 0x0a,
11365         0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe,
11366         0xce, 0xf0, 0xfe, 0xca,
11367         0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
11368         0x22, 0x00, 0x02, 0x5a,
11369         0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe, 0x24, 0x00, 0x02, 0x5a,
11370         0xfe, 0xd0, 0xf0, 0xfe,
11371         0xec, 0x0a, 0x0f, 0x93, 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f,
11372         0x4c, 0xfe, 0x10, 0x10,
11373         0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
11374         0x2a, 0x13, 0xfe, 0x4e,
11375         0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0, 0xfe, 0x20, 0x0b, 0xb1,
11376         0x16, 0x32, 0x2a, 0x73,
11377         0xdd, 0xb8, 0x22, 0xb9, 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25,
11378         0x32, 0x8c, 0xfe, 0x48,
11379         0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
11380         0xdb, 0x10, 0x11, 0xfe,
11381         0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd, 0x7f, 0xfe, 0x89, 0xf0,
11382         0x22, 0x30, 0x2e, 0xd8,
11383         0xbc, 0x7d, 0xbd, 0x7f, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1,
11384         0x45, 0x0f, 0xfe, 0x42,
11385         0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
11386         0x09, 0x04, 0x0b, 0xfe,
11387         0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54, 0x12, 0x4b, 0xfe, 0x28,
11388         0x00, 0x21, 0xfe, 0xa6,
11389         0x0c, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00,
11390         0xfe, 0xe2, 0x10, 0x01,
11391         0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
11392         0x01, 0x6f, 0x02, 0x29,
11393         0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e, 0x0b, 0xfe, 0xb4, 0x10,
11394         0x01, 0x86, 0x3e, 0x0b,
11395         0xfe, 0xaa, 0x10, 0x01, 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3,
11396         0x3e, 0x0b, 0x0f, 0xfe,
11397         0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
11398         0xe8, 0x59, 0x11, 0x2d,
11399         0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02, 0xfe, 0x2a, 0x03, 0x09,
11400         0x04, 0x0b, 0x84, 0x3e,
11401         0x0b, 0x0f, 0x00, 0xfe, 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12,
11402         0x09, 0x04, 0x1b, 0xfe,
11403         0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
11404         0x1c, 0x1c, 0xfe, 0x9d,
11405         0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35, 0xfe, 0xa9, 0x10, 0x0f,
11406         0xfe, 0x15, 0x00, 0xfe,
11407         0x04, 0xe6, 0x0b, 0x5f, 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10,
11408         0x0f, 0xfe, 0x47, 0x00,
11409         0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
11410         0xab, 0x70, 0x05, 0x6b,
11411         0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b, 0xfe, 0x9d, 0x41, 0xfe,
11412         0x1c, 0x42, 0x59, 0x01,
11413         0xda, 0x02, 0x29, 0xea, 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31,
11414         0x00, 0x37, 0x97, 0x01,
11415         0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
11416         0x1d, 0xfe, 0xce, 0x45,
11417         0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47, 0x4b, 0x89, 0xfe, 0x75,
11418         0x57, 0x05, 0x51, 0xfe,
11419         0x98, 0x56, 0xfe, 0x38, 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48,
11420         0x46, 0x09, 0x04, 0x1d,
11421         0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
11422         0x99, 0x01, 0x0e, 0xfe,
11423         0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe, 0x2a, 0x03, 0x0a, 0x51,
11424         0xfe, 0xee, 0x14, 0xee,
11425         0x3e, 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad,
11426         0x13, 0x02, 0x29, 0x1e,
11427         0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
11428         0xce, 0x1e, 0x2d, 0x47,
11429         0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe, 0xec, 0x0d, 0x13, 0x06,
11430         0x12, 0x4d, 0x01, 0xfe,
11431         0xe2, 0x15, 0x05, 0xfe, 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe,
11432         0xf0, 0x0d, 0xfe, 0x02,
11433         0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
11434         0xf6, 0xfe, 0x34, 0x01,
11435         0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4, 0x0d, 0xfe, 0x18, 0x13,
11436         0xaf, 0xfe, 0x02, 0xea,
11437         0xce, 0x62, 0x7a, 0xfe, 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c,
11438         0x05, 0xfe, 0x38, 0x01,
11439         0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
11440         0x0c, 0xfe, 0x62, 0x01,
11441         0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11, 0x2d, 0x8a, 0x13, 0x06,
11442         0x03, 0x23, 0x03, 0x1e,
11443         0x4d, 0xfe, 0xf7, 0x12, 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe,
11444         0x71, 0x13, 0xfe, 0x24,
11445         0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
11446         0xdc, 0xfe, 0x73, 0x57,
11447         0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, 0xfe,
11448         0x80, 0x5d, 0x03, 0xfe,
11449         0x03, 0x57, 0xb6, 0x23, 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6,
11450         0x75, 0x03, 0x09, 0x04,
11451         0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
11452         0xfe, 0x1e, 0x80, 0xe1,
11453         0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe, 0x0e, 0x13, 0xfe, 0x0e,
11454         0x90, 0xa3, 0xfe, 0x3c,
11455         0x90, 0xfe, 0x30, 0xf4, 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82,
11456         0x16, 0x2f, 0x07, 0x2d,
11457         0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
11458         0xe8, 0x11, 0xfe, 0xe9,
11459         0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01, 0xfe, 0x14, 0x16, 0xfe,
11460         0x1e, 0x1c, 0xfe, 0x14,
11461         0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01,
11462         0x09, 0x04, 0x4f, 0xfe,
11463         0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
11464         0x40, 0x12, 0x20, 0x63,
11465         0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x03, 0xfe, 0x08,
11466         0x1c, 0x05, 0xfe, 0xac,
11467         0x00, 0xfe, 0x06, 0x58, 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05,
11468         0xfe, 0xb0, 0x00, 0xfe,
11469         0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
11470         0x24, 0x69, 0x12, 0xc9,
11471         0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48, 0x5f, 0x17, 0x1d, 0xfe,
11472         0x90, 0x4d, 0xfe, 0x91,
11473         0x54, 0x21, 0xfe, 0x08, 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c,
11474         0xfe, 0x90, 0x4d, 0xfe,
11475         0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
11476         0x46, 0x1e, 0x20, 0xed,
11477         0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x32, 0x0f, 0xea,
11478         0x70, 0xfe, 0x14, 0x1c,
11479         0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee,
11480         0xfe, 0x07, 0xe6, 0x1d,
11481         0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
11482         0xfa, 0xef, 0xfe, 0x42,
11483         0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a, 0x42, 0x01, 0x0e, 0xb0,
11484         0xfe, 0x36, 0x12, 0xf0,
11485         0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
11486         0x3d, 0x75, 0x07, 0x10,
11487         0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
11488         0x10, 0x07, 0x7e, 0x45,
11489         0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03, 0xfe, 0x44, 0x58, 0x74,
11490         0xfe, 0x01, 0xec, 0x97,
11491         0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76,
11492         0x27, 0x01, 0xda, 0xfe,
11493         0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
11494         0xfe, 0x48, 0x12, 0x07,
11495         0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30, 0x12, 0x07, 0xc2, 0x16,
11496         0xfe, 0x3e, 0x11, 0x07,
11497         0xfe, 0x23, 0x00, 0x16, 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8,
11498         0x11, 0x07, 0x19, 0xfe,
11499         0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
11500         0x01, 0x08, 0x8c, 0x43,
11501         0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01, 0xfe, 0x32, 0x0e, 0x11,
11502         0x7e, 0x02, 0x29, 0x2b,
11503         0x2f, 0x07, 0x9b, 0xfe, 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe,
11504         0xfc, 0x10, 0x09, 0x04,
11505         0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
11506         0xc6, 0x10, 0x1e, 0x58,
11507         0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77, 0xfe, 0x82, 0x0c, 0x0c,
11508         0x54, 0x18, 0x55, 0x23,
11509         0x0c, 0x7b, 0x0c, 0x7c, 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01,
11510         0xa5, 0xc0, 0x38, 0xc1,
11511         0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
11512         0x05, 0xfa, 0x4e, 0xfe,
11513         0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56,
11514         0x0c, 0x56, 0x18, 0x57,
11515         0x83, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe,
11516         0x00, 0x56, 0xfe, 0xa1,
11517         0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
11518         0x58, 0xfe, 0x1f, 0x40,
11519         0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x05, 0x56,
11520         0x31, 0x57, 0xfe, 0x44,
11521         0x50, 0xfe, 0xc6, 0x50, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe,
11522         0x8a, 0x50, 0x05, 0x39,
11523         0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
11524         0x12, 0xcd, 0x02, 0x5b,
11525         0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5, 0x07, 0x06, 0x21, 0x44,
11526         0x2f, 0x07, 0x9b, 0x21,
11527         0x5b, 0x01, 0x6e, 0x1c, 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79,
11528         0x39, 0x68, 0x3a, 0xfe,
11529         0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
11530         0x51, 0xfe, 0x8e, 0x51,
11531         0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19, 0x41, 0x02, 0x5b, 0x2b,
11532         0x01, 0x08, 0x25, 0x32,
11533         0x1f, 0xa2, 0x30, 0x2e, 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b,
11534         0x3b, 0x02, 0x44, 0x01,
11535         0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
11536         0x01, 0x08, 0x1f, 0xa2,
11537         0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x60, 0x05, 0xfe, 0x9c,
11538         0x00, 0x28, 0x84, 0x49,
11539         0x04, 0x19, 0x34, 0x9f, 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06,
11540         0x78, 0x3d, 0xfe, 0xda,
11541         0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
11542         0x05, 0xc6, 0x28, 0x84,
11543         0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8,
11544         0x14, 0xfe, 0x03, 0x17,
11545         0x05, 0x50, 0xb4, 0x0c, 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01,
11546         0xfe, 0xaa, 0x14, 0x02,
11547         0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
11548         0x21, 0x44, 0x01, 0xfe,
11549         0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14, 0xfe, 0xa4, 0x14, 0x87,
11550         0xfe, 0x4a, 0xf4, 0x0b,
11551         0x16, 0x44, 0xfe, 0x4a, 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a,
11552         0x85, 0x02, 0x5b, 0x05,
11553         0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
11554         0xd8, 0x14, 0x02, 0x5c,
11555         0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe, 0xe0, 0x12, 0x72, 0xf1,
11556         0x01, 0x08, 0x23, 0x72,
11557         0x03, 0x8f, 0xfe, 0xdc, 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca,
11558         0x12, 0x5e, 0x2b, 0x01,
11559         0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
11560         0x1c, 0xfe, 0xff, 0x7f,
11561         0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00,
11562         0x57, 0x48, 0x8b, 0x1c,
11563         0x3d, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02,
11564         0x00, 0x57, 0x48, 0x8b,
11565         0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
11566         0x03, 0x0a, 0x50, 0x01,
11567         0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c, 0x10, 0xff, 0x03, 0x00,
11568         0x54, 0xfe, 0x00, 0xf4,
11569         0x19, 0x48, 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe,
11570         0x03, 0x7c, 0x63, 0x27,
11571         0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
11572         0xfe, 0x82, 0x4a, 0xfe,
11573         0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01, 0xfe, 0x14, 0x18, 0xfe,
11574         0x42, 0x48, 0x5f, 0x60,
11575         0x89, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08,
11576         0x1f, 0xfe, 0xa2, 0x14,
11577         0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
11578         0xcc, 0x12, 0x49, 0x04,
11579         0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2, 0x4b, 0xc3, 0x64, 0xfe,
11580         0xe8, 0x13, 0x3b, 0x13,
11581         0x06, 0x17, 0xc3, 0x78, 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55,
11582         0xa1, 0xff, 0x02, 0x83,
11583         0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
11584         0x13, 0x06, 0xfe, 0x56,
11585         0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00, 0x8e, 0xe4, 0x0a, 0xfe,
11586         0x64, 0x00, 0x17, 0x93,
11587         0x13, 0x06, 0xfe, 0x28, 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe,
11588         0xc8, 0x00, 0x8e, 0xe4,
11589         0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
11590         0x01, 0xba, 0xfe, 0x4e,
11591         0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4, 0x94, 0xfe, 0x56, 0xf0,
11592         0xfe, 0x60, 0x14, 0xfe,
11593         0x04, 0xf4, 0x6c, 0xfe, 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01,
11594         0xfe, 0x22, 0x13, 0x1c,
11595         0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
11596         0xfe, 0x9c, 0x14, 0xb7,
11597         0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x19, 0xba,
11598         0xfe, 0x9c, 0x14, 0xb7,
11599         0x19, 0x83, 0x60, 0x23, 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06,
11600         0xfe, 0xb4, 0x56, 0xfe,
11601         0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
11602         0xe5, 0x15, 0x0b, 0x01,
11603         0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xe5, 0x72, 0xfe, 0x89,
11604         0x49, 0x01, 0x08, 0x03,
11605         0x15, 0x06, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6,
11606         0x15, 0x06, 0x01, 0x08,
11607         0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
11608         0x4a, 0x01, 0x08, 0x03,
11609         0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44, 0x13, 0xad, 0x12, 0xcc,
11610         0xfe, 0x49, 0xf4, 0x00,
11611         0x3b, 0x72, 0x9f, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01,
11612         0x08, 0x2f, 0x07, 0xfe,
11613         0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
11614         0x01, 0x43, 0x1e, 0xcd,
11615         0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03, 0x0a, 0x42, 0x01, 0x0e,
11616         0xed, 0x88, 0x07, 0x10,
11617         0xa4, 0x0a, 0x80, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a,
11618         0x80, 0x01, 0x0e, 0x88,
11619         0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
11620         0x88, 0x03, 0x0a, 0x42,
11621         0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x42, 0x01, 0x0e,
11622         0xfe, 0x80, 0x80, 0xf2,
11623         0xfe, 0x49, 0xe4, 0x10, 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51,
11624         0x01, 0x82, 0x03, 0x17,
11625         0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
11626         0xfe, 0x24, 0x1c, 0xfe,
11627         0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01, 0xfe, 0xfc, 0x16, 0xe0,
11628         0x91, 0x1d, 0x66, 0xfe,
11629         0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe,
11630         0xda, 0x10, 0x17, 0x10,
11631         0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
11632         0x05, 0xfe, 0x66, 0x01,
11633         0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06,
11634         0xfe, 0x3c, 0x50, 0x66,
11635         0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe,
11636         0x40, 0x16, 0xfe, 0xb6,
11637         0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
11638         0x10, 0x71, 0xfe, 0x83,
11639         0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x38, 0x90,
11640         0xfe, 0x62, 0x16, 0xfe,
11641         0x94, 0x14, 0xfe, 0x10, 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19,
11642         0xfe, 0x98, 0xe7, 0x00,
11643         0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
11644         0xfe, 0x30, 0xbc, 0xfe,
11645         0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
11646         0xc5, 0x90, 0xfe, 0x9a,
11647         0x16, 0xfe, 0x5c, 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe,
11648         0x42, 0x10, 0xfe, 0x02,
11649         0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
11650         0xfe, 0x1d, 0xf7, 0x4f,
11651         0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x91, 0x4f,
11652         0x47, 0xfe, 0x83, 0x58,
11653         0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11,
11654         0xfe, 0xdd, 0x00, 0x63,
11655         0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
11656         0x06, 0x37, 0x95, 0xa9,
11657         0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17, 0x23, 0x03, 0xfe, 0x7e,
11658         0x18, 0x1c, 0x1a, 0x5d,
11659         0x13, 0x0d, 0x03, 0x71, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe,
11660         0xe1, 0x10, 0x78, 0x2c,
11661         0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
11662         0x13, 0x3c, 0x8a, 0x0a,
11663         0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
11664         0xe3, 0xfe, 0x00, 0xcc,
11665         0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01,
11666         0x0e, 0xf2, 0x01, 0x6f,
11667         0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
11668         0xf6, 0xfe, 0xd6, 0xf0,
11669         0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c, 0xe7, 0x0b, 0x0f, 0xfe,
11670         0x15, 0x00, 0x59, 0x76,
11671         0x27, 0x01, 0xda, 0x17, 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35,
11672         0x11, 0x2d, 0x01, 0x6f,
11673         0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
11674         0xc8, 0xfe, 0x48, 0x55,
11675         0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73, 0x12, 0x98, 0x03, 0x0a,
11676         0x99, 0x01, 0x0e, 0xf0,
11677         0x0a, 0x40, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73,
11678         0x75, 0x03, 0x0a, 0x42,
11679         0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
11680         0x0e, 0x73, 0x75, 0x03,
11681         0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18, 0x05, 0xfe, 0x90, 0x00,
11682         0xfe, 0x3a, 0x45, 0x5b,
11683         0xfe, 0x4e, 0xe4, 0xc2, 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00,
11684         0xfe, 0x02, 0xe6, 0x1b,
11685         0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
11686         0xfe, 0x94, 0x00, 0xfe,
11687         0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe, 0x96, 0x00, 0xfe, 0x02,
11688         0xe6, 0x2c, 0xfe, 0x4e,
11689         0x45, 0xfe, 0x0c, 0x12, 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69,
11690         0x03, 0x07, 0x7a, 0xfe,
11691         0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
11692         0x07, 0x1b, 0xfe, 0x5a,
11693         0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26, 0x10, 0x07, 0x1a, 0x5d,
11694         0x24, 0x2c, 0xdc, 0x07,
11695         0x0b, 0x5d, 0x24, 0x93, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d,
11696         0x9f, 0xad, 0x03, 0x14,
11697         0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
11698         0x03, 0x25, 0xfe, 0xca,
11699         0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6, 0x18, 0x03, 0xff, 0x1a,
11700         0x00, 0x00,
11701 };
11702
11703 static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf);     /* 0x13AD */
11704 static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL;     /* Expanded little-endian checksum. */
11705
11706 /* Microcode buffer is kept after initialization for error recovery. */
11707 static unsigned char _adv_asc38C0800_buf[] = {
11708         0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
11709         0x01, 0x00, 0x48, 0xe4,
11710         0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19, 0x00, 0xfa, 0xff, 0xff,
11711         0x1c, 0x0f, 0x00, 0xf6,
11712         0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6,
11713         0x09, 0xe7, 0x55, 0xf0,
11714         0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
11715         0x18, 0xf4, 0x08, 0x00,
11716         0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0, 0x82, 0x0d, 0x00, 0xe6,
11717         0x86, 0xf0, 0xb1, 0xf0,
11718         0x98, 0x57, 0x01, 0xfc, 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c,
11719         0x3c, 0x00, 0xbb, 0x00,
11720         0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
11721         0xba, 0x13, 0x18, 0x40,
11722         0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc, 0x3e, 0x00, 0x6c, 0x01,
11723         0x6e, 0x01, 0x74, 0x01,
11724         0x76, 0x01, 0xb9, 0x54, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00,
11725         0xc0, 0x00, 0x01, 0x01,
11726         0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
11727         0x08, 0x12, 0x02, 0x4a,
11728         0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4,
11729         0x5d, 0xf0, 0x02, 0xfa,
11730         0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01,
11731         0x68, 0x01, 0x6a, 0x01,
11732         0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
11733         0x06, 0x13, 0x4c, 0x1c,
11734         0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x0c, 0x00,
11735         0x0f, 0x00, 0x47, 0x00,
11736         0xbe, 0x00, 0x00, 0x01, 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c,
11737         0x4e, 0x1c, 0x10, 0x44,
11738         0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
11739         0x05, 0x00, 0x34, 0x00,
11740         0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4a, 0x0b,
11741         0x42, 0x0c, 0x12, 0x0f,
11742         0x0c, 0x10, 0x22, 0x11, 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48,
11743         0x00, 0x4e, 0x42, 0x54,
11744         0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
11745         0x59, 0xf0, 0xb8, 0xf0,
11746         0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc, 0x05, 0xfc, 0x06, 0x00,
11747         0x19, 0x00, 0x33, 0x00,
11748         0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00,
11749         0xe7, 0x00, 0xe2, 0x03,
11750         0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
11751         0x12, 0x13, 0x24, 0x14,
11752         0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17, 0x20, 0x1c, 0x34, 0x1c,
11753         0x36, 0x1c, 0x08, 0x44,
11754         0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54,
11755         0x3a, 0x55, 0x83, 0x55,
11756         0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
11757         0x0c, 0xf0, 0x04, 0xf8,
11758         0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x9e, 0x00,
11759         0xa8, 0x00, 0xaa, 0x00,
11760         0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01,
11761         0xc4, 0x01, 0xc6, 0x01,
11762         0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
11763         0x68, 0x08, 0x69, 0x08,
11764         0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f, 0x12, 0x10, 0x1a, 0x10,
11765         0xed, 0x10, 0xf1, 0x10,
11766         0x2a, 0x11, 0x06, 0x12, 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13,
11767         0x1e, 0x13, 0x46, 0x14,
11768         0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
11769         0xca, 0x18, 0xe6, 0x19,
11770         0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0xfe, 0x9c,
11771         0xf0, 0x2b, 0x02, 0xfe,
11772         0xac, 0x0d, 0xff, 0x10, 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6,
11773         0xfe, 0x84, 0x01, 0xff,
11774         0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
11775         0x00, 0xfe, 0x57, 0x24,
11776         0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00, 0x00, 0x11, 0xff, 0x09,
11777         0x00, 0x00, 0xff, 0x08,
11778         0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
11779         0xff, 0xff, 0xff, 0x11,
11780         0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
11781         0xfe, 0x04, 0xf7, 0xd6,
11782         0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe, 0x04, 0xf7, 0xd6, 0x99,
11783         0x0a, 0x42, 0x2c, 0xfe,
11784         0x3d, 0xf0, 0xfe, 0x06, 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0,
11785         0xfe, 0xf4, 0x01, 0xfe,
11786         0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
11787         0x02, 0xfe, 0xc8, 0x0d,
11788         0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
11789         0x1c, 0x03, 0xfe, 0xa6,
11790         0x00, 0xfe, 0xd3, 0x12, 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48,
11791         0xf0, 0xfe, 0x8a, 0x02,
11792         0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
11793         0xfe, 0x46, 0xf0, 0xfe,
11794         0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
11795         0x48, 0x02, 0xfe, 0x44,
11796         0xf0, 0xfe, 0x4c, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a,
11797         0xaa, 0x18, 0x06, 0x14,
11798         0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
11799         0x1e, 0x1c, 0xfe, 0xe9,
11800         0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xce,
11801         0x09, 0x70, 0x01, 0xa8,
11802         0x02, 0x2b, 0x15, 0x59, 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70,
11803         0x01, 0x87, 0xfe, 0xbd,
11804         0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
11805         0x58, 0x1c, 0x18, 0x06,
11806         0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0x23,
11807         0xfe, 0x98, 0x02, 0xfe,
11808         0x5a, 0x1c, 0xf8, 0xfe, 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2,
11809         0x01, 0xfe, 0x48, 0x10,
11810         0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
11811         0x69, 0x10, 0x18, 0x06,
11812         0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43, 0x13, 0x20, 0xfe, 0x05,
11813         0xf6, 0xce, 0x01, 0xfe,
11814         0x4a, 0x17, 0x08, 0x54, 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe,
11815         0x82, 0x16, 0x02, 0x2b,
11816         0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
11817         0xfe, 0x41, 0x58, 0x09,
11818         0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe, 0x10, 0x03, 0x01, 0xfe,
11819         0x82, 0x16, 0x02, 0x2b,
11820         0x2c, 0x4f, 0xfe, 0x02, 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43,
11821         0xfe, 0x77, 0x57, 0xfe,
11822         0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
11823         0xfe, 0x40, 0x1c, 0x1c,
11824         0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x48,
11825         0x03, 0xfe, 0x11, 0xf0,
11826         0xa7, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10,
11827         0xfe, 0x11, 0x00, 0x02,
11828         0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
11829         0x21, 0x22, 0xa3, 0xb7,
11830         0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78, 0x01, 0xfe, 0xb4, 0x16,
11831         0x12, 0xd1, 0x1c, 0xd9,
11832         0xfe, 0x01, 0xf0, 0xd9, 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12,
11833         0xfe, 0xe4, 0x00, 0x27,
11834         0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
11835         0x06, 0xf0, 0xfe, 0xc8,
11836         0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a, 0x06, 0x02, 0x24, 0x03,
11837         0x70, 0x28, 0x17, 0xfe,
11838         0xfa, 0x04, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8,
11839         0xf9, 0x2c, 0x99, 0x19,
11840         0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
11841         0x74, 0x01, 0xaf, 0x8c,
11842         0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda, 0x09, 0xd1, 0x01, 0x0e,
11843         0x8d, 0x51, 0x64, 0x79,
11844         0x2a, 0x03, 0x70, 0x28, 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b,
11845         0xfe, 0x6a, 0x02, 0x02,
11846         0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
11847         0xfe, 0x3c, 0x04, 0x3b,
11848         0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2d, 0xff, 0x02,
11849         0x00, 0x10, 0x01, 0x0b,
11850         0x1d, 0xfe, 0xe4, 0x04, 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde,
11851         0xfe, 0x4c, 0x44, 0xfe,
11852         0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
11853         0xda, 0x4f, 0x79, 0x2a,
11854         0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62, 0x13, 0x08, 0x05, 0x1b,
11855         0xfe, 0x2a, 0x13, 0x32,
11856         0x07, 0x82, 0xfe, 0x52, 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c,
11857         0x54, 0x6b, 0xda, 0xfe,
11858         0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
11859         0x08, 0x13, 0x32, 0x07,
11860         0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x1c, 0x12, 0x15, 0x9d,
11861         0x08, 0x05, 0x06, 0x4d,
11862         0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24,
11863         0x2d, 0x12, 0xfe, 0xe6,
11864         0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
11865         0x02, 0x2b, 0xfe, 0x42,
11866         0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
11867         0xfe, 0x87, 0x80, 0xfe,
11868         0x31, 0xe4, 0x5b, 0x08, 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80,
11869         0x07, 0x19, 0xfe, 0x7c,
11870         0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
11871         0x17, 0xfe, 0x90, 0x05,
11872         0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe, 0x56, 0x13, 0x03, 0xfe,
11873         0xa0, 0x00, 0x28, 0xfe,
11874         0x4e, 0x12, 0x67, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c,
11875         0x34, 0xfe, 0x89, 0x48,
11876         0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
11877         0x12, 0xfe, 0xe3, 0x00,
11878         0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
11879         0x70, 0x05, 0x88, 0x25,
11880         0xfe, 0x21, 0x00, 0xab, 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe,
11881         0x09, 0x48, 0xff, 0x02,
11882         0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
11883         0x08, 0x53, 0x05, 0xcb,
11884         0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39, 0xfe, 0x27, 0x01, 0x08,
11885         0x05, 0x1b, 0xfe, 0x22,
11886         0x12, 0x41, 0x01, 0xb2, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe,
11887         0x0d, 0x00, 0x01, 0x36,
11888         0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
11889         0x03, 0x5c, 0x28, 0xfe,
11890         0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18, 0x06, 0x09, 0x06, 0x53,
11891         0x05, 0x1f, 0xfe, 0x02,
11892         0x12, 0x50, 0x01, 0xfe, 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5,
11893         0x01, 0x4b, 0x12, 0xfe,
11894         0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
11895         0x12, 0x03, 0x45, 0x28,
11896         0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01, 0xfe, 0x76, 0x19, 0xfe,
11897         0x43, 0x48, 0xc4, 0xcc,
11898         0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4,
11899         0x6e, 0x41, 0x01, 0xb2,
11900         0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
11901         0xfe, 0xcc, 0x15, 0x1d,
11902         0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe, 0xe5, 0x00, 0x03,
11903         0x45, 0xc1, 0x0c, 0x45,
11904         0x18, 0x06, 0x01, 0xb2, 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe,
11905         0xe2, 0x00, 0x27, 0xdb,
11906         0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
11907         0xfe, 0x06, 0xf0, 0xfe,
11908         0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05, 0x0a, 0xfe, 0x2e, 0x12,
11909         0x16, 0x19, 0x01, 0x0b,
11910         0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
11911         0xfe, 0x99, 0xa4, 0x01,
11912         0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
11913         0x12, 0x08, 0x05, 0x1a,
11914         0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
11915         0x0b, 0x16, 0x00, 0x01,
11916         0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02,
11917         0xe2, 0x6c, 0x58, 0xbe,
11918         0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
11919         0xfe, 0x09, 0x6f, 0xba,
11920         0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d, 0x8b, 0x6c, 0x7f, 0x27,
11921         0xfe, 0x54, 0x07, 0x1c,
11922         0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c,
11923         0x07, 0x02, 0x24, 0x01,
11924         0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
11925         0x2c, 0x90, 0xfe, 0xae,
11926         0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x54, 0x5a,
11927         0x37, 0x22, 0x20, 0x07,
11928         0x11, 0xfe, 0x0e, 0x12, 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a,
11929         0xfe, 0x06, 0x10, 0xfe,
11930         0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
11931         0x37, 0x01, 0xb3, 0xb8,
11932         0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe, 0x08, 0x50, 0xfe, 0x8a,
11933         0x50, 0xfe, 0x44, 0x51,
11934         0xfe, 0xc6, 0x51, 0x88, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e,
11935         0x14, 0x5f, 0xfe, 0x0c,
11936         0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
11937         0x14, 0x3e, 0xfe, 0x4a,
11938         0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
11939         0x90, 0x0c, 0x60, 0x14,
11940         0x61, 0x08, 0x05, 0x5b, 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62,
11941         0xfe, 0x44, 0x90, 0xfe,
11942         0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
11943         0x0c, 0x5e, 0x14, 0x5f,
11944         0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d, 0x14, 0x3e, 0x0c, 0x2e,
11945         0x14, 0x3c, 0x21, 0x0c,
11946         0x49, 0x0c, 0x63, 0x08, 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11,
11947         0x27, 0xdd, 0xfe, 0x9e,
11948         0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
11949         0x9a, 0x08, 0xc6, 0xfe,
11950         0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x94, 0x08,
11951         0x95, 0x86, 0x02, 0x24,
11952         0x01, 0x4b, 0xfe, 0xc9, 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05,
11953         0x06, 0xfe, 0x10, 0x12,
11954         0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
11955         0x1c, 0x02, 0xfe, 0x18,
11956         0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a, 0xfe, 0x7a, 0x12, 0xfe,
11957         0x2c, 0x1c, 0xfe, 0xaa,
11958         0xf0, 0xfe, 0xd2, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe,
11959         0xde, 0x09, 0xfe, 0xb7,
11960         0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
11961         0xfe, 0xf1, 0x18, 0xfe,
11962         0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe,
11963         0x14, 0x59, 0xfe, 0x95,
11964         0x59, 0x1c, 0x85, 0xfe, 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0,
11965         0xfe, 0xf0, 0x08, 0xb5,
11966         0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
11967         0x0b, 0xb6, 0xfe, 0xbf,
11968         0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe, 0x00, 0xfe, 0xfe, 0x1c,
11969         0x12, 0xc2, 0xfe, 0xd2,
11970         0xf0, 0x85, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e,
11971         0x06, 0x17, 0x85, 0xc5,
11972         0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
11973         0x9d, 0x01, 0x36, 0x10,
11974         0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10, 0x80, 0x02, 0x65, 0xfe,
11975         0x98, 0x80, 0xfe, 0x19,
11976         0xe4, 0x0a, 0xfe, 0x1a, 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18,
11977         0xfe, 0x44, 0x54, 0xbe,
11978         0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
11979         0x02, 0x4a, 0x08, 0x05,
11980         0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f, 0x14, 0x40, 0x9b, 0x2e,
11981         0x9c, 0x3c, 0xfe, 0x6c,
11982         0x18, 0xfe, 0xed, 0x18, 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f,
11983         0x3b, 0x40, 0x03, 0x49,
11984         0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
11985         0x8f, 0xfe, 0xe3, 0x54,
11986         0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0xfe, 0x37, 0xf0, 0xfe,
11987         0xda, 0x09, 0xfe, 0x8b,
11988         0xf0, 0xfe, 0x60, 0x09, 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa,
11989         0x0a, 0x3a, 0x49, 0x3b,
11990         0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
11991         0xad, 0xfe, 0x01, 0x59,
11992         0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a, 0xfe, 0x24, 0x0a, 0x3a,
11993         0x49, 0x8f, 0xfe, 0xe3,
11994         0x54, 0x57, 0x49, 0x7d, 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02,
11995         0x4a, 0x3a, 0x49, 0x3b,
11996         0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
11997         0x02, 0x4a, 0x08, 0x05,
11998         0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe, 0x66, 0x13, 0x22, 0x62,
11999         0xb7, 0xfe, 0x03, 0xa1,
12000         0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
12001         0xfe, 0x86, 0x91, 0x6a,
12002         0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
12003         0x61, 0x0c, 0x7f, 0x14,
12004         0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8, 0x6a, 0x2a, 0x13, 0x62,
12005         0x9b, 0x2e, 0x9c, 0x3c,
12006         0x3a, 0x3f, 0x3b, 0x40, 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05,
12007         0xfa, 0x3c, 0x01, 0xef,
12008         0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
12009         0xe4, 0x08, 0x05, 0x1f,
12010         0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37,
12011         0x03, 0x5e, 0x29, 0x5f,
12012         0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe,
12013         0xf4, 0x09, 0x08, 0x05,
12014         0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
12015         0x81, 0x50, 0xfe, 0x10,
12016         0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32, 0x07, 0xa6, 0x17, 0xfe,
12017         0x08, 0x09, 0x12, 0xa6,
12018         0x08, 0x05, 0x0a, 0xfe, 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe,
12019         0x08, 0x09, 0xfe, 0x0c,
12020         0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
12021         0x08, 0x05, 0x0a, 0xfe,
12022         0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xf4, 0xc2, 0xfe, 0xd1,
12023         0xf0, 0xe2, 0x15, 0x7e,
12024         0x01, 0x36, 0x10, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19,
12025         0x57, 0x3d, 0xfe, 0xed,
12026         0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
12027         0x00, 0xff, 0x35, 0xfe,
12028         0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6, 0x0b, 0xfe, 0x76, 0x18,
12029         0x1e, 0x19, 0x8a, 0x03,
12030         0xd2, 0x1e, 0x06, 0xfe, 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65,
12031         0xfe, 0xd1, 0xf0, 0xfe,
12032         0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
12033         0x10, 0xfe, 0xce, 0xf0,
12034         0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xca, 0x0b,
12035         0x10, 0xfe, 0x22, 0x00,
12036         0x02, 0x65, 0xfe, 0xcb, 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00,
12037         0x02, 0x65, 0xfe, 0xd0,
12038         0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
12039         0x0b, 0x10, 0x58, 0xfe,
12040         0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05, 0x1f, 0x4d, 0x10, 0xfe,
12041         0x12, 0x00, 0x2c, 0x0f,
12042         0xfe, 0x4e, 0x11, 0x27, 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14,
12043         0x0c, 0xbc, 0x17, 0x34,
12044         0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
12045         0x0c, 0x1c, 0x34, 0x94,
12046         0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6, 0xdc, 0x02, 0x24, 0x01,
12047         0x4b, 0xfe, 0xdb, 0x10,
12048         0x12, 0xfe, 0xe8, 0x00, 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe,
12049         0x89, 0xf0, 0x24, 0x33,
12050         0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
12051         0x33, 0x31, 0xdf, 0xbc,
12052         0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c, 0x06, 0xfe, 0x81, 0x49,
12053         0x17, 0xfe, 0x2c, 0x0d,
12054         0x08, 0x05, 0x0a, 0xfe, 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54,
12055         0x12, 0x55, 0xfe, 0x28,
12056         0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
12057         0x44, 0xfe, 0x28, 0x00,
12058         0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09, 0xa4, 0x01, 0xfe, 0x26,
12059         0x0f, 0x64, 0x12, 0x2f,
12060         0x01, 0x73, 0x02, 0x2b, 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44,
12061         0x0a, 0xfe, 0xb4, 0x10,
12062         0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
12063         0xfe, 0x34, 0x46, 0xac,
12064         0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96, 0x10, 0x08, 0x54, 0x0a,
12065         0x37, 0x01, 0xf5, 0x01,
12066         0xf6, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02,
12067         0xfe, 0x2e, 0x03, 0x08,
12068         0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
12069         0x1a, 0xfe, 0x58, 0x12,
12070         0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
12071         0xfe, 0x50, 0x0d, 0xfe,
12072         0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37,
12073         0xfe, 0xa9, 0x10, 0x10,
12074         0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
12075         0xfe, 0x13, 0x00, 0xfe,
12076         0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41, 0x00, 0xaa, 0x10, 0xfe,
12077         0x24, 0x00, 0x8c, 0xb5,
12078         0xb6, 0x74, 0x03, 0x70, 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a,
12079         0xfe, 0x9d, 0x41, 0xfe,
12080         0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
12081         0xb4, 0x15, 0xfe, 0x31,
12082         0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02, 0xd7, 0x42, 0xfe, 0x06,
12083         0xec, 0xd0, 0xfc, 0x44,
12084         0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47,
12085         0x4b, 0x91, 0xfe, 0x75,
12086         0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
12087         0x0e, 0xfe, 0x44, 0x48,
12088         0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09, 0x46, 0x01, 0x0e, 0x41,
12089         0xfe, 0x41, 0x58, 0x09,
12090         0xa4, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe,
12091         0x2e, 0x03, 0x09, 0x5d,
12092         0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
12093         0xce, 0x47, 0xfe, 0xad,
12094         0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x9e, 0x12, 0x21, 0x13,
12095         0x59, 0x13, 0x9f, 0x13,
12096         0xd5, 0x22, 0x2f, 0x41, 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe,
12097         0xe0, 0x0e, 0x0f, 0x06,
12098         0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
12099         0x3a, 0x01, 0x56, 0xfe,
12100         0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00, 0x66, 0xfe, 0x04, 0xec,
12101         0x20, 0x4f, 0xfe, 0x05,
12102         0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe,
12103         0x48, 0xf4, 0x0d, 0xfe,
12104         0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
12105         0x15, 0x1a, 0x39, 0xa0,
12106         0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x1e, 0xfe, 0xf0, 0xff,
12107         0x0c, 0xfe, 0x60, 0x01,
12108         0x03, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25,
12109         0x06, 0x13, 0x2f, 0x12,
12110         0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
12111         0x22, 0x9f, 0xb7, 0x13,
12112         0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24, 0x1c, 0x15, 0x19, 0x39,
12113         0xa0, 0xb4, 0xfe, 0xd9,
12114         0x10, 0xc3, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04,
12115         0xc3, 0xfe, 0x03, 0xdc,
12116         0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
12117         0xfe, 0x00, 0xcc, 0x04,
12118         0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05, 0x58, 0xfe, 0x22, 0x13,
12119         0xfe, 0x1c, 0x80, 0x07,
12120         0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae,
12121         0xfe, 0x0c, 0x90, 0xfe,
12122         0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
12123         0x0a, 0xfe, 0x3c, 0x50,
12124         0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f, 0xad, 0x01, 0xfe, 0xb4,
12125         0x16, 0x08, 0x05, 0x1b,
12126         0x4e, 0x01, 0xf5, 0x01, 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58,
12127         0xfe, 0x2c, 0x13, 0x01,
12128         0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
12129         0x0c, 0xfe, 0x64, 0x01,
12130         0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe, 0x12, 0x12, 0xfe, 0x03,
12131         0x80, 0x8d, 0xfe, 0x01,
12132         0xec, 0x20, 0xfe, 0x80, 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64,
12133         0x22, 0x20, 0xfb, 0x79,
12134         0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
12135         0x03, 0xfe, 0xae, 0x00,
12136
12137         0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe,
12138         0xb2, 0x00, 0xfe, 0x09,
12139         0x58, 0xfe, 0x0a, 0x1c, 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c,
12140         0x45, 0x0f, 0x46, 0x52,
12141         0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
12142         0x0f, 0x44, 0x11, 0x0f,
12143         0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xe4,
12144         0x25, 0x11, 0x13, 0x20,
12145         0x7c, 0x6f, 0x4f, 0x22, 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14,
12146         0x56, 0xfe, 0xd6, 0xf0,
12147         0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
12148         0x18, 0x1c, 0x04, 0x42,
12149         0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b, 0xfe, 0xce, 0x47, 0xfe,
12150         0xf5, 0x13, 0x04, 0x01,
12151         0xb0, 0x7c, 0x6f, 0x4f, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
12152         0x13, 0x32, 0x07, 0x2f,
12153         0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
12154         0x41, 0x48, 0xfe, 0x45,
12155         0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78,
12156         0x07, 0x11, 0xac, 0x09,
12157         0x84, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07,
12158         0x82, 0x4e, 0xfe, 0x14,
12159         0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
12160         0xfe, 0x01, 0xec, 0xa2,
12161         0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1a, 0x79,
12162         0x2a, 0x01, 0xe3, 0xfe,
12163         0xdd, 0x10, 0x2c, 0xc7, 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a,
12164         0xfe, 0x48, 0x12, 0x07,
12165         0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
12166         0xfe, 0x32, 0x12, 0x07,
12167         0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17, 0xfe, 0x9c, 0x12, 0x07,
12168         0x1f, 0xfe, 0x12, 0x12,
12169         0x07, 0x00, 0x17, 0x24, 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b,
12170         0x94, 0x4b, 0x04, 0x2d,
12171         0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
12172         0x32, 0x07, 0xa6, 0xfe,
12173         0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe, 0xf0, 0x11, 0x08, 0x05,
12174         0x5a, 0xfe, 0x72, 0x12,
12175         0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62,
12176         0xfe, 0x26, 0x13, 0x03,
12177         0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
12178         0x0c, 0x7f, 0x0c, 0x80,
12179         0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01, 0xef, 0x9b, 0x2e, 0x9c,
12180         0x3c, 0xfe, 0x04, 0x55,
12181         0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe,
12182         0x91, 0x10, 0x03, 0x3f,
12183         0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
12184         0x88, 0x9b, 0x2e, 0x9c,
12185         0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
12186         0x56, 0x0c, 0x5e, 0x14,
12187         0x5f, 0x08, 0x05, 0x5a, 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40,
12188         0x03, 0x60, 0x29, 0x61,
12189         0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
12190         0x50, 0xfe, 0xc6, 0x50,
12191         0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x3d,
12192         0x29, 0x3e, 0xfe, 0x40,
12193         0x50, 0xfe, 0xc2, 0x50, 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72,
12194         0x2d, 0x01, 0x0b, 0x1d,
12195         0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
12196         0x72, 0x01, 0xaf, 0x1e,
12197         0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a, 0x3d, 0x3b, 0x3e, 0xfe,
12198         0x0a, 0x55, 0x35, 0xfe,
12199         0x8b, 0x55, 0x57, 0x3d, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51,
12200         0x02, 0x72, 0xfe, 0x19,
12201         0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
12202         0x1d, 0xe8, 0x33, 0x31,
12203         0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a, 0x4d, 0x02, 0x4c, 0x01,
12204         0x0b, 0x1c, 0x34, 0x1d,
12205         0xe8, 0x33, 0x31, 0xdf, 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8,
12206         0x33, 0x31, 0xfe, 0xe8,
12207         0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
12208         0x05, 0x1f, 0x35, 0xa9,
12209         0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06, 0x7c, 0x43, 0xfe, 0xda,
12210         0x14, 0x01, 0xaf, 0x8c,
12211         0xfe, 0x4b, 0x45, 0xee, 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a,
12212         0x03, 0x45, 0x28, 0x35,
12213         0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
12214         0x03, 0x5c, 0xc1, 0x0c,
12215         0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0x9e, 0x15, 0x02,
12216         0x89, 0x01, 0x0b, 0x1c,
12217         0x34, 0x1d, 0x4c, 0x33, 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1,
12218         0xfe, 0x42, 0x58, 0xf1,
12219         0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
12220         0xf4, 0x06, 0xea, 0x32,
12221         0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x67, 0x2d,
12222         0x01, 0x0b, 0x26, 0x89,
12223         0x01, 0xfe, 0xcc, 0x15, 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13,
12224         0x26, 0xfe, 0xd4, 0x13,
12225         0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
12226         0x13, 0x1c, 0xfe, 0xd0,
12227         0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01, 0x0b, 0xfe, 0xd5, 0x10,
12228         0x0f, 0x71, 0xff, 0x02,
12229         0x00, 0x57, 0x52, 0x93, 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe,
12230         0x00, 0x5c, 0x04, 0x0f,
12231         0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
12232         0xfe, 0x00, 0x5c, 0x04,
12233         0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x04, 0x0f, 0x71, 0xff,
12234         0x02, 0x00, 0x57, 0x52,
12235         0x93, 0xfe, 0x0b, 0x58, 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01,
12236         0x87, 0x04, 0xfe, 0x03,
12237         0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
12238         0xfe, 0x00, 0x7d, 0xfe,
12239         0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x6a, 0x2a, 0x0c, 0x5e,
12240         0x14, 0x5f, 0x57, 0x3f,
12241         0x7d, 0x40, 0x04, 0xdd, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83,
12242         0x5a, 0x8d, 0x04, 0x01,
12243         0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
12244         0xfe, 0x96, 0x15, 0x33,
12245         0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33, 0x31, 0xfe, 0xe8,
12246         0x0a, 0xfe, 0xc1, 0x59,
12247         0x03, 0xcd, 0x28, 0xfe, 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13,
12248         0x21, 0x69, 0x1a, 0xee,
12249         0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
12250         0x30, 0xfe, 0x78, 0x10,
12251         0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83, 0x55, 0x69, 0x19, 0xae,
12252         0x98, 0xfe, 0x30, 0x00,
12253         0x96, 0xf2, 0x18, 0x6d, 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed,
12254         0x98, 0xfe, 0x64, 0x00,
12255         0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
12256         0x10, 0x69, 0x06, 0xfe,
12257         0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2, 0x09, 0xfe, 0xc8, 0x00,
12258         0x18, 0x59, 0x0f, 0x06,
12259         0x88, 0x98, 0xfe, 0x90, 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe,
12260         0x43, 0xf4, 0x9f, 0xfe,
12261         0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
12262         0x9e, 0xfe, 0xf3, 0x10,
12263         0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e, 0x43, 0xec, 0xfe, 0x00,
12264         0x17, 0xfe, 0x4d, 0xe4,
12265         0x6e, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00,
12266         0x17, 0xfe, 0x4d, 0xe4,
12267         0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
12268         0xf4, 0x00, 0xe9, 0x91,
12269         0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x04, 0x51, 0x0f, 0x0a,
12270         0x04, 0x16, 0x06, 0x01,
12271         0x0b, 0x26, 0xf3, 0x16, 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01,
12272         0x0b, 0x26, 0xf3, 0x76,
12273         0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
12274         0x16, 0x19, 0x01, 0x0b,
12275         0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0xfe, 0x89, 0x49, 0x01,
12276         0x0b, 0x26, 0xb1, 0x76,
12277         0xfe, 0x89, 0x4a, 0x01, 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06,
12278         0xfe, 0x48, 0x13, 0xb8,
12279         0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
12280         0xec, 0xfe, 0x27, 0x01,
12281         0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x2e, 0x16, 0x32,
12282         0x07, 0xfe, 0xe3, 0x00,
12283         0xfe, 0x20, 0x13, 0x1d, 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b,
12284         0x22, 0xd4, 0x07, 0x06,
12285         0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
12286         0x07, 0x11, 0xae, 0x09,
12287         0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x84, 0x01,
12288         0x0e, 0x8e, 0xfe, 0x80,
12289         0xe7, 0x11, 0x07, 0x11, 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04,
12290         0x09, 0x48, 0x01, 0x0e,
12291         0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
12292         0x80, 0xfe, 0x80, 0x4c,
12293         0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c,
12294         0x09, 0x5d, 0x01, 0x87,
12295         0x04, 0x18, 0x11, 0x75, 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe,
12296         0x19, 0xde, 0xfe, 0x24,
12297         0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
12298         0x17, 0xad, 0x9a, 0x1b,
12299         0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04, 0xb9, 0x23, 0xfe, 0xde,
12300         0x16, 0xfe, 0xda, 0x10,
12301         0x18, 0x11, 0x75, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe,
12302         0x18, 0x58, 0x03, 0xfe,
12303         0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
12304         0xf4, 0x06, 0xfe, 0x3c,
12305         0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x1f,
12306         0x97, 0xfe, 0x38, 0x17,
12307         0xfe, 0xb6, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c,
12308         0x10, 0x18, 0x11, 0x75,
12309         0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
12310         0x2e, 0x97, 0xfe, 0x5a,
12311         0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c, 0x1a, 0xfe, 0xaf, 0x19,
12312         0xfe, 0x98, 0xe7, 0x00,
12313         0x04, 0xb9, 0x23, 0xfe, 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75,
12314         0xfe, 0x30, 0xbc, 0xfe,
12315         0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
12316         0xcb, 0x97, 0xfe, 0x92,
12317         0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x7e, 0x17, 0xfe,
12318         0x42, 0x10, 0xfe, 0x02,
12319         0xf6, 0x11, 0x75, 0xfe, 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe,
12320         0x03, 0xa1, 0xfe, 0x1d,
12321         0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
12322         0x9a, 0x5b, 0x41, 0xfe,
12323         0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x11, 0xfe, 0x81, 0xe7,
12324         0x11, 0x12, 0xfe, 0xdd,
12325         0x00, 0x6a, 0x2a, 0x04, 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8,
12326         0x17, 0x15, 0x06, 0x39,
12327         0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
12328         0xfe, 0x7e, 0x18, 0x1e,
12329         0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2, 0x1e, 0x06, 0xfe, 0xef,
12330         0x12, 0xfe, 0xe1, 0x10,
12331         0x7c, 0x6f, 0x4f, 0x32, 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42,
12332         0x13, 0x42, 0x92, 0x09,
12333         0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
12334         0xf0, 0xfe, 0x00, 0xcc,
12335         0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01,
12336         0x0e, 0xfe, 0x80, 0x4c,
12337         0x01, 0x73, 0xfe, 0x16, 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe,
12338         0x24, 0x12, 0xfe, 0x14,
12339         0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
12340         0xe7, 0x0a, 0x10, 0xfe,
12341         0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18, 0x06, 0x04, 0x42, 0x92,
12342         0x08, 0x54, 0x1b, 0x37,
12343         0x12, 0x2f, 0x01, 0x73, 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba,
12344         0x90, 0x3a, 0xce, 0x3b,
12345         0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
12346         0x13, 0xa3, 0x04, 0x09,
12347         0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46, 0x01, 0x0e, 0xfe, 0x49,
12348         0x44, 0x17, 0xfe, 0xe8,
12349         0x18, 0x77, 0x78, 0x04, 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09,
12350         0x5d, 0x01, 0xa8, 0x09,
12351         0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
12352         0x1c, 0x19, 0x03, 0xfe,
12353         0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xc9,
12354         0x6b, 0xfe, 0x2e, 0x19,
12355         0x03, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4,
12356         0xfe, 0x0b, 0x00, 0x6b,
12357         0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
12358         0x08, 0x10, 0x03, 0xfe,
12359         0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e, 0x45, 0xea, 0xba, 0xff,
12360         0x04, 0x68, 0x54, 0xe7,
12361         0x1e, 0x6e, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe,
12362         0x1a, 0xf4, 0xfe, 0x00,
12363         0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
12364         0x04, 0x07, 0x7e, 0xfe,
12365         0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
12366         0x07, 0x1a, 0xfe, 0x5a,
12367         0xf0, 0xfe, 0x92, 0x19, 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66,
12368         0x25, 0x6d, 0xe5, 0x07,
12369         0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
12370         0xa9, 0xb8, 0x04, 0x15,
12371         0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe, 0x81, 0x03, 0x83, 0xfe,
12372         0x40, 0x5c, 0x04, 0x1c,
12373         0xf7, 0xfe, 0x14, 0xf0, 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b,
12374         0xf7, 0xfe, 0x82, 0xf0,
12375         0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
12376 };
12377
12378 static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf);       /* 0x14E1 */
12379 static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL;  /* Expanded little-endian checksum. */
12380
12381 /* Microcode buffer is kept after initialization for error recovery. */
12382 static unsigned char _adv_asc38C1600_buf[] = {
12383         0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
12384         0x18, 0xe4, 0x01, 0x00,
12385         0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13, 0x2e, 0x1e, 0x02, 0x00,
12386         0x07, 0x17, 0xc0, 0x5f,
12387         0x00, 0xfa, 0xff, 0xff, 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7,
12388         0x85, 0xf0, 0x86, 0xf0,
12389         0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
12390         0x98, 0x57, 0x01, 0xe6,
12391         0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4, 0x08, 0x00, 0xf0, 0x1d,
12392         0x38, 0x54, 0x32, 0xf0,
12393         0x10, 0x00, 0xc2, 0x0e, 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4,
12394         0x00, 0xe6, 0xb1, 0xf0,
12395         0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
12396         0x06, 0x13, 0x0c, 0x1c,
12397         0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc, 0xbc, 0x0e, 0xa2, 0x12,
12398         0xb9, 0x54, 0x00, 0x80,
12399         0x62, 0x0a, 0x5a, 0x12, 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56,
12400         0x03, 0xe6, 0x01, 0xea,
12401         0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
12402         0x04, 0x13, 0xbb, 0x55,
12403         0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4, 0x40, 0x00, 0xb6, 0x00,
12404         0xbb, 0x00, 0xc0, 0x00,
12405         0x00, 0x01, 0x01, 0x01, 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12,
12406         0x4c, 0x1c, 0x4e, 0x1c,
12407         0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
12408         0x24, 0x01, 0x3c, 0x01,
12409         0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01,
12410         0x78, 0x01, 0x7c, 0x01,
12411         0xc6, 0x0e, 0x0c, 0x10, 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c,
12412         0x6e, 0x1e, 0x02, 0x48,
12413         0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
12414         0x03, 0xfc, 0x06, 0x00,
12415         0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12, 0x18, 0x1a, 0x70, 0x1a,
12416         0x30, 0x1c, 0x38, 0x1c,
12417         0x10, 0x44, 0x00, 0x4c, 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea,
12418         0x5d, 0xf0, 0xa7, 0xf0,
12419         0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
12420         0x33, 0x00, 0x34, 0x00,
12421         0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01,
12422         0x79, 0x01, 0x3c, 0x09,
12423         0x68, 0x0d, 0x02, 0x10, 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13,
12424         0x40, 0x16, 0x50, 0x16,
12425         0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
12426         0x05, 0xf0, 0x09, 0xf0,
12427         0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7, 0x0a, 0x00, 0x9b, 0x00,
12428         0x9c, 0x00, 0xa4, 0x00,
12429         0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08,
12430         0xe9, 0x09, 0x5c, 0x0c,
12431         0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
12432         0x42, 0x1d, 0x08, 0x44,
12433         0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x89, 0x48, 0x68, 0x54,
12434         0x83, 0x55, 0x83, 0x59,
12435         0x31, 0xe4, 0x02, 0xe6, 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0,
12436         0x4b, 0xf4, 0x04, 0xf8,
12437         0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
12438         0xa8, 0x00, 0xaa, 0x00,
12439         0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01, 0x26, 0x01, 0x60, 0x01,
12440         0x7a, 0x01, 0x82, 0x01,
12441         0xc8, 0x01, 0xca, 0x01, 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07,
12442         0x68, 0x08, 0x10, 0x0d,
12443         0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
12444         0xf3, 0x10, 0x06, 0x12,
12445         0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13, 0x10, 0x13, 0xfe, 0x9c,
12446         0xf0, 0x35, 0x05, 0xfe,
12447         0xec, 0x0e, 0xff, 0x10, 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8,
12448         0xfe, 0x88, 0x01, 0xff,
12449         0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
12450         0x00, 0xfe, 0x57, 0x24,
12451         0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00, 0x00, 0x1a, 0xff, 0x09,
12452         0x00, 0x00, 0xff, 0x08,
12453         0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
12454         0xff, 0xff, 0xff, 0x13,
12455         0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
12456         0xfe, 0x04, 0xf7, 0xe8,
12457         0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe, 0x04, 0xf7, 0xe8, 0x7d,
12458         0x0d, 0x51, 0x37, 0xfe,
12459         0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0,
12460         0xfe, 0xf8, 0x01, 0xfe,
12461         0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
12462         0x05, 0xfe, 0x08, 0x0f,
12463         0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05, 0xfe, 0x0e, 0x03, 0xfe,
12464         0x28, 0x1c, 0x03, 0xfe,
12465         0xa6, 0x00, 0xfe, 0xd1, 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe,
12466         0x48, 0xf0, 0xfe, 0x90,
12467         0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
12468         0x02, 0xfe, 0x46, 0xf0,
12469         0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60, 0x02, 0xfe, 0x43, 0xf0,
12470         0xfe, 0x4e, 0x02, 0xfe,
12471         0x44, 0xf0, 0xfe, 0x52, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c,
12472         0x0d, 0xa2, 0x1c, 0x07,
12473         0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
12474         0x1c, 0xf5, 0xfe, 0x1e,
12475         0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc,
12476         0xde, 0x0a, 0x81, 0x01,
12477         0xa3, 0x05, 0x35, 0x1f, 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a,
12478         0x81, 0x01, 0x5c, 0xfe,
12479         0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
12480         0xfe, 0x58, 0x1c, 0x1c,
12481         0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c, 0x02,
12482         0x2b, 0xfe, 0x9e, 0x02,
12483         0xfe, 0x5a, 0x1c, 0xfe, 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30,
12484         0x00, 0x47, 0xb8, 0x01,
12485         0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
12486         0x1a, 0x31, 0xfe, 0x69,
12487         0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0x01, 0xfe,
12488         0x1e, 0x1e, 0x20, 0x2c,
12489         0xfe, 0x05, 0xf6, 0xde, 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a,
12490         0x44, 0x15, 0x56, 0x51,
12491         0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
12492         0x01, 0x18, 0x09, 0x00,
12493         0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0x01,
12494         0x18, 0xfe, 0xc8, 0x54,
12495         0x7b, 0xfe, 0x1c, 0x03, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60,
12496         0xfe, 0x02, 0xe8, 0x30,
12497         0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
12498         0xfe, 0xe4, 0x01, 0xfe,
12499         0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40, 0x1c, 0x2a, 0xeb, 0xfe,
12500         0x26, 0xf0, 0xfe, 0x66,
12501         0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe,
12502         0xef, 0x10, 0xfe, 0x9f,
12503         0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
12504         0x70, 0x37, 0xfe, 0x48,
12505         0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x26,
12506         0x21, 0xb9, 0xc7, 0x20,
12507         0xb9, 0x0a, 0x57, 0x01, 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15,
12508         0xe1, 0x2a, 0xeb, 0xfe,
12509         0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
12510         0x15, 0xfe, 0xe4, 0x00,
12511         0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe, 0xc6, 0x03, 0x01, 0x41,
12512         0xfe, 0x06, 0xf0, 0xfe,
12513         0xd6, 0x03, 0xaf, 0xa0, 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29,
12514         0x03, 0x81, 0x1e, 0x1b,
12515         0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
12516         0xea, 0xfe, 0x46, 0x1c,
12517         0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
12518         0xfe, 0x48, 0x1c, 0x75,
12519         0x01, 0xa6, 0x86, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a,
12520         0xe1, 0x01, 0x18, 0x77,
12521         0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
12522         0x8f, 0xfe, 0x70, 0x02,
12523         0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29, 0x2f, 0xfe, 0x4e, 0x04,
12524         0x16, 0xfe, 0x4a, 0x04,
12525         0x7e, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff,
12526         0x02, 0x00, 0x10, 0x01,
12527         0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
12528         0xee, 0xfe, 0x4c, 0x44,
12529         0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13, 0x34, 0xfe, 0x4c, 0x54,
12530         0x7b, 0xec, 0x60, 0x8d,
12531         0x30, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01,
12532         0x0c, 0x06, 0x28, 0xfe,
12533         0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
12534         0x13, 0x34, 0xfe, 0x4c,
12535         0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x54,
12536         0x13, 0x01, 0x0c, 0x06,
12537         0x28, 0xa5, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06,
12538         0x28, 0xf9, 0x1f, 0x7f,
12539         0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
12540         0xfe, 0xa4, 0x0e, 0x05,
12541         0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe, 0x1c, 0x90, 0x04, 0xfe,
12542         0x9c, 0x93, 0x3a, 0x0b,
12543         0x0e, 0x8b, 0x02, 0x1f, 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b,
12544         0x7d, 0x1d, 0xfe, 0x46,
12545         0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
12546         0xfe, 0x87, 0x83, 0xfe,
12547         0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x98,
12548         0x13, 0x0f, 0xfe, 0x20,
12549         0x80, 0x04, 0xfe, 0xa0, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84,
12550         0x12, 0x01, 0x38, 0x06,
12551         0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
12552         0x05, 0xd0, 0x54, 0x01,
12553         0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x1e, 0xfe,
12554         0x50, 0x12, 0x5e, 0xff,
12555         0x02, 0x00, 0x10, 0x2f, 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02,
12556         0x00, 0x10, 0x2f, 0xfe,
12557         0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
12558         0x38, 0xfe, 0x4a, 0xf0,
12559         0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba, 0x05, 0x71, 0x2e, 0xfe,
12560         0x21, 0x00, 0xf1, 0x2e,
12561         0xfe, 0x22, 0x00, 0xa2, 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00,
12562         0x10, 0x2f, 0xfe, 0xd0,
12563         0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
12564         0x1c, 0x00, 0x4d, 0x01,
12565         0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27, 0x01, 0x01, 0x0c, 0x06,
12566         0x28, 0xfe, 0x24, 0x12,
12567         0x3e, 0x01, 0x84, 0x1f, 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe,
12568         0x0d, 0x00, 0x01, 0x42,
12569         0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
12570         0x03, 0xb6, 0x1e, 0xfe,
12571         0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13, 0x3e, 0x01, 0x84, 0x17,
12572         0xfe, 0x72, 0x06, 0x0a,
12573         0x07, 0x01, 0x38, 0x06, 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56,
12574         0x19, 0x16, 0xfe, 0x68,
12575         0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
12576         0x03, 0x9a, 0x1e, 0xfe,
12577         0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13, 0x01, 0xc6, 0x09, 0x12,
12578         0x48, 0xfe, 0x92, 0x06,
12579         0x2e, 0x12, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13,
12580         0x58, 0xff, 0x02, 0x00,
12581         0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
12582         0xfe, 0xea, 0x06, 0x01,
12583         0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01, 0xfe, 0x84, 0x19, 0x16,
12584         0xfe, 0xe0, 0x06, 0x15,
12585         0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07,
12586         0x01, 0x84, 0xfe, 0xae,
12587         0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
12588         0x1e, 0xfe, 0x1a, 0x12,
12589         0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
12590         0x43, 0x48, 0x62, 0x80,
12591         0xf0, 0x45, 0x0a, 0x95, 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24,
12592         0x36, 0xfe, 0x02, 0xf6,
12593         0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
12594         0xd0, 0x0d, 0x17, 0xfe,
12595         0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe, 0x90, 0x07, 0x26, 0x20,
12596         0x9e, 0x15, 0x82, 0x01,
12597         0x41, 0x15, 0xe2, 0x21, 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58,
12598         0x57, 0x10, 0xe6, 0x05,
12599         0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
12600         0xfe, 0x9c, 0x32, 0x5f,
12601         0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00, 0x2f, 0xed, 0x2a, 0x3c,
12602         0xfe, 0x0a, 0xf0, 0xfe,
12603         0xce, 0x07, 0xae, 0xfe, 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08,
12604         0xaf, 0xa0, 0x05, 0x29,
12605         0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
12606         0x00, 0x01, 0x08, 0x14,
12607         0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08,
12608         0x14, 0x00, 0x05, 0xfe,
12609         0xc6, 0x09, 0x01, 0x76, 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06,
12610         0x12, 0xfe, 0x30, 0x13,
12611         0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
12612         0x01, 0x08, 0x14, 0x00,
12613         0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00, 0x05, 0xef, 0x7c, 0x4a,
12614         0x78, 0x4f, 0x0f, 0xfe,
12615         0x9a, 0x81, 0x04, 0xfe, 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d,
12616         0x28, 0x48, 0xfe, 0x6c,
12617         0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
12618         0x12, 0x53, 0x63, 0x4e,
12619         0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe,
12620         0x6c, 0x08, 0xaf, 0xa0,
12621         0xae, 0xfe, 0x96, 0x08, 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24,
12622         0x05, 0xed, 0xfe, 0x9c,
12623         0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
12624         0x1e, 0xfe, 0x99, 0x58,
12625         0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe, 0x16, 0x09, 0x10, 0x6a,
12626         0x22, 0x6b, 0x01, 0x0c,
12627         0x61, 0x54, 0x44, 0x21, 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e,
12628         0x1e, 0x47, 0x2c, 0x7a,
12629         0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
12630         0x01, 0x0c, 0x61, 0x65,
12631         0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20, 0x6e, 0x01, 0xfe, 0x6a,
12632         0x16, 0xfe, 0x08, 0x50,
12633         0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10,
12634         0x01, 0xfe, 0xce, 0x1e,
12635         0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
12636         0x01, 0xfe, 0xfe, 0x1e,
12637         0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b, 0x22, 0x4c, 0xfe, 0x8a,
12638         0x10, 0x01, 0x0c, 0x06,
12639         0x54, 0xfe, 0x50, 0x12, 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e,
12640         0x10, 0x6a, 0x22, 0x6b,
12641         0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
12642         0xfe, 0x9f, 0x83, 0x33,
12643         0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90, 0x04, 0xfe, 0xc4, 0x93,
12644         0x3a, 0x0b, 0xfe, 0xc6,
12645         0x90, 0x04, 0xfe, 0xc6, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d,
12646         0x01, 0xfe, 0xce, 0x1e,
12647         0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
12648         0x04, 0xfe, 0xc0, 0x93,
12649         0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2, 0x93, 0x79, 0x0b, 0x0e,
12650         0x10, 0x4b, 0x22, 0x4c,
12651         0x10, 0x64, 0x22, 0x34, 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe,
12652         0x4e, 0x11, 0x2f, 0xfe,
12653         0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
12654         0x3c, 0x37, 0x88, 0xf5,
12655         0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a, 0xd2, 0xfe, 0x1e, 0x0a,
12656         0xd3, 0xfe, 0x42, 0x0a,
12657         0xae, 0xfe, 0x12, 0x0a, 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0,
12658         0x05, 0x29, 0x01, 0x41,
12659         0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
12660         0xfe, 0x14, 0x12, 0x01,
12661         0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x74, 0x12, 0xfe,
12662         0x2e, 0x1c, 0x05, 0xfe,
12663         0x1a, 0x0c, 0x01, 0x76, 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41,
12664         0xfe, 0x2c, 0x1c, 0xfe,
12665         0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
12666         0x92, 0x10, 0xc4, 0xf6,
12667         0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe, 0x1a, 0x0c, 0xc5, 0xfe,
12668         0xe7, 0x10, 0xfe, 0x2b,
12669         0xf0, 0xbf, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12,
12670         0xac, 0xfe, 0xd2, 0xf0,
12671         0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
12672         0x1b, 0xbf, 0xd4, 0x5b,
12673         0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5, 0xfe, 0xa9, 0x10, 0x75,
12674         0x5e, 0x32, 0x1f, 0x7f,
12675         0x01, 0x42, 0x19, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98,
12676         0x05, 0x70, 0xfe, 0x74,
12677         0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
12678         0x0f, 0x4d, 0x01, 0xfe,
12679         0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05, 0x5b, 0x01, 0x0c, 0x06,
12680         0x0d, 0x2b, 0xfe, 0xe2,
12681         0x0b, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24,
12682         0xfe, 0x88, 0x13, 0x21,
12683         0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
12684         0x83, 0x83, 0xfe, 0xc9,
12685         0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42, 0x13, 0x0f, 0xfe, 0x04,
12686         0x91, 0x04, 0xfe, 0x84,
12687         0x93, 0xfe, 0xca, 0x57, 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93,
12688         0xfe, 0xcb, 0x57, 0x0b,
12689         0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
12690         0x6a, 0x3b, 0x6b, 0x10,
12691         0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01, 0xc2, 0xc8, 0x7a, 0x30,
12692         0x20, 0x6e, 0xdb, 0x64,
12693         0xdc, 0x34, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55,
12694         0xfe, 0x04, 0xfa, 0x64,
12695         0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
12696         0x10, 0x98, 0x91, 0x6c,
12697         0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x91,
12698         0x4b, 0x7e, 0x4c, 0x01,
12699         0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10,
12700         0x58, 0xfe, 0x91, 0x58,
12701         0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
12702         0x1b, 0x40, 0x01, 0x0c,
12703         0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe, 0x8e, 0x1e, 0x4f, 0x0f,
12704         0xfe, 0x10, 0x90, 0x04,
12705         0xfe, 0x90, 0x93, 0x3a, 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93,
12706         0x79, 0x0b, 0x0e, 0xfe,
12707         0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
12708         0x01, 0x0c, 0x06, 0x0d,
12709         0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e, 0xfe, 0x6e, 0x0a, 0xfe,
12710         0x0c, 0x58, 0xfe, 0x8d,
12711         0x58, 0x05, 0x5b, 0x26, 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99,
12712         0x83, 0x33, 0x0b, 0x0e,
12713         0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
12714         0x19, 0xfe, 0x19, 0x41,
12715         0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef, 0x1f, 0x92, 0x01, 0x42,
12716         0x19, 0xfe, 0x44, 0x00,
12717         0xfe, 0x90, 0x10, 0xfe, 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda,
12718         0x4c, 0xfe, 0x0c, 0x51,
12719         0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
12720         0x76, 0x10, 0xac, 0xfe,
12721         0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x5d, 0x03,
12722         0xe3, 0x23, 0x07, 0xfe,
12723         0x08, 0x13, 0x19, 0xfe, 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe,
12724         0xcc, 0x0c, 0x1f, 0x92,
12725         0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
12726         0x0c, 0xfe, 0x3e, 0x10,
12727         0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe, 0x22, 0x00, 0x05, 0x70,
12728         0xfe, 0xcb, 0xf0, 0xfe,
12729         0xea, 0x0c, 0x19, 0xfe, 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe,
12730         0xf4, 0x0c, 0x19, 0x94,
12731         0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
12732         0xfe, 0xcc, 0xf0, 0xef,
12733         0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12, 0x00, 0x37, 0x13, 0xfe,
12734         0x4e, 0x11, 0x2f, 0xfe,
12735         0x16, 0x0d, 0xfe, 0x9e, 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b,
12736         0x3c, 0x37, 0x88, 0xf5,
12737         0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
12738         0x2f, 0xfe, 0x3e, 0x0d,
12739         0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0, 0xd4, 0x9f, 0xd5, 0x9f,
12740         0xd2, 0x9f, 0xd3, 0x9f,
12741         0x05, 0x29, 0x01, 0x41, 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4,
12742         0xc5, 0x75, 0xd7, 0x99,
12743         0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
12744         0x9c, 0x2f, 0xfe, 0x8c,
12745         0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01, 0x48, 0xa4, 0x19, 0xfe,
12746         0x42, 0x00, 0x05, 0x70,
12747         0x90, 0x07, 0xfe, 0x81, 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06,
12748         0x0d, 0xfe, 0x44, 0x13,
12749         0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
12750         0xfe, 0xda, 0x0e, 0x0a,
12751         0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe, 0x28, 0x00, 0xfe, 0xfa,
12752         0x10, 0x01, 0xfe, 0xf4,
12753         0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40,
12754         0x15, 0x56, 0x01, 0x85,
12755         0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
12756         0xcc, 0x10, 0x01, 0xa7,
12757         0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f, 0xfe, 0x19, 0x82, 0x04,
12758         0xfe, 0x99, 0x83, 0xfe,
12759         0xcc, 0x47, 0x0b, 0x0e, 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe,
12760         0x43, 0x00, 0xfe, 0xa2,
12761         0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
12762         0x00, 0x1d, 0x40, 0x15,
12763         0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01, 0xfe, 0x9e, 0x1e, 0x05,
12764         0xfe, 0x3a, 0x03, 0x01,
12765         0x0c, 0x06, 0x0d, 0x5d, 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01,
12766         0x76, 0x06, 0x12, 0xfe,
12767         0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
12768         0xfe, 0x9d, 0xf0, 0xfe,
12769         0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x94, 0x0e, 0x01,
12770         0x0c, 0x61, 0x12, 0x44,
12771         0xfe, 0x9f, 0x10, 0x19, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f,
12772         0xfe, 0x2e, 0x10, 0x19,
12773         0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
12774         0xfe, 0x41, 0x00, 0xa2,
12775         0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75, 0x03, 0x81, 0x1e, 0x2b,
12776         0xea, 0x4f, 0xfe, 0x04,
12777         0xe6, 0x12, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05,
12778         0x35, 0xfe, 0x12, 0x1c,
12779         0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
12780         0xfe, 0xd4, 0x11, 0x05,
12781         0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e, 0x47, 0x46, 0x28, 0xfe,
12782         0xce, 0x45, 0x31, 0x51,
12783         0xfe, 0x06, 0xea, 0xe0, 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03,
12784         0x67, 0xfe, 0x98, 0x56,
12785         0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
12786         0x0c, 0x06, 0x28, 0xfe,
12787         0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe, 0x41, 0x58, 0x0a, 0xba,
12788         0xfe, 0xfa, 0x14, 0xfe,
12789         0x49, 0x54, 0xb0, 0xfe, 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67,
12790         0xfe, 0xe0, 0x14, 0xfe,
12791         0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
12792         0xfe, 0xad, 0x13, 0x05,
12793         0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12, 0x26, 0x20, 0x96, 0x20,
12794         0xe7, 0xfe, 0x08, 0x1c,
12795         0xfe, 0x7c, 0x19, 0xfe, 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe,
12796         0x48, 0x55, 0xa5, 0x3b,
12797         0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
12798         0xf0, 0x1a, 0x03, 0xfe,
12799         0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe, 0x1e, 0x10, 0xfe, 0x02,
12800         0xec, 0xe7, 0x53, 0x00,
12801         0x36, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
12802         0x01, 0xfe, 0x62, 0x1b,
12803         0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
12804         0xea, 0xe7, 0x53, 0x92,
12805         0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3, 0xfe, 0x2a, 0x10, 0x03,
12806         0xfe, 0x38, 0x01, 0x23,
12807         0xfe, 0xf0, 0xff, 0x10, 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62,
12808         0x01, 0x01, 0xfe, 0x1e,
12809         0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
12810         0x26, 0x02, 0x21, 0x96,
12811         0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13, 0x1f, 0x1d, 0x47, 0xb5,
12812         0xc3, 0xfe, 0xe1, 0x10,
12813         0xcf, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf,
12814         0xfe, 0x03, 0xdc, 0xfe,
12815         0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
12816         0x00, 0xcc, 0x02, 0xfe,
12817         0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13,
12818         0x0f, 0xfe, 0x1c, 0x80,
12819         0x04, 0xfe, 0x9c, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13,
12820         0x0f, 0xfe, 0x1e, 0x80,
12821         0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
12822         0x1d, 0x80, 0x04, 0xfe,
12823         0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c, 0x13, 0x01, 0xfe, 0xee,
12824         0x1e, 0xac, 0xfe, 0x14,
12825         0x13, 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e,
12826         0x1f, 0xfe, 0x30, 0xf4,
12827         0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
12828         0x56, 0xfb, 0x01, 0xfe,
12829         0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01, 0xfe, 0xf4, 0x1c, 0x01,
12830         0xfe, 0x00, 0x1d, 0x15,
12831         0xfe, 0xe9, 0x00, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe,
12832         0x22, 0x1b, 0xfe, 0x1e,
12833         0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
12834         0x96, 0x90, 0x04, 0xfe,
12835         0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64, 0x01, 0x22, 0xfe, 0x66,
12836         0x01, 0x01, 0x0c, 0x06,
12837         0x65, 0xf9, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b,
12838         0x0e, 0x77, 0xfe, 0x01,
12839         0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
12840         0x21, 0x2c, 0xfe, 0x00,
12841         0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe,
12842         0x06, 0x58, 0x03, 0xfe,
12843         0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58,
12844         0x03, 0xfe, 0xb2, 0x00,
12845         0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
12846         0x66, 0x10, 0x55, 0x10,
12847         0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe, 0x90, 0x4d, 0xfe, 0x91,
12848         0x54, 0x2b, 0xfe, 0x88,
12849         0x11, 0x46, 0x1a, 0x13, 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe,
12850         0x91, 0x54, 0x2b, 0xfe,
12851         0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
12852         0x00, 0x40, 0x8d, 0x2c,
12853         0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xb2, 0x11, 0xfe,
12854         0x12, 0x1c, 0x75, 0xfe,
12855         0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c,
12856         0x14, 0xfe, 0x0e, 0x47,
12857         0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
12858         0xa7, 0x90, 0x34, 0x60,
12859         0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0xfe, 0x02, 0x80,
12860         0x09, 0x56, 0xfe, 0x34,
12861         0x13, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48,
12862         0xfe, 0x45, 0x48, 0x01,
12863         0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
12864         0x09, 0x1a, 0xa5, 0x0a,
12865         0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85, 0xf2, 0x09, 0x9b, 0xa4,
12866         0xfe, 0x14, 0x56, 0xfe,
12867         0xd6, 0xf0, 0xfe, 0xec, 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01,
12868         0xec, 0xb8, 0xfe, 0x9e,
12869         0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
12870         0xf4, 0xfe, 0xdd, 0x10,
12871         0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee, 0x09, 0x12, 0xfe, 0x48,
12872         0x12, 0x09, 0x0d, 0xfe,
12873         0x56, 0x12, 0x09, 0x1d, 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4,
12874         0x13, 0x09, 0xfe, 0x23,
12875         0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
12876         0x24, 0xfe, 0x12, 0x12,
12877         0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42, 0xa1, 0x32, 0x01, 0x08,
12878         0xae, 0x41, 0x02, 0x32,
12879         0xfe, 0x62, 0x08, 0x0a, 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05,
12880         0x35, 0x32, 0x01, 0x43,
12881         0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
12882         0x13, 0x01, 0x0c, 0x06,
12883         0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe,
12884         0xe5, 0x55, 0xb0, 0xfe,
12885         0x4a, 0x13, 0x21, 0x6e, 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e,
12886         0xfe, 0xb6, 0x0e, 0x10,
12887         0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
12888         0x88, 0x20, 0x6e, 0x01,
12889         0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x04, 0x55, 0xfe, 0xa5,
12890         0x55, 0xfe, 0x04, 0xfa,
12891         0x64, 0xfe, 0x05, 0xfa, 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d,
12892         0xfe, 0x40, 0x56, 0xfe,
12893         0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
12894         0x44, 0x55, 0xfe, 0xe5,
12895         0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x10,
12896         0x68, 0x22, 0x69, 0x01,
12897         0x0c, 0x06, 0x54, 0xf9, 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b,
12898         0x6b, 0xfe, 0x2c, 0x50,
12899         0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
12900         0x50, 0x03, 0x68, 0x3b,
12901         0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x4b, 0x3b, 0x4c, 0xfe,
12902         0x40, 0x50, 0xfe, 0xc2,
12903         0x50, 0x05, 0x73, 0x2e, 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08,
12904         0x16, 0x3d, 0x27, 0x25,
12905         0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
12906         0xa6, 0x23, 0x3f, 0x1b,
12907         0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13, 0x91, 0x4b, 0x7e, 0x4c,
12908         0xfe, 0x0a, 0x55, 0x31,
12909         0xfe, 0x8b, 0x55, 0xd9, 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e,
12910         0x51, 0x05, 0x72, 0x01,
12911         0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
12912         0x2a, 0x3c, 0x16, 0xc0,
12913         0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d, 0x83, 0x2d, 0x7f, 0x1b,
12914         0xfe, 0x66, 0x15, 0x05,
12915         0x3d, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d,
12916         0x2b, 0x3d, 0x01, 0x08,
12917         0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
12918         0xb6, 0x1e, 0x83, 0x01,
12919         0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45, 0x2d, 0x00, 0xa4, 0x46,
12920         0x07, 0x90, 0x3f, 0x01,
12921         0xfe, 0xf8, 0x15, 0x01, 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13,
12922         0x01, 0x43, 0x09, 0x82,
12923         0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
12924         0x05, 0x72, 0xfe, 0xc0,
12925         0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x5e,
12926         0x32, 0x01, 0x08, 0x17,
12927         0x73, 0x01, 0xfe, 0x56, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16,
12928         0x3d, 0x27, 0x25, 0xbd,
12929         0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
12930         0xe8, 0x14, 0x01, 0xa6,
12931         0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe, 0x4a, 0xf4, 0x07, 0xfe,
12932         0x0e, 0x12, 0x01, 0x43,
12933         0x09, 0x82, 0x4e, 0x05, 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32,
12934         0x01, 0x08, 0x17, 0x73,
12935         0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
12936         0x27, 0x25, 0xbd, 0x09,
12937         0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b, 0xfe, 0xaa, 0x14, 0xfe,
12938         0xb6, 0x14, 0x86, 0xa8,
12939         0xb2, 0x0d, 0x1b, 0x3d, 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09,
12940         0x82, 0x4e, 0x05, 0x72,
12941         0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
12942         0xfe, 0xc0, 0x19, 0x05,
12943         0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17, 0xfe, 0xe2, 0x15, 0x5f,
12944         0xcc, 0x01, 0x08, 0x26,
12945         0x5f, 0x02, 0x8f, 0xfe, 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe,
12946         0xcc, 0x15, 0x5e, 0x32,
12947         0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
12948         0xad, 0x23, 0xfe, 0xff,
12949         0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02,
12950         0x00, 0x57, 0x52, 0xad,
12951         0x23, 0x3f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff,
12952         0x02, 0x00, 0x57, 0x52,
12953         0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
12954         0x02, 0x13, 0x58, 0xff,
12955         0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58, 0x02, 0x0a, 0x66, 0x01,
12956         0x5c, 0x0a, 0x55, 0x01,
12957         0x5c, 0x0a, 0x6f, 0x01, 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a,
12958         0xff, 0x03, 0x00, 0x54,
12959         0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
12960         0x7c, 0x3a, 0x0b, 0x0e,
12961         0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a, 0x19, 0xfe, 0xfb, 0x19,
12962         0xfe, 0x1a, 0xf7, 0x00,
12963         0xfe, 0x1b, 0xf7, 0x00, 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c,
12964         0xda, 0x6d, 0x02, 0xfe,
12965         0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
12966         0x02, 0x01, 0xc6, 0xfe,
12967         0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17, 0x27,
12968         0x25, 0xbe, 0x01, 0x08,
12969         0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59,
12970         0x03, 0x9a, 0x1e, 0xfe,
12971         0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
12972         0x48, 0xfe, 0x08, 0x17,
12973         0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d, 0xb4, 0x7b, 0xfe, 0x26,
12974         0x17, 0x4d, 0x13, 0x07,
12975         0x1c, 0xb4, 0x90, 0x04, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1,
12976         0xff, 0x02, 0x83, 0x55,
12977         0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
12978         0x17, 0x1c, 0x63, 0x13,
12979         0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16, 0x13, 0xd6, 0xfe, 0x64,
12980         0x00, 0xb0, 0xfe, 0x80,
12981         0x17, 0x0a, 0xfe, 0x64, 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10,
12982         0x53, 0x07, 0xfe, 0x60,
12983         0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
12984         0x00, 0x1c, 0x95, 0x13,
12985         0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0x8c, 0x17, 0x45, 0xf3,
12986         0xfe, 0x43, 0xf4, 0x96,
12987         0xfe, 0x56, 0xf0, 0xfe, 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43,
12988         0xf4, 0x94, 0xf6, 0x8b,
12989         0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
12990         0xda, 0x17, 0x62, 0x49,
12991         0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x80,
12992         0x71, 0x50, 0x26, 0xfe,
12993         0x4d, 0xf4, 0x00, 0xf7, 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3,
12994         0x58, 0x02, 0x50, 0x13,
12995         0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
12996         0x25, 0xbe, 0xfe, 0x03,
12997         0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe9,
12998         0x0a, 0x01, 0x08, 0x16,
12999         0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01,
13000         0x01, 0x08, 0x16, 0xa9,
13001         0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
13002         0x08, 0x16, 0xa9, 0x27,
13003         0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01, 0x03, 0xb6, 0x1e, 0x83,
13004         0x01, 0x38, 0x06, 0x24,
13005         0x31, 0xa2, 0x78, 0xf2, 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1,
13006         0x78, 0x03, 0x9a, 0x1e,
13007         0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
13008         0xfe, 0x40, 0x5a, 0x23,
13009         0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x49, 0x71, 0x8c,
13010         0x80, 0x48, 0xfe, 0xaa,
13011         0x18, 0x62, 0x80, 0xfe, 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01,
13012         0xfe, 0xac, 0x1d, 0xfe,
13013         0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
13014         0x43, 0x48, 0x2d, 0x93,
13015         0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe, 0x40, 0x10, 0x2d, 0xb4,
13016         0x36, 0xfe, 0x34, 0xf4,
13017         0x04, 0xfe, 0x34, 0x10, 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe,
13018         0x28, 0x10, 0xfe, 0xc0,
13019         0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
13020         0x18, 0x45, 0xfe, 0x1c,
13021         0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe, 0x0c,
13022         0x19, 0xfe, 0x04, 0xf4,
13023         0x58, 0xfe, 0x40, 0xf4, 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d,
13024         0x21, 0xfe, 0x7f, 0x01,
13025         0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
13026         0x7e, 0x01, 0xfe, 0xc8,
13027         0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01, 0xfe, 0x48, 0x45, 0xfa,
13028         0x21, 0xfe, 0x81, 0x01,
13029         0xfe, 0xc8, 0x44, 0x4e, 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50,
13030         0x13, 0x0d, 0x02, 0x14,
13031         0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
13032         0xfe, 0x82, 0x19, 0x14,
13033         0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f, 0xfe, 0x89, 0x49, 0x01,
13034         0x08, 0x02, 0x14, 0x07,
13035         0x01, 0x08, 0x17, 0xc1, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07,
13036         0x01, 0x08, 0x17, 0xc1,
13037         0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
13038         0x08, 0x02, 0x50, 0x02,
13039         0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f, 0x01, 0x08, 0x17, 0x74,
13040         0x14, 0x12, 0x01, 0x08,
13041         0x17, 0x74, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01,
13042         0x08, 0x17, 0x74, 0xfe,
13043         0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
13044         0x74, 0x5f, 0xcc, 0x01,
13045         0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c, 0x13, 0xc8, 0x20, 0xe4,
13046         0xfe, 0x49, 0xf4, 0x00,
13047         0x4d, 0x5f, 0xa1, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff,
13048         0x02, 0x00, 0x10, 0x2f,
13049         0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
13050         0x16, 0xfe, 0x64, 0x1a,
13051         0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09, 0x07, 0x5d, 0x01, 0x0c,
13052         0x61, 0x07, 0x44, 0x02,
13053         0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12,
13054         0x13, 0x0a, 0x9d, 0x01,
13055         0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
13056         0xfe, 0x80, 0xe7, 0x1a,
13057         0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe, 0xb2, 0x16, 0xaa, 0x02,
13058         0x0a, 0x5a, 0x01, 0x18,
13059         0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe,
13060         0x7e, 0x1e, 0xfe, 0x80,
13061         0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
13062         0xfe, 0x80, 0x4c, 0x0a,
13063         0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c, 0xe5, 0xfe, 0x18, 0xdf,
13064         0xfe, 0x19, 0xde, 0xfe,
13065         0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe,
13066         0x2a, 0x1c, 0xfa, 0xb3,
13067         0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
13068         0xf4, 0x1a, 0xfe, 0xfa,
13069         0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x24,
13070         0xfe, 0x18, 0x58, 0x03,
13071         0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f,
13072         0xfe, 0x30, 0xf4, 0x07,
13073         0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
13074         0xf7, 0x24, 0xb1, 0xfe,
13075         0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x26, 0x1b,
13076         0xfe, 0xba, 0x10, 0x1c,
13077         0x1a, 0x87, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
13078         0x1d, 0xf7, 0x54, 0xb1,
13079         0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
13080         0xaf, 0x19, 0xfe, 0x98,
13081         0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b, 0xfe, 0x8a, 0x10, 0x1c,
13082         0x1a, 0x87, 0x8b, 0x0f,
13083         0xfe, 0x30, 0x90, 0x04, 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58,
13084         0xfe, 0x32, 0x90, 0x04,
13085         0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
13086         0x7c, 0x12, 0xfe, 0x0f,
13087         0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6, 0x1b, 0xfe, 0x5e, 0x14,
13088         0x31, 0x02, 0xc9, 0x2b,
13089         0xfe, 0x96, 0x1b, 0x5c, 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe,
13090         0x6a, 0xfe, 0x19, 0xfe,
13091         0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
13092         0x1b, 0xfe, 0x36, 0x14,
13093         0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19,
13094         0xfe, 0x80, 0xe7, 0x1a,
13095         0xfe, 0x81, 0xe7, 0x1a, 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a,
13096         0x30, 0xfe, 0x12, 0x45,
13097         0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
13098         0x39, 0xf0, 0x75, 0x26,
13099         0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13, 0x11, 0x02, 0x87, 0x03,
13100         0xe3, 0x23, 0x07, 0xfe,
13101         0xef, 0x12, 0xfe, 0xe1, 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09,
13102         0x56, 0xfe, 0x3c, 0x13,
13103         0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
13104         0x01, 0x18, 0xcb, 0xfe,
13105         0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xfe, 0xb2, 0x16,
13106         0xfe, 0x00, 0xcc, 0xcb,
13107         0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18,
13108         0xfe, 0x80, 0x4c, 0x01,
13109         0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
13110         0x12, 0xfe, 0x14, 0x56,
13111         0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d, 0x02, 0xfe, 0x9c, 0xe7,
13112         0x0d, 0x19, 0xfe, 0x15,
13113         0x00, 0x40, 0x8d, 0x30, 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06,
13114         0x83, 0xfe, 0x18, 0x80,
13115         0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
13116         0x90, 0xfe, 0xba, 0x90,
13117         0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31, 0xfe, 0xc9, 0x55, 0x02,
13118         0x21, 0xb9, 0x88, 0x20,
13119         0xb9, 0x02, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01,
13120         0x18, 0xfe, 0x49, 0x44,
13121         0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
13122         0x1a, 0xa4, 0x0a, 0x67,
13123         0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89, 0x02, 0xfe, 0x4e, 0xe4,
13124         0x1d, 0x7b, 0xfe, 0x52,
13125         0x1d, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe,
13126         0x4e, 0xe4, 0xdd, 0x7b,
13127         0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
13128         0xfe, 0x4e, 0xe4, 0xfe,
13129         0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe, 0x94, 0x00, 0xd1, 0x24,
13130         0xfe, 0x08, 0x10, 0x03,
13131         0xfe, 0x96, 0x00, 0xd1, 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04,
13132         0x68, 0x54, 0xfe, 0xf1,
13133         0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
13134         0xfe, 0x1a, 0xf4, 0xfe,
13135         0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa, 0x1d, 0x13, 0x1d, 0x02,
13136         0x09, 0x92, 0xfe, 0x5a,
13137         0xf0, 0xfe, 0xba, 0x1d, 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe,
13138         0x5a, 0xf0, 0xfe, 0xc8,
13139         0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
13140         0x1a, 0x10, 0x09, 0x0d,
13141         0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e, 0x95, 0xa1, 0xc8, 0x02,
13142         0x1f, 0x93, 0x01, 0x42,
13143         0xfe, 0x04, 0xfe, 0x99, 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e,
13144         0xfe, 0x14, 0xf0, 0x08,
13145         0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
13146         0xfe, 0x82, 0xf0, 0xfe,
13147         0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80, 0x83, 0x33, 0x0b, 0x0e,
13148         0x02, 0x0f, 0xfe, 0x18,
13149         0x80, 0x04, 0xfe, 0x98, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02,
13150         0x80, 0x04, 0xfe, 0x82,
13151         0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
13152         0x83, 0x33, 0x0b, 0x0e,
13153         0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b, 0x83, 0x33, 0x0b, 0x0e,
13154         0x02, 0x0f, 0xfe, 0x04,
13155         0x80, 0x04, 0xfe, 0x84, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80,
13156         0x80, 0x04, 0xfe, 0x80,
13157         0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
13158         0xfe, 0x99, 0x83, 0xfe,
13159         0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x83, 0x04, 0xfe, 0x86,
13160         0x83, 0xfe, 0xce, 0x47,
13161         0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a,
13162         0x0b, 0x0e, 0x02, 0x0f,
13163         0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
13164         0xfe, 0x08, 0x90, 0x04,
13165         0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x8a, 0x90, 0x04,
13166         0xfe, 0x8a, 0x93, 0x79,
13167         0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a,
13168         0x0b, 0x0e, 0x02, 0x0f,
13169         0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
13170         0xfe, 0x3c, 0x90, 0x04,
13171         0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b, 0x0f, 0xfe, 0x03, 0x80,
13172         0x04, 0xfe, 0x83, 0x83,
13173         0x33, 0x0b, 0x77, 0x0e, 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
13174 };
13175
13176 static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf);       /* 0x1673 */
13177 static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL;  /* Expanded little-endian checksum. */
13178
13179 /*
13180  * EEPROM Configuration.
13181  *
13182  * All drivers should use this structure to set the default EEPROM
13183  * configuration. The BIOS now uses this structure when it is built.
13184  * Additional structure information can be found in a_condor.h where
13185  * the structure is defined.
13186  *
13187  * The *_Field_IsChar structs are needed to correct for endianness.
13188  * These values are read from the board 16 bits at a time directly
13189  * into the structs. Because some fields are char, the values will be
13190  * in the wrong order. The *_Field_IsChar tells when to flip the
13191  * bytes. Data read and written to PCI memory is automatically swapped
13192  * on big-endian platforms so char fields read as words are actually being
13193  * unswapped on big-endian platforms.
13194  */
13195 static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = {
13196         ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
13197         0x0000,                 /* cfg_msw */
13198         0xFFFF,                 /* disc_enable */
13199         0xFFFF,                 /* wdtr_able */
13200         0xFFFF,                 /* sdtr_able */
13201         0xFFFF,                 /* start_motor */
13202         0xFFFF,                 /* tagqng_able */
13203         0xFFFF,                 /* bios_scan */
13204         0,                      /* scam_tolerant */
13205         7,                      /* adapter_scsi_id */
13206         0,                      /* bios_boot_delay */
13207         3,                      /* scsi_reset_delay */
13208         0,                      /* bios_id_lun */
13209         0,                      /* termination */
13210         0,                      /* reserved1 */
13211         0xFFE7,                 /* bios_ctrl */
13212         0xFFFF,                 /* ultra_able */
13213         0,                      /* reserved2 */
13214         ASC_DEF_MAX_HOST_QNG,   /* max_host_qng */
13215         ASC_DEF_MAX_DVC_QNG,    /* max_dvc_qng */
13216         0,                      /* dvc_cntl */
13217         0,                      /* bug_fix */
13218         0,                      /* serial_number_word1 */
13219         0,                      /* serial_number_word2 */
13220         0,                      /* serial_number_word3 */
13221         0,                      /* check_sum */
13222         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13223         ,                       /* oem_name[16] */
13224         0,                      /* dvc_err_code */
13225         0,                      /* adv_err_code */
13226         0,                      /* adv_err_addr */
13227         0,                      /* saved_dvc_err_code */
13228         0,                      /* saved_adv_err_code */
13229         0,                      /* saved_adv_err_addr */
13230         0                       /* num_of_err */
13231 };
13232
13233 static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = {
13234         0,                      /* cfg_lsw */
13235         0,                      /* cfg_msw */
13236         0,                      /* -disc_enable */
13237         0,                      /* wdtr_able */
13238         0,                      /* sdtr_able */
13239         0,                      /* start_motor */
13240         0,                      /* tagqng_able */
13241         0,                      /* bios_scan */
13242         0,                      /* scam_tolerant */
13243         1,                      /* adapter_scsi_id */
13244         1,                      /* bios_boot_delay */
13245         1,                      /* scsi_reset_delay */
13246         1,                      /* bios_id_lun */
13247         1,                      /* termination */
13248         1,                      /* reserved1 */
13249         0,                      /* bios_ctrl */
13250         0,                      /* ultra_able */
13251         0,                      /* reserved2 */
13252         1,                      /* max_host_qng */
13253         1,                      /* max_dvc_qng */
13254         0,                      /* dvc_cntl */
13255         0,                      /* bug_fix */
13256         0,                      /* serial_number_word1 */
13257         0,                      /* serial_number_word2 */
13258         0,                      /* serial_number_word3 */
13259         0,                      /* check_sum */
13260         {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13261         ,                       /* oem_name[16] */
13262         0,                      /* dvc_err_code */
13263         0,                      /* adv_err_code */
13264         0,                      /* adv_err_addr */
13265         0,                      /* saved_dvc_err_code */
13266         0,                      /* saved_adv_err_code */
13267         0,                      /* saved_adv_err_addr */
13268         0                       /* num_of_err */
13269 };
13270
13271 static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = {
13272         ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
13273         0x0000,                 /* 01 cfg_msw */
13274         0xFFFF,                 /* 02 disc_enable */
13275         0xFFFF,                 /* 03 wdtr_able */
13276         0x4444,                 /* 04 sdtr_speed1 */
13277         0xFFFF,                 /* 05 start_motor */
13278         0xFFFF,                 /* 06 tagqng_able */
13279         0xFFFF,                 /* 07 bios_scan */
13280         0,                      /* 08 scam_tolerant */
13281         7,                      /* 09 adapter_scsi_id */
13282         0,                      /*    bios_boot_delay */
13283         3,                      /* 10 scsi_reset_delay */
13284         0,                      /*    bios_id_lun */
13285         0,                      /* 11 termination_se */
13286         0,                      /*    termination_lvd */
13287         0xFFE7,                 /* 12 bios_ctrl */
13288         0x4444,                 /* 13 sdtr_speed2 */
13289         0x4444,                 /* 14 sdtr_speed3 */
13290         ASC_DEF_MAX_HOST_QNG,   /* 15 max_host_qng */
13291         ASC_DEF_MAX_DVC_QNG,    /*    max_dvc_qng */
13292         0,                      /* 16 dvc_cntl */
13293         0x4444,                 /* 17 sdtr_speed4 */
13294         0,                      /* 18 serial_number_word1 */
13295         0,                      /* 19 serial_number_word2 */
13296         0,                      /* 20 serial_number_word3 */
13297         0,                      /* 21 check_sum */
13298         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13299         ,                       /* 22-29 oem_name[16] */
13300         0,                      /* 30 dvc_err_code */
13301         0,                      /* 31 adv_err_code */
13302         0,                      /* 32 adv_err_addr */
13303         0,                      /* 33 saved_dvc_err_code */
13304         0,                      /* 34 saved_adv_err_code */
13305         0,                      /* 35 saved_adv_err_addr */
13306         0,                      /* 36 reserved */
13307         0,                      /* 37 reserved */
13308         0,                      /* 38 reserved */
13309         0,                      /* 39 reserved */
13310         0,                      /* 40 reserved */
13311         0,                      /* 41 reserved */
13312         0,                      /* 42 reserved */
13313         0,                      /* 43 reserved */
13314         0,                      /* 44 reserved */
13315         0,                      /* 45 reserved */
13316         0,                      /* 46 reserved */
13317         0,                      /* 47 reserved */
13318         0,                      /* 48 reserved */
13319         0,                      /* 49 reserved */
13320         0,                      /* 50 reserved */
13321         0,                      /* 51 reserved */
13322         0,                      /* 52 reserved */
13323         0,                      /* 53 reserved */
13324         0,                      /* 54 reserved */
13325         0,                      /* 55 reserved */
13326         0,                      /* 56 cisptr_lsw */
13327         0,                      /* 57 cisprt_msw */
13328         PCI_VENDOR_ID_ASP,      /* 58 subsysvid */
13329         PCI_DEVICE_ID_38C0800_REV1,     /* 59 subsysid */
13330         0,                      /* 60 reserved */
13331         0,                      /* 61 reserved */
13332         0,                      /* 62 reserved */
13333         0                       /* 63 reserved */
13334 };
13335
13336 static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = {
13337         0,                      /* 00 cfg_lsw */
13338         0,                      /* 01 cfg_msw */
13339         0,                      /* 02 disc_enable */
13340         0,                      /* 03 wdtr_able */
13341         0,                      /* 04 sdtr_speed1 */
13342         0,                      /* 05 start_motor */
13343         0,                      /* 06 tagqng_able */
13344         0,                      /* 07 bios_scan */
13345         0,                      /* 08 scam_tolerant */
13346         1,                      /* 09 adapter_scsi_id */
13347         1,                      /*    bios_boot_delay */
13348         1,                      /* 10 scsi_reset_delay */
13349         1,                      /*    bios_id_lun */
13350         1,                      /* 11 termination_se */
13351         1,                      /*    termination_lvd */
13352         0,                      /* 12 bios_ctrl */
13353         0,                      /* 13 sdtr_speed2 */
13354         0,                      /* 14 sdtr_speed3 */
13355         1,                      /* 15 max_host_qng */
13356         1,                      /*    max_dvc_qng */
13357         0,                      /* 16 dvc_cntl */
13358         0,                      /* 17 sdtr_speed4 */
13359         0,                      /* 18 serial_number_word1 */
13360         0,                      /* 19 serial_number_word2 */
13361         0,                      /* 20 serial_number_word3 */
13362         0,                      /* 21 check_sum */
13363         {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13364         ,                       /* 22-29 oem_name[16] */
13365         0,                      /* 30 dvc_err_code */
13366         0,                      /* 31 adv_err_code */
13367         0,                      /* 32 adv_err_addr */
13368         0,                      /* 33 saved_dvc_err_code */
13369         0,                      /* 34 saved_adv_err_code */
13370         0,                      /* 35 saved_adv_err_addr */
13371         0,                      /* 36 reserved */
13372         0,                      /* 37 reserved */
13373         0,                      /* 38 reserved */
13374         0,                      /* 39 reserved */
13375         0,                      /* 40 reserved */
13376         0,                      /* 41 reserved */
13377         0,                      /* 42 reserved */
13378         0,                      /* 43 reserved */
13379         0,                      /* 44 reserved */
13380         0,                      /* 45 reserved */
13381         0,                      /* 46 reserved */
13382         0,                      /* 47 reserved */
13383         0,                      /* 48 reserved */
13384         0,                      /* 49 reserved */
13385         0,                      /* 50 reserved */
13386         0,                      /* 51 reserved */
13387         0,                      /* 52 reserved */
13388         0,                      /* 53 reserved */
13389         0,                      /* 54 reserved */
13390         0,                      /* 55 reserved */
13391         0,                      /* 56 cisptr_lsw */
13392         0,                      /* 57 cisprt_msw */
13393         0,                      /* 58 subsysvid */
13394         0,                      /* 59 subsysid */
13395         0,                      /* 60 reserved */
13396         0,                      /* 61 reserved */
13397         0,                      /* 62 reserved */
13398         0                       /* 63 reserved */
13399 };
13400
13401 static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = {
13402         ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
13403         0x0000,                 /* 01 cfg_msw */
13404         0xFFFF,                 /* 02 disc_enable */
13405         0xFFFF,                 /* 03 wdtr_able */
13406         0x5555,                 /* 04 sdtr_speed1 */
13407         0xFFFF,                 /* 05 start_motor */
13408         0xFFFF,                 /* 06 tagqng_able */
13409         0xFFFF,                 /* 07 bios_scan */
13410         0,                      /* 08 scam_tolerant */
13411         7,                      /* 09 adapter_scsi_id */
13412         0,                      /*    bios_boot_delay */
13413         3,                      /* 10 scsi_reset_delay */
13414         0,                      /*    bios_id_lun */
13415         0,                      /* 11 termination_se */
13416         0,                      /*    termination_lvd */
13417         0xFFE7,                 /* 12 bios_ctrl */
13418         0x5555,                 /* 13 sdtr_speed2 */
13419         0x5555,                 /* 14 sdtr_speed3 */
13420         ASC_DEF_MAX_HOST_QNG,   /* 15 max_host_qng */
13421         ASC_DEF_MAX_DVC_QNG,    /*    max_dvc_qng */
13422         0,                      /* 16 dvc_cntl */
13423         0x5555,                 /* 17 sdtr_speed4 */
13424         0,                      /* 18 serial_number_word1 */
13425         0,                      /* 19 serial_number_word2 */
13426         0,                      /* 20 serial_number_word3 */
13427         0,                      /* 21 check_sum */
13428         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13429         ,                       /* 22-29 oem_name[16] */
13430         0,                      /* 30 dvc_err_code */
13431         0,                      /* 31 adv_err_code */
13432         0,                      /* 32 adv_err_addr */
13433         0,                      /* 33 saved_dvc_err_code */
13434         0,                      /* 34 saved_adv_err_code */
13435         0,                      /* 35 saved_adv_err_addr */
13436         0,                      /* 36 reserved */
13437         0,                      /* 37 reserved */
13438         0,                      /* 38 reserved */
13439         0,                      /* 39 reserved */
13440         0,                      /* 40 reserved */
13441         0,                      /* 41 reserved */
13442         0,                      /* 42 reserved */
13443         0,                      /* 43 reserved */
13444         0,                      /* 44 reserved */
13445         0,                      /* 45 reserved */
13446         0,                      /* 46 reserved */
13447         0,                      /* 47 reserved */
13448         0,                      /* 48 reserved */
13449         0,                      /* 49 reserved */
13450         0,                      /* 50 reserved */
13451         0,                      /* 51 reserved */
13452         0,                      /* 52 reserved */
13453         0,                      /* 53 reserved */
13454         0,                      /* 54 reserved */
13455         0,                      /* 55 reserved */
13456         0,                      /* 56 cisptr_lsw */
13457         0,                      /* 57 cisprt_msw */
13458         PCI_VENDOR_ID_ASP,      /* 58 subsysvid */
13459         PCI_DEVICE_ID_38C1600_REV1,     /* 59 subsysid */
13460         0,                      /* 60 reserved */
13461         0,                      /* 61 reserved */
13462         0,                      /* 62 reserved */
13463         0                       /* 63 reserved */
13464 };
13465
13466 static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = {
13467         0,                      /* 00 cfg_lsw */
13468         0,                      /* 01 cfg_msw */
13469         0,                      /* 02 disc_enable */
13470         0,                      /* 03 wdtr_able */
13471         0,                      /* 04 sdtr_speed1 */
13472         0,                      /* 05 start_motor */
13473         0,                      /* 06 tagqng_able */
13474         0,                      /* 07 bios_scan */
13475         0,                      /* 08 scam_tolerant */
13476         1,                      /* 09 adapter_scsi_id */
13477         1,                      /*    bios_boot_delay */
13478         1,                      /* 10 scsi_reset_delay */
13479         1,                      /*    bios_id_lun */
13480         1,                      /* 11 termination_se */
13481         1,                      /*    termination_lvd */
13482         0,                      /* 12 bios_ctrl */
13483         0,                      /* 13 sdtr_speed2 */
13484         0,                      /* 14 sdtr_speed3 */
13485         1,                      /* 15 max_host_qng */
13486         1,                      /*    max_dvc_qng */
13487         0,                      /* 16 dvc_cntl */
13488         0,                      /* 17 sdtr_speed4 */
13489         0,                      /* 18 serial_number_word1 */
13490         0,                      /* 19 serial_number_word2 */
13491         0,                      /* 20 serial_number_word3 */
13492         0,                      /* 21 check_sum */
13493         {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13494         ,                       /* 22-29 oem_name[16] */
13495         0,                      /* 30 dvc_err_code */
13496         0,                      /* 31 adv_err_code */
13497         0,                      /* 32 adv_err_addr */
13498         0,                      /* 33 saved_dvc_err_code */
13499         0,                      /* 34 saved_adv_err_code */
13500         0,                      /* 35 saved_adv_err_addr */
13501         0,                      /* 36 reserved */
13502         0,                      /* 37 reserved */
13503         0,                      /* 38 reserved */
13504         0,                      /* 39 reserved */
13505         0,                      /* 40 reserved */
13506         0,                      /* 41 reserved */
13507         0,                      /* 42 reserved */
13508         0,                      /* 43 reserved */
13509         0,                      /* 44 reserved */
13510         0,                      /* 45 reserved */
13511         0,                      /* 46 reserved */
13512         0,                      /* 47 reserved */
13513         0,                      /* 48 reserved */
13514         0,                      /* 49 reserved */
13515         0,                      /* 50 reserved */
13516         0,                      /* 51 reserved */
13517         0,                      /* 52 reserved */
13518         0,                      /* 53 reserved */
13519         0,                      /* 54 reserved */
13520         0,                      /* 55 reserved */
13521         0,                      /* 56 cisptr_lsw */
13522         0,                      /* 57 cisprt_msw */
13523         0,                      /* 58 subsysvid */
13524         0,                      /* 59 subsysid */
13525         0,                      /* 60 reserved */
13526         0,                      /* 61 reserved */
13527         0,                      /* 62 reserved */
13528         0                       /* 63 reserved */
13529 };
13530
13531 /*
13532  * Initialize the ADV_DVC_VAR structure.
13533  *
13534  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13535  *
13536  * For a non-fatal error return a warning code. If there are no warnings
13537  * then 0 is returned.
13538  */
13539 static int __devinit
13540 AdvInitGetConfig(struct pci_dev *pdev, ADV_DVC_VAR *asc_dvc)
13541 {
13542         unsigned short warn_code = 0;
13543         AdvPortAddr iop_base = asc_dvc->iop_base;
13544         u16 cmd;
13545         int status;
13546
13547         asc_dvc->err_code = 0;
13548
13549         /*
13550          * Save the state of the PCI Configuration Command Register
13551          * "Parity Error Response Control" Bit. If the bit is clear (0),
13552          * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
13553          * DMA parity errors.
13554          */
13555         asc_dvc->cfg->control_flag = 0;
13556         pci_read_config_word(pdev, PCI_COMMAND, &cmd);
13557         if ((cmd & PCI_COMMAND_PARITY) == 0)
13558                 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
13559
13560         asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
13561             ADV_LIB_VERSION_MINOR;
13562         asc_dvc->cfg->chip_version =
13563             AdvGetChipVersion(iop_base, asc_dvc->bus_type);
13564
13565         ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
13566                  (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
13567                  (ushort)ADV_CHIP_ID_BYTE);
13568
13569         ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
13570                  (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
13571                  (ushort)ADV_CHIP_ID_WORD);
13572
13573         /*
13574          * Reset the chip to start and allow register writes.
13575          */
13576         if (AdvFindSignature(iop_base) == 0) {
13577                 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
13578                 return ADV_ERROR;
13579         } else {
13580                 /*
13581                  * The caller must set 'chip_type' to a valid setting.
13582                  */
13583                 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
13584                     asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
13585                     asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
13586                         asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
13587                         return ADV_ERROR;
13588                 }
13589
13590                 /*
13591                  * Reset Chip.
13592                  */
13593                 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13594                                      ADV_CTRL_REG_CMD_RESET);
13595                 DvcSleepMilliSecond(100);
13596                 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13597                                      ADV_CTRL_REG_CMD_WR_IO_REG);
13598
13599                 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
13600                         status = AdvInitFrom38C1600EEP(asc_dvc);
13601                 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
13602                         status = AdvInitFrom38C0800EEP(asc_dvc);
13603                 } else {
13604                         status = AdvInitFrom3550EEP(asc_dvc);
13605                 }
13606                 warn_code |= status;
13607         }
13608
13609         return warn_code;
13610 }
13611
13612 /*
13613  * Initialize the ASC-3550.
13614  *
13615  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13616  *
13617  * For a non-fatal error return a warning code. If there are no warnings
13618  * then 0 is returned.
13619  *
13620  * Needed after initialization for error recovery.
13621  */
13622 static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
13623 {
13624         AdvPortAddr iop_base;
13625         ushort warn_code;
13626         ADV_DCNT sum;
13627         int begin_addr;
13628         int end_addr;
13629         ushort code_sum;
13630         int word;
13631         int j;
13632         int adv_asc3550_expanded_size;
13633         ADV_CARR_T *carrp;
13634         ADV_DCNT contig_len;
13635         ADV_SDCNT buf_size;
13636         ADV_PADDR carr_paddr;
13637         int i;
13638         ushort scsi_cfg1;
13639         uchar tid;
13640         ushort bios_mem[ASC_MC_BIOSLEN / 2];    /* BIOS RISC Memory 0x40-0x8F. */
13641         ushort wdtr_able = 0, sdtr_able, tagqng_able;
13642         uchar max_cmd[ADV_MAX_TID + 1];
13643
13644         /* If there is already an error, don't continue. */
13645         if (asc_dvc->err_code != 0) {
13646                 return ADV_ERROR;
13647         }
13648
13649         /*
13650          * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
13651          */
13652         if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
13653                 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
13654                 return ADV_ERROR;
13655         }
13656
13657         warn_code = 0;
13658         iop_base = asc_dvc->iop_base;
13659
13660         /*
13661          * Save the RISC memory BIOS region before writing the microcode.
13662          * The BIOS may already be loaded and using its RISC LRAM region
13663          * so its region must be saved and restored.
13664          *
13665          * Note: This code makes the assumption, which is currently true,
13666          * that a chip reset does not clear RISC LRAM.
13667          */
13668         for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
13669                 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
13670                                 bios_mem[i]);
13671         }
13672
13673         /*
13674          * Save current per TID negotiated values.
13675          */
13676         if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
13677                 ushort bios_version, major, minor;
13678
13679                 bios_version =
13680                     bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
13681                 major = (bios_version >> 12) & 0xF;
13682                 minor = (bios_version >> 8) & 0xF;
13683                 if (major < 3 || (major == 3 && minor == 1)) {
13684                         /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
13685                         AdvReadWordLram(iop_base, 0x120, wdtr_able);
13686                 } else {
13687                         AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
13688                 }
13689         }
13690         AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
13691         AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
13692         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
13693                 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
13694                                 max_cmd[tid]);
13695         }
13696
13697         /*
13698          * Load the Microcode
13699          *
13700          * Write the microcode image to RISC memory starting at address 0.
13701          */
13702         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
13703         /* Assume the following compressed format of the microcode buffer:
13704          *
13705          *  254 word (508 byte) table indexed by byte code followed
13706          *  by the following byte codes:
13707          *
13708          *    1-Byte Code:
13709          *      00: Emit word 0 in table.
13710          *      01: Emit word 1 in table.
13711          *      .
13712          *      FD: Emit word 253 in table.
13713          *
13714          *    Multi-Byte Code:
13715          *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
13716          *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
13717          */
13718         word = 0;
13719         for (i = 253 * 2; i < _adv_asc3550_size; i++) {
13720                 if (_adv_asc3550_buf[i] == 0xff) {
13721                         for (j = 0; j < _adv_asc3550_buf[i + 1]; j++) {
13722                                 AdvWriteWordAutoIncLram(iop_base, (((ushort)
13723                                                                     _adv_asc3550_buf
13724                                                                     [i +
13725                                                                      3] << 8) |
13726                                                                    _adv_asc3550_buf
13727                                                                    [i + 2]));
13728                                 word++;
13729                         }
13730                         i += 3;
13731                 } else if (_adv_asc3550_buf[i] == 0xfe) {
13732                         AdvWriteWordAutoIncLram(iop_base, (((ushort)
13733                                                             _adv_asc3550_buf[i +
13734                                                                              2]
13735                                                             << 8) |
13736                                                            _adv_asc3550_buf[i +
13737                                                                             1]));
13738                         i += 2;
13739                         word++;
13740                 } else {
13741                         AdvWriteWordAutoIncLram(iop_base, (((ushort)
13742                                                             _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) | _adv_asc3550_buf[_adv_asc3550_buf[i] * 2]));
13743                         word++;
13744                 }
13745         }
13746
13747         /*
13748          * Set 'word' for later use to clear the rest of memory and save
13749          * the expanded mcode size.
13750          */
13751         word *= 2;
13752         adv_asc3550_expanded_size = word;
13753
13754         /*
13755          * Clear the rest of ASC-3550 Internal RAM (8KB).
13756          */
13757         for (; word < ADV_3550_MEMSIZE; word += 2) {
13758                 AdvWriteWordAutoIncLram(iop_base, 0);
13759         }
13760
13761         /*
13762          * Verify the microcode checksum.
13763          */
13764         sum = 0;
13765         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
13766
13767         for (word = 0; word < adv_asc3550_expanded_size; word += 2) {
13768                 sum += AdvReadWordAutoIncLram(iop_base);
13769         }
13770
13771         if (sum != _adv_asc3550_chksum) {
13772                 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
13773                 return ADV_ERROR;
13774         }
13775
13776         /*
13777          * Restore the RISC memory BIOS region.
13778          */
13779         for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
13780                 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
13781                                  bios_mem[i]);
13782         }
13783
13784         /*
13785          * Calculate and write the microcode code checksum to the microcode
13786          * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
13787          */
13788         AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
13789         AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
13790         code_sum = 0;
13791         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
13792         for (word = begin_addr; word < end_addr; word += 2) {
13793                 code_sum += AdvReadWordAutoIncLram(iop_base);
13794         }
13795         AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
13796
13797         /*
13798          * Read and save microcode version and date.
13799          */
13800         AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
13801                         asc_dvc->cfg->mcode_date);
13802         AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
13803                         asc_dvc->cfg->mcode_version);
13804
13805         /*
13806          * Set the chip type to indicate the ASC3550.
13807          */
13808         AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
13809
13810         /*
13811          * If the PCI Configuration Command Register "Parity Error Response
13812          * Control" Bit was clear (0), then set the microcode variable
13813          * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
13814          * to ignore DMA parity errors.
13815          */
13816         if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
13817                 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
13818                 word |= CONTROL_FLAG_IGNORE_PERR;
13819                 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
13820         }
13821
13822         /*
13823          * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
13824          * threshold of 128 bytes. This register is only accessible to the host.
13825          */
13826         AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
13827                              START_CTL_EMFU | READ_CMD_MRM);
13828
13829         /*
13830          * Microcode operating variables for WDTR, SDTR, and command tag
13831          * queuing will be set in slave_configure() based on what a
13832          * device reports it is capable of in Inquiry byte 7.
13833          *
13834          * If SCSI Bus Resets have been disabled, then directly set
13835          * SDTR and WDTR from the EEPROM configuration. This will allow
13836          * the BIOS and warm boot to work without a SCSI bus hang on
13837          * the Inquiry caused by host and target mismatched DTR values.
13838          * Without the SCSI Bus Reset, before an Inquiry a device can't
13839          * be assumed to be in Asynchronous, Narrow mode.
13840          */
13841         if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
13842                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
13843                                  asc_dvc->wdtr_able);
13844                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
13845                                  asc_dvc->sdtr_able);
13846         }
13847
13848         /*
13849          * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
13850          * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
13851          * bitmask. These values determine the maximum SDTR speed negotiated
13852          * with a device.
13853          *
13854          * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
13855          * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
13856          * without determining here whether the device supports SDTR.
13857          *
13858          * 4-bit speed  SDTR speed name
13859          * ===========  ===============
13860          * 0000b (0x0)  SDTR disabled
13861          * 0001b (0x1)  5 Mhz
13862          * 0010b (0x2)  10 Mhz
13863          * 0011b (0x3)  20 Mhz (Ultra)
13864          * 0100b (0x4)  40 Mhz (LVD/Ultra2)
13865          * 0101b (0x5)  80 Mhz (LVD2/Ultra3)
13866          * 0110b (0x6)  Undefined
13867          * .
13868          * 1111b (0xF)  Undefined
13869          */
13870         word = 0;
13871         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
13872                 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
13873                         /* Set Ultra speed for TID 'tid'. */
13874                         word |= (0x3 << (4 * (tid % 4)));
13875                 } else {
13876                         /* Set Fast speed for TID 'tid'. */
13877                         word |= (0x2 << (4 * (tid % 4)));
13878                 }
13879                 if (tid == 3) { /* Check if done with sdtr_speed1. */
13880                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
13881                         word = 0;
13882                 } else if (tid == 7) {  /* Check if done with sdtr_speed2. */
13883                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
13884                         word = 0;
13885                 } else if (tid == 11) { /* Check if done with sdtr_speed3. */
13886                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
13887                         word = 0;
13888                 } else if (tid == 15) { /* Check if done with sdtr_speed4. */
13889                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
13890                         /* End of loop. */
13891                 }
13892         }
13893
13894         /*
13895          * Set microcode operating variable for the disconnect per TID bitmask.
13896          */
13897         AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
13898                          asc_dvc->cfg->disc_enable);
13899
13900         /*
13901          * Set SCSI_CFG0 Microcode Default Value.
13902          *
13903          * The microcode will set the SCSI_CFG0 register using this value
13904          * after it is started below.
13905          */
13906         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
13907                          PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
13908                          asc_dvc->chip_scsi_id);
13909
13910         /*
13911          * Determine SCSI_CFG1 Microcode Default Value.
13912          *
13913          * The microcode will set the SCSI_CFG1 register using this value
13914          * after it is started below.
13915          */
13916
13917         /* Read current SCSI_CFG1 Register value. */
13918         scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
13919
13920         /*
13921          * If all three connectors are in use, return an error.
13922          */
13923         if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
13924             (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
13925                 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
13926                 return ADV_ERROR;
13927         }
13928
13929         /*
13930          * If the internal narrow cable is reversed all of the SCSI_CTRL
13931          * register signals will be set. Check for and return an error if
13932          * this condition is found.
13933          */
13934         if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
13935                 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
13936                 return ADV_ERROR;
13937         }
13938
13939         /*
13940          * If this is a differential board and a single-ended device
13941          * is attached to one of the connectors, return an error.
13942          */
13943         if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
13944                 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
13945                 return ADV_ERROR;
13946         }
13947
13948         /*
13949          * If automatic termination control is enabled, then set the
13950          * termination value based on a table listed in a_condor.h.
13951          *
13952          * If manual termination was specified with an EEPROM setting
13953          * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
13954          * is ready to be 'ored' into SCSI_CFG1.
13955          */
13956         if (asc_dvc->cfg->termination == 0) {
13957                 /*
13958                  * The software always controls termination by setting TERM_CTL_SEL.
13959                  * If TERM_CTL_SEL were set to 0, the hardware would set termination.
13960                  */
13961                 asc_dvc->cfg->termination |= TERM_CTL_SEL;
13962
13963                 switch (scsi_cfg1 & CABLE_DETECT) {
13964                         /* TERM_CTL_H: on, TERM_CTL_L: on */
13965                 case 0x3:
13966                 case 0x7:
13967                 case 0xB:
13968                 case 0xD:
13969                 case 0xE:
13970                 case 0xF:
13971                         asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
13972                         break;
13973
13974                         /* TERM_CTL_H: on, TERM_CTL_L: off */
13975                 case 0x1:
13976                 case 0x5:
13977                 case 0x9:
13978                 case 0xA:
13979                 case 0xC:
13980                         asc_dvc->cfg->termination |= TERM_CTL_H;
13981                         break;
13982
13983                         /* TERM_CTL_H: off, TERM_CTL_L: off */
13984                 case 0x2:
13985                 case 0x6:
13986                         break;
13987                 }
13988         }
13989
13990         /*
13991          * Clear any set TERM_CTL_H and TERM_CTL_L bits.
13992          */
13993         scsi_cfg1 &= ~TERM_CTL;
13994
13995         /*
13996          * Invert the TERM_CTL_H and TERM_CTL_L bits and then
13997          * set 'scsi_cfg1'. The TERM_POL bit does not need to be
13998          * referenced, because the hardware internally inverts
13999          * the Termination High and Low bits if TERM_POL is set.
14000          */
14001         scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
14002
14003         /*
14004          * Set SCSI_CFG1 Microcode Default Value
14005          *
14006          * Set filter value and possibly modified termination control
14007          * bits in the Microcode SCSI_CFG1 Register Value.
14008          *
14009          * The microcode will set the SCSI_CFG1 register using this value
14010          * after it is started below.
14011          */
14012         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
14013                          FLTR_DISABLE | scsi_cfg1);
14014
14015         /*
14016          * Set MEM_CFG Microcode Default Value
14017          *
14018          * The microcode will set the MEM_CFG register using this value
14019          * after it is started below.
14020          *
14021          * MEM_CFG may be accessed as a word or byte, but only bits 0-7
14022          * are defined.
14023          *
14024          * ASC-3550 has 8KB internal memory.
14025          */
14026         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
14027                          BIOS_EN | RAM_SZ_8KB);
14028
14029         /*
14030          * Set SEL_MASK Microcode Default Value
14031          *
14032          * The microcode will set the SEL_MASK register using this value
14033          * after it is started below.
14034          */
14035         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
14036                          ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
14037
14038         /*
14039          * Build carrier freelist.
14040          *
14041          * Driver must have already allocated memory and set 'carrier_buf'.
14042          */
14043         ASC_ASSERT(asc_dvc->carrier_buf != NULL);
14044
14045         carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
14046         asc_dvc->carr_freelist = NULL;
14047         if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
14048                 buf_size = ADV_CARRIER_BUFSIZE;
14049         } else {
14050                 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
14051         }
14052
14053         do {
14054                 /*
14055                  * Get physical address of the carrier 'carrp'.
14056                  */
14057                 contig_len = sizeof(ADV_CARR_T);
14058                 carr_paddr =
14059                     cpu_to_le32(DvcGetPhyAddr
14060                                 (asc_dvc, NULL, (uchar *)carrp,
14061                                  (ADV_SDCNT *)&contig_len,
14062                                  ADV_IS_CARRIER_FLAG));
14063
14064                 buf_size -= sizeof(ADV_CARR_T);
14065
14066                 /*
14067                  * If the current carrier is not physically contiguous, then
14068                  * maybe there was a page crossing. Try the next carrier aligned
14069                  * start address.
14070                  */
14071                 if (contig_len < sizeof(ADV_CARR_T)) {
14072                         carrp++;
14073                         continue;
14074                 }
14075
14076                 carrp->carr_pa = carr_paddr;
14077                 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
14078
14079                 /*
14080                  * Insert the carrier at the beginning of the freelist.
14081                  */
14082                 carrp->next_vpa =
14083                     cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
14084                 asc_dvc->carr_freelist = carrp;
14085
14086                 carrp++;
14087         }
14088         while (buf_size > 0);
14089
14090         /*
14091          * Set-up the Host->RISC Initiator Command Queue (ICQ).
14092          */
14093
14094         if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
14095                 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14096                 return ADV_ERROR;
14097         }
14098         asc_dvc->carr_freelist = (ADV_CARR_T *)
14099             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
14100
14101         /*
14102          * The first command issued will be placed in the stopper carrier.
14103          */
14104         asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14105
14106         /*
14107          * Set RISC ICQ physical address start value.
14108          */
14109         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
14110
14111         /*
14112          * Set-up the RISC->Host Initiator Response Queue (IRQ).
14113          */
14114         if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
14115                 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14116                 return ADV_ERROR;
14117         }
14118         asc_dvc->carr_freelist = (ADV_CARR_T *)
14119             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
14120
14121         /*
14122          * The first command completed by the RISC will be placed in
14123          * the stopper.
14124          *
14125          * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
14126          * completed the RISC will set the ASC_RQ_STOPPER bit.
14127          */
14128         asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14129
14130         /*
14131          * Set RISC IRQ physical address start value.
14132          */
14133         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
14134         asc_dvc->carr_pending_cnt = 0;
14135
14136         AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
14137                              (ADV_INTR_ENABLE_HOST_INTR |
14138                               ADV_INTR_ENABLE_GLOBAL_INTR));
14139
14140         AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
14141         AdvWriteWordRegister(iop_base, IOPW_PC, word);
14142
14143         /* finally, finally, gentlemen, start your engine */
14144         AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
14145
14146         /*
14147          * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
14148          * Resets should be performed. The RISC has to be running
14149          * to issue a SCSI Bus Reset.
14150          */
14151         if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
14152                 /*
14153                  * If the BIOS Signature is present in memory, restore the
14154                  * BIOS Handshake Configuration Table and do not perform
14155                  * a SCSI Bus Reset.
14156                  */
14157                 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
14158                     0x55AA) {
14159                         /*
14160                          * Restore per TID negotiated values.
14161                          */
14162                         AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14163                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14164                         AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
14165                                          tagqng_able);
14166                         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14167                                 AdvWriteByteLram(iop_base,
14168                                                  ASC_MC_NUMBER_OF_MAX_CMD + tid,
14169                                                  max_cmd[tid]);
14170                         }
14171                 } else {
14172                         if (AdvResetSB(asc_dvc) != ADV_TRUE) {
14173                                 warn_code = ASC_WARN_BUSRESET_ERROR;
14174                         }
14175                 }
14176         }
14177
14178         return warn_code;
14179 }
14180
14181 /*
14182  * Initialize the ASC-38C0800.
14183  *
14184  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14185  *
14186  * For a non-fatal error return a warning code. If there are no warnings
14187  * then 0 is returned.
14188  *
14189  * Needed after initialization for error recovery.
14190  */
14191 static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
14192 {
14193         AdvPortAddr iop_base;
14194         ushort warn_code;
14195         ADV_DCNT sum;
14196         int begin_addr;
14197         int end_addr;
14198         ushort code_sum;
14199         int word;
14200         int j;
14201         int adv_asc38C0800_expanded_size;
14202         ADV_CARR_T *carrp;
14203         ADV_DCNT contig_len;
14204         ADV_SDCNT buf_size;
14205         ADV_PADDR carr_paddr;
14206         int i;
14207         ushort scsi_cfg1;
14208         uchar byte;
14209         uchar tid;
14210         ushort bios_mem[ASC_MC_BIOSLEN / 2];    /* BIOS RISC Memory 0x40-0x8F. */
14211         ushort wdtr_able, sdtr_able, tagqng_able;
14212         uchar max_cmd[ADV_MAX_TID + 1];
14213
14214         /* If there is already an error, don't continue. */
14215         if (asc_dvc->err_code != 0) {
14216                 return ADV_ERROR;
14217         }
14218
14219         /*
14220          * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
14221          */
14222         if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
14223                 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
14224                 return ADV_ERROR;
14225         }
14226
14227         warn_code = 0;
14228         iop_base = asc_dvc->iop_base;
14229
14230         /*
14231          * Save the RISC memory BIOS region before writing the microcode.
14232          * The BIOS may already be loaded and using its RISC LRAM region
14233          * so its region must be saved and restored.
14234          *
14235          * Note: This code makes the assumption, which is currently true,
14236          * that a chip reset does not clear RISC LRAM.
14237          */
14238         for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14239                 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14240                                 bios_mem[i]);
14241         }
14242
14243         /*
14244          * Save current per TID negotiated values.
14245          */
14246         AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14247         AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14248         AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14249         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14250                 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14251                                 max_cmd[tid]);
14252         }
14253
14254         /*
14255          * RAM BIST (RAM Built-In Self Test)
14256          *
14257          * Address : I/O base + offset 0x38h register (byte).
14258          * Function: Bit 7-6(RW) : RAM mode
14259          *                          Normal Mode   : 0x00
14260          *                          Pre-test Mode : 0x40
14261          *                          RAM Test Mode : 0x80
14262          *           Bit 5       : unused
14263          *           Bit 4(RO)   : Done bit
14264          *           Bit 3-0(RO) : Status
14265          *                          Host Error    : 0x08
14266          *                          Int_RAM Error : 0x04
14267          *                          RISC Error    : 0x02
14268          *                          SCSI Error    : 0x01
14269          *                          No Error      : 0x00
14270          *
14271          * Note: RAM BIST code should be put right here, before loading the
14272          * microcode and after saving the RISC memory BIOS region.
14273          */
14274
14275         /*
14276          * LRAM Pre-test
14277          *
14278          * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
14279          * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
14280          * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
14281          * to NORMAL_MODE, return an error too.
14282          */
14283         for (i = 0; i < 2; i++) {
14284                 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
14285                 DvcSleepMilliSecond(10);        /* Wait for 10ms before reading back. */
14286                 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14287                 if ((byte & RAM_TEST_DONE) == 0
14288                     || (byte & 0x0F) != PRE_TEST_VALUE) {
14289                         asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14290                         return ADV_ERROR;
14291                 }
14292
14293                 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14294                 DvcSleepMilliSecond(10);        /* Wait for 10ms before reading back. */
14295                 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
14296                     != NORMAL_VALUE) {
14297                         asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14298                         return ADV_ERROR;
14299                 }
14300         }
14301
14302         /*
14303          * LRAM Test - It takes about 1.5 ms to run through the test.
14304          *
14305          * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
14306          * If Done bit not set or Status not 0, save register byte, set the
14307          * err_code, and return an error.
14308          */
14309         AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
14310         DvcSleepMilliSecond(10);        /* Wait for 10ms before checking status. */
14311
14312         byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14313         if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
14314                 /* Get here if Done bit not set or Status not 0. */
14315                 asc_dvc->bist_err_code = byte;  /* for BIOS display message */
14316                 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
14317                 return ADV_ERROR;
14318         }
14319
14320         /* We need to reset back to normal mode after LRAM test passes. */
14321         AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14322
14323         /*
14324          * Load the Microcode
14325          *
14326          * Write the microcode image to RISC memory starting at address 0.
14327          *
14328          */
14329         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14330
14331         /* Assume the following compressed format of the microcode buffer:
14332          *
14333          *  254 word (508 byte) table indexed by byte code followed
14334          *  by the following byte codes:
14335          *
14336          *    1-Byte Code:
14337          *      00: Emit word 0 in table.
14338          *      01: Emit word 1 in table.
14339          *      .
14340          *      FD: Emit word 253 in table.
14341          *
14342          *    Multi-Byte Code:
14343          *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14344          *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14345          */
14346         word = 0;
14347         for (i = 253 * 2; i < _adv_asc38C0800_size; i++) {
14348                 if (_adv_asc38C0800_buf[i] == 0xff) {
14349                         for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++) {
14350                                 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14351                                                                     _adv_asc38C0800_buf
14352                                                                     [i +
14353                                                                      3] << 8) |
14354                                                                    _adv_asc38C0800_buf
14355                                                                    [i + 2]));
14356                                 word++;
14357                         }
14358                         i += 3;
14359                 } else if (_adv_asc38C0800_buf[i] == 0xfe) {
14360                         AdvWriteWordAutoIncLram(iop_base, (((ushort)
14361                                                             _adv_asc38C0800_buf
14362                                                             [i +
14363                                                              2] << 8) |
14364                                                            _adv_asc38C0800_buf[i
14365                                                                                +
14366                                                                                1]));
14367                         i += 2;
14368                         word++;
14369                 } else {
14370                         AdvWriteWordAutoIncLram(iop_base, (((ushort)
14371                                                             _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) | _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2]));
14372                         word++;
14373                 }
14374         }
14375
14376         /*
14377          * Set 'word' for later use to clear the rest of memory and save
14378          * the expanded mcode size.
14379          */
14380         word *= 2;
14381         adv_asc38C0800_expanded_size = word;
14382
14383         /*
14384          * Clear the rest of ASC-38C0800 Internal RAM (16KB).
14385          */
14386         for (; word < ADV_38C0800_MEMSIZE; word += 2) {
14387                 AdvWriteWordAutoIncLram(iop_base, 0);
14388         }
14389
14390         /*
14391          * Verify the microcode checksum.
14392          */
14393         sum = 0;
14394         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14395
14396         for (word = 0; word < adv_asc38C0800_expanded_size; word += 2) {
14397                 sum += AdvReadWordAutoIncLram(iop_base);
14398         }
14399         ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i);
14400
14401         ASC_DBG2(1,
14402                  "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n",
14403                  (ulong)sum, (ulong)_adv_asc38C0800_chksum);
14404
14405         if (sum != _adv_asc38C0800_chksum) {
14406                 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
14407                 return ADV_ERROR;
14408         }
14409
14410         /*
14411          * Restore the RISC memory BIOS region.
14412          */
14413         for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14414                 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14415                                  bios_mem[i]);
14416         }
14417
14418         /*
14419          * Calculate and write the microcode code checksum to the microcode
14420          * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
14421          */
14422         AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
14423         AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
14424         code_sum = 0;
14425         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
14426         for (word = begin_addr; word < end_addr; word += 2) {
14427                 code_sum += AdvReadWordAutoIncLram(iop_base);
14428         }
14429         AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
14430
14431         /*
14432          * Read microcode version and date.
14433          */
14434         AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
14435                         asc_dvc->cfg->mcode_date);
14436         AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
14437                         asc_dvc->cfg->mcode_version);
14438
14439         /*
14440          * Set the chip type to indicate the ASC38C0800.
14441          */
14442         AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
14443
14444         /*
14445          * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
14446          * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
14447          * cable detection and then we are able to read C_DET[3:0].
14448          *
14449          * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
14450          * Microcode Default Value' section below.
14451          */
14452         scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14453         AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
14454                              scsi_cfg1 | DIS_TERM_DRV);
14455
14456         /*
14457          * If the PCI Configuration Command Register "Parity Error Response
14458          * Control" Bit was clear (0), then set the microcode variable
14459          * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
14460          * to ignore DMA parity errors.
14461          */
14462         if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
14463                 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14464                 word |= CONTROL_FLAG_IGNORE_PERR;
14465                 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14466         }
14467
14468         /*
14469          * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
14470          * bits for the default FIFO threshold.
14471          *
14472          * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
14473          *
14474          * For DMA Errata #4 set the BC_THRESH_ENB bit.
14475          */
14476         AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
14477                              BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
14478                              READ_CMD_MRM);
14479
14480         /*
14481          * Microcode operating variables for WDTR, SDTR, and command tag
14482          * queuing will be set in slave_configure() based on what a
14483          * device reports it is capable of in Inquiry byte 7.
14484          *
14485          * If SCSI Bus Resets have been disabled, then directly set
14486          * SDTR and WDTR from the EEPROM configuration. This will allow
14487          * the BIOS and warm boot to work without a SCSI bus hang on
14488          * the Inquiry caused by host and target mismatched DTR values.
14489          * Without the SCSI Bus Reset, before an Inquiry a device can't
14490          * be assumed to be in Asynchronous, Narrow mode.
14491          */
14492         if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
14493                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
14494                                  asc_dvc->wdtr_able);
14495                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
14496                                  asc_dvc->sdtr_able);
14497         }
14498
14499         /*
14500          * Set microcode operating variables for DISC and SDTR_SPEED1,
14501          * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
14502          * configuration values.
14503          *
14504          * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
14505          * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
14506          * without determining here whether the device supports SDTR.
14507          */
14508         AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
14509                          asc_dvc->cfg->disc_enable);
14510         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
14511         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
14512         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
14513         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
14514
14515         /*
14516          * Set SCSI_CFG0 Microcode Default Value.
14517          *
14518          * The microcode will set the SCSI_CFG0 register using this value
14519          * after it is started below.
14520          */
14521         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
14522                          PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
14523                          asc_dvc->chip_scsi_id);
14524
14525         /*
14526          * Determine SCSI_CFG1 Microcode Default Value.
14527          *
14528          * The microcode will set the SCSI_CFG1 register using this value
14529          * after it is started below.
14530          */
14531
14532         /* Read current SCSI_CFG1 Register value. */
14533         scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14534
14535         /*
14536          * If the internal narrow cable is reversed all of the SCSI_CTRL
14537          * register signals will be set. Check for and return an error if
14538          * this condition is found.
14539          */
14540         if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
14541                 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
14542                 return ADV_ERROR;
14543         }
14544
14545         /*
14546          * All kind of combinations of devices attached to one of four connectors
14547          * are acceptable except HVD device attached. For example, LVD device can
14548          * be attached to SE connector while SE device attached to LVD connector.
14549          * If LVD device attached to SE connector, it only runs up to Ultra speed.
14550          *
14551          * If an HVD device is attached to one of LVD connectors, return an error.
14552          * However, there is no way to detect HVD device attached to SE connectors.
14553          */
14554         if (scsi_cfg1 & HVD) {
14555                 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
14556                 return ADV_ERROR;
14557         }
14558
14559         /*
14560          * If either SE or LVD automatic termination control is enabled, then
14561          * set the termination value based on a table listed in a_condor.h.
14562          *
14563          * If manual termination was specified with an EEPROM setting then
14564          * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to
14565          * be 'ored' into SCSI_CFG1.
14566          */
14567         if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
14568                 /* SE automatic termination control is enabled. */
14569                 switch (scsi_cfg1 & C_DET_SE) {
14570                         /* TERM_SE_HI: on, TERM_SE_LO: on */
14571                 case 0x1:
14572                 case 0x2:
14573                 case 0x3:
14574                         asc_dvc->cfg->termination |= TERM_SE;
14575                         break;
14576
14577                         /* TERM_SE_HI: on, TERM_SE_LO: off */
14578                 case 0x0:
14579                         asc_dvc->cfg->termination |= TERM_SE_HI;
14580                         break;
14581                 }
14582         }
14583
14584         if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
14585                 /* LVD automatic termination control is enabled. */
14586                 switch (scsi_cfg1 & C_DET_LVD) {
14587                         /* TERM_LVD_HI: on, TERM_LVD_LO: on */
14588                 case 0x4:
14589                 case 0x8:
14590                 case 0xC:
14591                         asc_dvc->cfg->termination |= TERM_LVD;
14592                         break;
14593
14594                         /* TERM_LVD_HI: off, TERM_LVD_LO: off */
14595                 case 0x0:
14596                         break;
14597                 }
14598         }
14599
14600         /*
14601          * Clear any set TERM_SE and TERM_LVD bits.
14602          */
14603         scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
14604
14605         /*
14606          * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
14607          */
14608         scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
14609
14610         /*
14611          * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits
14612          * and set possibly modified termination control bits in the Microcode
14613          * SCSI_CFG1 Register Value.
14614          */
14615         scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
14616
14617         /*
14618          * Set SCSI_CFG1 Microcode Default Value
14619          *
14620          * Set possibly modified termination control and reset DIS_TERM_DRV
14621          * bits in the Microcode SCSI_CFG1 Register Value.
14622          *
14623          * The microcode will set the SCSI_CFG1 register using this value
14624          * after it is started below.
14625          */
14626         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
14627
14628         /*
14629          * Set MEM_CFG Microcode Default Value
14630          *
14631          * The microcode will set the MEM_CFG register using this value
14632          * after it is started below.
14633          *
14634          * MEM_CFG may be accessed as a word or byte, but only bits 0-7
14635          * are defined.
14636          *
14637          * ASC-38C0800 has 16KB internal memory.
14638          */
14639         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
14640                          BIOS_EN | RAM_SZ_16KB);
14641
14642         /*
14643          * Set SEL_MASK Microcode Default Value
14644          *
14645          * The microcode will set the SEL_MASK register using this value
14646          * after it is started below.
14647          */
14648         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
14649                          ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
14650
14651         /*
14652          * Build the carrier freelist.
14653          *
14654          * Driver must have already allocated memory and set 'carrier_buf'.
14655          */
14656         ASC_ASSERT(asc_dvc->carrier_buf != NULL);
14657
14658         carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
14659         asc_dvc->carr_freelist = NULL;
14660         if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
14661                 buf_size = ADV_CARRIER_BUFSIZE;
14662         } else {
14663                 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
14664         }
14665
14666         do {
14667                 /*
14668                  * Get physical address for the carrier 'carrp'.
14669                  */
14670                 contig_len = sizeof(ADV_CARR_T);
14671                 carr_paddr =
14672                     cpu_to_le32(DvcGetPhyAddr
14673                                 (asc_dvc, NULL, (uchar *)carrp,
14674                                  (ADV_SDCNT *)&contig_len,
14675                                  ADV_IS_CARRIER_FLAG));
14676
14677                 buf_size -= sizeof(ADV_CARR_T);
14678
14679                 /*
14680                  * If the current carrier is not physically contiguous, then
14681                  * maybe there was a page crossing. Try the next carrier aligned
14682                  * start address.
14683                  */
14684                 if (contig_len < sizeof(ADV_CARR_T)) {
14685                         carrp++;
14686                         continue;
14687                 }
14688
14689                 carrp->carr_pa = carr_paddr;
14690                 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
14691
14692                 /*
14693                  * Insert the carrier at the beginning of the freelist.
14694                  */
14695                 carrp->next_vpa =
14696                     cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
14697                 asc_dvc->carr_freelist = carrp;
14698
14699                 carrp++;
14700         }
14701         while (buf_size > 0);
14702
14703         /*
14704          * Set-up the Host->RISC Initiator Command Queue (ICQ).
14705          */
14706
14707         if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
14708                 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14709                 return ADV_ERROR;
14710         }
14711         asc_dvc->carr_freelist = (ADV_CARR_T *)
14712             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
14713
14714         /*
14715          * The first command issued will be placed in the stopper carrier.
14716          */
14717         asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14718
14719         /*
14720          * Set RISC ICQ physical address start value.
14721          * carr_pa is LE, must be native before write
14722          */
14723         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
14724
14725         /*
14726          * Set-up the RISC->Host Initiator Response Queue (IRQ).
14727          */
14728         if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
14729                 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14730                 return ADV_ERROR;
14731         }
14732         asc_dvc->carr_freelist = (ADV_CARR_T *)
14733             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
14734
14735         /*
14736          * The first command completed by the RISC will be placed in
14737          * the stopper.
14738          *
14739          * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
14740          * completed the RISC will set the ASC_RQ_STOPPER bit.
14741          */
14742         asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14743
14744         /*
14745          * Set RISC IRQ physical address start value.
14746          *
14747          * carr_pa is LE, must be native before write *
14748          */
14749         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
14750         asc_dvc->carr_pending_cnt = 0;
14751
14752         AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
14753                              (ADV_INTR_ENABLE_HOST_INTR |
14754                               ADV_INTR_ENABLE_GLOBAL_INTR));
14755
14756         AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
14757         AdvWriteWordRegister(iop_base, IOPW_PC, word);
14758
14759         /* finally, finally, gentlemen, start your engine */
14760         AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
14761
14762         /*
14763          * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
14764          * Resets should be performed. The RISC has to be running
14765          * to issue a SCSI Bus Reset.
14766          */
14767         if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
14768                 /*
14769                  * If the BIOS Signature is present in memory, restore the
14770                  * BIOS Handshake Configuration Table and do not perform
14771                  * a SCSI Bus Reset.
14772                  */
14773                 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
14774                     0x55AA) {
14775                         /*
14776                          * Restore per TID negotiated values.
14777                          */
14778                         AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14779                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14780                         AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
14781                                          tagqng_able);
14782                         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14783                                 AdvWriteByteLram(iop_base,
14784                                                  ASC_MC_NUMBER_OF_MAX_CMD + tid,
14785                                                  max_cmd[tid]);
14786                         }
14787                 } else {
14788                         if (AdvResetSB(asc_dvc) != ADV_TRUE) {
14789                                 warn_code = ASC_WARN_BUSRESET_ERROR;
14790                         }
14791                 }
14792         }
14793
14794         return warn_code;
14795 }
14796
14797 /*
14798  * Initialize the ASC-38C1600.
14799  *
14800  * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
14801  *
14802  * For a non-fatal error return a warning code. If there are no warnings
14803  * then 0 is returned.
14804  *
14805  * Needed after initialization for error recovery.
14806  */
14807 static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
14808 {
14809         AdvPortAddr iop_base;
14810         ushort warn_code;
14811         ADV_DCNT sum;
14812         int begin_addr;
14813         int end_addr;
14814         ushort code_sum;
14815         long word;
14816         int j;
14817         int adv_asc38C1600_expanded_size;
14818         ADV_CARR_T *carrp;
14819         ADV_DCNT contig_len;
14820         ADV_SDCNT buf_size;
14821         ADV_PADDR carr_paddr;
14822         int i;
14823         ushort scsi_cfg1;
14824         uchar byte;
14825         uchar tid;
14826         ushort bios_mem[ASC_MC_BIOSLEN / 2];    /* BIOS RISC Memory 0x40-0x8F. */
14827         ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
14828         uchar max_cmd[ASC_MAX_TID + 1];
14829
14830         /* If there is already an error, don't continue. */
14831         if (asc_dvc->err_code != 0) {
14832                 return ADV_ERROR;
14833         }
14834
14835         /*
14836          * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
14837          */
14838         if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
14839                 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
14840                 return ADV_ERROR;
14841         }
14842
14843         warn_code = 0;
14844         iop_base = asc_dvc->iop_base;
14845
14846         /*
14847          * Save the RISC memory BIOS region before writing the microcode.
14848          * The BIOS may already be loaded and using its RISC LRAM region
14849          * so its region must be saved and restored.
14850          *
14851          * Note: This code makes the assumption, which is currently true,
14852          * that a chip reset does not clear RISC LRAM.
14853          */
14854         for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14855                 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14856                                 bios_mem[i]);
14857         }
14858
14859         /*
14860          * Save current per TID negotiated values.
14861          */
14862         AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14863         AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14864         AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
14865         AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14866         for (tid = 0; tid <= ASC_MAX_TID; tid++) {
14867                 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14868                                 max_cmd[tid]);
14869         }
14870
14871         /*
14872          * RAM BIST (Built-In Self Test)
14873          *
14874          * Address : I/O base + offset 0x38h register (byte).
14875          * Function: Bit 7-6(RW) : RAM mode
14876          *                          Normal Mode   : 0x00
14877          *                          Pre-test Mode : 0x40
14878          *                          RAM Test Mode : 0x80
14879          *           Bit 5       : unused
14880          *           Bit 4(RO)   : Done bit
14881          *           Bit 3-0(RO) : Status
14882          *                          Host Error    : 0x08
14883          *                          Int_RAM Error : 0x04
14884          *                          RISC Error    : 0x02
14885          *                          SCSI Error    : 0x01
14886          *                          No Error      : 0x00
14887          *
14888          * Note: RAM BIST code should be put right here, before loading the
14889          * microcode and after saving the RISC memory BIOS region.
14890          */
14891
14892         /*
14893          * LRAM Pre-test
14894          *
14895          * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
14896          * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
14897          * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
14898          * to NORMAL_MODE, return an error too.
14899          */
14900         for (i = 0; i < 2; i++) {
14901                 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
14902                 DvcSleepMilliSecond(10);        /* Wait for 10ms before reading back. */
14903                 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14904                 if ((byte & RAM_TEST_DONE) == 0
14905                     || (byte & 0x0F) != PRE_TEST_VALUE) {
14906                         asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14907                         return ADV_ERROR;
14908                 }
14909
14910                 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14911                 DvcSleepMilliSecond(10);        /* Wait for 10ms before reading back. */
14912                 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
14913                     != NORMAL_VALUE) {
14914                         asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14915                         return ADV_ERROR;
14916                 }
14917         }
14918
14919         /*
14920          * LRAM Test - It takes about 1.5 ms to run through the test.
14921          *
14922          * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
14923          * If Done bit not set or Status not 0, save register byte, set the
14924          * err_code, and return an error.
14925          */
14926         AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
14927         DvcSleepMilliSecond(10);        /* Wait for 10ms before checking status. */
14928
14929         byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14930         if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
14931                 /* Get here if Done bit not set or Status not 0. */
14932                 asc_dvc->bist_err_code = byte;  /* for BIOS display message */
14933                 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
14934                 return ADV_ERROR;
14935         }
14936
14937         /* We need to reset back to normal mode after LRAM test passes. */
14938         AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14939
14940         /*
14941          * Load the Microcode
14942          *
14943          * Write the microcode image to RISC memory starting at address 0.
14944          *
14945          */
14946         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14947
14948         /*
14949          * Assume the following compressed format of the microcode buffer:
14950          *
14951          *  254 word (508 byte) table indexed by byte code followed
14952          *  by the following byte codes:
14953          *
14954          *    1-Byte Code:
14955          *      00: Emit word 0 in table.
14956          *      01: Emit word 1 in table.
14957          *      .
14958          *      FD: Emit word 253 in table.
14959          *
14960          *    Multi-Byte Code:
14961          *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14962          *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14963          */
14964         word = 0;
14965         for (i = 253 * 2; i < _adv_asc38C1600_size; i++) {
14966                 if (_adv_asc38C1600_buf[i] == 0xff) {
14967                         for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++) {
14968                                 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14969                                                                     _adv_asc38C1600_buf
14970                                                                     [i +
14971                                                                      3] << 8) |
14972                                                                    _adv_asc38C1600_buf
14973                                                                    [i + 2]));
14974                                 word++;
14975                         }
14976                         i += 3;
14977                 } else if (_adv_asc38C1600_buf[i] == 0xfe) {
14978                         AdvWriteWordAutoIncLram(iop_base, (((ushort)
14979                                                             _adv_asc38C1600_buf
14980                                                             [i +
14981                                                              2] << 8) |
14982                                                            _adv_asc38C1600_buf[i
14983                                                                                +
14984                                                                                1]));
14985                         i += 2;
14986                         word++;
14987                 } else {
14988                         AdvWriteWordAutoIncLram(iop_base, (((ushort)
14989                                                             _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) | _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2]));
14990                         word++;
14991                 }
14992         }
14993
14994         /*
14995          * Set 'word' for later use to clear the rest of memory and save
14996          * the expanded mcode size.
14997          */
14998         word *= 2;
14999         adv_asc38C1600_expanded_size = word;
15000
15001         /*
15002          * Clear the rest of ASC-38C1600 Internal RAM (32KB).
15003          */
15004         for (; word < ADV_38C1600_MEMSIZE; word += 2) {
15005                 AdvWriteWordAutoIncLram(iop_base, 0);
15006         }
15007
15008         /*
15009          * Verify the microcode checksum.
15010          */
15011         sum = 0;
15012         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15013
15014         for (word = 0; word < adv_asc38C1600_expanded_size; word += 2) {
15015                 sum += AdvReadWordAutoIncLram(iop_base);
15016         }
15017
15018         if (sum != _adv_asc38C1600_chksum) {
15019                 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15020                 return ADV_ERROR;
15021         }
15022
15023         /*
15024          * Restore the RISC memory BIOS region.
15025          */
15026         for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
15027                 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
15028                                  bios_mem[i]);
15029         }
15030
15031         /*
15032          * Calculate and write the microcode code checksum to the microcode
15033          * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15034          */
15035         AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15036         AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15037         code_sum = 0;
15038         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15039         for (word = begin_addr; word < end_addr; word += 2) {
15040                 code_sum += AdvReadWordAutoIncLram(iop_base);
15041         }
15042         AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15043
15044         /*
15045          * Read microcode version and date.
15046          */
15047         AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
15048                         asc_dvc->cfg->mcode_date);
15049         AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
15050                         asc_dvc->cfg->mcode_version);
15051
15052         /*
15053          * Set the chip type to indicate the ASC38C1600.
15054          */
15055         AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
15056
15057         /*
15058          * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
15059          * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
15060          * cable detection and then we are able to read C_DET[3:0].
15061          *
15062          * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
15063          * Microcode Default Value' section below.
15064          */
15065         scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15066         AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
15067                              scsi_cfg1 | DIS_TERM_DRV);
15068
15069         /*
15070          * If the PCI Configuration Command Register "Parity Error Response
15071          * Control" Bit was clear (0), then set the microcode variable
15072          * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15073          * to ignore DMA parity errors.
15074          */
15075         if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
15076                 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15077                 word |= CONTROL_FLAG_IGNORE_PERR;
15078                 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15079         }
15080
15081         /*
15082          * If the BIOS control flag AIPP (Asynchronous Information
15083          * Phase Protection) disable bit is not set, then set the firmware
15084          * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
15085          * AIPP checking and encoding.
15086          */
15087         if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
15088                 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15089                 word |= CONTROL_FLAG_ENABLE_AIPP;
15090                 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15091         }
15092
15093         /*
15094          * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
15095          * and START_CTL_TH [3:2].
15096          */
15097         AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15098                              FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
15099
15100         /*
15101          * Microcode operating variables for WDTR, SDTR, and command tag
15102          * queuing will be set in slave_configure() based on what a
15103          * device reports it is capable of in Inquiry byte 7.
15104          *
15105          * If SCSI Bus Resets have been disabled, then directly set
15106          * SDTR and WDTR from the EEPROM configuration. This will allow
15107          * the BIOS and warm boot to work without a SCSI bus hang on
15108          * the Inquiry caused by host and target mismatched DTR values.
15109          * Without the SCSI Bus Reset, before an Inquiry a device can't
15110          * be assumed to be in Asynchronous, Narrow mode.
15111          */
15112         if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
15113                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
15114                                  asc_dvc->wdtr_able);
15115                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
15116                                  asc_dvc->sdtr_able);
15117         }
15118
15119         /*
15120          * Set microcode operating variables for DISC and SDTR_SPEED1,
15121          * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
15122          * configuration values.
15123          *
15124          * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15125          * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15126          * without determining here whether the device supports SDTR.
15127          */
15128         AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
15129                          asc_dvc->cfg->disc_enable);
15130         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
15131         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
15132         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
15133         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
15134
15135         /*
15136          * Set SCSI_CFG0 Microcode Default Value.
15137          *
15138          * The microcode will set the SCSI_CFG0 register using this value
15139          * after it is started below.
15140          */
15141         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15142                          PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15143                          asc_dvc->chip_scsi_id);
15144
15145         /*
15146          * Calculate SCSI_CFG1 Microcode Default Value.
15147          *
15148          * The microcode will set the SCSI_CFG1 register using this value
15149          * after it is started below.
15150          *
15151          * Each ASC-38C1600 function has only two cable detect bits.
15152          * The bus mode override bits are in IOPB_SOFT_OVER_WR.
15153          */
15154         scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15155
15156         /*
15157          * If the cable is reversed all of the SCSI_CTRL register signals
15158          * will be set. Check for and return an error if this condition is
15159          * found.
15160          */
15161         if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
15162                 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15163                 return ADV_ERROR;
15164         }
15165
15166         /*
15167          * Each ASC-38C1600 function has two connectors. Only an HVD device
15168          * can not be connected to either connector. An LVD device or SE device
15169          * may be connected to either connecor. If an SE device is connected,
15170          * then at most Ultra speed (20 Mhz) can be used on both connectors.
15171          *
15172          * If an HVD device is attached, return an error.
15173          */
15174         if (scsi_cfg1 & HVD) {
15175                 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
15176                 return ADV_ERROR;
15177         }
15178
15179         /*
15180          * Each function in the ASC-38C1600 uses only the SE cable detect and
15181          * termination because there are two connectors for each function. Each
15182          * function may use either LVD or SE mode. Corresponding the SE automatic
15183          * termination control EEPROM bits are used for each function. Each
15184          * function has its own EEPROM. If SE automatic control is enabled for
15185          * the function, then set the termination value based on a table listed
15186          * in a_condor.h.
15187          *
15188          * If manual termination is specified in the EEPROM for the function,
15189          * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
15190          * ready to be 'ored' into SCSI_CFG1.
15191          */
15192         if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
15193                 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
15194                 /* SE automatic termination control is enabled. */
15195                 switch (scsi_cfg1 & C_DET_SE) {
15196                         /* TERM_SE_HI: on, TERM_SE_LO: on */
15197                 case 0x1:
15198                 case 0x2:
15199                 case 0x3:
15200                         asc_dvc->cfg->termination |= TERM_SE;
15201                         break;
15202
15203                 case 0x0:
15204                         if (PCI_FUNC(pdev->devfn) == 0) {
15205                                 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
15206                         } else {
15207                                 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
15208                                 asc_dvc->cfg->termination |= TERM_SE_HI;
15209                         }
15210                         break;
15211                 }
15212         }
15213
15214         /*
15215          * Clear any set TERM_SE bits.
15216          */
15217         scsi_cfg1 &= ~TERM_SE;
15218
15219         /*
15220          * Invert the TERM_SE bits and then set 'scsi_cfg1'.
15221          */
15222         scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
15223
15224         /*
15225          * Clear Big Endian and Terminator Polarity bits and set possibly
15226          * modified termination control bits in the Microcode SCSI_CFG1
15227          * Register Value.
15228          *
15229          * Big Endian bit is not used even on big endian machines.
15230          */
15231         scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
15232
15233         /*
15234          * Set SCSI_CFG1 Microcode Default Value
15235          *
15236          * Set possibly modified termination control bits in the Microcode
15237          * SCSI_CFG1 Register Value.
15238          *
15239          * The microcode will set the SCSI_CFG1 register using this value
15240          * after it is started below.
15241          */
15242         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15243
15244         /*
15245          * Set MEM_CFG Microcode Default Value
15246          *
15247          * The microcode will set the MEM_CFG register using this value
15248          * after it is started below.
15249          *
15250          * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15251          * are defined.
15252          *
15253          * ASC-38C1600 has 32KB internal memory.
15254          *
15255          * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
15256          * out a special 16K Adv Library and Microcode version. After the issue
15257          * resolved, we should turn back to the 32K support. Both a_condor.h and
15258          * mcode.sas files also need to be updated.
15259          *
15260          * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15261          *  BIOS_EN | RAM_SZ_32KB);
15262          */
15263         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15264                          BIOS_EN | RAM_SZ_16KB);
15265
15266         /*
15267          * Set SEL_MASK Microcode Default Value
15268          *
15269          * The microcode will set the SEL_MASK register using this value
15270          * after it is started below.
15271          */
15272         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15273                          ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15274
15275         /*
15276          * Build the carrier freelist.
15277          *
15278          * Driver must have already allocated memory and set 'carrier_buf'.
15279          */
15280
15281         ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15282
15283         carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15284         asc_dvc->carr_freelist = NULL;
15285         if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
15286                 buf_size = ADV_CARRIER_BUFSIZE;
15287         } else {
15288                 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15289         }
15290
15291         do {
15292                 /*
15293                  * Get physical address for the carrier 'carrp'.
15294                  */
15295                 contig_len = sizeof(ADV_CARR_T);
15296                 carr_paddr =
15297                     cpu_to_le32(DvcGetPhyAddr
15298                                 (asc_dvc, NULL, (uchar *)carrp,
15299                                  (ADV_SDCNT *)&contig_len,
15300                                  ADV_IS_CARRIER_FLAG));
15301
15302                 buf_size -= sizeof(ADV_CARR_T);
15303
15304                 /*
15305                  * If the current carrier is not physically contiguous, then
15306                  * maybe there was a page crossing. Try the next carrier aligned
15307                  * start address.
15308                  */
15309                 if (contig_len < sizeof(ADV_CARR_T)) {
15310                         carrp++;
15311                         continue;
15312                 }
15313
15314                 carrp->carr_pa = carr_paddr;
15315                 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15316
15317                 /*
15318                  * Insert the carrier at the beginning of the freelist.
15319                  */
15320                 carrp->next_vpa =
15321                     cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15322                 asc_dvc->carr_freelist = carrp;
15323
15324                 carrp++;
15325         }
15326         while (buf_size > 0);
15327
15328         /*
15329          * Set-up the Host->RISC Initiator Command Queue (ICQ).
15330          */
15331         if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
15332                 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15333                 return ADV_ERROR;
15334         }
15335         asc_dvc->carr_freelist = (ADV_CARR_T *)
15336             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15337
15338         /*
15339          * The first command issued will be placed in the stopper carrier.
15340          */
15341         asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15342
15343         /*
15344          * Set RISC ICQ physical address start value. Initialize the
15345          * COMMA register to the same value otherwise the RISC will
15346          * prematurely detect a command is available.
15347          */
15348         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15349         AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
15350                               le32_to_cpu(asc_dvc->icq_sp->carr_pa));
15351
15352         /*
15353          * Set-up the RISC->Host Initiator Response Queue (IRQ).
15354          */
15355         if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
15356                 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15357                 return ADV_ERROR;
15358         }
15359         asc_dvc->carr_freelist = (ADV_CARR_T *)
15360             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15361
15362         /*
15363          * The first command completed by the RISC will be placed in
15364          * the stopper.
15365          *
15366          * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15367          * completed the RISC will set the ASC_RQ_STOPPER bit.
15368          */
15369         asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15370
15371         /*
15372          * Set RISC IRQ physical address start value.
15373          */
15374         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15375         asc_dvc->carr_pending_cnt = 0;
15376
15377         AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15378                              (ADV_INTR_ENABLE_HOST_INTR |
15379                               ADV_INTR_ENABLE_GLOBAL_INTR));
15380         AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15381         AdvWriteWordRegister(iop_base, IOPW_PC, word);
15382
15383         /* finally, finally, gentlemen, start your engine */
15384         AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15385
15386         /*
15387          * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15388          * Resets should be performed. The RISC has to be running
15389          * to issue a SCSI Bus Reset.
15390          */
15391         if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
15392                 /*
15393                  * If the BIOS Signature is present in memory, restore the
15394                  * per TID microcode operating variables.
15395                  */
15396                 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
15397                     0x55AA) {
15398                         /*
15399                          * Restore per TID negotiated values.
15400                          */
15401                         AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15402                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15403                         AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
15404                         AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
15405                                          tagqng_able);
15406                         for (tid = 0; tid <= ASC_MAX_TID; tid++) {
15407                                 AdvWriteByteLram(iop_base,
15408                                                  ASC_MC_NUMBER_OF_MAX_CMD + tid,
15409                                                  max_cmd[tid]);
15410                         }
15411                 } else {
15412                         if (AdvResetSB(asc_dvc) != ADV_TRUE) {
15413                                 warn_code = ASC_WARN_BUSRESET_ERROR;
15414                         }
15415                 }
15416         }
15417
15418         return warn_code;
15419 }
15420
15421 /*
15422  * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
15423  * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
15424  * all of this is done.
15425  *
15426  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15427  *
15428  * For a non-fatal error return a warning code. If there are no warnings
15429  * then 0 is returned.
15430  *
15431  * Note: Chip is stopped on entry.
15432  */
15433 static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
15434 {
15435         AdvPortAddr iop_base;
15436         ushort warn_code;
15437         ADVEEP_3550_CONFIG eep_config;
15438
15439         iop_base = asc_dvc->iop_base;
15440
15441         warn_code = 0;
15442
15443         /*
15444          * Read the board's EEPROM configuration.
15445          *
15446          * Set default values if a bad checksum is found.
15447          */
15448         if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
15449                 warn_code |= ASC_WARN_EEPROM_CHKSUM;
15450
15451                 /*
15452                  * Set EEPROM default values.
15453                  */
15454                 memcpy(&eep_config, &Default_3550_EEPROM_Config,
15455                         sizeof(ADVEEP_3550_CONFIG));
15456
15457                 /*
15458                  * Assume the 6 byte board serial number that was read from
15459                  * EEPROM is correct even if the EEPROM checksum failed.
15460                  */
15461                 eep_config.serial_number_word3 =
15462                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
15463
15464                 eep_config.serial_number_word2 =
15465                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
15466
15467                 eep_config.serial_number_word1 =
15468                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
15469
15470                 AdvSet3550EEPConfig(iop_base, &eep_config);
15471         }
15472         /*
15473          * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
15474          * EEPROM configuration that was read.
15475          *
15476          * This is the mapping of EEPROM fields to Adv Library fields.
15477          */
15478         asc_dvc->wdtr_able = eep_config.wdtr_able;
15479         asc_dvc->sdtr_able = eep_config.sdtr_able;
15480         asc_dvc->ultra_able = eep_config.ultra_able;
15481         asc_dvc->tagqng_able = eep_config.tagqng_able;
15482         asc_dvc->cfg->disc_enable = eep_config.disc_enable;
15483         asc_dvc->max_host_qng = eep_config.max_host_qng;
15484         asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15485         asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
15486         asc_dvc->start_motor = eep_config.start_motor;
15487         asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
15488         asc_dvc->bios_ctrl = eep_config.bios_ctrl;
15489         asc_dvc->no_scam = eep_config.scam_tolerant;
15490         asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
15491         asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
15492         asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
15493
15494         /*
15495          * Set the host maximum queuing (max. 253, min. 16) and the per device
15496          * maximum queuing (max. 63, min. 4).
15497          */
15498         if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
15499                 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15500         } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
15501                 /* If the value is zero, assume it is uninitialized. */
15502                 if (eep_config.max_host_qng == 0) {
15503                         eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15504                 } else {
15505                         eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
15506                 }
15507         }
15508
15509         if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
15510                 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15511         } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
15512                 /* If the value is zero, assume it is uninitialized. */
15513                 if (eep_config.max_dvc_qng == 0) {
15514                         eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15515                 } else {
15516                         eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
15517                 }
15518         }
15519
15520         /*
15521          * If 'max_dvc_qng' is greater than 'max_host_qng', then
15522          * set 'max_dvc_qng' to 'max_host_qng'.
15523          */
15524         if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
15525                 eep_config.max_dvc_qng = eep_config.max_host_qng;
15526         }
15527
15528         /*
15529          * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
15530          * values based on possibly adjusted EEPROM values.
15531          */
15532         asc_dvc->max_host_qng = eep_config.max_host_qng;
15533         asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15534
15535         /*
15536          * If the EEPROM 'termination' field is set to automatic (0), then set
15537          * the ADV_DVC_CFG 'termination' field to automatic also.
15538          *
15539          * If the termination is specified with a non-zero 'termination'
15540          * value check that a legal value is set and set the ADV_DVC_CFG
15541          * 'termination' field appropriately.
15542          */
15543         if (eep_config.termination == 0) {
15544                 asc_dvc->cfg->termination = 0;  /* auto termination */
15545         } else {
15546                 /* Enable manual control with low off / high off. */
15547                 if (eep_config.termination == 1) {
15548                         asc_dvc->cfg->termination = TERM_CTL_SEL;
15549
15550                         /* Enable manual control with low off / high on. */
15551                 } else if (eep_config.termination == 2) {
15552                         asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
15553
15554                         /* Enable manual control with low on / high on. */
15555                 } else if (eep_config.termination == 3) {
15556                         asc_dvc->cfg->termination =
15557                             TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
15558                 } else {
15559                         /*
15560                          * The EEPROM 'termination' field contains a bad value. Use
15561                          * automatic termination instead.
15562                          */
15563                         asc_dvc->cfg->termination = 0;
15564                         warn_code |= ASC_WARN_EEPROM_TERMINATION;
15565                 }
15566         }
15567
15568         return warn_code;
15569 }
15570
15571 /*
15572  * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
15573  * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
15574  * all of this is done.
15575  *
15576  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15577  *
15578  * For a non-fatal error return a warning code. If there are no warnings
15579  * then 0 is returned.
15580  *
15581  * Note: Chip is stopped on entry.
15582  */
15583 static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
15584 {
15585         AdvPortAddr iop_base;
15586         ushort warn_code;
15587         ADVEEP_38C0800_CONFIG eep_config;
15588         uchar tid, termination;
15589         ushort sdtr_speed = 0;
15590
15591         iop_base = asc_dvc->iop_base;
15592
15593         warn_code = 0;
15594
15595         /*
15596          * Read the board's EEPROM configuration.
15597          *
15598          * Set default values if a bad checksum is found.
15599          */
15600         if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
15601             eep_config.check_sum) {
15602                 warn_code |= ASC_WARN_EEPROM_CHKSUM;
15603
15604                 /*
15605                  * Set EEPROM default values.
15606                  */
15607                 memcpy(&eep_config, &Default_38C0800_EEPROM_Config,
15608                         sizeof(ADVEEP_38C0800_CONFIG));
15609
15610                 /*
15611                  * Assume the 6 byte board serial number that was read from
15612                  * EEPROM is correct even if the EEPROM checksum failed.
15613                  */
15614                 eep_config.serial_number_word3 =
15615                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
15616
15617                 eep_config.serial_number_word2 =
15618                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
15619
15620                 eep_config.serial_number_word1 =
15621                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
15622
15623                 AdvSet38C0800EEPConfig(iop_base, &eep_config);
15624         }
15625         /*
15626          * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
15627          * EEPROM configuration that was read.
15628          *
15629          * This is the mapping of EEPROM fields to Adv Library fields.
15630          */
15631         asc_dvc->wdtr_able = eep_config.wdtr_able;
15632         asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
15633         asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
15634         asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
15635         asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
15636         asc_dvc->tagqng_able = eep_config.tagqng_able;
15637         asc_dvc->cfg->disc_enable = eep_config.disc_enable;
15638         asc_dvc->max_host_qng = eep_config.max_host_qng;
15639         asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15640         asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
15641         asc_dvc->start_motor = eep_config.start_motor;
15642         asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
15643         asc_dvc->bios_ctrl = eep_config.bios_ctrl;
15644         asc_dvc->no_scam = eep_config.scam_tolerant;
15645         asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
15646         asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
15647         asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
15648
15649         /*
15650          * For every Target ID if any of its 'sdtr_speed[1234]' bits
15651          * are set, then set an 'sdtr_able' bit for it.
15652          */
15653         asc_dvc->sdtr_able = 0;
15654         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
15655                 if (tid == 0) {
15656                         sdtr_speed = asc_dvc->sdtr_speed1;
15657                 } else if (tid == 4) {
15658                         sdtr_speed = asc_dvc->sdtr_speed2;
15659                 } else if (tid == 8) {
15660                         sdtr_speed = asc_dvc->sdtr_speed3;
15661                 } else if (tid == 12) {
15662                         sdtr_speed = asc_dvc->sdtr_speed4;
15663                 }
15664                 if (sdtr_speed & ADV_MAX_TID) {
15665                         asc_dvc->sdtr_able |= (1 << tid);
15666                 }
15667                 sdtr_speed >>= 4;
15668         }
15669
15670         /*
15671          * Set the host maximum queuing (max. 253, min. 16) and the per device
15672          * maximum queuing (max. 63, min. 4).
15673          */
15674         if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
15675                 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15676         } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
15677                 /* If the value is zero, assume it is uninitialized. */
15678                 if (eep_config.max_host_qng == 0) {
15679                         eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15680                 } else {
15681                         eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
15682                 }
15683         }
15684
15685         if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
15686                 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15687         } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
15688                 /* If the value is zero, assume it is uninitialized. */
15689                 if (eep_config.max_dvc_qng == 0) {
15690                         eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15691                 } else {
15692                         eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
15693                 }
15694         }
15695
15696         /*
15697          * If 'max_dvc_qng' is greater than 'max_host_qng', then
15698          * set 'max_dvc_qng' to 'max_host_qng'.
15699          */
15700         if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
15701                 eep_config.max_dvc_qng = eep_config.max_host_qng;
15702         }
15703
15704         /*
15705          * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
15706          * values based on possibly adjusted EEPROM values.
15707          */
15708         asc_dvc->max_host_qng = eep_config.max_host_qng;
15709         asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15710
15711         /*
15712          * If the EEPROM 'termination' field is set to automatic (0), then set
15713          * the ADV_DVC_CFG 'termination' field to automatic also.
15714          *
15715          * If the termination is specified with a non-zero 'termination'
15716          * value check that a legal value is set and set the ADV_DVC_CFG
15717          * 'termination' field appropriately.
15718          */
15719         if (eep_config.termination_se == 0) {
15720                 termination = 0;        /* auto termination for SE */
15721         } else {
15722                 /* Enable manual control with low off / high off. */
15723                 if (eep_config.termination_se == 1) {
15724                         termination = 0;
15725
15726                         /* Enable manual control with low off / high on. */
15727                 } else if (eep_config.termination_se == 2) {
15728                         termination = TERM_SE_HI;
15729
15730                         /* Enable manual control with low on / high on. */
15731                 } else if (eep_config.termination_se == 3) {
15732                         termination = TERM_SE;
15733                 } else {
15734                         /*
15735                          * The EEPROM 'termination_se' field contains a bad value.
15736                          * Use automatic termination instead.
15737                          */
15738                         termination = 0;
15739                         warn_code |= ASC_WARN_EEPROM_TERMINATION;
15740                 }
15741         }
15742
15743         if (eep_config.termination_lvd == 0) {
15744                 asc_dvc->cfg->termination = termination;        /* auto termination for LVD */
15745         } else {
15746                 /* Enable manual control with low off / high off. */
15747                 if (eep_config.termination_lvd == 1) {
15748                         asc_dvc->cfg->termination = termination;
15749
15750                         /* Enable manual control with low off / high on. */
15751                 } else if (eep_config.termination_lvd == 2) {
15752                         asc_dvc->cfg->termination = termination | TERM_LVD_HI;
15753
15754                         /* Enable manual control with low on / high on. */
15755                 } else if (eep_config.termination_lvd == 3) {
15756                         asc_dvc->cfg->termination = termination | TERM_LVD;
15757                 } else {
15758                         /*
15759                          * The EEPROM 'termination_lvd' field contains a bad value.
15760                          * Use automatic termination instead.
15761                          */
15762                         asc_dvc->cfg->termination = termination;
15763                         warn_code |= ASC_WARN_EEPROM_TERMINATION;
15764                 }
15765         }
15766
15767         return warn_code;
15768 }
15769
15770 /*
15771  * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
15772  * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
15773  * all of this is done.
15774  *
15775  * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
15776  *
15777  * For a non-fatal error return a warning code. If there are no warnings
15778  * then 0 is returned.
15779  *
15780  * Note: Chip is stopped on entry.
15781  */
15782 static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
15783 {
15784         AdvPortAddr iop_base;
15785         ushort warn_code;
15786         ADVEEP_38C1600_CONFIG eep_config;
15787         uchar tid, termination;
15788         ushort sdtr_speed = 0;
15789
15790         iop_base = asc_dvc->iop_base;
15791
15792         warn_code = 0;
15793
15794         /*
15795          * Read the board's EEPROM configuration.
15796          *
15797          * Set default values if a bad checksum is found.
15798          */
15799         if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
15800             eep_config.check_sum) {
15801                 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
15802                 warn_code |= ASC_WARN_EEPROM_CHKSUM;
15803
15804                 /*
15805                  * Set EEPROM default values.
15806                  */
15807                 memcpy(&eep_config, &Default_38C1600_EEPROM_Config,
15808                         sizeof(ADVEEP_38C1600_CONFIG));
15809
15810                 if (PCI_FUNC(pdev->devfn) != 0) {
15811                         u8 ints;
15812                         /*
15813                          * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60
15814                          * and old Mac system booting problem. The Expansion
15815                          * ROM must be disabled in Function 1 for these systems
15816                          */
15817                         eep_config.cfg_lsw &= ~ADV_EEPROM_BIOS_ENABLE;
15818                         /*
15819                          * Clear the INTAB (bit 11) if the GPIO 0 input
15820                          * indicates the Function 1 interrupt line is wired
15821                          * to INTB.
15822                          *
15823                          * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
15824                          *   1 - Function 1 interrupt line wired to INT A.
15825                          *   0 - Function 1 interrupt line wired to INT B.
15826                          *
15827                          * Note: Function 0 is always wired to INTA.
15828                          * Put all 5 GPIO bits in input mode and then read
15829                          * their input values.
15830                          */
15831                         AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0);
15832                         ints = AdvReadByteRegister(iop_base, IOPB_GPIO_DATA);
15833                         if ((ints & 0x01) == 0)
15834                                 eep_config.cfg_lsw &= ~ADV_EEPROM_INTAB;
15835                 }
15836
15837                 /*
15838                  * Assume the 6 byte board serial number that was read from
15839                  * EEPROM is correct even if the EEPROM checksum failed.
15840                  */
15841                 eep_config.serial_number_word3 =
15842                         AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
15843                 eep_config.serial_number_word2 =
15844                         AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
15845                 eep_config.serial_number_word1 =
15846                         AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
15847
15848                 AdvSet38C1600EEPConfig(iop_base, &eep_config);
15849         }
15850
15851         /*
15852          * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
15853          * EEPROM configuration that was read.
15854          *
15855          * This is the mapping of EEPROM fields to Adv Library fields.
15856          */
15857         asc_dvc->wdtr_able = eep_config.wdtr_able;
15858         asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
15859         asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
15860         asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
15861         asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
15862         asc_dvc->ppr_able = 0;
15863         asc_dvc->tagqng_able = eep_config.tagqng_able;
15864         asc_dvc->cfg->disc_enable = eep_config.disc_enable;
15865         asc_dvc->max_host_qng = eep_config.max_host_qng;
15866         asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15867         asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
15868         asc_dvc->start_motor = eep_config.start_motor;
15869         asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
15870         asc_dvc->bios_ctrl = eep_config.bios_ctrl;
15871         asc_dvc->no_scam = eep_config.scam_tolerant;
15872
15873         /*
15874          * For every Target ID if any of its 'sdtr_speed[1234]' bits
15875          * are set, then set an 'sdtr_able' bit for it.
15876          */
15877         asc_dvc->sdtr_able = 0;
15878         for (tid = 0; tid <= ASC_MAX_TID; tid++) {
15879                 if (tid == 0) {
15880                         sdtr_speed = asc_dvc->sdtr_speed1;
15881                 } else if (tid == 4) {
15882                         sdtr_speed = asc_dvc->sdtr_speed2;
15883                 } else if (tid == 8) {
15884                         sdtr_speed = asc_dvc->sdtr_speed3;
15885                 } else if (tid == 12) {
15886                         sdtr_speed = asc_dvc->sdtr_speed4;
15887                 }
15888                 if (sdtr_speed & ASC_MAX_TID) {
15889                         asc_dvc->sdtr_able |= (1 << tid);
15890                 }
15891                 sdtr_speed >>= 4;
15892         }
15893
15894         /*
15895          * Set the host maximum queuing (max. 253, min. 16) and the per device
15896          * maximum queuing (max. 63, min. 4).
15897          */
15898         if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
15899                 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15900         } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
15901                 /* If the value is zero, assume it is uninitialized. */
15902                 if (eep_config.max_host_qng == 0) {
15903                         eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15904                 } else {
15905                         eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
15906                 }
15907         }
15908
15909         if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
15910                 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15911         } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
15912                 /* If the value is zero, assume it is uninitialized. */
15913                 if (eep_config.max_dvc_qng == 0) {
15914                         eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15915                 } else {
15916                         eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
15917                 }
15918         }
15919
15920         /*
15921          * If 'max_dvc_qng' is greater than 'max_host_qng', then
15922          * set 'max_dvc_qng' to 'max_host_qng'.
15923          */
15924         if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
15925                 eep_config.max_dvc_qng = eep_config.max_host_qng;
15926         }
15927
15928         /*
15929          * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
15930          * values based on possibly adjusted EEPROM values.
15931          */
15932         asc_dvc->max_host_qng = eep_config.max_host_qng;
15933         asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15934
15935         /*
15936          * If the EEPROM 'termination' field is set to automatic (0), then set
15937          * the ASC_DVC_CFG 'termination' field to automatic also.
15938          *
15939          * If the termination is specified with a non-zero 'termination'
15940          * value check that a legal value is set and set the ASC_DVC_CFG
15941          * 'termination' field appropriately.
15942          */
15943         if (eep_config.termination_se == 0) {
15944                 termination = 0;        /* auto termination for SE */
15945         } else {
15946                 /* Enable manual control with low off / high off. */
15947                 if (eep_config.termination_se == 1) {
15948                         termination = 0;
15949
15950                         /* Enable manual control with low off / high on. */
15951                 } else if (eep_config.termination_se == 2) {
15952                         termination = TERM_SE_HI;
15953
15954                         /* Enable manual control with low on / high on. */
15955                 } else if (eep_config.termination_se == 3) {
15956                         termination = TERM_SE;
15957                 } else {
15958                         /*
15959                          * The EEPROM 'termination_se' field contains a bad value.
15960                          * Use automatic termination instead.
15961                          */
15962                         termination = 0;
15963                         warn_code |= ASC_WARN_EEPROM_TERMINATION;
15964                 }
15965         }
15966
15967         if (eep_config.termination_lvd == 0) {
15968                 asc_dvc->cfg->termination = termination;        /* auto termination for LVD */
15969         } else {
15970                 /* Enable manual control with low off / high off. */
15971                 if (eep_config.termination_lvd == 1) {
15972                         asc_dvc->cfg->termination = termination;
15973
15974                         /* Enable manual control with low off / high on. */
15975                 } else if (eep_config.termination_lvd == 2) {
15976                         asc_dvc->cfg->termination = termination | TERM_LVD_HI;
15977
15978                         /* Enable manual control with low on / high on. */
15979                 } else if (eep_config.termination_lvd == 3) {
15980                         asc_dvc->cfg->termination = termination | TERM_LVD;
15981                 } else {
15982                         /*
15983                          * The EEPROM 'termination_lvd' field contains a bad value.
15984                          * Use automatic termination instead.
15985                          */
15986                         asc_dvc->cfg->termination = termination;
15987                         warn_code |= ASC_WARN_EEPROM_TERMINATION;
15988                 }
15989         }
15990
15991         return warn_code;
15992 }
15993
15994 /*
15995  * Read EEPROM configuration into the specified buffer.
15996  *
15997  * Return a checksum based on the EEPROM configuration read.
15998  */
15999 static ushort __devinit
16000 AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
16001 {
16002         ushort wval, chksum;
16003         ushort *wbuf;
16004         int eep_addr;
16005         ushort *charfields;
16006
16007         charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
16008         wbuf = (ushort *)cfg_buf;
16009         chksum = 0;
16010
16011         for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16012              eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16013                 wval = AdvReadEEPWord(iop_base, eep_addr);
16014                 chksum += wval; /* Checksum is calculated from word values. */
16015                 if (*charfields++) {
16016                         *wbuf = le16_to_cpu(wval);
16017                 } else {
16018                         *wbuf = wval;
16019                 }
16020         }
16021         /* Read checksum word. */
16022         *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16023         wbuf++;
16024         charfields++;
16025
16026         /* Read rest of EEPROM not covered by the checksum. */
16027         for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16028              eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16029                 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16030                 if (*charfields++) {
16031                         *wbuf = le16_to_cpu(*wbuf);
16032                 }
16033         }
16034         return chksum;
16035 }
16036
16037 /*
16038  * Read EEPROM configuration into the specified buffer.
16039  *
16040  * Return a checksum based on the EEPROM configuration read.
16041  */
16042 static ushort __devinit
16043 AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
16044 {
16045         ushort wval, chksum;
16046         ushort *wbuf;
16047         int eep_addr;
16048         ushort *charfields;
16049
16050         charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
16051         wbuf = (ushort *)cfg_buf;
16052         chksum = 0;
16053
16054         for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16055              eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16056                 wval = AdvReadEEPWord(iop_base, eep_addr);
16057                 chksum += wval; /* Checksum is calculated from word values. */
16058                 if (*charfields++) {
16059                         *wbuf = le16_to_cpu(wval);
16060                 } else {
16061                         *wbuf = wval;
16062                 }
16063         }
16064         /* Read checksum word. */
16065         *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16066         wbuf++;
16067         charfields++;
16068
16069         /* Read rest of EEPROM not covered by the checksum. */
16070         for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16071              eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16072                 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16073                 if (*charfields++) {
16074                         *wbuf = le16_to_cpu(*wbuf);
16075                 }
16076         }
16077         return chksum;
16078 }
16079
16080 /*
16081  * Read EEPROM configuration into the specified buffer.
16082  *
16083  * Return a checksum based on the EEPROM configuration read.
16084  */
16085 static ushort __devinit
16086 AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
16087 {
16088         ushort wval, chksum;
16089         ushort *wbuf;
16090         int eep_addr;
16091         ushort *charfields;
16092
16093         charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
16094         wbuf = (ushort *)cfg_buf;
16095         chksum = 0;
16096
16097         for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16098              eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16099                 wval = AdvReadEEPWord(iop_base, eep_addr);
16100                 chksum += wval; /* Checksum is calculated from word values. */
16101                 if (*charfields++) {
16102                         *wbuf = le16_to_cpu(wval);
16103                 } else {
16104                         *wbuf = wval;
16105                 }
16106         }
16107         /* Read checksum word. */
16108         *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16109         wbuf++;
16110         charfields++;
16111
16112         /* Read rest of EEPROM not covered by the checksum. */
16113         for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16114              eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16115                 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16116                 if (*charfields++) {
16117                         *wbuf = le16_to_cpu(*wbuf);
16118                 }
16119         }
16120         return chksum;
16121 }
16122
16123 /*
16124  * Read the EEPROM from specified location
16125  */
16126 static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
16127 {
16128         AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16129                              ASC_EEP_CMD_READ | eep_word_addr);
16130         AdvWaitEEPCmd(iop_base);
16131         return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
16132 }
16133
16134 /*
16135  * Wait for EEPROM command to complete
16136  */
16137 static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base)
16138 {
16139         int eep_delay_ms;
16140
16141         for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
16142                 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
16143                     ASC_EEP_CMD_DONE) {
16144                         break;
16145                 }
16146                 DvcSleepMilliSecond(1);
16147         }
16148         if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
16149             0) {
16150                 ASC_ASSERT(0);
16151         }
16152         return;
16153 }
16154
16155 /*
16156  * Write the EEPROM from 'cfg_buf'.
16157  */
16158 void __devinit
16159 AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
16160 {
16161         ushort *wbuf;
16162         ushort addr, chksum;
16163         ushort *charfields;
16164
16165         wbuf = (ushort *)cfg_buf;
16166         charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
16167         chksum = 0;
16168
16169         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16170         AdvWaitEEPCmd(iop_base);
16171
16172         /*
16173          * Write EEPROM from word 0 to word 20.
16174          */
16175         for (addr = ADV_EEP_DVC_CFG_BEGIN;
16176              addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16177                 ushort word;
16178
16179                 if (*charfields++) {
16180                         word = cpu_to_le16(*wbuf);
16181                 } else {
16182                         word = *wbuf;
16183                 }
16184                 chksum += *wbuf;        /* Checksum is calculated from word values. */
16185                 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16186                 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16187                                      ASC_EEP_CMD_WRITE | addr);
16188                 AdvWaitEEPCmd(iop_base);
16189                 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16190         }
16191
16192         /*
16193          * Write EEPROM checksum at word 21.
16194          */
16195         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16196         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16197         AdvWaitEEPCmd(iop_base);
16198         wbuf++;
16199         charfields++;
16200
16201         /*
16202          * Write EEPROM OEM name at words 22 to 29.
16203          */
16204         for (addr = ADV_EEP_DVC_CTL_BEGIN;
16205              addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16206                 ushort word;
16207
16208                 if (*charfields++) {
16209                         word = cpu_to_le16(*wbuf);
16210                 } else {
16211                         word = *wbuf;
16212                 }
16213                 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16214                 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16215                                      ASC_EEP_CMD_WRITE | addr);
16216                 AdvWaitEEPCmd(iop_base);
16217         }
16218         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16219         AdvWaitEEPCmd(iop_base);
16220         return;
16221 }
16222
16223 /*
16224  * Write the EEPROM from 'cfg_buf'.
16225  */
16226 void __devinit
16227 AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
16228 {
16229         ushort *wbuf;
16230         ushort *charfields;
16231         ushort addr, chksum;
16232
16233         wbuf = (ushort *)cfg_buf;
16234         charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
16235         chksum = 0;
16236
16237         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16238         AdvWaitEEPCmd(iop_base);
16239
16240         /*
16241          * Write EEPROM from word 0 to word 20.
16242          */
16243         for (addr = ADV_EEP_DVC_CFG_BEGIN;
16244              addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16245                 ushort word;
16246
16247                 if (*charfields++) {
16248                         word = cpu_to_le16(*wbuf);
16249                 } else {
16250                         word = *wbuf;
16251                 }
16252                 chksum += *wbuf;        /* Checksum is calculated from word values. */
16253                 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16254                 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16255                                      ASC_EEP_CMD_WRITE | addr);
16256                 AdvWaitEEPCmd(iop_base);
16257                 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16258         }
16259
16260         /*
16261          * Write EEPROM checksum at word 21.
16262          */
16263         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16264         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16265         AdvWaitEEPCmd(iop_base);
16266         wbuf++;
16267         charfields++;
16268
16269         /*
16270          * Write EEPROM OEM name at words 22 to 29.
16271          */
16272         for (addr = ADV_EEP_DVC_CTL_BEGIN;
16273              addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16274                 ushort word;
16275
16276                 if (*charfields++) {
16277                         word = cpu_to_le16(*wbuf);
16278                 } else {
16279                         word = *wbuf;
16280                 }
16281                 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16282                 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16283                                      ASC_EEP_CMD_WRITE | addr);
16284                 AdvWaitEEPCmd(iop_base);
16285         }
16286         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16287         AdvWaitEEPCmd(iop_base);
16288         return;
16289 }
16290
16291 /*
16292  * Write the EEPROM from 'cfg_buf'.
16293  */
16294 void __devinit
16295 AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
16296 {
16297         ushort *wbuf;
16298         ushort *charfields;
16299         ushort addr, chksum;
16300
16301         wbuf = (ushort *)cfg_buf;
16302         charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
16303         chksum = 0;
16304
16305         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16306         AdvWaitEEPCmd(iop_base);
16307
16308         /*
16309          * Write EEPROM from word 0 to word 20.
16310          */
16311         for (addr = ADV_EEP_DVC_CFG_BEGIN;
16312              addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16313                 ushort word;
16314
16315                 if (*charfields++) {
16316                         word = cpu_to_le16(*wbuf);
16317                 } else {
16318                         word = *wbuf;
16319                 }
16320                 chksum += *wbuf;        /* Checksum is calculated from word values. */
16321                 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16322                 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16323                                      ASC_EEP_CMD_WRITE | addr);
16324                 AdvWaitEEPCmd(iop_base);
16325                 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16326         }
16327
16328         /*
16329          * Write EEPROM checksum at word 21.
16330          */
16331         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16332         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16333         AdvWaitEEPCmd(iop_base);
16334         wbuf++;
16335         charfields++;
16336
16337         /*
16338          * Write EEPROM OEM name at words 22 to 29.
16339          */
16340         for (addr = ADV_EEP_DVC_CTL_BEGIN;
16341              addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16342                 ushort word;
16343
16344                 if (*charfields++) {
16345                         word = cpu_to_le16(*wbuf);
16346                 } else {
16347                         word = *wbuf;
16348                 }
16349                 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16350                 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16351                                      ASC_EEP_CMD_WRITE | addr);
16352                 AdvWaitEEPCmd(iop_base);
16353         }
16354         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16355         AdvWaitEEPCmd(iop_base);
16356         return;
16357 }
16358
16359 /* a_advlib.c */
16360 /*
16361  * AdvExeScsiQueue() - Send a request to the RISC microcode program.
16362  *
16363  *   Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
16364  *   add the carrier to the ICQ (Initiator Command Queue), and tickle the
16365  *   RISC to notify it a new command is ready to be executed.
16366  *
16367  * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
16368  * set to SCSI_MAX_RETRY.
16369  *
16370  * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
16371  * for DMA addresses or math operations are byte swapped to little-endian
16372  * order.
16373  *
16374  * Return:
16375  *      ADV_SUCCESS(1) - The request was successfully queued.
16376  *      ADV_BUSY(0) -    Resource unavailable; Retry again after pending
16377  *                       request completes.
16378  *      ADV_ERROR(-1) -  Invalid ADV_SCSI_REQ_Q request structure
16379  *                       host IC error.
16380  */
16381 static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
16382 {
16383         ulong last_int_level;
16384         AdvPortAddr iop_base;
16385         ADV_DCNT req_size;
16386         ADV_PADDR req_paddr;
16387         ADV_CARR_T *new_carrp;
16388
16389         ASC_ASSERT(scsiq != NULL);      /* 'scsiq' should never be NULL. */
16390
16391         /*
16392          * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
16393          */
16394         if (scsiq->target_id > ADV_MAX_TID) {
16395                 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
16396                 scsiq->done_status = QD_WITH_ERROR;
16397                 return ADV_ERROR;
16398         }
16399
16400         iop_base = asc_dvc->iop_base;
16401
16402         last_int_level = DvcEnterCritical();
16403
16404         /*
16405          * Allocate a carrier ensuring at least one carrier always
16406          * remains on the freelist and initialize fields.
16407          */
16408         if ((new_carrp = asc_dvc->carr_freelist) == NULL) {
16409                 DvcLeaveCritical(last_int_level);
16410                 return ADV_BUSY;
16411         }
16412         asc_dvc->carr_freelist = (ADV_CARR_T *)
16413             ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
16414         asc_dvc->carr_pending_cnt++;
16415
16416         /*
16417          * Set the carrier to be a stopper by setting 'next_vpa'
16418          * to the stopper value. The current stopper will be changed
16419          * below to point to the new stopper.
16420          */
16421         new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16422
16423         /*
16424          * Clear the ADV_SCSI_REQ_Q done flag.
16425          */
16426         scsiq->a_flag &= ~ADV_SCSIQ_DONE;
16427
16428         req_size = sizeof(ADV_SCSI_REQ_Q);
16429         req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq,
16430                                   (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG);
16431
16432         ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr);
16433         ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
16434
16435         /* Wait for assertion before making little-endian */
16436         req_paddr = cpu_to_le32(req_paddr);
16437
16438         /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
16439         scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
16440         scsiq->scsiq_rptr = req_paddr;
16441
16442         scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
16443         /*
16444          * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
16445          * order during initialization.
16446          */
16447         scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
16448
16449         /*
16450          * Use the current stopper to send the ADV_SCSI_REQ_Q command to
16451          * the microcode. The newly allocated stopper will become the new
16452          * stopper.
16453          */
16454         asc_dvc->icq_sp->areq_vpa = req_paddr;
16455
16456         /*
16457          * Set the 'next_vpa' pointer for the old stopper to be the
16458          * physical address of the new stopper. The RISC can only
16459          * follow physical addresses.
16460          */
16461         asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
16462
16463         /*
16464          * Set the host adapter stopper pointer to point to the new carrier.
16465          */
16466         asc_dvc->icq_sp = new_carrp;
16467
16468         if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
16469             asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
16470                 /*
16471                  * Tickle the RISC to tell it to read its Command Queue Head pointer.
16472                  */
16473                 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
16474                 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
16475                         /*
16476                          * Clear the tickle value. In the ASC-3550 the RISC flag
16477                          * command 'clr_tickle_a' does not work unless the host
16478                          * value is cleared.
16479                          */
16480                         AdvWriteByteRegister(iop_base, IOPB_TICKLE,
16481                                              ADV_TICKLE_NOP);
16482                 }
16483         } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16484                 /*
16485                  * Notify the RISC a carrier is ready by writing the physical
16486                  * address of the new carrier stopper to the COMMA register.
16487                  */
16488                 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
16489                                       le32_to_cpu(new_carrp->carr_pa));
16490         }
16491
16492         DvcLeaveCritical(last_int_level);
16493
16494         return ADV_SUCCESS;
16495 }
16496
16497 /*
16498  * Reset SCSI Bus and purge all outstanding requests.
16499  *
16500  * Return Value:
16501  *      ADV_TRUE(1) -   All requests are purged and SCSI Bus is reset.
16502  *      ADV_FALSE(0) -  Microcode command failed.
16503  *      ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
16504  *                      may be hung which requires driver recovery.
16505  */
16506 static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
16507 {
16508         int status;
16509
16510         /*
16511          * Send the SCSI Bus Reset idle start idle command which asserts
16512          * the SCSI Bus Reset signal.
16513          */
16514         status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
16515         if (status != ADV_TRUE) {
16516                 return status;
16517         }
16518
16519         /*
16520          * Delay for the specified SCSI Bus Reset hold time.
16521          *
16522          * The hold time delay is done on the host because the RISC has no
16523          * microsecond accurate timer.
16524          */
16525         DvcDelayMicroSecond(asc_dvc, (ushort)ASC_SCSI_RESET_HOLD_TIME_US);
16526
16527         /*
16528          * Send the SCSI Bus Reset end idle command which de-asserts
16529          * the SCSI Bus Reset signal and purges any pending requests.
16530          */
16531         status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
16532         if (status != ADV_TRUE) {
16533                 return status;
16534         }
16535
16536         DvcSleepMilliSecond((ADV_DCNT)asc_dvc->scsi_reset_wait * 1000);
16537
16538         return status;
16539 }
16540
16541 /*
16542  * Reset chip and SCSI Bus.
16543  *
16544  * Return Value:
16545  *      ADV_TRUE(1) -   Chip re-initialization and SCSI Bus Reset successful.
16546  *      ADV_FALSE(0) -  Chip re-initialization and SCSI Bus Reset failure.
16547  */
16548 static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
16549 {
16550         int status;
16551         ushort wdtr_able, sdtr_able, tagqng_able;
16552         ushort ppr_able = 0;
16553         uchar tid, max_cmd[ADV_MAX_TID + 1];
16554         AdvPortAddr iop_base;
16555         ushort bios_sig;
16556
16557         iop_base = asc_dvc->iop_base;
16558
16559         /*
16560          * Save current per TID negotiated values.
16561          */
16562         AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16563         AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16564         if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16565                 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16566         }
16567         AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16568         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
16569                 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16570                                 max_cmd[tid]);
16571         }
16572
16573         /*
16574          * Force the AdvInitAsc3550/38C0800Driver() function to
16575          * perform a SCSI Bus Reset by clearing the BIOS signature word.
16576          * The initialization functions assumes a SCSI Bus Reset is not
16577          * needed if the BIOS signature word is present.
16578          */
16579         AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
16580         AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
16581
16582         /*
16583          * Stop chip and reset it.
16584          */
16585         AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
16586         AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
16587         DvcSleepMilliSecond(100);
16588         AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
16589                              ADV_CTRL_REG_CMD_WR_IO_REG);
16590
16591         /*
16592          * Reset Adv Library error code, if any, and try
16593          * re-initializing the chip.
16594          */
16595         asc_dvc->err_code = 0;
16596         if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16597                 status = AdvInitAsc38C1600Driver(asc_dvc);
16598         } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
16599                 status = AdvInitAsc38C0800Driver(asc_dvc);
16600         } else {
16601                 status = AdvInitAsc3550Driver(asc_dvc);
16602         }
16603
16604         /* Translate initialization return value to status value. */
16605         if (status == 0) {
16606                 status = ADV_TRUE;
16607         } else {
16608                 status = ADV_FALSE;
16609         }
16610
16611         /*
16612          * Restore the BIOS signature word.
16613          */
16614         AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
16615
16616         /*
16617          * Restore per TID negotiated values.
16618          */
16619         AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16620         AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16621         if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16622                 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16623         }
16624         AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16625         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
16626                 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16627                                  max_cmd[tid]);
16628         }
16629
16630         return status;
16631 }
16632
16633 /*
16634  * Adv Library Interrupt Service Routine
16635  *
16636  *  This function is called by a driver's interrupt service routine.
16637  *  The function disables and re-enables interrupts.
16638  *
16639  *  When a microcode idle command is completed, the ADV_DVC_VAR
16640  *  'idle_cmd_done' field is set to ADV_TRUE.
16641  *
16642  *  Note: AdvISR() can be called when interrupts are disabled or even
16643  *  when there is no hardware interrupt condition present. It will
16644  *  always check for completed idle commands and microcode requests.
16645  *  This is an important feature that shouldn't be changed because it
16646  *  allows commands to be completed from polling mode loops.
16647  *
16648  * Return:
16649  *   ADV_TRUE(1) - interrupt was pending
16650  *   ADV_FALSE(0) - no interrupt was pending
16651  */
16652 static int AdvISR(ADV_DVC_VAR *asc_dvc)
16653 {
16654         AdvPortAddr iop_base;
16655         uchar int_stat;
16656         ushort target_bit;
16657         ADV_CARR_T *free_carrp;
16658         ADV_VADDR irq_next_vpa;
16659         int flags;
16660         ADV_SCSI_REQ_Q *scsiq;
16661
16662         flags = DvcEnterCritical();
16663
16664         iop_base = asc_dvc->iop_base;
16665
16666         /* Reading the register clears the interrupt. */
16667         int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
16668
16669         if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
16670                          ADV_INTR_STATUS_INTRC)) == 0) {
16671                 DvcLeaveCritical(flags);
16672                 return ADV_FALSE;
16673         }
16674
16675         /*
16676          * Notify the driver of an asynchronous microcode condition by
16677          * calling the adv_async_callback function. The function
16678          * is passed the microcode ASC_MC_INTRB_CODE byte value.
16679          */
16680         if (int_stat & ADV_INTR_STATUS_INTRB) {
16681                 uchar intrb_code;
16682
16683                 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
16684
16685                 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
16686                     asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
16687                         if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
16688                             asc_dvc->carr_pending_cnt != 0) {
16689                                 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
16690                                                      ADV_TICKLE_A);
16691                                 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
16692                                         AdvWriteByteRegister(iop_base,
16693                                                              IOPB_TICKLE,
16694                                                              ADV_TICKLE_NOP);
16695                                 }
16696                         }
16697                 }
16698
16699                 adv_async_callback(asc_dvc, intrb_code);
16700         }
16701
16702         /*
16703          * Check if the IRQ stopper carrier contains a completed request.
16704          */
16705         while (((irq_next_vpa =
16706                  le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) {
16707                 /*
16708                  * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
16709                  * The RISC will have set 'areq_vpa' to a virtual address.
16710                  *
16711                  * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
16712                  * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
16713                  * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
16714                  * in AdvExeScsiQueue().
16715                  */
16716                 scsiq = (ADV_SCSI_REQ_Q *)
16717                     ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
16718
16719                 /*
16720                  * Request finished with good status and the queue was not
16721                  * DMAed to host memory by the firmware. Set all status fields
16722                  * to indicate good status.
16723                  */
16724                 if ((irq_next_vpa & ASC_RQ_GOOD) != 0) {
16725                         scsiq->done_status = QD_NO_ERROR;
16726                         scsiq->host_status = scsiq->scsi_status = 0;
16727                         scsiq->data_cnt = 0L;
16728                 }
16729
16730                 /*
16731                  * Advance the stopper pointer to the next carrier
16732                  * ignoring the lower four bits. Free the previous
16733                  * stopper carrier.
16734                  */
16735                 free_carrp = asc_dvc->irq_sp;
16736                 asc_dvc->irq_sp = (ADV_CARR_T *)
16737                     ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
16738
16739                 free_carrp->next_vpa =
16740                     cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
16741                 asc_dvc->carr_freelist = free_carrp;
16742                 asc_dvc->carr_pending_cnt--;
16743
16744                 ASC_ASSERT(scsiq != NULL);
16745                 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
16746
16747                 /*
16748                  * Clear request microcode control flag.
16749                  */
16750                 scsiq->cntl = 0;
16751
16752                 /*
16753                  * Notify the driver of the completed request by passing
16754                  * the ADV_SCSI_REQ_Q pointer to its callback function.
16755                  */
16756                 scsiq->a_flag |= ADV_SCSIQ_DONE;
16757                 adv_isr_callback(asc_dvc, scsiq);
16758                 /*
16759                  * Note: After the driver callback function is called, 'scsiq'
16760                  * can no longer be referenced.
16761                  *
16762                  * Fall through and continue processing other completed
16763                  * requests...
16764                  */
16765
16766                 /*
16767                  * Disable interrupts again in case the driver inadvertently
16768                  * enabled interrupts in its callback function.
16769                  *
16770                  * The DvcEnterCritical() return value is ignored, because
16771                  * the 'flags' saved when AdvISR() was first entered will be
16772                  * used to restore the interrupt flag on exit.
16773                  */
16774                 (void)DvcEnterCritical();
16775         }
16776         DvcLeaveCritical(flags);
16777         return ADV_TRUE;
16778 }
16779
16780 /*
16781  * Send an idle command to the chip and wait for completion.
16782  *
16783  * Command completion is polled for once per microsecond.
16784  *
16785  * The function can be called from anywhere including an interrupt handler.
16786  * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
16787  * functions to prevent reentrancy.
16788  *
16789  * Return Values:
16790  *   ADV_TRUE - command completed successfully
16791  *   ADV_FALSE - command failed
16792  *   ADV_ERROR - command timed out
16793  */
16794 static int
16795 AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
16796                ushort idle_cmd, ADV_DCNT idle_cmd_parameter)
16797 {
16798         ulong last_int_level;
16799         int result;
16800         ADV_DCNT i, j;
16801         AdvPortAddr iop_base;
16802
16803         last_int_level = DvcEnterCritical();
16804
16805         iop_base = asc_dvc->iop_base;
16806
16807         /*
16808          * Clear the idle command status which is set by the microcode
16809          * to a non-zero value to indicate when the command is completed.
16810          * The non-zero result is one of the IDLE_CMD_STATUS_* values
16811          * defined in a_advlib.h.
16812          */
16813         AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
16814
16815         /*
16816          * Write the idle command value after the idle command parameter
16817          * has been written to avoid a race condition. If the order is not
16818          * followed, the microcode may process the idle command before the
16819          * parameters have been written to LRAM.
16820          */
16821         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
16822                                 cpu_to_le32(idle_cmd_parameter));
16823         AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
16824
16825         /*
16826          * Tickle the RISC to tell it to process the idle command.
16827          */
16828         AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
16829         if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
16830                 /*
16831                  * Clear the tickle value. In the ASC-3550 the RISC flag
16832                  * command 'clr_tickle_b' does not work unless the host
16833                  * value is cleared.
16834                  */
16835                 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
16836         }
16837
16838         /* Wait for up to 100 millisecond for the idle command to timeout. */
16839         for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
16840                 /* Poll once each microsecond for command completion. */
16841                 for (j = 0; j < SCSI_US_PER_MSEC; j++) {
16842                         AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
16843                                         result);
16844                         if (result != 0) {
16845                                 DvcLeaveCritical(last_int_level);
16846                                 return result;
16847                         }
16848                         DvcDelayMicroSecond(asc_dvc, (ushort)1);
16849                 }
16850         }
16851
16852         ASC_ASSERT(0);          /* The idle command should never timeout. */
16853         DvcLeaveCritical(last_int_level);
16854         return ADV_ERROR;
16855 }
16856
16857 static int __devinit
16858 advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp)
16859 {
16860         int req_cnt = 0;
16861         adv_req_t *reqp = NULL;
16862         int sg_cnt = 0;
16863         adv_sgblk_t *sgp;
16864         int warn_code, err_code;
16865
16866         /*
16867          * Allocate buffer carrier structures. The total size
16868          * is about 4 KB, so allocate all at once.
16869          */
16870         boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
16871         ASC_DBG1(1, "advansys_wide_init_chip: carrp 0x%p\n", boardp->carrp);
16872
16873         if (!boardp->carrp)
16874                 goto kmalloc_failed;
16875
16876         /*
16877          * Allocate up to 'max_host_qng' request structures for the Wide
16878          * board. The total size is about 16 KB, so allocate all at once.
16879          * If the allocation fails decrement and try again.
16880          */
16881         for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) {
16882                 reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL);
16883
16884                 ASC_DBG3(1, "advansys_wide_init_chip: reqp 0x%p, req_cnt %d, "
16885                          "bytes %lu\n", reqp, req_cnt,
16886                          (ulong)sizeof(adv_req_t) * req_cnt);
16887
16888                 if (reqp)
16889                         break;
16890         }
16891
16892         if (!reqp)
16893                 goto kmalloc_failed;
16894
16895         boardp->orig_reqp = reqp;
16896
16897         /*
16898          * Allocate up to ADV_TOT_SG_BLOCK request structures for
16899          * the Wide board. Each structure is about 136 bytes.
16900          */
16901         boardp->adv_sgblkp = NULL;
16902         for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
16903                 sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
16904
16905                 if (!sgp)
16906                         break;
16907
16908                 sgp->next_sgblkp = boardp->adv_sgblkp;
16909                 boardp->adv_sgblkp = sgp;
16910
16911         }
16912
16913         ASC_DBG3(1, "advansys_wide_init_chip: sg_cnt %d * %u = %u bytes\n",
16914                  sg_cnt, sizeof(adv_sgblk_t),
16915                  (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
16916
16917         if (!boardp->adv_sgblkp)
16918                 goto kmalloc_failed;
16919
16920         adv_dvc_varp->carrier_buf = boardp->carrp;
16921
16922         /*
16923          * Point 'adv_reqp' to the request structures and
16924          * link them together.
16925          */
16926         req_cnt--;
16927         reqp[req_cnt].next_reqp = NULL;
16928         for (; req_cnt > 0; req_cnt--) {
16929                 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
16930         }
16931         boardp->adv_reqp = &reqp[0];
16932
16933         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
16934                 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc3550Driver()\n");
16935                 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
16936         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
16937                 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C0800Driver()"
16938                            "\n");
16939                 warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
16940         } else {
16941                 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C1600Driver()"
16942                            "\n");
16943                 warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
16944         }
16945         err_code = adv_dvc_varp->err_code;
16946
16947         if (warn_code || err_code) {
16948                 ASC_PRINT3("advansys_wide_init_chip: board %d error: warn 0x%x,"
16949                            " error 0x%x\n", boardp->id, warn_code, err_code);
16950         }
16951
16952         goto exit;
16953
16954  kmalloc_failed:
16955         ASC_PRINT1("advansys_wide_init_chip: board %d error: kmalloc() "
16956                    "failed\n", boardp->id);
16957         err_code = ADV_ERROR;
16958  exit:
16959         return err_code;
16960 }
16961
16962 static void advansys_wide_free_mem(asc_board_t *boardp)
16963 {
16964         kfree(boardp->carrp);
16965         boardp->carrp = NULL;
16966         kfree(boardp->orig_reqp);
16967         boardp->orig_reqp = boardp->adv_reqp = NULL;
16968         while (boardp->adv_sgblkp) {
16969                 adv_sgblk_t *sgp = boardp->adv_sgblkp;
16970                 boardp->adv_sgblkp = sgp->next_sgblkp;
16971                 kfree(sgp);
16972         }
16973 }
16974
16975 static struct Scsi_Host *__devinit
16976 advansys_board_found(int iop, struct device *dev, int bus_type)
16977 {
16978         struct Scsi_Host *shost;
16979         struct pci_dev *pdev = bus_type == ASC_IS_PCI ? to_pci_dev(dev) : NULL;
16980         asc_board_t *boardp;
16981         ASC_DVC_VAR *asc_dvc_varp = NULL;
16982         ADV_DVC_VAR *adv_dvc_varp = NULL;
16983         int share_irq;
16984         int warn_code, err_code;
16985         int ret;
16986
16987         /*
16988          * Register the adapter, get its configuration, and
16989          * initialize it.
16990          */
16991         ASC_DBG(2, "advansys_board_found: scsi_host_alloc()\n");
16992         shost = scsi_host_alloc(&advansys_template, sizeof(asc_board_t));
16993         if (!shost)
16994                 return NULL;
16995
16996         /* Initialize private per board data */
16997         boardp = ASC_BOARDP(shost);
16998         memset(boardp, 0, sizeof(asc_board_t));
16999         boardp->id = asc_board_count++;
17000         spin_lock_init(&boardp->lock);
17001         boardp->dev = dev;
17002
17003         /*
17004          * Handle both narrow and wide boards.
17005          *
17006          * If a Wide board was detected, set the board structure
17007          * wide board flag. Set-up the board structure based on
17008          * the board type.
17009          */
17010 #ifdef CONFIG_PCI
17011         if (bus_type == ASC_IS_PCI &&
17012             (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
17013              pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
17014              pdev->device == PCI_DEVICE_ID_38C1600_REV1)) {
17015                 boardp->flags |= ASC_IS_WIDE_BOARD;
17016         }
17017 #endif /* CONFIG_PCI */
17018
17019         if (ASC_NARROW_BOARD(boardp)) {
17020                 ASC_DBG(1, "advansys_board_found: narrow board\n");
17021                 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
17022                 asc_dvc_varp->bus_type = bus_type;
17023                 asc_dvc_varp->drv_ptr = boardp;
17024                 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
17025                 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
17026                 asc_dvc_varp->iop_base = iop;
17027         } else {
17028 #ifdef CONFIG_PCI
17029                 ASC_DBG(1, "advansys_board_found: wide board\n");
17030                 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
17031                 adv_dvc_varp->drv_ptr = boardp;
17032                 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
17033                 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
17034                         ASC_DBG(1, "advansys_board_found: ASC-3550\n");
17035                         adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
17036                 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
17037                         ASC_DBG(1, "advansys_board_found: ASC-38C0800\n");
17038                         adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
17039                 } else {
17040                         ASC_DBG(1, "advansys_board_found: ASC-38C1600\n");
17041                         adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
17042                 }
17043
17044                 boardp->asc_n_io_port = pci_resource_len(pdev, 1);
17045                 boardp->ioremap_addr = ioremap(pci_resource_start(pdev, 1),
17046                                                boardp->asc_n_io_port);
17047                 if (!boardp->ioremap_addr) {
17048                         ASC_PRINT3
17049                             ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n",
17050                              boardp->id, pci_resource_start(pdev, 1),
17051                              boardp->asc_n_io_port);
17052                         goto err_shost;
17053                 }
17054                 adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr
17055                 ASC_DBG1(1, "advansys_board_found: iop_base: 0x%lx\n",
17056                          adv_dvc_varp->iop_base);
17057
17058                 /*
17059                  * Even though it isn't used to access wide boards, other
17060                  * than for the debug line below, save I/O Port address so
17061                  * that it can be reported.
17062                  */
17063                 boardp->ioport = iop;
17064
17065                 ASC_DBG2(1, "advansys_board_found: iopb_chip_id_1 0x%x, "
17066                          "iopw_chip_id_0 0x%x\n", (ushort)inp(iop + 1),
17067                          (ushort)inpw(iop));
17068 #endif /* CONFIG_PCI */
17069         }
17070
17071 #ifdef CONFIG_PROC_FS
17072         /*
17073          * Allocate buffer for printing information from
17074          * /proc/scsi/advansys/[0...].
17075          */
17076         boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
17077         if (!boardp->prtbuf) {
17078                 ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) "
17079                            "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE);
17080                 goto err_unmap;
17081         }
17082 #endif /* CONFIG_PROC_FS */
17083
17084         if (ASC_NARROW_BOARD(boardp)) {
17085                 /*
17086                  * Set the board bus type and PCI IRQ before
17087                  * calling AscInitGetConfig().
17088                  */
17089                 switch (asc_dvc_varp->bus_type) {
17090 #ifdef CONFIG_ISA
17091                 case ASC_IS_ISA:
17092                         shost->unchecked_isa_dma = TRUE;
17093                         share_irq = 0;
17094                         break;
17095                 case ASC_IS_VL:
17096                         shost->unchecked_isa_dma = FALSE;
17097                         share_irq = 0;
17098                         break;
17099                 case ASC_IS_EISA:
17100                         shost->unchecked_isa_dma = FALSE;
17101                         share_irq = IRQF_SHARED;
17102                         break;
17103 #endif /* CONFIG_ISA */
17104 #ifdef CONFIG_PCI
17105                 case ASC_IS_PCI:
17106                         shost->irq = asc_dvc_varp->irq_no = pdev->irq;
17107                         shost->unchecked_isa_dma = FALSE;
17108                         share_irq = IRQF_SHARED;
17109                         break;
17110 #endif /* CONFIG_PCI */
17111                 default:
17112                         ASC_PRINT2
17113                             ("advansys_board_found: board %d: unknown adapter type: %d\n",
17114                              boardp->id, asc_dvc_varp->bus_type);
17115                         shost->unchecked_isa_dma = TRUE;
17116                         share_irq = 0;
17117                         break;
17118                 }
17119         } else {
17120                 /*
17121                  * For Wide boards set PCI information before calling
17122                  * AdvInitGetConfig().
17123                  */
17124 #ifdef CONFIG_PCI
17125                 shost->irq = adv_dvc_varp->irq_no = pdev->irq;
17126                 shost->unchecked_isa_dma = FALSE;
17127                 share_irq = IRQF_SHARED;
17128 #endif /* CONFIG_PCI */
17129         }
17130
17131         /*
17132          * Read the board configuration.
17133          */
17134         if (ASC_NARROW_BOARD(boardp)) {
17135                 /*
17136                  * NOTE: AscInitGetConfig() may change the board's
17137                  * bus_type value. The bus_type value should no
17138                  * longer be used. If the bus_type field must be
17139                  * referenced only use the bit-wise AND operator "&".
17140                  */
17141                 ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n");
17142                 switch (ret = AscInitGetConfig(asc_dvc_varp)) {
17143                 case 0: /* No error */
17144                         break;
17145                 case ASC_WARN_IO_PORT_ROTATE:
17146                         ASC_PRINT1
17147                             ("AscInitGetConfig: board %d: I/O port address modified\n",
17148                              boardp->id);
17149                         break;
17150                 case ASC_WARN_AUTO_CONFIG:
17151                         ASC_PRINT1
17152                             ("AscInitGetConfig: board %d: I/O port increment switch enabled\n",
17153                              boardp->id);
17154                         break;
17155                 case ASC_WARN_EEPROM_CHKSUM:
17156                         ASC_PRINT1
17157                             ("AscInitGetConfig: board %d: EEPROM checksum error\n",
17158                              boardp->id);
17159                         break;
17160                 case ASC_WARN_IRQ_MODIFIED:
17161                         ASC_PRINT1
17162                             ("AscInitGetConfig: board %d: IRQ modified\n",
17163                              boardp->id);
17164                         break;
17165                 case ASC_WARN_CMD_QNG_CONFLICT:
17166                         ASC_PRINT1
17167                             ("AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
17168                              boardp->id);
17169                         break;
17170                 default:
17171                         ASC_PRINT2
17172                             ("AscInitGetConfig: board %d: unknown warning: 0x%x\n",
17173                              boardp->id, ret);
17174                         break;
17175                 }
17176                 if ((err_code = asc_dvc_varp->err_code) != 0) {
17177                         ASC_PRINT3
17178                             ("AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
17179                              boardp->id,
17180                              asc_dvc_varp->init_state, asc_dvc_varp->err_code);
17181                 }
17182         } else {
17183                 ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n");
17184
17185                 ret = AdvInitGetConfig(pdev, adv_dvc_varp);
17186                 if (ret != 0) {
17187                         ASC_PRINT2
17188                             ("AdvInitGetConfig: board %d: warning: 0x%x\n",
17189                              boardp->id, ret);
17190                 }
17191                 if ((err_code = adv_dvc_varp->err_code) != 0) {
17192                         ASC_PRINT2
17193                             ("AdvInitGetConfig: board %d error: err_code 0x%x\n",
17194                              boardp->id, adv_dvc_varp->err_code);
17195                 }
17196         }
17197
17198         if (err_code != 0)
17199                 goto err_free_proc;
17200
17201         /*
17202          * Save the EEPROM configuration so that it can be displayed
17203          * from /proc/scsi/advansys/[0...].
17204          */
17205         if (ASC_NARROW_BOARD(boardp)) {
17206
17207                 ASCEEP_CONFIG *ep;
17208
17209                 /*
17210                  * Set the adapter's target id bit in the 'init_tidmask' field.
17211                  */
17212                 boardp->init_tidmask |=
17213                     ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
17214
17215                 /*
17216                  * Save EEPROM settings for the board.
17217                  */
17218                 ep = &boardp->eep_config.asc_eep;
17219
17220                 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
17221                 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
17222                 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
17223                 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
17224                 ep->start_motor = asc_dvc_varp->start_motor;
17225                 ep->cntl = asc_dvc_varp->dvc_cntl;
17226                 ep->no_scam = asc_dvc_varp->no_scam;
17227                 ep->max_total_qng = asc_dvc_varp->max_total_qng;
17228                 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
17229                 /* 'max_tag_qng' is set to the same value for every device. */
17230                 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
17231                 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
17232                 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
17233                 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
17234                 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
17235                 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
17236                 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
17237
17238                 /*
17239                  * Modify board configuration.
17240                  */
17241                 ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n");
17242                 switch (ret = AscInitSetConfig(pdev, asc_dvc_varp)) {
17243                 case 0: /* No error. */
17244                         break;
17245                 case ASC_WARN_IO_PORT_ROTATE:
17246                         ASC_PRINT1
17247                             ("AscInitSetConfig: board %d: I/O port address modified\n",
17248                              boardp->id);
17249                         break;
17250                 case ASC_WARN_AUTO_CONFIG:
17251                         ASC_PRINT1
17252                             ("AscInitSetConfig: board %d: I/O port increment switch enabled\n",
17253                              boardp->id);
17254                         break;
17255                 case ASC_WARN_EEPROM_CHKSUM:
17256                         ASC_PRINT1
17257                             ("AscInitSetConfig: board %d: EEPROM checksum error\n",
17258                              boardp->id);
17259                         break;
17260                 case ASC_WARN_IRQ_MODIFIED:
17261                         ASC_PRINT1
17262                             ("AscInitSetConfig: board %d: IRQ modified\n",
17263                              boardp->id);
17264                         break;
17265                 case ASC_WARN_CMD_QNG_CONFLICT:
17266                         ASC_PRINT1
17267                             ("AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
17268                              boardp->id);
17269                         break;
17270                 default:
17271                         ASC_PRINT2
17272                             ("AscInitSetConfig: board %d: unknown warning: 0x%x\n",
17273                              boardp->id, ret);
17274                         break;
17275                 }
17276                 if (asc_dvc_varp->err_code != 0) {
17277                         ASC_PRINT3
17278                             ("AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
17279                              boardp->id,
17280                              asc_dvc_varp->init_state, asc_dvc_varp->err_code);
17281                         goto err_free_proc;
17282                 }
17283
17284                 /*
17285                  * Finish initializing the 'Scsi_Host' structure.
17286                  */
17287                 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
17288                 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
17289                         shost->irq = asc_dvc_varp->irq_no;
17290                 }
17291         } else {
17292                 ADVEEP_3550_CONFIG *ep_3550;
17293                 ADVEEP_38C0800_CONFIG *ep_38C0800;
17294                 ADVEEP_38C1600_CONFIG *ep_38C1600;
17295
17296                 /*
17297                  * Save Wide EEP Configuration Information.
17298                  */
17299                 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
17300                         ep_3550 = &boardp->eep_config.adv_3550_eep;
17301
17302                         ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
17303                         ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
17304                         ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
17305                         ep_3550->termination = adv_dvc_varp->cfg->termination;
17306                         ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
17307                         ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
17308                         ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
17309                         ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
17310                         ep_3550->ultra_able = adv_dvc_varp->ultra_able;
17311                         ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
17312                         ep_3550->start_motor = adv_dvc_varp->start_motor;
17313                         ep_3550->scsi_reset_delay =
17314                             adv_dvc_varp->scsi_reset_wait;
17315                         ep_3550->serial_number_word1 =
17316                             adv_dvc_varp->cfg->serial1;
17317                         ep_3550->serial_number_word2 =
17318                             adv_dvc_varp->cfg->serial2;
17319                         ep_3550->serial_number_word3 =
17320                             adv_dvc_varp->cfg->serial3;
17321                 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
17322                         ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
17323
17324                         ep_38C0800->adapter_scsi_id =
17325                             adv_dvc_varp->chip_scsi_id;
17326                         ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
17327                         ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
17328                         ep_38C0800->termination_lvd =
17329                             adv_dvc_varp->cfg->termination;
17330                         ep_38C0800->disc_enable =
17331                             adv_dvc_varp->cfg->disc_enable;
17332                         ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
17333                         ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
17334                         ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
17335                         ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
17336                         ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
17337                         ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
17338                         ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
17339                         ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
17340                         ep_38C0800->start_motor = adv_dvc_varp->start_motor;
17341                         ep_38C0800->scsi_reset_delay =
17342                             adv_dvc_varp->scsi_reset_wait;
17343                         ep_38C0800->serial_number_word1 =
17344                             adv_dvc_varp->cfg->serial1;
17345                         ep_38C0800->serial_number_word2 =
17346                             adv_dvc_varp->cfg->serial2;
17347                         ep_38C0800->serial_number_word3 =
17348                             adv_dvc_varp->cfg->serial3;
17349                 } else {
17350                         ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
17351
17352                         ep_38C1600->adapter_scsi_id =
17353                             adv_dvc_varp->chip_scsi_id;
17354                         ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
17355                         ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
17356                         ep_38C1600->termination_lvd =
17357                             adv_dvc_varp->cfg->termination;
17358                         ep_38C1600->disc_enable =
17359                             adv_dvc_varp->cfg->disc_enable;
17360                         ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
17361                         ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
17362                         ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
17363                         ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
17364                         ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
17365                         ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
17366                         ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
17367                         ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
17368                         ep_38C1600->start_motor = adv_dvc_varp->start_motor;
17369                         ep_38C1600->scsi_reset_delay =
17370                             adv_dvc_varp->scsi_reset_wait;
17371                         ep_38C1600->serial_number_word1 =
17372                             adv_dvc_varp->cfg->serial1;
17373                         ep_38C1600->serial_number_word2 =
17374                             adv_dvc_varp->cfg->serial2;
17375                         ep_38C1600->serial_number_word3 =
17376                             adv_dvc_varp->cfg->serial3;
17377                 }
17378
17379                 /*
17380                  * Set the adapter's target id bit in the 'init_tidmask' field.
17381                  */
17382                 boardp->init_tidmask |=
17383                     ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
17384         }
17385
17386         /*
17387          * Channels are numbered beginning with 0. For AdvanSys one host
17388          * structure supports one channel. Multi-channel boards have a
17389          * separate host structure for each channel.
17390          */
17391         shost->max_channel = 0;
17392         if (ASC_NARROW_BOARD(boardp)) {
17393                 shost->max_id = ASC_MAX_TID + 1;
17394                 shost->max_lun = ASC_MAX_LUN + 1;
17395
17396                 shost->io_port = asc_dvc_varp->iop_base;
17397                 boardp->asc_n_io_port = ASC_IOADR_GAP;
17398                 shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
17399
17400                 /* Set maximum number of queues the adapter can handle. */
17401                 shost->can_queue = asc_dvc_varp->max_total_qng;
17402         } else {
17403                 shost->max_id = ADV_MAX_TID + 1;
17404                 shost->max_lun = ADV_MAX_LUN + 1;
17405
17406                 /*
17407                  * Save the I/O Port address and length even though
17408                  * I/O ports are not used to access Wide boards.
17409                  * Instead the Wide boards are accessed with
17410                  * PCI Memory Mapped I/O.
17411                  */
17412                 shost->io_port = iop;
17413
17414                 shost->this_id = adv_dvc_varp->chip_scsi_id;
17415
17416                 /* Set maximum number of queues the adapter can handle. */
17417                 shost->can_queue = adv_dvc_varp->max_host_qng;
17418         }
17419
17420         /*
17421          * Following v1.3.89, 'cmd_per_lun' is no longer needed
17422          * and should be set to zero.
17423          *
17424          * But because of a bug introduced in v1.3.89 if the driver is
17425          * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
17426          * SCSI function 'allocate_device' will panic. To allow the driver
17427          * to work as a module in these kernels set 'cmd_per_lun' to 1.
17428          *
17429          * Note: This is wrong.  cmd_per_lun should be set to the depth
17430          * you want on untagged devices always.
17431          #ifdef MODULE
17432          */
17433         shost->cmd_per_lun = 1;
17434 /* #else
17435             shost->cmd_per_lun = 0;
17436 #endif */
17437
17438         /*
17439          * Set the maximum number of scatter-gather elements the
17440          * adapter can handle.
17441          */
17442         if (ASC_NARROW_BOARD(boardp)) {
17443                 /*
17444                  * Allow two commands with 'sg_tablesize' scatter-gather
17445                  * elements to be executed simultaneously. This value is
17446                  * the theoretical hardware limit. It may be decreased
17447                  * below.
17448                  */
17449                 shost->sg_tablesize =
17450                     (((asc_dvc_varp->max_total_qng - 2) / 2) *
17451                      ASC_SG_LIST_PER_Q) + 1;
17452         } else {
17453                 shost->sg_tablesize = ADV_MAX_SG_LIST;
17454         }
17455
17456         /*
17457          * The value of 'sg_tablesize' can not exceed the SCSI
17458          * mid-level driver definition of SG_ALL. SG_ALL also
17459          * must not be exceeded, because it is used to define the
17460          * size of the scatter-gather table in 'struct asc_sg_head'.
17461          */
17462         if (shost->sg_tablesize > SG_ALL) {
17463                 shost->sg_tablesize = SG_ALL;
17464         }
17465
17466         ASC_DBG1(1, "advansys_board_found: sg_tablesize: %d\n", shost->sg_tablesize);
17467
17468         /* BIOS start address. */
17469         if (ASC_NARROW_BOARD(boardp)) {
17470                 shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
17471                                                     asc_dvc_varp->bus_type);
17472         } else {
17473                 /*
17474                  * Fill-in BIOS board variables. The Wide BIOS saves
17475                  * information in LRAM that is used by the driver.
17476                  */
17477                 AdvReadWordLram(adv_dvc_varp->iop_base,
17478                                 BIOS_SIGNATURE, boardp->bios_signature);
17479                 AdvReadWordLram(adv_dvc_varp->iop_base,
17480                                 BIOS_VERSION, boardp->bios_version);
17481                 AdvReadWordLram(adv_dvc_varp->iop_base,
17482                                 BIOS_CODESEG, boardp->bios_codeseg);
17483                 AdvReadWordLram(adv_dvc_varp->iop_base,
17484                                 BIOS_CODELEN, boardp->bios_codelen);
17485
17486                 ASC_DBG2(1,
17487                          "advansys_board_found: bios_signature 0x%x, bios_version 0x%x\n",
17488                          boardp->bios_signature, boardp->bios_version);
17489
17490                 ASC_DBG2(1,
17491                          "advansys_board_found: bios_codeseg 0x%x, bios_codelen 0x%x\n",
17492                          boardp->bios_codeseg, boardp->bios_codelen);
17493
17494                 /*
17495                  * If the BIOS saved a valid signature, then fill in
17496                  * the BIOS code segment base address.
17497                  */
17498                 if (boardp->bios_signature == 0x55AA) {
17499                         /*
17500                          * Convert x86 realmode code segment to a linear
17501                          * address by shifting left 4.
17502                          */
17503                         shost->base = ((ulong)boardp->bios_codeseg << 4);
17504                 } else {
17505                         shost->base = 0;
17506                 }
17507         }
17508
17509         /*
17510          * Register Board Resources - I/O Port, DMA, IRQ
17511          */
17512
17513         /* Register DMA Channel for Narrow boards. */
17514         shost->dma_channel = NO_ISA_DMA;        /* Default to no ISA DMA. */
17515 #ifdef CONFIG_ISA
17516         if (ASC_NARROW_BOARD(boardp)) {
17517                 /* Register DMA channel for ISA bus. */
17518                 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
17519                         shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
17520                         ret = request_dma(shost->dma_channel, "advansys");
17521                         if (ret) {
17522                                 ASC_PRINT3
17523                                     ("advansys_board_found: board %d: request_dma() %d failed %d\n",
17524                                      boardp->id, shost->dma_channel, ret);
17525                                 goto err_free_proc;
17526                         }
17527                         AscEnableIsaDma(shost->dma_channel);
17528                 }
17529         }
17530 #endif /* CONFIG_ISA */
17531
17532         /* Register IRQ Number. */
17533         ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", shost->irq);
17534
17535         ret = request_irq(shost->irq, advansys_interrupt, share_irq,
17536                           "advansys", shost);
17537
17538         if (ret) {
17539                 if (ret == -EBUSY) {
17540                         ASC_PRINT2
17541                             ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n",
17542                              boardp->id, shost->irq);
17543                 } else if (ret == -EINVAL) {
17544                         ASC_PRINT2
17545                             ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n",
17546                              boardp->id, shost->irq);
17547                 } else {
17548                         ASC_PRINT3
17549                             ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n",
17550                              boardp->id, shost->irq, ret);
17551                 }
17552                 goto err_free_dma;
17553         }
17554
17555         /*
17556          * Initialize board RISC chip and enable interrupts.
17557          */
17558         if (ASC_NARROW_BOARD(boardp)) {
17559                 ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n");
17560                 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
17561                 err_code = asc_dvc_varp->err_code;
17562
17563                 if (warn_code || err_code) {
17564                         ASC_PRINT4
17565                             ("advansys_board_found: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
17566                              boardp->id,
17567                              asc_dvc_varp->init_state, warn_code, err_code);
17568                 }
17569         } else {
17570                 err_code = advansys_wide_init_chip(boardp, adv_dvc_varp);
17571         }
17572
17573         if (err_code != 0)
17574                 goto err_free_wide_mem;
17575
17576         ASC_DBG_PRT_SCSI_HOST(2, shost);
17577
17578         ret = scsi_add_host(shost, dev);
17579         if (ret)
17580                 goto err_free_wide_mem;
17581
17582         scsi_scan_host(shost);
17583         return shost;
17584
17585  err_free_wide_mem:
17586         advansys_wide_free_mem(boardp);
17587         free_irq(shost->irq, shost);
17588  err_free_dma:
17589         if (shost->dma_channel != NO_ISA_DMA)
17590                 free_dma(shost->dma_channel);
17591  err_free_proc:
17592         kfree(boardp->prtbuf);
17593  err_unmap:
17594         if (boardp->ioremap_addr)
17595                 iounmap(boardp->ioremap_addr);
17596  err_shost:
17597         scsi_host_put(shost);
17598         return NULL;
17599 }
17600
17601 /*
17602  * advansys_release()
17603  *
17604  * Release resources allocated for a single AdvanSys adapter.
17605  */
17606 static int advansys_release(struct Scsi_Host *shost)
17607 {
17608         asc_board_t *boardp;
17609
17610         ASC_DBG(1, "advansys_release: begin\n");
17611         scsi_remove_host(shost);
17612         boardp = ASC_BOARDP(shost);
17613         free_irq(shost->irq, shost);
17614         if (shost->dma_channel != NO_ISA_DMA) {
17615                 ASC_DBG(1, "advansys_release: free_dma()\n");
17616                 free_dma(shost->dma_channel);
17617         }
17618         if (ASC_WIDE_BOARD(boardp)) {
17619                 iounmap(boardp->ioremap_addr);
17620                 advansys_wide_free_mem(boardp);
17621         }
17622         kfree(boardp->prtbuf);
17623         scsi_host_put(shost);
17624         ASC_DBG(1, "advansys_release: end\n");
17625         return 0;
17626 }
17627
17628 static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = {
17629         0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
17630         0x0210, 0x0230, 0x0250, 0x0330
17631 };
17632
17633 static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
17634 {
17635         PortAddr iop_base = _asc_def_iop_base[id];
17636         struct Scsi_Host *shost;
17637
17638         if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
17639                 ASC_DBG1(1, "advansys_isa_match: I/O port 0x%x busy\n",
17640                          iop_base);
17641                 return -ENODEV;
17642         }
17643         ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base);
17644         if (!AscFindSignature(iop_base))
17645                 goto nodev;
17646         if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
17647                 goto nodev;
17648
17649         shost = advansys_board_found(iop_base, dev, ASC_IS_ISA);
17650         if (!shost)
17651                 goto nodev;
17652
17653         dev_set_drvdata(dev, shost);
17654         return 0;
17655
17656  nodev:
17657         release_region(iop_base, ASC_IOADR_GAP);
17658         return -ENODEV;
17659 }
17660
17661 static int __devexit advansys_isa_remove(struct device *dev, unsigned int id)
17662 {
17663         int ioport = _asc_def_iop_base[id];
17664         advansys_release(dev_get_drvdata(dev));
17665         release_region(ioport, ASC_IOADR_GAP);
17666         return 0;
17667 }
17668
17669 static struct isa_driver advansys_isa_driver = {
17670         .probe          = advansys_isa_probe,
17671         .remove         = __devexit_p(advansys_isa_remove),
17672         .driver = {
17673                 .owner  = THIS_MODULE,
17674                 .name   = "advansys",
17675         },
17676 };
17677
17678 static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
17679 {
17680         PortAddr iop_base = _asc_def_iop_base[id];
17681         struct Scsi_Host *shost;
17682
17683         if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
17684                 ASC_DBG1(1, "advansys_vlb_match: I/O port 0x%x busy\n",
17685                          iop_base);
17686                 return -ENODEV;
17687         }
17688         ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base);
17689         if (!AscFindSignature(iop_base))
17690                 goto nodev;
17691         /*
17692          * I don't think this condition can actually happen, but the old
17693          * driver did it, and the chances of finding a VLB setup in 2007
17694          * to do testing with is slight to none.
17695          */
17696         if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
17697                 goto nodev;
17698
17699         shost = advansys_board_found(iop_base, dev, ASC_IS_VL);
17700         if (!shost)
17701                 goto nodev;
17702
17703         dev_set_drvdata(dev, shost);
17704         return 0;
17705
17706  nodev:
17707         release_region(iop_base, ASC_IOADR_GAP);
17708         return -ENODEV;
17709 }
17710
17711 static struct isa_driver advansys_vlb_driver = {
17712         .probe          = advansys_vlb_probe,
17713         .remove         = __devexit_p(advansys_isa_remove),
17714         .driver = {
17715                 .owner  = THIS_MODULE,
17716                 .name   = "advansys",
17717         },
17718 };
17719
17720 static struct eisa_device_id advansys_eisa_table[] __devinitdata = {
17721         { "ABP7401" },
17722         { "ABP7501" },
17723         { "" }
17724 };
17725
17726 MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
17727
17728 /*
17729  * EISA is a little more tricky than PCI; each EISA device may have two
17730  * channels, and this driver is written to make each channel its own Scsi_Host
17731  */
17732 struct eisa_scsi_data {
17733         struct Scsi_Host *host[2];
17734 };
17735
17736 static int __devinit advansys_eisa_probe(struct device *dev)
17737 {
17738         int i, ioport;
17739         int err;
17740         struct eisa_device *edev = to_eisa_device(dev);
17741         struct eisa_scsi_data *data;
17742
17743         err = -ENOMEM;
17744         data = kzalloc(sizeof(*data), GFP_KERNEL);
17745         if (!data)
17746                 goto fail;
17747         ioport = edev->base_addr + 0xc30;
17748
17749         err = -ENODEV;
17750         for (i = 0; i < 2; i++, ioport += 0x20) {
17751                 if (!request_region(ioport, ASC_IOADR_GAP, "advansys")) {
17752                         printk(KERN_WARNING "Region %x-%x busy\n", ioport,
17753                                ioport + ASC_IOADR_GAP - 1);
17754                         continue;
17755                 }
17756                 if (!AscFindSignature(ioport)) {
17757                         release_region(ioport, ASC_IOADR_GAP);
17758                         continue;
17759                 }
17760
17761                 /*
17762                  * I don't know why we need to do this for EISA chips, but
17763                  * not for any others.  It looks to be equivalent to
17764                  * AscGetChipCfgMsw, but I may have overlooked something,
17765                  * so I'm not converting it until I get an EISA board to
17766                  * test with.
17767                  */
17768                 inw(ioport + 4);
17769                 data->host[i] = advansys_board_found(ioport, dev, ASC_IS_EISA);
17770                 if (data->host[i]) {
17771                         err = 0;
17772                 } else {
17773                         release_region(ioport, ASC_IOADR_GAP);
17774                 }
17775         }
17776
17777         if (err) {
17778                 kfree(data);
17779         } else {
17780                 dev_set_drvdata(dev, data);
17781         }
17782
17783  fail:
17784         return err;
17785 }
17786
17787 static __devexit int advansys_eisa_remove(struct device *dev)
17788 {
17789         int i;
17790         struct eisa_scsi_data *data = dev_get_drvdata(dev);
17791
17792         for (i = 0; i < 2; i++) {
17793                 int ioport;
17794                 struct Scsi_Host *shost = data->host[i];
17795                 if (!shost)
17796                         continue;
17797                 ioport = shost->io_port;
17798                 advansys_release(shost);
17799                 release_region(ioport, ASC_IOADR_GAP);
17800         }
17801
17802         kfree(data);
17803         return 0;
17804 }
17805
17806 static struct eisa_driver advansys_eisa_driver = {
17807         .id_table =             advansys_eisa_table,
17808         .driver = {
17809                 .name =         "advansys",
17810                 .probe =        advansys_eisa_probe,
17811                 .remove =       __devexit_p(advansys_eisa_remove),
17812         }
17813 };
17814
17815 /* PCI Devices supported by this driver */
17816 static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
17817         {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
17818          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
17819         {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
17820          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
17821         {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
17822          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
17823         {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
17824          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
17825         {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
17826          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
17827         {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
17828          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
17829         {}
17830 };
17831
17832 MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
17833
17834 static void __devinit advansys_set_latency(struct pci_dev *pdev)
17835 {
17836         if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
17837             (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
17838                 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0);
17839         } else {
17840                 u8 latency;
17841                 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
17842                 if (latency < 0x20)
17843                         pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x20);
17844         }
17845 }
17846
17847 static int __devinit
17848 advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
17849 {
17850         int err, ioport;
17851         struct Scsi_Host *shost;
17852
17853         err = pci_enable_device(pdev);
17854         if (err)
17855                 goto fail;
17856         err = pci_request_regions(pdev, "advansys");
17857         if (err)
17858                 goto disable_device;
17859         pci_set_master(pdev);
17860         advansys_set_latency(pdev);
17861
17862         if (pci_resource_len(pdev, 0) == 0)
17863                 goto nodev;
17864
17865         ioport = pci_resource_start(pdev, 0);
17866         shost = advansys_board_found(ioport, &pdev->dev, ASC_IS_PCI);
17867
17868         if (!shost)
17869                 goto nodev;
17870
17871         pci_set_drvdata(pdev, shost);
17872         return 0;
17873
17874  nodev:
17875         err = -ENODEV;
17876         pci_release_regions(pdev);
17877  disable_device:
17878         pci_disable_device(pdev);
17879  fail:
17880         return err;
17881 }
17882
17883 static void __devexit advansys_pci_remove(struct pci_dev *pdev)
17884 {
17885         advansys_release(pci_get_drvdata(pdev));
17886         pci_release_regions(pdev);
17887         pci_disable_device(pdev);
17888 }
17889
17890 static struct pci_driver advansys_pci_driver = {
17891         .name =         "advansys",
17892         .id_table =     advansys_pci_tbl,
17893         .probe =        advansys_pci_probe,
17894         .remove =       __devexit_p(advansys_pci_remove),
17895 };
17896
17897 static int __init advansys_init(void)
17898 {
17899         int error;
17900
17901         error = isa_register_driver(&advansys_isa_driver,
17902                                     ASC_IOADR_TABLE_MAX_IX);
17903         if (error)
17904                 goto fail;
17905
17906         error = isa_register_driver(&advansys_vlb_driver,
17907                                     ASC_IOADR_TABLE_MAX_IX);
17908         if (error)
17909                 goto unregister_isa;
17910
17911         error = eisa_driver_register(&advansys_eisa_driver);
17912         if (error)
17913                 goto unregister_vlb;
17914
17915         error = pci_register_driver(&advansys_pci_driver);
17916         if (error)
17917                 goto unregister_eisa;
17918
17919         return 0;
17920
17921  unregister_eisa:
17922         eisa_driver_unregister(&advansys_eisa_driver);
17923  unregister_vlb:
17924         isa_unregister_driver(&advansys_vlb_driver);
17925  unregister_isa:
17926         isa_unregister_driver(&advansys_isa_driver);
17927  fail:
17928         return error;
17929 }
17930
17931 static void __exit advansys_exit(void)
17932 {
17933         pci_unregister_driver(&advansys_pci_driver);
17934         eisa_driver_unregister(&advansys_eisa_driver);
17935         isa_unregister_driver(&advansys_vlb_driver);
17936         isa_unregister_driver(&advansys_isa_driver);
17937 }
17938
17939 module_init(advansys_init);
17940 module_exit(advansys_exit);
17941
17942 MODULE_LICENSE("GPL");